]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/unbound/validator/val_secalgo.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / unbound / validator / val_secalgo.c
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, &params)) {
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 */