xref: /freebsd/contrib/unbound/validator/val_secalgo.c (revision 59e2ff550c448126b988150ce800cdf73bb5103e)
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
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.
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 /* 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"
47 #include "util/log.h"
48 #include "sldns/rrdef.h"
49 #include "sldns/keyraw.h"
50 #include "sldns/sbuffer.h"
51 
52 #if !defined(HAVE_SSL) && !defined(HAVE_NSS)
53 #error "Need crypto library to do digital signature cryptography"
54 #endif
55 
56 /* OpenSSL implementation */
57 #ifdef HAVE_SSL
58 #ifdef HAVE_OPENSSL_ERR_H
59 #include <openssl/err.h>
60 #endif
61 
62 #ifdef HAVE_OPENSSL_RAND_H
63 #include <openssl/rand.h>
64 #endif
65 
66 #ifdef HAVE_OPENSSL_CONF_H
67 #include <openssl/conf.h>
68 #endif
69 
70 #ifdef HAVE_OPENSSL_ENGINE_H
71 #include <openssl/engine.h>
72 #endif
73 
74 /**
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.
78  */
79 size_t
80 ds_digest_size_supported(int algo)
81 {
82 	switch(algo) {
83 #ifdef HAVE_EVP_SHA1
84 		case LDNS_SHA1:
85 			return SHA_DIGEST_LENGTH;
86 #endif
87 #ifdef HAVE_EVP_SHA256
88 		case LDNS_SHA256:
89 			return SHA256_DIGEST_LENGTH;
90 #endif
91 #ifdef USE_GOST
92 		case LDNS_HASH_GOST:
93 			if(EVP_get_digestbyname("md_gost94"))
94 				return 32;
95 			else	return 0;
96 #endif
97 #ifdef USE_ECDSA
98 		case LDNS_SHA384:
99 			return SHA384_DIGEST_LENGTH;
100 #endif
101 		default: break;
102 	}
103 	return 0;
104 }
105 
106 #ifdef USE_GOST
107 /** Perform GOST hash */
108 static int
109 do_gost94(unsigned char* data, size_t len, unsigned char* dest)
110 {
111 	const EVP_MD* md = EVP_get_digestbyname("md_gost94");
112 	if(!md)
113 		return 0;
114 	return sldns_digest_evp(data, (unsigned int)len, dest, md);
115 }
116 #endif
117 
118 int
119 secalgo_ds_digest(int algo, unsigned char* buf, size_t len,
120 	unsigned char* res)
121 {
122 	switch(algo) {
123 #ifdef HAVE_EVP_SHA1
124 		case LDNS_SHA1:
125 			(void)SHA1(buf, len, res);
126 			return 1;
127 #endif
128 #ifdef HAVE_EVP_SHA256
129 		case LDNS_SHA256:
130 			(void)SHA256(buf, len, res);
131 			return 1;
132 #endif
133 #ifdef USE_GOST
134 		case LDNS_HASH_GOST:
135 			if(do_gost94(buf, len, res))
136 				return 1;
137 			break;
138 #endif
139 #ifdef USE_ECDSA
140 		case LDNS_SHA384:
141 			(void)SHA384(buf, len, res);
142 			return 1;
143 #endif
144 		default:
145 			verbose(VERB_QUERY, "unknown DS digest algorithm %d",
146 				algo);
147 			break;
148 	}
149 	return 0;
150 }
151 
152 /** return true if DNSKEY algorithm id is supported */
153 int
154 dnskey_algo_id_is_supported(int id)
155 {
156 	switch(id) {
157 	case LDNS_RSAMD5:
158 		/* RFC 6725 deprecates RSAMD5 */
159 		return 0;
160 	case LDNS_DSA:
161 	case LDNS_DSA_NSEC3:
162 	case LDNS_RSASHA1:
163 	case LDNS_RSASHA1_NSEC3:
164 #if defined(HAVE_EVP_SHA256) && defined(USE_SHA2)
165 	case LDNS_RSASHA256:
166 #endif
167 #if defined(HAVE_EVP_SHA512) && defined(USE_SHA2)
168 	case LDNS_RSASHA512:
169 #endif
170 #ifdef USE_ECDSA
171 	case LDNS_ECDSAP256SHA256:
172 	case LDNS_ECDSAP384SHA384:
173 #endif
174 		return 1;
175 #ifdef USE_GOST
176 	case LDNS_ECC_GOST:
177 		/* we support GOST if it can be loaded */
178 		return sldns_key_EVP_load_gost_id();
179 #endif
180 	default:
181 		return 0;
182 	}
183 }
184 
185 /**
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().
189  */
190 static void
191 log_crypto_error(const char* str, unsigned long e)
192 {
193 	char buf[128];
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);
199 }
200 
201 /**
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.
207  */
208 static int
209 setup_dsa_sig(unsigned char** sig, unsigned int* len)
210 {
211 	unsigned char* orig = *sig;
212 	unsigned int origlen = *len;
213 	int newlen;
214 	BIGNUM *R, *S;
215 	DSA_SIG *dsasig;
216 
217 	/* extract the R and S field from the sig buffer */
218 	if(origlen < 1 + 2*SHA_DIGEST_LENGTH)
219 		return 0;
220 	R = BN_new();
221 	if(!R) return 0;
222 	(void) BN_bin2bn(orig + 1, SHA_DIGEST_LENGTH, R);
223 	S = BN_new();
224 	if(!S) return 0;
225 	(void) BN_bin2bn(orig + 21, SHA_DIGEST_LENGTH, S);
226 	dsasig = DSA_SIG_new();
227 	if(!dsasig) return 0;
228 
229 	dsasig->r = R;
230 	dsasig->s = S;
231 	*sig = NULL;
232 	newlen = i2d_DSA_SIG(dsasig, sig);
233 	if(newlen < 0) {
234 		DSA_SIG_free(dsasig);
235 		free(*sig);
236 		return 0;
237 	}
238 	*len = (unsigned int)newlen;
239 	DSA_SIG_free(dsasig);
240 	return 1;
241 }
242 
243 #ifdef USE_ECDSA
244 /**
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.
251  */
252 static int
253 setup_ecdsa_sig(unsigned char** sig, unsigned int* len)
254 {
255 	ECDSA_SIG* ecdsa_sig;
256 	int newlen;
257 	int bnsize = (int)((*len)/2);
258 	/* if too short or not even length, fails */
259 	if(*len < 16 || bnsize*2 != (int)*len)
260 		return 0;
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);
268 		return 0;
269 	}
270 
271 	/* spool it into ASN format */
272 	*sig = NULL;
273 	newlen = i2d_ECDSA_SIG(ecdsa_sig, sig);
274 	if(newlen <= 0) {
275 		ECDSA_SIG_free(ecdsa_sig);
276 		free(*sig);
277 		return 0;
278 	}
279 	*len = (unsigned int)newlen;
280 	ECDSA_SIG_free(ecdsa_sig);
281 	return 1;
282 }
283 #endif /* USE_ECDSA */
284 
285 /**
286  * Setup key and digest for verification. Adjust sig if necessary.
287  *
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.
294  */
295 static int
296 setup_key_digest(int algo, EVP_PKEY** evp_key, const EVP_MD** digest_type,
297 	unsigned char* key, size_t keylen)
298 {
299 	DSA* dsa;
300 	RSA* rsa;
301 
302 	switch(algo) {
303 		case LDNS_DSA:
304 		case LDNS_DSA_NSEC3:
305 			*evp_key = EVP_PKEY_new();
306 			if(!*evp_key) {
307 				log_err("verify: malloc failure in crypto");
308 				return 0;
309 			}
310 			dsa = sldns_key_buf2dsa_raw(key, keylen);
311 			if(!dsa) {
312 				verbose(VERB_QUERY, "verify: "
313 					"sldns_key_buf2dsa_raw failed");
314 				return 0;
315 			}
316 			if(EVP_PKEY_assign_DSA(*evp_key, dsa) == 0) {
317 				verbose(VERB_QUERY, "verify: "
318 					"EVP_PKEY_assign_DSA failed");
319 				return 0;
320 			}
321 			*digest_type = EVP_dss1();
322 
323 			break;
324 		case LDNS_RSASHA1:
325 		case LDNS_RSASHA1_NSEC3:
326 #if defined(HAVE_EVP_SHA256) && defined(USE_SHA2)
327 		case LDNS_RSASHA256:
328 #endif
329 #if defined(HAVE_EVP_SHA512) && defined(USE_SHA2)
330 		case LDNS_RSASHA512:
331 #endif
332 			*evp_key = EVP_PKEY_new();
333 			if(!*evp_key) {
334 				log_err("verify: malloc failure in crypto");
335 				return 0;
336 			}
337 			rsa = sldns_key_buf2rsa_raw(key, keylen);
338 			if(!rsa) {
339 				verbose(VERB_QUERY, "verify: "
340 					"sldns_key_buf2rsa_raw SHA failed");
341 				return 0;
342 			}
343 			if(EVP_PKEY_assign_RSA(*evp_key, rsa) == 0) {
344 				verbose(VERB_QUERY, "verify: "
345 					"EVP_PKEY_assign_RSA SHA failed");
346 				return 0;
347 			}
348 
349 			/* select SHA version */
350 #if defined(HAVE_EVP_SHA256) && defined(USE_SHA2)
351 			if(algo == LDNS_RSASHA256)
352 				*digest_type = EVP_sha256();
353 			else
354 #endif
355 #if defined(HAVE_EVP_SHA512) && defined(USE_SHA2)
356 				if(algo == LDNS_RSASHA512)
357 				*digest_type = EVP_sha512();
358 			else
359 #endif
360 				*digest_type = EVP_sha1();
361 
362 			break;
363 		case LDNS_RSAMD5:
364 			*evp_key = EVP_PKEY_new();
365 			if(!*evp_key) {
366 				log_err("verify: malloc failure in crypto");
367 				return 0;
368 			}
369 			rsa = sldns_key_buf2rsa_raw(key, keylen);
370 			if(!rsa) {
371 				verbose(VERB_QUERY, "verify: "
372 					"sldns_key_buf2rsa_raw MD5 failed");
373 				return 0;
374 			}
375 			if(EVP_PKEY_assign_RSA(*evp_key, rsa) == 0) {
376 				verbose(VERB_QUERY, "verify: "
377 					"EVP_PKEY_assign_RSA MD5 failed");
378 				return 0;
379 			}
380 			*digest_type = EVP_md5();
381 
382 			break;
383 #ifdef USE_GOST
384 		case LDNS_ECC_GOST:
385 			*evp_key = sldns_gost2pkey_raw(key, keylen);
386 			if(!*evp_key) {
387 				verbose(VERB_QUERY, "verify: "
388 					"sldns_gost2pkey_raw failed");
389 				return 0;
390 			}
391 			*digest_type = EVP_get_digestbyname("md_gost94");
392 			if(!*digest_type) {
393 				verbose(VERB_QUERY, "verify: "
394 					"EVP_getdigest md_gost94 failed");
395 				return 0;
396 			}
397 			break;
398 #endif
399 #ifdef USE_ECDSA
400 		case LDNS_ECDSAP256SHA256:
401 			*evp_key = sldns_ecdsa2pkey_raw(key, keylen,
402 				LDNS_ECDSAP256SHA256);
403 			if(!*evp_key) {
404 				verbose(VERB_QUERY, "verify: "
405 					"sldns_ecdsa2pkey_raw failed");
406 				return 0;
407 			}
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 */
411 			{
412 				static int md_ecdsa_256_done = 0;
413 				static EVP_MD md;
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;
419 					md = m;
420 				}
421 				*digest_type = &md;
422 			}
423 #else
424 			*digest_type = EVP_sha256();
425 #endif
426 			break;
427 		case LDNS_ECDSAP384SHA384:
428 			*evp_key = sldns_ecdsa2pkey_raw(key, keylen,
429 				LDNS_ECDSAP384SHA384);
430 			if(!*evp_key) {
431 				verbose(VERB_QUERY, "verify: "
432 					"sldns_ecdsa2pkey_raw failed");
433 				return 0;
434 			}
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 */
438 			{
439 				static int md_ecdsa_384_done = 0;
440 				static EVP_MD md;
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;
446 					md = m;
447 				}
448 				*digest_type = &md;
449 			}
450 #else
451 			*digest_type = EVP_sha384();
452 #endif
453 			break;
454 #endif /* USE_ECDSA */
455 		default:
456 			verbose(VERB_QUERY, "verify: unknown algorithm %d",
457 				algo);
458 			return 0;
459 	}
460 	return 1;
461 }
462 
463 /**
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.
475  */
476 enum sec_status
477 verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock,
478 	unsigned int sigblock_len, unsigned char* key, unsigned int keylen,
479 	char** reason)
480 {
481 	const EVP_MD *digest_type;
482 	EVP_MD_CTX ctx;
483 	int res, dofree = 0;
484 	EVP_PKEY *evp_key = NULL;
485 
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;
491 	}
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;
500 		}
501 		dofree = 1;
502 	}
503 #ifdef USE_ECDSA
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;
511 		}
512 		dofree = 1;
513 	}
514 #endif /* USE_ECDSA */
515 
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;
523 	}
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;
530 	}
531 
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;
538 	}
539 	EVP_PKEY_free(evp_key);
540 
541 	if(dofree)
542 		free(sigblock);
543 
544 	if(res == 1) {
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;
550 	}
551 
552 	log_crypto_error("verify:", ERR_get_error());
553 	return sec_status_unchecked;
554 }
555 
556 /**************************************************/
557 #elif defined(HAVE_NSS)
558 /* libnss implementation */
559 /* nss3 */
560 #include "sechash.h"
561 #include "pk11pub.h"
562 #include "keyhi.h"
563 #include "secerr.h"
564 #include "cryptohi.h"
565 /* nspr4 */
566 #include "prerror.h"
567 
568 size_t
569 ds_digest_size_supported(int algo)
570 {
571 	/* uses libNSS */
572 	switch(algo) {
573 		case LDNS_SHA1:
574 			return SHA1_LENGTH;
575 #ifdef USE_SHA2
576 		case LDNS_SHA256:
577 			return SHA256_LENGTH;
578 #endif
579 #ifdef USE_ECDSA
580 		case LDNS_SHA384:
581 			return SHA384_LENGTH;
582 #endif
583 		/* GOST not supported in NSS */
584 		case LDNS_HASH_GOST:
585 		default: break;
586 	}
587 	return 0;
588 }
589 
590 int
591 secalgo_ds_digest(int algo, unsigned char* buf, size_t len,
592 	unsigned char* res)
593 {
594 	/* uses libNSS */
595 	switch(algo) {
596 		case LDNS_SHA1:
597 			return HASH_HashBuf(HASH_AlgSHA1, res, buf, len)
598 				== SECSuccess;
599 #if defined(USE_SHA2)
600 		case LDNS_SHA256:
601 			return HASH_HashBuf(HASH_AlgSHA256, res, buf, len)
602 				== SECSuccess;
603 #endif
604 #ifdef USE_ECDSA
605 		case LDNS_SHA384:
606 			return HASH_HashBuf(HASH_AlgSHA384, res, buf, len)
607 				== SECSuccess;
608 #endif
609 		case LDNS_HASH_GOST:
610 		default:
611 			verbose(VERB_QUERY, "unknown DS digest algorithm %d",
612 				algo);
613 			break;
614 	}
615 	return 0;
616 }
617 
618 int
619 dnskey_algo_id_is_supported(int id)
620 {
621 	/* uses libNSS */
622 	switch(id) {
623 	case LDNS_RSAMD5:
624 		/* RFC 6725 deprecates RSAMD5 */
625 		return 0;
626 	case LDNS_DSA:
627 	case LDNS_DSA_NSEC3:
628 	case LDNS_RSASHA1:
629 	case LDNS_RSASHA1_NSEC3:
630 #ifdef USE_SHA2
631 	case LDNS_RSASHA256:
632 #endif
633 #ifdef USE_SHA2
634 	case LDNS_RSASHA512:
635 #endif
636 		return 1;
637 #ifdef USE_ECDSA
638 	case LDNS_ECDSAP256SHA256:
639 	case LDNS_ECDSAP384SHA384:
640 		return PK11_TokenExists(CKM_ECDSA);
641 #endif
642 	case LDNS_ECC_GOST:
643 	default:
644 		return 0;
645 	}
646 }
647 
648 /* return a new public key for NSS */
649 static SECKEYPublicKey* nss_key_create(KeyType ktype)
650 {
651 	SECKEYPublicKey* key;
652 	PLArenaPool* arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
653 	if(!arena) {
654 		log_err("out of memory, PORT_NewArena failed");
655 		return NULL;
656 	}
657 	key = PORT_ArenaZNew(arena, SECKEYPublicKey);
658 	if(!key) {
659 		log_err("out of memory, PORT_ArenaZNew failed");
660 		PORT_FreeArena(arena, PR_FALSE);
661 		return NULL;
662 	}
663 	key->arena = arena;
664 	key->keyType = ktype;
665 	key->pkcs11Slot = NULL;
666 	key->pkcs11ID = CK_INVALID_HANDLE;
667 	return key;
668 }
669 
670 static SECKEYPublicKey* nss_buf2ecdsa(unsigned char* key, size_t len, int algo)
671 {
672 	SECKEYPublicKey* pk;
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
679 	};
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
684 	};
685 	unsigned char buf[256+2]; /* sufficient for 2*384/8+1 */
686 
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 */
694 	} else    return NULL;
695 
696 	buf[0] = 0x04; /* POINT_FORM_UNCOMPRESSED */
697 	memmove(buf+1, key, len);
698 	pub.data = buf;
699 	pub.len = len+1;
700 	if(algo == LDNS_ECDSAP256SHA256) {
701 		params.data = param256;
702 		params.len = sizeof(param256);
703 	} else {
704 		params.data = param384;
705 		params.len = sizeof(param384);
706 	}
707 
708 	pk = nss_key_create(ecKey);
709 	if(!pk)
710 		return NULL;
711 	pk->u.ec.size = (len/2)*8;
712 	if(SECITEM_CopyItem(pk->arena, &pk->u.ec.publicValue, &pub)) {
713 		SECKEY_DestroyPublicKey(pk);
714 		return NULL;
715 	}
716 	if(SECITEM_CopyItem(pk->arena, &pk->u.ec.DEREncodedParams, &params)) {
717 		SECKEY_DestroyPublicKey(pk);
718 		return NULL;
719 	}
720 
721 	return pk;
722 }
723 
724 static SECKEYPublicKey* nss_buf2dsa(unsigned char* key, size_t len)
725 {
726 	SECKEYPublicKey* pk;
727 	uint8_t T;
728 	uint16_t length;
729 	uint16_t offset;
730 	SECItem Q = {siBuffer, NULL, 0};
731 	SECItem P = {siBuffer, NULL, 0};
732 	SECItem G = {siBuffer, NULL, 0};
733 	SECItem Y = {siBuffer, NULL, 0};
734 
735 	if(len == 0)
736 		return NULL;
737 	T = (uint8_t)key[0];
738 	length = (64 + T * 8);
739 	offset = 1;
740 
741 	if (T > 8) {
742 		return NULL;
743 	}
744 	if(len < (size_t)1 + SHA1_LENGTH + 3*length)
745 		return NULL;
746 
747 	Q.data = key+offset;
748 	Q.len = SHA1_LENGTH;
749 	offset += SHA1_LENGTH;
750 
751 	P.data = key+offset;
752 	P.len = length;
753 	offset += length;
754 
755 	G.data = key+offset;
756 	G.len = length;
757 	offset += length;
758 
759 	Y.data = key+offset;
760 	Y.len = length;
761 	offset += length;
762 
763 	pk = nss_key_create(dsaKey);
764 	if(!pk)
765 		return NULL;
766 	if(SECITEM_CopyItem(pk->arena, &pk->u.dsa.params.prime, &P)) {
767 		SECKEY_DestroyPublicKey(pk);
768 		return NULL;
769 	}
770 	if(SECITEM_CopyItem(pk->arena, &pk->u.dsa.params.subPrime, &Q)) {
771 		SECKEY_DestroyPublicKey(pk);
772 		return NULL;
773 	}
774 	if(SECITEM_CopyItem(pk->arena, &pk->u.dsa.params.base, &G)) {
775 		SECKEY_DestroyPublicKey(pk);
776 		return NULL;
777 	}
778 	if(SECITEM_CopyItem(pk->arena, &pk->u.dsa.publicValue, &Y)) {
779 		SECKEY_DestroyPublicKey(pk);
780 		return NULL;
781 	}
782 	return pk;
783 }
784 
785 static SECKEYPublicKey* nss_buf2rsa(unsigned char* key, size_t len)
786 {
787 	SECKEYPublicKey* pk;
788 	uint16_t exp;
789 	uint16_t offset;
790 	uint16_t int16;
791 	SECItem modulus = {siBuffer, NULL, 0};
792 	SECItem exponent = {siBuffer, NULL, 0};
793 	if(len == 0)
794 		return NULL;
795 	if(key[0] == 0) {
796 		if(len < 3)
797 			return NULL;
798 		/* the exponent is too large so it's places further */
799 		memmove(&int16, key+1, 2);
800 		exp = ntohs(int16);
801 		offset = 3;
802 	} else {
803 		exp = key[0];
804 		offset = 1;
805 	}
806 
807 	/* key length at least one */
808 	if(len < (size_t)offset + exp + 1)
809 		return NULL;
810 
811 	exponent.data = key+offset;
812 	exponent.len = exp;
813 	offset += exp;
814 	modulus.data = key+offset;
815 	modulus.len = (len - offset);
816 
817 	pk = nss_key_create(rsaKey);
818 	if(!pk)
819 		return NULL;
820 	if(SECITEM_CopyItem(pk->arena, &pk->u.rsa.modulus, &modulus)) {
821 		SECKEY_DestroyPublicKey(pk);
822 		return NULL;
823 	}
824 	if(SECITEM_CopyItem(pk->arena, &pk->u.rsa.publicExponent, &exponent)) {
825 		SECKEY_DestroyPublicKey(pk);
826 		return NULL;
827 	}
828 	return pk;
829 }
830 
831 /**
832  * Setup key and digest for verification. Adjust sig if necessary.
833  *
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.
842  */
843 static int
844 nss_setup_key_digest(int algo, SECKEYPublicKey** pubkey, HASH_HashType* htype,
845 	unsigned char* key, size_t keylen, unsigned char** prefix,
846 	size_t* prefixlen)
847 {
848 	/* uses libNSS */
849 
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};
856 	/* from RFC5702 */
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};
861 	/* from RFC6234 */
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};
865 	*/
866 
867 	switch(algo) {
868 		case LDNS_DSA:
869 		case LDNS_DSA_NSEC3:
870 			*pubkey = nss_buf2dsa(key, keylen);
871 			if(!*pubkey) {
872 				log_err("verify: malloc failure in crypto");
873 				return 0;
874 			}
875 			*htype = HASH_AlgSHA1;
876 			/* no prefix for DSA verification */
877 			break;
878 		case LDNS_RSASHA1:
879 		case LDNS_RSASHA1_NSEC3:
880 #ifdef USE_SHA2
881 		case LDNS_RSASHA256:
882 #endif
883 #ifdef USE_SHA2
884 		case LDNS_RSASHA512:
885 #endif
886 			*pubkey = nss_buf2rsa(key, keylen);
887 			if(!*pubkey) {
888 				log_err("verify: malloc failure in crypto");
889 				return 0;
890 			}
891 			/* select SHA version */
892 #ifdef USE_SHA2
893 			if(algo == LDNS_RSASHA256) {
894 				*htype = HASH_AlgSHA256;
895 				*prefix = p_sha256;
896 				*prefixlen = sizeof(p_sha256);
897 			} else
898 #endif
899 #ifdef USE_SHA2
900 				if(algo == LDNS_RSASHA512) {
901 				*htype = HASH_AlgSHA512;
902 				*prefix = p_sha512;
903 				*prefixlen = sizeof(p_sha512);
904 			} else
905 #endif
906 			{
907 				*htype = HASH_AlgSHA1;
908 				*prefix = p_sha1;
909 				*prefixlen = sizeof(p_sha1);
910 			}
911 
912 			break;
913 		case LDNS_RSAMD5:
914 			*pubkey = nss_buf2rsa(key, keylen);
915 			if(!*pubkey) {
916 				log_err("verify: malloc failure in crypto");
917 				return 0;
918 			}
919 			*htype = HASH_AlgMD5;
920 			*prefix = p_md5;
921 			*prefixlen = sizeof(p_md5);
922 
923 			break;
924 #ifdef USE_ECDSA
925 		case LDNS_ECDSAP256SHA256:
926 			*pubkey = nss_buf2ecdsa(key, keylen,
927 				LDNS_ECDSAP256SHA256);
928 			if(!*pubkey) {
929 				log_err("verify: malloc failure in crypto");
930 				return 0;
931 			}
932 			*htype = HASH_AlgSHA256;
933 			/* no prefix for DSA verification */
934 			break;
935 		case LDNS_ECDSAP384SHA384:
936 			*pubkey = nss_buf2ecdsa(key, keylen,
937 				LDNS_ECDSAP384SHA384);
938 			if(!*pubkey) {
939 				log_err("verify: malloc failure in crypto");
940 				return 0;
941 			}
942 			*htype = HASH_AlgSHA384;
943 			/* no prefix for DSA verification */
944 			break;
945 #endif /* USE_ECDSA */
946 		case LDNS_ECC_GOST:
947 		default:
948 			verbose(VERB_QUERY, "verify: unknown algorithm %d",
949 				algo);
950 			return 0;
951 	}
952 	return 1;
953 }
954 
955 /**
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.
967  */
968 enum sec_status
969 verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock,
970 	unsigned int sigblock_len, unsigned char* key, unsigned int keylen,
971 	char** reason)
972 {
973 	/* uses libNSS */
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};
981 	SECStatus res;
982 	unsigned char* prefix = NULL; /* prefix for hash, RFC3110, RFC5702 */
983 	size_t prefixlen = 0;
984 	int err;
985 
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;
992 	}
993 
994 	/* need to convert DSA, ECDSA signatures? */
995 	if((algo == LDNS_DSA || algo == LDNS_DSA_NSEC3)) {
996 		if(sigblock_len == 1+2*SHA1_LENGTH) {
997 			secsig.data ++;
998 			secsig.len --;
999 		} else {
1000 			SECItem* p = DSAU_DecodeDerSig(&secsig);
1001 			if(!p) {
1002 				verbose(VERB_QUERY, "verify: failed DER decode");
1003 				*reason = "signature DER decode failed";
1004 				SECKEY_DestroyPublicKey(pubkey);
1005 				return sec_status_bogus;
1006 			}
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;
1012 			}
1013 			SECITEM_FreeItem(p, PR_TRUE);
1014 		}
1015 	}
1016 
1017 	/* do the signature cryptography work */
1018 	/* hash the data */
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;
1024 	}
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;
1030 	}
1031 	if(prefix) {
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;
1037 		}
1038 		sechash.data = hash2;
1039 		sechash.len = prefixlen+hashlen;
1040 		memcpy(sechash.data, prefix, prefixlen);
1041 		memmove(sechash.data+prefixlen, hash, hashlen);
1042 	}
1043 
1044 	/* verify the signature */
1045 	res = PK11_Verify(pubkey, &secsig, &sechash, NULL /*wincx*/);
1046 	SECKEY_DestroyPublicKey(pubkey);
1047 
1048 	if(res == SECSuccess) {
1049 		return sec_status_secure;
1050 	}
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,
1062 		 * not unchecked */
1063 		*reason = "signature crypto failed";
1064 		return sec_status_bogus;
1065 	}
1066 	verbose(VERB_QUERY, "verify: signature mismatch: %s",
1067 		PORT_ErrorToString(err));
1068 	*reason = "signature crypto failed";
1069 	return sec_status_bogus;
1070 }
1071 
1072 
1073 #endif /* HAVE_SSL or HAVE_NSS */
1074