1 /* 2 * validator/val_secalgo.c - validator security algorithm functions. 3 * 4 * Copyright (c) 2012, NLnet Labs. All rights reserved. 5 * 6 * This software is open source. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * Redistributions of source code must retain the above copyright notice, 13 * this list of conditions and the following disclaimer. 14 * 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. 18 * 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. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 25 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 26 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE 27 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 * POSSIBILITY OF SUCH DAMAGE. 34 */ 35 36 /** 37 * \file 38 * 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). 42 */ 43 #include "config.h" 44 #include <ldns/ldns.h> 45 #include "validator/val_secalgo.h" 46 #include "util/data/packed_rrset.h" 47 #include "util/log.h" 48 49 #if !defined(HAVE_SSL) && !defined(HAVE_NSS) 50 #error "Need crypto library to do digital signature cryptography" 51 #endif 52 53 /* OpenSSL implementation */ 54 #ifdef HAVE_SSL 55 #ifdef HAVE_OPENSSL_ERR_H 56 #include <openssl/err.h> 57 #endif 58 59 #ifdef HAVE_OPENSSL_RAND_H 60 #include <openssl/rand.h> 61 #endif 62 63 #ifdef HAVE_OPENSSL_CONF_H 64 #include <openssl/conf.h> 65 #endif 66 67 #ifdef HAVE_OPENSSL_ENGINE_H 68 #include <openssl/engine.h> 69 #endif 70 71 /** 72 * Return size of DS digest according to its hash algorithm. 73 * @param algo: DS digest algo. 74 * @return size in bytes of digest, or 0 if not supported. 75 */ 76 size_t 77 ds_digest_size_supported(int algo) 78 { 79 switch(algo) { 80 #ifdef HAVE_EVP_SHA1 81 case LDNS_SHA1: 82 return SHA_DIGEST_LENGTH; 83 #endif 84 #ifdef HAVE_EVP_SHA256 85 case LDNS_SHA256: 86 return SHA256_DIGEST_LENGTH; 87 #endif 88 #ifdef USE_GOST 89 case LDNS_HASH_GOST: 90 if(EVP_get_digestbyname("md_gost94")) 91 return 32; 92 else return 0; 93 #endif 94 #ifdef USE_ECDSA 95 case LDNS_SHA384: 96 return SHA384_DIGEST_LENGTH; 97 #endif 98 default: break; 99 } 100 return 0; 101 } 102 103 #ifdef USE_GOST 104 /** Perform GOST hash */ 105 static int 106 do_gost94(unsigned char* data, size_t len, unsigned char* dest) 107 { 108 const EVP_MD* md = EVP_get_digestbyname("md_gost94"); 109 if(!md) 110 return 0; 111 return ldns_digest_evp(data, (unsigned int)len, dest, md); 112 } 113 #endif 114 115 int 116 secalgo_ds_digest(int algo, unsigned char* buf, size_t len, 117 unsigned char* res) 118 { 119 switch(algo) { 120 #ifdef HAVE_EVP_SHA1 121 case LDNS_SHA1: 122 (void)SHA1(buf, len, res); 123 return 1; 124 #endif 125 #ifdef HAVE_EVP_SHA256 126 case LDNS_SHA256: 127 (void)SHA256(buf, len, res); 128 return 1; 129 #endif 130 #ifdef USE_GOST 131 case LDNS_HASH_GOST: 132 if(do_gost94(buf, len, res)) 133 return 1; 134 break; 135 #endif 136 #ifdef USE_ECDSA 137 case LDNS_SHA384: 138 (void)SHA384(buf, len, res); 139 return 1; 140 #endif 141 default: 142 verbose(VERB_QUERY, "unknown DS digest algorithm %d", 143 algo); 144 break; 145 } 146 return 0; 147 } 148 149 /** return true if DNSKEY algorithm id is supported */ 150 int 151 dnskey_algo_id_is_supported(int id) 152 { 153 switch(id) { 154 case LDNS_RSAMD5: 155 /* RFC 6725 deprecates RSAMD5 */ 156 return 0; 157 case LDNS_DSA: 158 case LDNS_DSA_NSEC3: 159 case LDNS_RSASHA1: 160 case LDNS_RSASHA1_NSEC3: 161 #if defined(HAVE_EVP_SHA256) && defined(USE_SHA2) 162 case LDNS_RSASHA256: 163 #endif 164 #if defined(HAVE_EVP_SHA512) && defined(USE_SHA2) 165 case LDNS_RSASHA512: 166 #endif 167 #ifdef USE_ECDSA 168 case LDNS_ECDSAP256SHA256: 169 case LDNS_ECDSAP384SHA384: 170 #endif 171 return 1; 172 #ifdef USE_GOST 173 case LDNS_ECC_GOST: 174 /* we support GOST if it can be loaded */ 175 return ldns_key_EVP_load_gost_id(); 176 #endif 177 default: 178 return 0; 179 } 180 } 181 182 /** 183 * Output a libcrypto openssl error to the logfile. 184 * @param str: string to add to it. 185 * @param e: the error to output, error number from ERR_get_error(). 186 */ 187 static void 188 log_crypto_error(const char* str, unsigned long e) 189 { 190 char buf[128]; 191 /* or use ERR_error_string if ERR_error_string_n is not avail TODO */ 192 ERR_error_string_n(e, buf, sizeof(buf)); 193 /* buf now contains */ 194 /* error:[error code]:[library name]:[function name]:[reason string] */ 195 log_err("%s crypto %s", str, buf); 196 } 197 198 /** 199 * Setup DSA key digest in DER encoding ... 200 * @param sig: input is signature output alloced ptr (unless failure). 201 * caller must free alloced ptr if this routine returns true. 202 * @param len: input is initial siglen, output is output len. 203 * @return false on failure. 204 */ 205 static int 206 setup_dsa_sig(unsigned char** sig, unsigned int* len) 207 { 208 unsigned char* orig = *sig; 209 unsigned int origlen = *len; 210 int newlen; 211 BIGNUM *R, *S; 212 DSA_SIG *dsasig; 213 214 /* extract the R and S field from the sig buffer */ 215 if(origlen < 1 + 2*SHA_DIGEST_LENGTH) 216 return 0; 217 R = BN_new(); 218 if(!R) return 0; 219 (void) BN_bin2bn(orig + 1, SHA_DIGEST_LENGTH, R); 220 S = BN_new(); 221 if(!S) return 0; 222 (void) BN_bin2bn(orig + 21, SHA_DIGEST_LENGTH, S); 223 dsasig = DSA_SIG_new(); 224 if(!dsasig) return 0; 225 226 dsasig->r = R; 227 dsasig->s = S; 228 *sig = NULL; 229 newlen = i2d_DSA_SIG(dsasig, sig); 230 if(newlen < 0) { 231 DSA_SIG_free(dsasig); 232 free(*sig); 233 return 0; 234 } 235 *len = (unsigned int)newlen; 236 DSA_SIG_free(dsasig); 237 return 1; 238 } 239 240 #ifdef USE_ECDSA 241 /** 242 * Setup the ECDSA signature in its encoding that the library wants. 243 * Converts from plain numbers to ASN formatted. 244 * @param sig: input is signature, output alloced ptr (unless failure). 245 * caller must free alloced ptr if this routine returns true. 246 * @param len: input is initial siglen, output is output len. 247 * @return false on failure. 248 */ 249 static int 250 setup_ecdsa_sig(unsigned char** sig, unsigned int* len) 251 { 252 ECDSA_SIG* ecdsa_sig; 253 int newlen; 254 int bnsize = (int)((*len)/2); 255 /* if too short or not even length, fails */ 256 if(*len < 16 || bnsize*2 != (int)*len) 257 return 0; 258 /* use the raw data to parse two evenly long BIGNUMs, "r | s". */ 259 ecdsa_sig = ECDSA_SIG_new(); 260 if(!ecdsa_sig) return 0; 261 ecdsa_sig->r = BN_bin2bn(*sig, bnsize, ecdsa_sig->r); 262 ecdsa_sig->s = BN_bin2bn(*sig+bnsize, bnsize, ecdsa_sig->s); 263 if(!ecdsa_sig->r || !ecdsa_sig->s) { 264 ECDSA_SIG_free(ecdsa_sig); 265 return 0; 266 } 267 268 /* spool it into ASN format */ 269 *sig = NULL; 270 newlen = i2d_ECDSA_SIG(ecdsa_sig, sig); 271 if(newlen <= 0) { 272 ECDSA_SIG_free(ecdsa_sig); 273 free(*sig); 274 return 0; 275 } 276 *len = (unsigned int)newlen; 277 ECDSA_SIG_free(ecdsa_sig); 278 return 1; 279 } 280 #endif /* USE_ECDSA */ 281 282 /** 283 * Setup key and digest for verification. Adjust sig if necessary. 284 * 285 * @param algo: key algorithm 286 * @param evp_key: EVP PKEY public key to create. 287 * @param digest_type: digest type to use 288 * @param key: key to setup for. 289 * @param keylen: length of key. 290 * @return false on failure. 291 */ 292 static int 293 setup_key_digest(int algo, EVP_PKEY** evp_key, const EVP_MD** digest_type, 294 unsigned char* key, size_t keylen) 295 { 296 DSA* dsa; 297 RSA* rsa; 298 299 switch(algo) { 300 case LDNS_DSA: 301 case LDNS_DSA_NSEC3: 302 *evp_key = EVP_PKEY_new(); 303 if(!*evp_key) { 304 log_err("verify: malloc failure in crypto"); 305 return 0; 306 } 307 dsa = ldns_key_buf2dsa_raw(key, keylen); 308 if(!dsa) { 309 verbose(VERB_QUERY, "verify: " 310 "ldns_key_buf2dsa_raw failed"); 311 return 0; 312 } 313 if(EVP_PKEY_assign_DSA(*evp_key, dsa) == 0) { 314 verbose(VERB_QUERY, "verify: " 315 "EVP_PKEY_assign_DSA failed"); 316 return 0; 317 } 318 *digest_type = EVP_dss1(); 319 320 break; 321 case LDNS_RSASHA1: 322 case LDNS_RSASHA1_NSEC3: 323 #if defined(HAVE_EVP_SHA256) && defined(USE_SHA2) 324 case LDNS_RSASHA256: 325 #endif 326 #if defined(HAVE_EVP_SHA512) && defined(USE_SHA2) 327 case LDNS_RSASHA512: 328 #endif 329 *evp_key = EVP_PKEY_new(); 330 if(!*evp_key) { 331 log_err("verify: malloc failure in crypto"); 332 return 0; 333 } 334 rsa = ldns_key_buf2rsa_raw(key, keylen); 335 if(!rsa) { 336 verbose(VERB_QUERY, "verify: " 337 "ldns_key_buf2rsa_raw SHA failed"); 338 return 0; 339 } 340 if(EVP_PKEY_assign_RSA(*evp_key, rsa) == 0) { 341 verbose(VERB_QUERY, "verify: " 342 "EVP_PKEY_assign_RSA SHA failed"); 343 return 0; 344 } 345 346 /* select SHA version */ 347 #if defined(HAVE_EVP_SHA256) && defined(USE_SHA2) 348 if(algo == LDNS_RSASHA256) 349 *digest_type = EVP_sha256(); 350 else 351 #endif 352 #if defined(HAVE_EVP_SHA512) && defined(USE_SHA2) 353 if(algo == LDNS_RSASHA512) 354 *digest_type = EVP_sha512(); 355 else 356 #endif 357 *digest_type = EVP_sha1(); 358 359 break; 360 case LDNS_RSAMD5: 361 *evp_key = EVP_PKEY_new(); 362 if(!*evp_key) { 363 log_err("verify: malloc failure in crypto"); 364 return 0; 365 } 366 rsa = ldns_key_buf2rsa_raw(key, keylen); 367 if(!rsa) { 368 verbose(VERB_QUERY, "verify: " 369 "ldns_key_buf2rsa_raw MD5 failed"); 370 return 0; 371 } 372 if(EVP_PKEY_assign_RSA(*evp_key, rsa) == 0) { 373 verbose(VERB_QUERY, "verify: " 374 "EVP_PKEY_assign_RSA MD5 failed"); 375 return 0; 376 } 377 *digest_type = EVP_md5(); 378 379 break; 380 #ifdef USE_GOST 381 case LDNS_ECC_GOST: 382 *evp_key = ldns_gost2pkey_raw(key, keylen); 383 if(!*evp_key) { 384 verbose(VERB_QUERY, "verify: " 385 "ldns_gost2pkey_raw failed"); 386 return 0; 387 } 388 *digest_type = EVP_get_digestbyname("md_gost94"); 389 if(!*digest_type) { 390 verbose(VERB_QUERY, "verify: " 391 "EVP_getdigest md_gost94 failed"); 392 return 0; 393 } 394 break; 395 #endif 396 #ifdef USE_ECDSA 397 case LDNS_ECDSAP256SHA256: 398 *evp_key = ldns_ecdsa2pkey_raw(key, keylen, 399 LDNS_ECDSAP256SHA256); 400 if(!*evp_key) { 401 verbose(VERB_QUERY, "verify: " 402 "ldns_ecdsa2pkey_raw failed"); 403 return 0; 404 } 405 #ifdef USE_ECDSA_EVP_WORKAROUND 406 /* openssl before 1.0.0 fixes RSA with the SHA256 407 * hash in EVP. We create one for ecdsa_sha256 */ 408 { 409 static int md_ecdsa_256_done = 0; 410 static EVP_MD md; 411 if(!md_ecdsa_256_done) { 412 EVP_MD m = *EVP_sha256(); 413 md_ecdsa_256_done = 1; 414 m.required_pkey_type[0] = (*evp_key)->type; 415 m.verify = (void*)ECDSA_verify; 416 md = m; 417 } 418 *digest_type = &md; 419 } 420 #else 421 *digest_type = EVP_sha256(); 422 #endif 423 break; 424 case LDNS_ECDSAP384SHA384: 425 *evp_key = ldns_ecdsa2pkey_raw(key, keylen, 426 LDNS_ECDSAP384SHA384); 427 if(!*evp_key) { 428 verbose(VERB_QUERY, "verify: " 429 "ldns_ecdsa2pkey_raw failed"); 430 return 0; 431 } 432 #ifdef USE_ECDSA_EVP_WORKAROUND 433 /* openssl before 1.0.0 fixes RSA with the SHA384 434 * hash in EVP. We create one for ecdsa_sha384 */ 435 { 436 static int md_ecdsa_384_done = 0; 437 static EVP_MD md; 438 if(!md_ecdsa_384_done) { 439 EVP_MD m = *EVP_sha384(); 440 md_ecdsa_384_done = 1; 441 m.required_pkey_type[0] = (*evp_key)->type; 442 m.verify = (void*)ECDSA_verify; 443 md = m; 444 } 445 *digest_type = &md; 446 } 447 #else 448 *digest_type = EVP_sha384(); 449 #endif 450 break; 451 #endif /* USE_ECDSA */ 452 default: 453 verbose(VERB_QUERY, "verify: unknown algorithm %d", 454 algo); 455 return 0; 456 } 457 return 1; 458 } 459 460 /** 461 * Check a canonical sig+rrset and signature against a dnskey 462 * @param buf: buffer with data to verify, the first rrsig part and the 463 * canonicalized rrset. 464 * @param algo: DNSKEY algorithm. 465 * @param sigblock: signature rdata field from RRSIG 466 * @param sigblock_len: length of sigblock data. 467 * @param key: public key data from DNSKEY RR. 468 * @param keylen: length of keydata. 469 * @param reason: bogus reason in more detail. 470 * @return secure if verification succeeded, bogus on crypto failure, 471 * unchecked on format errors and alloc failures. 472 */ 473 enum sec_status 474 verify_canonrrset(ldns_buffer* buf, int algo, unsigned char* sigblock, 475 unsigned int sigblock_len, unsigned char* key, unsigned int keylen, 476 char** reason) 477 { 478 const EVP_MD *digest_type; 479 EVP_MD_CTX ctx; 480 int res, dofree = 0; 481 EVP_PKEY *evp_key = NULL; 482 483 if(!setup_key_digest(algo, &evp_key, &digest_type, key, keylen)) { 484 verbose(VERB_QUERY, "verify: failed to setup key"); 485 *reason = "use of key for crypto failed"; 486 EVP_PKEY_free(evp_key); 487 return sec_status_bogus; 488 } 489 /* if it is a DSA signature in bind format, convert to DER format */ 490 if((algo == LDNS_DSA || algo == LDNS_DSA_NSEC3) && 491 sigblock_len == 1+2*SHA_DIGEST_LENGTH) { 492 if(!setup_dsa_sig(&sigblock, &sigblock_len)) { 493 verbose(VERB_QUERY, "verify: failed to setup DSA sig"); 494 *reason = "use of key for DSA crypto failed"; 495 EVP_PKEY_free(evp_key); 496 return sec_status_bogus; 497 } 498 dofree = 1; 499 } 500 #ifdef USE_ECDSA 501 else if(algo == LDNS_ECDSAP256SHA256 || algo == LDNS_ECDSAP384SHA384) { 502 /* EVP uses ASN prefix on sig, which is not in the wire data */ 503 if(!setup_ecdsa_sig(&sigblock, &sigblock_len)) { 504 verbose(VERB_QUERY, "verify: failed to setup ECDSA sig"); 505 *reason = "use of signature for ECDSA crypto failed"; 506 EVP_PKEY_free(evp_key); 507 return sec_status_bogus; 508 } 509 dofree = 1; 510 } 511 #endif /* USE_ECDSA */ 512 513 /* do the signature cryptography work */ 514 EVP_MD_CTX_init(&ctx); 515 if(EVP_VerifyInit(&ctx, digest_type) == 0) { 516 verbose(VERB_QUERY, "verify: EVP_VerifyInit failed"); 517 EVP_PKEY_free(evp_key); 518 if(dofree) free(sigblock); 519 return sec_status_unchecked; 520 } 521 if(EVP_VerifyUpdate(&ctx, (unsigned char*)ldns_buffer_begin(buf), 522 (unsigned int)ldns_buffer_limit(buf)) == 0) { 523 verbose(VERB_QUERY, "verify: EVP_VerifyUpdate failed"); 524 EVP_PKEY_free(evp_key); 525 if(dofree) free(sigblock); 526 return sec_status_unchecked; 527 } 528 529 res = EVP_VerifyFinal(&ctx, sigblock, sigblock_len, evp_key); 530 if(EVP_MD_CTX_cleanup(&ctx) == 0) { 531 verbose(VERB_QUERY, "verify: EVP_MD_CTX_cleanup failed"); 532 EVP_PKEY_free(evp_key); 533 if(dofree) free(sigblock); 534 return sec_status_unchecked; 535 } 536 EVP_PKEY_free(evp_key); 537 538 if(dofree) 539 free(sigblock); 540 541 if(res == 1) { 542 return sec_status_secure; 543 } else if(res == 0) { 544 verbose(VERB_QUERY, "verify: signature mismatch"); 545 *reason = "signature crypto failed"; 546 return sec_status_bogus; 547 } 548 549 log_crypto_error("verify:", ERR_get_error()); 550 return sec_status_unchecked; 551 } 552 553 /**************************************************/ 554 #elif defined(HAVE_NSS) 555 /* libnss implementation */ 556 /* nss3 */ 557 #include "sechash.h" 558 #include "pk11pub.h" 559 #include "keyhi.h" 560 #include "secerr.h" 561 #include "cryptohi.h" 562 /* nspr4 */ 563 #include "prerror.h" 564 565 size_t 566 ds_digest_size_supported(int algo) 567 { 568 /* uses libNSS */ 569 switch(algo) { 570 case LDNS_SHA1: 571 return SHA1_LENGTH; 572 #ifdef USE_SHA2 573 case LDNS_SHA256: 574 return SHA256_LENGTH; 575 #endif 576 #ifdef USE_ECDSA 577 case LDNS_SHA384: 578 return SHA384_LENGTH; 579 #endif 580 /* GOST not supported in NSS */ 581 case LDNS_HASH_GOST: 582 default: break; 583 } 584 return 0; 585 } 586 587 int 588 secalgo_ds_digest(int algo, unsigned char* buf, size_t len, 589 unsigned char* res) 590 { 591 /* uses libNSS */ 592 switch(algo) { 593 case LDNS_SHA1: 594 return HASH_HashBuf(HASH_AlgSHA1, res, buf, len) 595 == SECSuccess; 596 #if defined(USE_SHA2) 597 case LDNS_SHA256: 598 return HASH_HashBuf(HASH_AlgSHA256, res, buf, len) 599 == SECSuccess; 600 #endif 601 #ifdef USE_ECDSA 602 case LDNS_SHA384: 603 return HASH_HashBuf(HASH_AlgSHA384, res, buf, len) 604 == SECSuccess; 605 #endif 606 case LDNS_HASH_GOST: 607 default: 608 verbose(VERB_QUERY, "unknown DS digest algorithm %d", 609 algo); 610 break; 611 } 612 return 0; 613 } 614 615 int 616 dnskey_algo_id_is_supported(int id) 617 { 618 /* uses libNSS */ 619 switch(id) { 620 case LDNS_RSAMD5: 621 /* RFC 6725 deprecates RSAMD5 */ 622 return 0; 623 case LDNS_DSA: 624 case LDNS_DSA_NSEC3: 625 case LDNS_RSASHA1: 626 case LDNS_RSASHA1_NSEC3: 627 #ifdef USE_SHA2 628 case LDNS_RSASHA256: 629 #endif 630 #ifdef USE_SHA2 631 case LDNS_RSASHA512: 632 #endif 633 return 1; 634 #ifdef USE_ECDSA 635 case LDNS_ECDSAP256SHA256: 636 case LDNS_ECDSAP384SHA384: 637 return PK11_TokenExists(CKM_ECDSA); 638 #endif 639 case LDNS_ECC_GOST: 640 default: 641 return 0; 642 } 643 } 644 645 /* return a new public key for NSS */ 646 static SECKEYPublicKey* nss_key_create(KeyType ktype) 647 { 648 SECKEYPublicKey* key; 649 PLArenaPool* arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); 650 if(!arena) { 651 log_err("out of memory, PORT_NewArena failed"); 652 return NULL; 653 } 654 key = PORT_ArenaZNew(arena, SECKEYPublicKey); 655 if(!key) { 656 log_err("out of memory, PORT_ArenaZNew failed"); 657 PORT_FreeArena(arena, PR_FALSE); 658 return NULL; 659 } 660 key->arena = arena; 661 key->keyType = ktype; 662 key->pkcs11Slot = NULL; 663 key->pkcs11ID = CK_INVALID_HANDLE; 664 return key; 665 } 666 667 static SECKEYPublicKey* nss_buf2ecdsa(unsigned char* key, size_t len, int algo) 668 { 669 SECKEYPublicKey* pk; 670 SECItem pub = {siBuffer, NULL, 0}; 671 SECItem params = {siBuffer, NULL, 0}; 672 unsigned char param256[] = { 673 /* OBJECTIDENTIFIER 1.2.840.10045.3.1.7 (P-256) 674 * {iso(1) member-body(2) us(840) ansi-x962(10045) curves(3) prime(1) prime256v1(7)} */ 675 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07 676 }; 677 unsigned char param384[] = { 678 /* OBJECTIDENTIFIER 1.3.132.0.34 (P-384) 679 * {iso(1) identified-organization(3) certicom(132) curve(0) ansip384r1(34)} */ 680 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x22 681 }; 682 unsigned char buf[256+2]; /* sufficient for 2*384/8+1 */ 683 684 /* check length, which uncompressed must be 2 bignums */ 685 if(algo == LDNS_ECDSAP256SHA256) { 686 if(len != 2*256/8) return NULL; 687 /* ECCurve_X9_62_PRIME_256V1 */ 688 } else if(algo == LDNS_ECDSAP384SHA384) { 689 if(len != 2*384/8) return NULL; 690 /* ECCurve_X9_62_PRIME_384R1 */ 691 } else return NULL; 692 693 buf[0] = 0x04; /* POINT_FORM_UNCOMPRESSED */ 694 memmove(buf+1, key, len); 695 pub.data = buf; 696 pub.len = len+1; 697 if(algo == LDNS_ECDSAP256SHA256) { 698 params.data = param256; 699 params.len = sizeof(param256); 700 } else { 701 params.data = param384; 702 params.len = sizeof(param384); 703 } 704 705 pk = nss_key_create(ecKey); 706 if(!pk) 707 return NULL; 708 pk->u.ec.size = (len/2)*8; 709 if(SECITEM_CopyItem(pk->arena, &pk->u.ec.publicValue, &pub)) { 710 SECKEY_DestroyPublicKey(pk); 711 return NULL; 712 } 713 if(SECITEM_CopyItem(pk->arena, &pk->u.ec.DEREncodedParams, ¶ms)) { 714 SECKEY_DestroyPublicKey(pk); 715 return NULL; 716 } 717 718 return pk; 719 } 720 721 static SECKEYPublicKey* nss_buf2dsa(unsigned char* key, size_t len) 722 { 723 SECKEYPublicKey* pk; 724 uint8_t T; 725 uint16_t length; 726 uint16_t offset; 727 SECItem Q = {siBuffer, NULL, 0}; 728 SECItem P = {siBuffer, NULL, 0}; 729 SECItem G = {siBuffer, NULL, 0}; 730 SECItem Y = {siBuffer, NULL, 0}; 731 732 if(len == 0) 733 return NULL; 734 T = (uint8_t)key[0]; 735 length = (64 + T * 8); 736 offset = 1; 737 738 if (T > 8) { 739 return NULL; 740 } 741 if(len < (size_t)1 + SHA1_LENGTH + 3*length) 742 return NULL; 743 744 Q.data = key+offset; 745 Q.len = SHA1_LENGTH; 746 offset += SHA1_LENGTH; 747 748 P.data = key+offset; 749 P.len = length; 750 offset += length; 751 752 G.data = key+offset; 753 G.len = length; 754 offset += length; 755 756 Y.data = key+offset; 757 Y.len = length; 758 offset += length; 759 760 pk = nss_key_create(dsaKey); 761 if(!pk) 762 return NULL; 763 if(SECITEM_CopyItem(pk->arena, &pk->u.dsa.params.prime, &P)) { 764 SECKEY_DestroyPublicKey(pk); 765 return NULL; 766 } 767 if(SECITEM_CopyItem(pk->arena, &pk->u.dsa.params.subPrime, &Q)) { 768 SECKEY_DestroyPublicKey(pk); 769 return NULL; 770 } 771 if(SECITEM_CopyItem(pk->arena, &pk->u.dsa.params.base, &G)) { 772 SECKEY_DestroyPublicKey(pk); 773 return NULL; 774 } 775 if(SECITEM_CopyItem(pk->arena, &pk->u.dsa.publicValue, &Y)) { 776 SECKEY_DestroyPublicKey(pk); 777 return NULL; 778 } 779 return pk; 780 } 781 782 static SECKEYPublicKey* nss_buf2rsa(unsigned char* key, size_t len) 783 { 784 SECKEYPublicKey* pk; 785 uint16_t exp; 786 uint16_t offset; 787 uint16_t int16; 788 SECItem modulus = {siBuffer, NULL, 0}; 789 SECItem exponent = {siBuffer, NULL, 0}; 790 if(len == 0) 791 return NULL; 792 if(key[0] == 0) { 793 if(len < 3) 794 return NULL; 795 /* the exponent is too large so it's places further */ 796 memmove(&int16, key+1, 2); 797 exp = ntohs(int16); 798 offset = 3; 799 } else { 800 exp = key[0]; 801 offset = 1; 802 } 803 804 /* key length at least one */ 805 if(len < (size_t)offset + exp + 1) 806 return NULL; 807 808 exponent.data = key+offset; 809 exponent.len = exp; 810 offset += exp; 811 modulus.data = key+offset; 812 modulus.len = (len - offset); 813 814 pk = nss_key_create(rsaKey); 815 if(!pk) 816 return NULL; 817 if(SECITEM_CopyItem(pk->arena, &pk->u.rsa.modulus, &modulus)) { 818 SECKEY_DestroyPublicKey(pk); 819 return NULL; 820 } 821 if(SECITEM_CopyItem(pk->arena, &pk->u.rsa.publicExponent, &exponent)) { 822 SECKEY_DestroyPublicKey(pk); 823 return NULL; 824 } 825 return pk; 826 } 827 828 /** 829 * Setup key and digest for verification. Adjust sig if necessary. 830 * 831 * @param algo: key algorithm 832 * @param evp_key: EVP PKEY public key to create. 833 * @param digest_type: digest type to use 834 * @param key: key to setup for. 835 * @param keylen: length of key. 836 * @param prefix: if returned, the ASN prefix for the hashblob. 837 * @param prefixlen: length of the prefix. 838 * @return false on failure. 839 */ 840 static int 841 nss_setup_key_digest(int algo, SECKEYPublicKey** pubkey, HASH_HashType* htype, 842 unsigned char* key, size_t keylen, unsigned char** prefix, 843 size_t* prefixlen) 844 { 845 /* uses libNSS */ 846 847 /* hash prefix for md5, RFC2537 */ 848 unsigned char p_md5[] = {0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 849 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10}; 850 /* hash prefix to prepend to hash output, from RFC3110 */ 851 unsigned char p_sha1[] = {0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 852 0x0E, 0x03, 0x02, 0x1A, 0x05, 0x00, 0x04, 0x14}; 853 /* from RFC5702 */ 854 unsigned char p_sha256[] = {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 855 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20}; 856 unsigned char p_sha512[] = {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 857 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40}; 858 /* from RFC6234 */ 859 /* for future RSASHA384 .. 860 unsigned char p_sha384[] = {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 861 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30}; 862 */ 863 864 switch(algo) { 865 case LDNS_DSA: 866 case LDNS_DSA_NSEC3: 867 *pubkey = nss_buf2dsa(key, keylen); 868 if(!*pubkey) { 869 log_err("verify: malloc failure in crypto"); 870 return 0; 871 } 872 *htype = HASH_AlgSHA1; 873 /* no prefix for DSA verification */ 874 break; 875 case LDNS_RSASHA1: 876 case LDNS_RSASHA1_NSEC3: 877 #ifdef USE_SHA2 878 case LDNS_RSASHA256: 879 #endif 880 #ifdef USE_SHA2 881 case LDNS_RSASHA512: 882 #endif 883 *pubkey = nss_buf2rsa(key, keylen); 884 if(!*pubkey) { 885 log_err("verify: malloc failure in crypto"); 886 return 0; 887 } 888 /* select SHA version */ 889 #ifdef USE_SHA2 890 if(algo == LDNS_RSASHA256) { 891 *htype = HASH_AlgSHA256; 892 *prefix = p_sha256; 893 *prefixlen = sizeof(p_sha256); 894 } else 895 #endif 896 #ifdef USE_SHA2 897 if(algo == LDNS_RSASHA512) { 898 *htype = HASH_AlgSHA512; 899 *prefix = p_sha512; 900 *prefixlen = sizeof(p_sha512); 901 } else 902 #endif 903 { 904 *htype = HASH_AlgSHA1; 905 *prefix = p_sha1; 906 *prefixlen = sizeof(p_sha1); 907 } 908 909 break; 910 case LDNS_RSAMD5: 911 *pubkey = nss_buf2rsa(key, keylen); 912 if(!*pubkey) { 913 log_err("verify: malloc failure in crypto"); 914 return 0; 915 } 916 *htype = HASH_AlgMD5; 917 *prefix = p_md5; 918 *prefixlen = sizeof(p_md5); 919 920 break; 921 #ifdef USE_ECDSA 922 case LDNS_ECDSAP256SHA256: 923 *pubkey = nss_buf2ecdsa(key, keylen, 924 LDNS_ECDSAP256SHA256); 925 if(!*pubkey) { 926 log_err("verify: malloc failure in crypto"); 927 return 0; 928 } 929 *htype = HASH_AlgSHA256; 930 /* no prefix for DSA verification */ 931 break; 932 case LDNS_ECDSAP384SHA384: 933 *pubkey = nss_buf2ecdsa(key, keylen, 934 LDNS_ECDSAP384SHA384); 935 if(!*pubkey) { 936 log_err("verify: malloc failure in crypto"); 937 return 0; 938 } 939 *htype = HASH_AlgSHA384; 940 /* no prefix for DSA verification */ 941 break; 942 #endif /* USE_ECDSA */ 943 case LDNS_ECC_GOST: 944 default: 945 verbose(VERB_QUERY, "verify: unknown algorithm %d", 946 algo); 947 return 0; 948 } 949 return 1; 950 } 951 952 /** 953 * Check a canonical sig+rrset and signature against a dnskey 954 * @param buf: buffer with data to verify, the first rrsig part and the 955 * canonicalized rrset. 956 * @param algo: DNSKEY algorithm. 957 * @param sigblock: signature rdata field from RRSIG 958 * @param sigblock_len: length of sigblock data. 959 * @param key: public key data from DNSKEY RR. 960 * @param keylen: length of keydata. 961 * @param reason: bogus reason in more detail. 962 * @return secure if verification succeeded, bogus on crypto failure, 963 * unchecked on format errors and alloc failures. 964 */ 965 enum sec_status 966 verify_canonrrset(ldns_buffer* buf, int algo, unsigned char* sigblock, 967 unsigned int sigblock_len, unsigned char* key, unsigned int keylen, 968 char** reason) 969 { 970 /* uses libNSS */ 971 /* large enough for the different hashes */ 972 unsigned char hash[HASH_LENGTH_MAX]; 973 unsigned char hash2[HASH_LENGTH_MAX*2]; 974 HASH_HashType htype = 0; 975 SECKEYPublicKey* pubkey = NULL; 976 SECItem secsig = {siBuffer, sigblock, sigblock_len}; 977 SECItem sechash = {siBuffer, hash, 0}; 978 SECStatus res; 979 unsigned char* prefix = NULL; /* prefix for hash, RFC3110, RFC5702 */ 980 size_t prefixlen = 0; 981 int err; 982 983 if(!nss_setup_key_digest(algo, &pubkey, &htype, key, keylen, 984 &prefix, &prefixlen)) { 985 verbose(VERB_QUERY, "verify: failed to setup key"); 986 *reason = "use of key for crypto failed"; 987 SECKEY_DestroyPublicKey(pubkey); 988 return sec_status_bogus; 989 } 990 991 /* need to convert DSA, ECDSA signatures? */ 992 if((algo == LDNS_DSA || algo == LDNS_DSA_NSEC3)) { 993 if(sigblock_len == 1+2*SHA1_LENGTH) { 994 secsig.data ++; 995 secsig.len --; 996 } else { 997 SECItem* p = DSAU_DecodeDerSig(&secsig); 998 if(!p) { 999 verbose(VERB_QUERY, "verify: failed DER decode"); 1000 *reason = "signature DER decode failed"; 1001 SECKEY_DestroyPublicKey(pubkey); 1002 return sec_status_bogus; 1003 } 1004 if(SECITEM_CopyItem(pubkey->arena, &secsig, p)) { 1005 log_err("alloc failure in DER decode"); 1006 SECKEY_DestroyPublicKey(pubkey); 1007 SECITEM_FreeItem(p, PR_TRUE); 1008 return sec_status_unchecked; 1009 } 1010 SECITEM_FreeItem(p, PR_TRUE); 1011 } 1012 } 1013 1014 /* do the signature cryptography work */ 1015 /* hash the data */ 1016 sechash.len = HASH_ResultLen(htype); 1017 if(sechash.len > sizeof(hash)) { 1018 verbose(VERB_QUERY, "verify: hash too large for buffer"); 1019 SECKEY_DestroyPublicKey(pubkey); 1020 return sec_status_unchecked; 1021 } 1022 if(HASH_HashBuf(htype, hash, (unsigned char*)ldns_buffer_begin(buf), 1023 (unsigned int)ldns_buffer_limit(buf)) != SECSuccess) { 1024 verbose(VERB_QUERY, "verify: HASH_HashBuf failed"); 1025 SECKEY_DestroyPublicKey(pubkey); 1026 return sec_status_unchecked; 1027 } 1028 if(prefix) { 1029 int hashlen = sechash.len; 1030 if(prefixlen+hashlen > sizeof(hash2)) { 1031 verbose(VERB_QUERY, "verify: hashprefix too large"); 1032 SECKEY_DestroyPublicKey(pubkey); 1033 return sec_status_unchecked; 1034 } 1035 sechash.data = hash2; 1036 sechash.len = prefixlen+hashlen; 1037 memcpy(sechash.data, prefix, prefixlen); 1038 memmove(sechash.data+prefixlen, hash, hashlen); 1039 } 1040 1041 /* verify the signature */ 1042 res = PK11_Verify(pubkey, &secsig, &sechash, NULL /*wincx*/); 1043 SECKEY_DestroyPublicKey(pubkey); 1044 1045 if(res == SECSuccess) { 1046 return sec_status_secure; 1047 } 1048 err = PORT_GetError(); 1049 if(err != SEC_ERROR_BAD_SIGNATURE) { 1050 /* failed to verify */ 1051 verbose(VERB_QUERY, "verify: PK11_Verify failed: %s", 1052 PORT_ErrorToString(err)); 1053 /* if it is not supported, like ECC is removed, we get, 1054 * SEC_ERROR_NO_MODULE */ 1055 if(err == SEC_ERROR_NO_MODULE) 1056 return sec_status_unchecked; 1057 /* but other errors are commonly returned 1058 * for a bad signature from NSS. Thus we return bogus, 1059 * not unchecked */ 1060 *reason = "signature crypto failed"; 1061 return sec_status_bogus; 1062 } 1063 verbose(VERB_QUERY, "verify: signature mismatch: %s", 1064 PORT_ErrorToString(err)); 1065 *reason = "signature crypto failed"; 1066 return sec_status_bogus; 1067 } 1068 1069 1070 #endif /* HAVE_SSL or HAVE_NSS */ 1071