]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/unbound/validator/val_secalgo.c
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.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
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 "ldns/rrdef.h"
49 #include "ldns/keyraw.h"
50 #include "ldns/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 */