I'm trying to do a RRSIG
validation, I'm trying to use the openssl lib in PHP. But I'm having a problem to pass the public key to the openssl_verify
function.
This is a base code, using the Net/DNS2 library to do a DNS query with DNSSEC option. and get the DNSKEY and RRSIG.
<?php
require_once 'Net/DNS2.php';
$r = new Net_DNS2_Resolver(array('nameservers' => array('127.0.0.1')));
$r->dnssec = true;
try {
$result = $r->query('ip4afrika.nl', 'DNSKEY');
} catch(Net_DNS2_Exception $e) {
echo "::query() failed: ", $e->getMessage(), "\n";
die(); //
}
// print_r($result->answer);
$public_key_bin = base64_decode( $result->answer[0]->key ) ;
$public_key_str = $result->answer[0]->key; //echo $public_key_str; die();
// $public_key_res = openssl_x509_parse($public_key_bin);
$public_key_res = openssl_x509_read($public_key_str);
// $public_key_res = openssl_pkey_get_public($public_key_str);
while ($msg = openssl_error_string()) echo $msg . PHP_EOL;
I get this error messages,
when using:
$public_key_res = openssl_x509_read($public_key_str);
PHP Warning: openssl_x509_read(): supplied parameter cannot be
coerced into an X509 certificate! in /src/Net_DNS2-1.4.3/i.php on line
34 PHP Stack trace: PHP 1. {main}() /src/Net_DNS2-1.4.3/i.php:0 PHP
2. openssl_x509_read() /src/Net_DNS2-1.4.3/i.php:34 error:0906D06C:PEM routines:PEM_read_bio:no start line
so i tried adding the BEGIN/END headers
$public_key_str = '-----BEGIN CERTIFICATE-----' . PHP_EOL . $result->answer[0]->key . PHP_EOL . '-----END CERTIFICATE-----' ;
And got this error messages,
error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag
error:0D07803A:asn1 encoding routines:ASN1_ITEM_EX_D2I:nested asn1 error
error:0906700D:PEM routines:PEM_ASN1_read_bio:ASN1 lib
So it seems I'm feeding the function the wrong format, I'm still googling but any help would be welcome.
Eventually I like to validate the signature with:
openssl_verify($data, $signature, $public_key_res, 'RSA-SHA256');
Short answer:
If you just need the capability in PHP, you can just use https://github.com/metaregistrar/php-dnssec-validator .
Long Answer:
The reason you can't load the KEY data is because it's in a slightly different format. According to rfc3110:
Field Size
----- ----
exponent length 1 or 3 octets (see text)
exponent as specified by length field
modulus remaining space
Whereas RSA public keys are a bit more complex -- aside from the exponent and modulus, you need to prefix it with the correct OID as such (2nd answer).
After that the process is a bit gnarly:
Get the RRSIG record to get the signature and key tag (to determine which key to use)
Use the public keys from the correct DNSKEY RR to verify the signature against.
There's also a process described here (in python)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With