2 * validator/val_secalgo.c - validator security algorithm functions.
4 * Copyright (c) 2012, NLnet Labs. All rights reserved.
6 * This software is open source.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
15 * Redistributions in binary form must reproduce the above copyright notice,
16 * this list of conditions and the following disclaimer in the documentation
17 * and/or other materials provided with the distribution.
19 * Neither the name of the NLNET LABS nor the names of its contributors may
20 * be used to endorse or promote products derived from this software without
21 * specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
29 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 * This file contains helper functions for the validator module.
40 * These functions take raw data buffers, formatted for crypto verification,
41 * and do the library calls (for the crypto library in use).
44 /* packed_rrset on top to define enum types (forced by c99 standard) */
45 #include "util/data/packed_rrset.h"
46 #include "validator/val_secalgo.h"
48 #include "ldns/rrdef.h"
49 #include "ldns/keyraw.h"
50 #include "ldns/sbuffer.h"
52 #if !defined(HAVE_SSL) && !defined(HAVE_NSS)
53 #error "Need crypto library to do digital signature cryptography"
56 /* OpenSSL implementation */
58 #ifdef HAVE_OPENSSL_ERR_H
59 #include <openssl/err.h>
62 #ifdef HAVE_OPENSSL_RAND_H
63 #include <openssl/rand.h>
66 #ifdef HAVE_OPENSSL_CONF_H
67 #include <openssl/conf.h>
70 #ifdef HAVE_OPENSSL_ENGINE_H
71 #include <openssl/engine.h>
75 * Return size of DS digest according to its hash algorithm.
76 * @param algo: DS digest algo.
77 * @return size in bytes of digest, or 0 if not supported.
80 ds_digest_size_supported(int algo)
85 return SHA_DIGEST_LENGTH;
87 #ifdef HAVE_EVP_SHA256
89 return SHA256_DIGEST_LENGTH;
93 if(EVP_get_digestbyname("md_gost94"))
99 return SHA384_DIGEST_LENGTH;
107 /** Perform GOST hash */
109 do_gost94(unsigned char* data, size_t len, unsigned char* dest)
111 const EVP_MD* md = EVP_get_digestbyname("md_gost94");
114 return sldns_digest_evp(data, (unsigned int)len, dest, md);
119 secalgo_ds_digest(int algo, unsigned char* buf, size_t len,
125 (void)SHA1(buf, len, res);
128 #ifdef HAVE_EVP_SHA256
130 (void)SHA256(buf, len, res);
135 if(do_gost94(buf, len, res))
141 (void)SHA384(buf, len, res);
145 verbose(VERB_QUERY, "unknown DS digest algorithm %d",
152 /** return true if DNSKEY algorithm id is supported */
154 dnskey_algo_id_is_supported(int id)
158 /* RFC 6725 deprecates RSAMD5 */
163 case LDNS_RSASHA1_NSEC3:
164 #if defined(HAVE_EVP_SHA256) && defined(USE_SHA2)
167 #if defined(HAVE_EVP_SHA512) && defined(USE_SHA2)
171 case LDNS_ECDSAP256SHA256:
172 case LDNS_ECDSAP384SHA384:
177 /* we support GOST if it can be loaded */
178 return sldns_key_EVP_load_gost_id();
186 * Output a libcrypto openssl error to the logfile.
187 * @param str: string to add to it.
188 * @param e: the error to output, error number from ERR_get_error().
191 log_crypto_error(const char* str, unsigned long e)
194 /* or use ERR_error_string if ERR_error_string_n is not avail TODO */
195 ERR_error_string_n(e, buf, sizeof(buf));
196 /* buf now contains */
197 /* error:[error code]:[library name]:[function name]:[reason string] */
198 log_err("%s crypto %s", str, buf);
202 * Setup DSA key digest in DER encoding ...
203 * @param sig: input is signature output alloced ptr (unless failure).
204 * caller must free alloced ptr if this routine returns true.
205 * @param len: input is initial siglen, output is output len.
206 * @return false on failure.
209 setup_dsa_sig(unsigned char** sig, unsigned int* len)
211 unsigned char* orig = *sig;
212 unsigned int origlen = *len;
217 /* extract the R and S field from the sig buffer */
218 if(origlen < 1 + 2*SHA_DIGEST_LENGTH)
222 (void) BN_bin2bn(orig + 1, SHA_DIGEST_LENGTH, R);
225 (void) BN_bin2bn(orig + 21, SHA_DIGEST_LENGTH, S);
226 dsasig = DSA_SIG_new();
227 if(!dsasig) return 0;
232 newlen = i2d_DSA_SIG(dsasig, sig);
234 DSA_SIG_free(dsasig);
238 *len = (unsigned int)newlen;
239 DSA_SIG_free(dsasig);
245 * Setup the ECDSA signature in its encoding that the library wants.
246 * Converts from plain numbers to ASN formatted.
247 * @param sig: input is signature, output alloced ptr (unless failure).
248 * caller must free alloced ptr if this routine returns true.
249 * @param len: input is initial siglen, output is output len.
250 * @return false on failure.
253 setup_ecdsa_sig(unsigned char** sig, unsigned int* len)
255 ECDSA_SIG* ecdsa_sig;
257 int bnsize = (int)((*len)/2);
258 /* if too short or not even length, fails */
259 if(*len < 16 || bnsize*2 != (int)*len)
261 /* use the raw data to parse two evenly long BIGNUMs, "r | s". */
262 ecdsa_sig = ECDSA_SIG_new();
263 if(!ecdsa_sig) return 0;
264 ecdsa_sig->r = BN_bin2bn(*sig, bnsize, ecdsa_sig->r);
265 ecdsa_sig->s = BN_bin2bn(*sig+bnsize, bnsize, ecdsa_sig->s);
266 if(!ecdsa_sig->r || !ecdsa_sig->s) {
267 ECDSA_SIG_free(ecdsa_sig);
271 /* spool it into ASN format */
273 newlen = i2d_ECDSA_SIG(ecdsa_sig, sig);
275 ECDSA_SIG_free(ecdsa_sig);
279 *len = (unsigned int)newlen;
280 ECDSA_SIG_free(ecdsa_sig);
283 #endif /* USE_ECDSA */
286 * Setup key and digest for verification. Adjust sig if necessary.
288 * @param algo: key algorithm
289 * @param evp_key: EVP PKEY public key to create.
290 * @param digest_type: digest type to use
291 * @param key: key to setup for.
292 * @param keylen: length of key.
293 * @return false on failure.
296 setup_key_digest(int algo, EVP_PKEY** evp_key, const EVP_MD** digest_type,
297 unsigned char* key, size_t keylen)
305 *evp_key = EVP_PKEY_new();
307 log_err("verify: malloc failure in crypto");
310 dsa = sldns_key_buf2dsa_raw(key, keylen);
312 verbose(VERB_QUERY, "verify: "
313 "sldns_key_buf2dsa_raw failed");
316 if(EVP_PKEY_assign_DSA(*evp_key, dsa) == 0) {
317 verbose(VERB_QUERY, "verify: "
318 "EVP_PKEY_assign_DSA failed");
321 *digest_type = EVP_dss1();
325 case LDNS_RSASHA1_NSEC3:
326 #if defined(HAVE_EVP_SHA256) && defined(USE_SHA2)
329 #if defined(HAVE_EVP_SHA512) && defined(USE_SHA2)
332 *evp_key = EVP_PKEY_new();
334 log_err("verify: malloc failure in crypto");
337 rsa = sldns_key_buf2rsa_raw(key, keylen);
339 verbose(VERB_QUERY, "verify: "
340 "sldns_key_buf2rsa_raw SHA failed");
343 if(EVP_PKEY_assign_RSA(*evp_key, rsa) == 0) {
344 verbose(VERB_QUERY, "verify: "
345 "EVP_PKEY_assign_RSA SHA failed");
349 /* select SHA version */
350 #if defined(HAVE_EVP_SHA256) && defined(USE_SHA2)
351 if(algo == LDNS_RSASHA256)
352 *digest_type = EVP_sha256();
355 #if defined(HAVE_EVP_SHA512) && defined(USE_SHA2)
356 if(algo == LDNS_RSASHA512)
357 *digest_type = EVP_sha512();
360 *digest_type = EVP_sha1();
364 *evp_key = EVP_PKEY_new();
366 log_err("verify: malloc failure in crypto");
369 rsa = sldns_key_buf2rsa_raw(key, keylen);
371 verbose(VERB_QUERY, "verify: "
372 "sldns_key_buf2rsa_raw MD5 failed");
375 if(EVP_PKEY_assign_RSA(*evp_key, rsa) == 0) {
376 verbose(VERB_QUERY, "verify: "
377 "EVP_PKEY_assign_RSA MD5 failed");
380 *digest_type = EVP_md5();
385 *evp_key = sldns_gost2pkey_raw(key, keylen);
387 verbose(VERB_QUERY, "verify: "
388 "sldns_gost2pkey_raw failed");
391 *digest_type = EVP_get_digestbyname("md_gost94");
393 verbose(VERB_QUERY, "verify: "
394 "EVP_getdigest md_gost94 failed");
400 case LDNS_ECDSAP256SHA256:
401 *evp_key = sldns_ecdsa2pkey_raw(key, keylen,
402 LDNS_ECDSAP256SHA256);
404 verbose(VERB_QUERY, "verify: "
405 "sldns_ecdsa2pkey_raw failed");
408 #ifdef USE_ECDSA_EVP_WORKAROUND
409 /* openssl before 1.0.0 fixes RSA with the SHA256
410 * hash in EVP. We create one for ecdsa_sha256 */
412 static int md_ecdsa_256_done = 0;
414 if(!md_ecdsa_256_done) {
415 EVP_MD m = *EVP_sha256();
416 md_ecdsa_256_done = 1;
417 m.required_pkey_type[0] = (*evp_key)->type;
418 m.verify = (void*)ECDSA_verify;
424 *digest_type = EVP_sha256();
427 case LDNS_ECDSAP384SHA384:
428 *evp_key = sldns_ecdsa2pkey_raw(key, keylen,
429 LDNS_ECDSAP384SHA384);
431 verbose(VERB_QUERY, "verify: "
432 "sldns_ecdsa2pkey_raw failed");
435 #ifdef USE_ECDSA_EVP_WORKAROUND
436 /* openssl before 1.0.0 fixes RSA with the SHA384
437 * hash in EVP. We create one for ecdsa_sha384 */
439 static int md_ecdsa_384_done = 0;
441 if(!md_ecdsa_384_done) {
442 EVP_MD m = *EVP_sha384();
443 md_ecdsa_384_done = 1;
444 m.required_pkey_type[0] = (*evp_key)->type;
445 m.verify = (void*)ECDSA_verify;
451 *digest_type = EVP_sha384();
454 #endif /* USE_ECDSA */
456 verbose(VERB_QUERY, "verify: unknown algorithm %d",
464 * Check a canonical sig+rrset and signature against a dnskey
465 * @param buf: buffer with data to verify, the first rrsig part and the
466 * canonicalized rrset.
467 * @param algo: DNSKEY algorithm.
468 * @param sigblock: signature rdata field from RRSIG
469 * @param sigblock_len: length of sigblock data.
470 * @param key: public key data from DNSKEY RR.
471 * @param keylen: length of keydata.
472 * @param reason: bogus reason in more detail.
473 * @return secure if verification succeeded, bogus on crypto failure,
474 * unchecked on format errors and alloc failures.
477 verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock,
478 unsigned int sigblock_len, unsigned char* key, unsigned int keylen,
481 const EVP_MD *digest_type;
484 EVP_PKEY *evp_key = NULL;
486 if(!setup_key_digest(algo, &evp_key, &digest_type, key, keylen)) {
487 verbose(VERB_QUERY, "verify: failed to setup key");
488 *reason = "use of key for crypto failed";
489 EVP_PKEY_free(evp_key);
490 return sec_status_bogus;
492 /* if it is a DSA signature in bind format, convert to DER format */
493 if((algo == LDNS_DSA || algo == LDNS_DSA_NSEC3) &&
494 sigblock_len == 1+2*SHA_DIGEST_LENGTH) {
495 if(!setup_dsa_sig(&sigblock, &sigblock_len)) {
496 verbose(VERB_QUERY, "verify: failed to setup DSA sig");
497 *reason = "use of key for DSA crypto failed";
498 EVP_PKEY_free(evp_key);
499 return sec_status_bogus;
504 else if(algo == LDNS_ECDSAP256SHA256 || algo == LDNS_ECDSAP384SHA384) {
505 /* EVP uses ASN prefix on sig, which is not in the wire data */
506 if(!setup_ecdsa_sig(&sigblock, &sigblock_len)) {
507 verbose(VERB_QUERY, "verify: failed to setup ECDSA sig");
508 *reason = "use of signature for ECDSA crypto failed";
509 EVP_PKEY_free(evp_key);
510 return sec_status_bogus;
514 #endif /* USE_ECDSA */
516 /* do the signature cryptography work */
517 EVP_MD_CTX_init(&ctx);
518 if(EVP_VerifyInit(&ctx, digest_type) == 0) {
519 verbose(VERB_QUERY, "verify: EVP_VerifyInit failed");
520 EVP_PKEY_free(evp_key);
521 if(dofree) free(sigblock);
522 return sec_status_unchecked;
524 if(EVP_VerifyUpdate(&ctx, (unsigned char*)sldns_buffer_begin(buf),
525 (unsigned int)sldns_buffer_limit(buf)) == 0) {
526 verbose(VERB_QUERY, "verify: EVP_VerifyUpdate failed");
527 EVP_PKEY_free(evp_key);
528 if(dofree) free(sigblock);
529 return sec_status_unchecked;
532 res = EVP_VerifyFinal(&ctx, sigblock, sigblock_len, evp_key);
533 if(EVP_MD_CTX_cleanup(&ctx) == 0) {
534 verbose(VERB_QUERY, "verify: EVP_MD_CTX_cleanup failed");
535 EVP_PKEY_free(evp_key);
536 if(dofree) free(sigblock);
537 return sec_status_unchecked;
539 EVP_PKEY_free(evp_key);
545 return sec_status_secure;
546 } else if(res == 0) {
547 verbose(VERB_QUERY, "verify: signature mismatch");
548 *reason = "signature crypto failed";
549 return sec_status_bogus;
552 log_crypto_error("verify:", ERR_get_error());
553 return sec_status_unchecked;
556 /**************************************************/
557 #elif defined(HAVE_NSS)
558 /* libnss implementation */
564 #include "cryptohi.h"
569 ds_digest_size_supported(int algo)
577 return SHA256_LENGTH;
581 return SHA384_LENGTH;
583 /* GOST not supported in NSS */
591 secalgo_ds_digest(int algo, unsigned char* buf, size_t len,
597 return HASH_HashBuf(HASH_AlgSHA1, res, buf, len)
599 #if defined(USE_SHA2)
601 return HASH_HashBuf(HASH_AlgSHA256, res, buf, len)
606 return HASH_HashBuf(HASH_AlgSHA384, res, buf, len)
611 verbose(VERB_QUERY, "unknown DS digest algorithm %d",
619 dnskey_algo_id_is_supported(int id)
624 /* RFC 6725 deprecates RSAMD5 */
629 case LDNS_RSASHA1_NSEC3:
638 case LDNS_ECDSAP256SHA256:
639 case LDNS_ECDSAP384SHA384:
640 return PK11_TokenExists(CKM_ECDSA);
648 /* return a new public key for NSS */
649 static SECKEYPublicKey* nss_key_create(KeyType ktype)
651 SECKEYPublicKey* key;
652 PLArenaPool* arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
654 log_err("out of memory, PORT_NewArena failed");
657 key = PORT_ArenaZNew(arena, SECKEYPublicKey);
659 log_err("out of memory, PORT_ArenaZNew failed");
660 PORT_FreeArena(arena, PR_FALSE);
664 key->keyType = ktype;
665 key->pkcs11Slot = NULL;
666 key->pkcs11ID = CK_INVALID_HANDLE;
670 static SECKEYPublicKey* nss_buf2ecdsa(unsigned char* key, size_t len, int algo)
673 SECItem pub = {siBuffer, NULL, 0};
674 SECItem params = {siBuffer, NULL, 0};
675 static unsigned char param256[] = {
676 /* OBJECTIDENTIFIER 1.2.840.10045.3.1.7 (P-256)
677 * {iso(1) member-body(2) us(840) ansi-x962(10045) curves(3) prime(1) prime256v1(7)} */
678 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07
680 static unsigned char param384[] = {
681 /* OBJECTIDENTIFIER 1.3.132.0.34 (P-384)
682 * {iso(1) identified-organization(3) certicom(132) curve(0) ansip384r1(34)} */
683 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x22
685 unsigned char buf[256+2]; /* sufficient for 2*384/8+1 */
687 /* check length, which uncompressed must be 2 bignums */
688 if(algo == LDNS_ECDSAP256SHA256) {
689 if(len != 2*256/8) return NULL;
690 /* ECCurve_X9_62_PRIME_256V1 */
691 } else if(algo == LDNS_ECDSAP384SHA384) {
692 if(len != 2*384/8) return NULL;
693 /* ECCurve_X9_62_PRIME_384R1 */
696 buf[0] = 0x04; /* POINT_FORM_UNCOMPRESSED */
697 memmove(buf+1, key, len);
700 if(algo == LDNS_ECDSAP256SHA256) {
701 params.data = param256;
702 params.len = sizeof(param256);
704 params.data = param384;
705 params.len = sizeof(param384);
708 pk = nss_key_create(ecKey);
711 pk->u.ec.size = (len/2)*8;
712 if(SECITEM_CopyItem(pk->arena, &pk->u.ec.publicValue, &pub)) {
713 SECKEY_DestroyPublicKey(pk);
716 if(SECITEM_CopyItem(pk->arena, &pk->u.ec.DEREncodedParams, ¶ms)) {
717 SECKEY_DestroyPublicKey(pk);
724 static SECKEYPublicKey* nss_buf2dsa(unsigned char* key, size_t len)
730 SECItem Q = {siBuffer, NULL, 0};
731 SECItem P = {siBuffer, NULL, 0};
732 SECItem G = {siBuffer, NULL, 0};
733 SECItem Y = {siBuffer, NULL, 0};
738 length = (64 + T * 8);
744 if(len < (size_t)1 + SHA1_LENGTH + 3*length)
749 offset += SHA1_LENGTH;
763 pk = nss_key_create(dsaKey);
766 if(SECITEM_CopyItem(pk->arena, &pk->u.dsa.params.prime, &P)) {
767 SECKEY_DestroyPublicKey(pk);
770 if(SECITEM_CopyItem(pk->arena, &pk->u.dsa.params.subPrime, &Q)) {
771 SECKEY_DestroyPublicKey(pk);
774 if(SECITEM_CopyItem(pk->arena, &pk->u.dsa.params.base, &G)) {
775 SECKEY_DestroyPublicKey(pk);
778 if(SECITEM_CopyItem(pk->arena, &pk->u.dsa.publicValue, &Y)) {
779 SECKEY_DestroyPublicKey(pk);
785 static SECKEYPublicKey* nss_buf2rsa(unsigned char* key, size_t len)
791 SECItem modulus = {siBuffer, NULL, 0};
792 SECItem exponent = {siBuffer, NULL, 0};
798 /* the exponent is too large so it's places further */
799 memmove(&int16, key+1, 2);
807 /* key length at least one */
808 if(len < (size_t)offset + exp + 1)
811 exponent.data = key+offset;
814 modulus.data = key+offset;
815 modulus.len = (len - offset);
817 pk = nss_key_create(rsaKey);
820 if(SECITEM_CopyItem(pk->arena, &pk->u.rsa.modulus, &modulus)) {
821 SECKEY_DestroyPublicKey(pk);
824 if(SECITEM_CopyItem(pk->arena, &pk->u.rsa.publicExponent, &exponent)) {
825 SECKEY_DestroyPublicKey(pk);
832 * Setup key and digest for verification. Adjust sig if necessary.
834 * @param algo: key algorithm
835 * @param evp_key: EVP PKEY public key to create.
836 * @param digest_type: digest type to use
837 * @param key: key to setup for.
838 * @param keylen: length of key.
839 * @param prefix: if returned, the ASN prefix for the hashblob.
840 * @param prefixlen: length of the prefix.
841 * @return false on failure.
844 nss_setup_key_digest(int algo, SECKEYPublicKey** pubkey, HASH_HashType* htype,
845 unsigned char* key, size_t keylen, unsigned char** prefix,
850 /* hash prefix for md5, RFC2537 */
851 static unsigned char p_md5[] = {0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a,
852 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10};
853 /* hash prefix to prepend to hash output, from RFC3110 */
854 static unsigned char p_sha1[] = {0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B,
855 0x0E, 0x03, 0x02, 0x1A, 0x05, 0x00, 0x04, 0x14};
857 static unsigned char p_sha256[] = {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60,
858 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20};
859 static unsigned char p_sha512[] = {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60,
860 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40};
862 /* for future RSASHA384 ..
863 static unsigned char p_sha384[] = {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60,
864 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30};
870 *pubkey = nss_buf2dsa(key, keylen);
872 log_err("verify: malloc failure in crypto");
875 *htype = HASH_AlgSHA1;
876 /* no prefix for DSA verification */
879 case LDNS_RSASHA1_NSEC3:
886 *pubkey = nss_buf2rsa(key, keylen);
888 log_err("verify: malloc failure in crypto");
891 /* select SHA version */
893 if(algo == LDNS_RSASHA256) {
894 *htype = HASH_AlgSHA256;
896 *prefixlen = sizeof(p_sha256);
900 if(algo == LDNS_RSASHA512) {
901 *htype = HASH_AlgSHA512;
903 *prefixlen = sizeof(p_sha512);
907 *htype = HASH_AlgSHA1;
909 *prefixlen = sizeof(p_sha1);
914 *pubkey = nss_buf2rsa(key, keylen);
916 log_err("verify: malloc failure in crypto");
919 *htype = HASH_AlgMD5;
921 *prefixlen = sizeof(p_md5);
925 case LDNS_ECDSAP256SHA256:
926 *pubkey = nss_buf2ecdsa(key, keylen,
927 LDNS_ECDSAP256SHA256);
929 log_err("verify: malloc failure in crypto");
932 *htype = HASH_AlgSHA256;
933 /* no prefix for DSA verification */
935 case LDNS_ECDSAP384SHA384:
936 *pubkey = nss_buf2ecdsa(key, keylen,
937 LDNS_ECDSAP384SHA384);
939 log_err("verify: malloc failure in crypto");
942 *htype = HASH_AlgSHA384;
943 /* no prefix for DSA verification */
945 #endif /* USE_ECDSA */
948 verbose(VERB_QUERY, "verify: unknown algorithm %d",
956 * Check a canonical sig+rrset and signature against a dnskey
957 * @param buf: buffer with data to verify, the first rrsig part and the
958 * canonicalized rrset.
959 * @param algo: DNSKEY algorithm.
960 * @param sigblock: signature rdata field from RRSIG
961 * @param sigblock_len: length of sigblock data.
962 * @param key: public key data from DNSKEY RR.
963 * @param keylen: length of keydata.
964 * @param reason: bogus reason in more detail.
965 * @return secure if verification succeeded, bogus on crypto failure,
966 * unchecked on format errors and alloc failures.
969 verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock,
970 unsigned int sigblock_len, unsigned char* key, unsigned int keylen,
974 /* large enough for the different hashes */
975 unsigned char hash[HASH_LENGTH_MAX];
976 unsigned char hash2[HASH_LENGTH_MAX*2];
977 HASH_HashType htype = 0;
978 SECKEYPublicKey* pubkey = NULL;
979 SECItem secsig = {siBuffer, sigblock, sigblock_len};
980 SECItem sechash = {siBuffer, hash, 0};
982 unsigned char* prefix = NULL; /* prefix for hash, RFC3110, RFC5702 */
983 size_t prefixlen = 0;
986 if(!nss_setup_key_digest(algo, &pubkey, &htype, key, keylen,
987 &prefix, &prefixlen)) {
988 verbose(VERB_QUERY, "verify: failed to setup key");
989 *reason = "use of key for crypto failed";
990 SECKEY_DestroyPublicKey(pubkey);
991 return sec_status_bogus;
994 /* need to convert DSA, ECDSA signatures? */
995 if((algo == LDNS_DSA || algo == LDNS_DSA_NSEC3)) {
996 if(sigblock_len == 1+2*SHA1_LENGTH) {
1000 SECItem* p = DSAU_DecodeDerSig(&secsig);
1002 verbose(VERB_QUERY, "verify: failed DER decode");
1003 *reason = "signature DER decode failed";
1004 SECKEY_DestroyPublicKey(pubkey);
1005 return sec_status_bogus;
1007 if(SECITEM_CopyItem(pubkey->arena, &secsig, p)) {
1008 log_err("alloc failure in DER decode");
1009 SECKEY_DestroyPublicKey(pubkey);
1010 SECITEM_FreeItem(p, PR_TRUE);
1011 return sec_status_unchecked;
1013 SECITEM_FreeItem(p, PR_TRUE);
1017 /* do the signature cryptography work */
1019 sechash.len = HASH_ResultLen(htype);
1020 if(sechash.len > sizeof(hash)) {
1021 verbose(VERB_QUERY, "verify: hash too large for buffer");
1022 SECKEY_DestroyPublicKey(pubkey);
1023 return sec_status_unchecked;
1025 if(HASH_HashBuf(htype, hash, (unsigned char*)sldns_buffer_begin(buf),
1026 (unsigned int)sldns_buffer_limit(buf)) != SECSuccess) {
1027 verbose(VERB_QUERY, "verify: HASH_HashBuf failed");
1028 SECKEY_DestroyPublicKey(pubkey);
1029 return sec_status_unchecked;
1032 int hashlen = sechash.len;
1033 if(prefixlen+hashlen > sizeof(hash2)) {
1034 verbose(VERB_QUERY, "verify: hashprefix too large");
1035 SECKEY_DestroyPublicKey(pubkey);
1036 return sec_status_unchecked;
1038 sechash.data = hash2;
1039 sechash.len = prefixlen+hashlen;
1040 memcpy(sechash.data, prefix, prefixlen);
1041 memmove(sechash.data+prefixlen, hash, hashlen);
1044 /* verify the signature */
1045 res = PK11_Verify(pubkey, &secsig, &sechash, NULL /*wincx*/);
1046 SECKEY_DestroyPublicKey(pubkey);
1048 if(res == SECSuccess) {
1049 return sec_status_secure;
1051 err = PORT_GetError();
1052 if(err != SEC_ERROR_BAD_SIGNATURE) {
1053 /* failed to verify */
1054 verbose(VERB_QUERY, "verify: PK11_Verify failed: %s",
1055 PORT_ErrorToString(err));
1056 /* if it is not supported, like ECC is removed, we get,
1057 * SEC_ERROR_NO_MODULE */
1058 if(err == SEC_ERROR_NO_MODULE)
1059 return sec_status_unchecked;
1060 /* but other errors are commonly returned
1061 * for a bad signature from NSS. Thus we return bogus,
1063 *reason = "signature crypto failed";
1064 return sec_status_bogus;
1066 verbose(VERB_QUERY, "verify: signature mismatch: %s",
1067 PORT_ErrorToString(err));
1068 *reason = "signature crypto failed";
1069 return sec_status_bogus;
1073 #endif /* HAVE_SSL or HAVE_NSS */