]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/unbound/validator/val_secalgo.c
Upgrade to 1.8.1.
[FreeBSD/FreeBSD.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 "validator/val_nsec3.h"
48 #include "util/log.h"
49 #include "sldns/rrdef.h"
50 #include "sldns/keyraw.h"
51 #include "sldns/sbuffer.h"
52
53 #if !defined(HAVE_SSL) && !defined(HAVE_NSS) && !defined(HAVE_NETTLE)
54 #error "Need crypto library to do digital signature cryptography"
55 #endif
56
57 /* OpenSSL implementation */
58 #ifdef HAVE_SSL
59 #ifdef HAVE_OPENSSL_ERR_H
60 #include <openssl/err.h>
61 #endif
62
63 #ifdef HAVE_OPENSSL_RAND_H
64 #include <openssl/rand.h>
65 #endif
66
67 #ifdef HAVE_OPENSSL_CONF_H
68 #include <openssl/conf.h>
69 #endif
70
71 #ifdef HAVE_OPENSSL_ENGINE_H
72 #include <openssl/engine.h>
73 #endif
74
75 /** fake DSA support for unit tests */
76 int fake_dsa = 0;
77 /** fake SHA1 support for unit tests */
78 int fake_sha1 = 0;
79
80 /**
81  * Output a libcrypto openssl error to the logfile.
82  * @param str: string to add to it.
83  * @param e: the error to output, error number from ERR_get_error().
84  */
85 static void
86 log_crypto_error(const char* str, unsigned long e)
87 {
88         char buf[128];
89         /* or use ERR_error_string if ERR_error_string_n is not avail TODO */
90         ERR_error_string_n(e, buf, sizeof(buf));
91         /* buf now contains */
92         /* error:[error code]:[library name]:[function name]:[reason string] */
93         log_err("%s crypto %s", str, buf);
94 }
95
96 /* return size of digest if supported, or 0 otherwise */
97 size_t
98 nsec3_hash_algo_size_supported(int id)
99 {
100         switch(id) {
101         case NSEC3_HASH_SHA1:
102                 return SHA_DIGEST_LENGTH;
103         default:
104                 return 0;
105         }
106 }
107
108 /* perform nsec3 hash. return false on failure */
109 int
110 secalgo_nsec3_hash(int algo, unsigned char* buf, size_t len,
111         unsigned char* res)
112 {
113         switch(algo) {
114         case NSEC3_HASH_SHA1:
115 #ifdef OPENSSL_FIPS
116                 if(!sldns_digest_evp(buf, len, res, EVP_sha1()))
117                         log_crypto_error("could not digest with EVP_sha1",
118                                 ERR_get_error());
119 #else
120                 (void)SHA1(buf, len, res);
121 #endif
122                 return 1;
123         default:
124                 return 0;
125         }
126 }
127
128 void
129 secalgo_hash_sha256(unsigned char* buf, size_t len, unsigned char* res)
130 {
131 #ifdef OPENSSL_FIPS
132         if(!sldns_digest_evp(buf, len, res, EVP_sha256()))
133                 log_crypto_error("could not digest with EVP_sha256",
134                         ERR_get_error());
135 #else
136         (void)SHA256(buf, len, res);
137 #endif
138 }
139
140 /**
141  * Return size of DS digest according to its hash algorithm.
142  * @param algo: DS digest algo.
143  * @return size in bytes of digest, or 0 if not supported.
144  */
145 size_t
146 ds_digest_size_supported(int algo)
147 {
148         switch(algo) {
149                 case LDNS_SHA1:
150 #if defined(HAVE_EVP_SHA1) && defined(USE_SHA1)
151                         return SHA_DIGEST_LENGTH;
152 #else
153                         if(fake_sha1) return 20;
154                         return 0;
155 #endif
156 #ifdef HAVE_EVP_SHA256
157                 case LDNS_SHA256:
158                         return SHA256_DIGEST_LENGTH;
159 #endif
160 #ifdef USE_GOST
161                 case LDNS_HASH_GOST:
162                         /* we support GOST if it can be loaded */
163                         (void)sldns_key_EVP_load_gost_id();
164                         if(EVP_get_digestbyname("md_gost94"))
165                                 return 32;
166                         else    return 0;
167 #endif
168 #ifdef USE_ECDSA
169                 case LDNS_SHA384:
170                         return SHA384_DIGEST_LENGTH;
171 #endif
172                 default: break;
173         }
174         return 0;
175 }
176
177 #ifdef USE_GOST
178 /** Perform GOST hash */
179 static int
180 do_gost94(unsigned char* data, size_t len, unsigned char* dest)
181 {
182         const EVP_MD* md = EVP_get_digestbyname("md_gost94");
183         if(!md) 
184                 return 0;
185         return sldns_digest_evp(data, (unsigned int)len, dest, md);
186 }
187 #endif
188
189 int
190 secalgo_ds_digest(int algo, unsigned char* buf, size_t len,
191         unsigned char* res)
192 {
193         switch(algo) {
194 #if defined(HAVE_EVP_SHA1) && defined(USE_SHA1)
195                 case LDNS_SHA1:
196 #ifdef OPENSSL_FIPS
197                         if(!sldns_digest_evp(buf, len, res, EVP_sha1()))
198                                 log_crypto_error("could not digest with EVP_sha1",
199                                         ERR_get_error());
200 #else
201                         (void)SHA1(buf, len, res);
202 #endif
203                         return 1;
204 #endif
205 #ifdef HAVE_EVP_SHA256
206                 case LDNS_SHA256:
207 #ifdef OPENSSL_FIPS
208                         if(!sldns_digest_evp(buf, len, res, EVP_sha256()))
209                                 log_crypto_error("could not digest with EVP_sha256",
210                                         ERR_get_error());
211 #else
212                         (void)SHA256(buf, len, res);
213 #endif
214                         return 1;
215 #endif
216 #ifdef USE_GOST
217                 case LDNS_HASH_GOST:
218                         if(do_gost94(buf, len, res))
219                                 return 1;
220                         break;
221 #endif
222 #ifdef USE_ECDSA
223                 case LDNS_SHA384:
224 #ifdef OPENSSL_FIPS
225                         if(!sldns_digest_evp(buf, len, res, EVP_sha384()))
226                                 log_crypto_error("could not digest with EVP_sha384",
227                                         ERR_get_error());
228 #else
229                         (void)SHA384(buf, len, res);
230 #endif
231                         return 1;
232 #endif
233                 default: 
234                         verbose(VERB_QUERY, "unknown DS digest algorithm %d", 
235                                 algo);
236                         break;
237         }
238         return 0;
239 }
240
241 /** return true if DNSKEY algorithm id is supported */
242 int
243 dnskey_algo_id_is_supported(int id)
244 {
245         switch(id) {
246         case LDNS_RSAMD5:
247                 /* RFC 6725 deprecates RSAMD5 */
248                 return 0;
249         case LDNS_DSA:
250         case LDNS_DSA_NSEC3:
251 #if defined(USE_DSA) && defined(USE_SHA1)
252                 return 1;
253 #else
254                 if(fake_dsa || fake_sha1) return 1;
255                 return 0;
256 #endif
257
258         case LDNS_RSASHA1:
259         case LDNS_RSASHA1_NSEC3:
260 #ifdef USE_SHA1
261                 return 1;
262 #else
263                 if(fake_sha1) return 1;
264                 return 0;
265 #endif
266
267 #if defined(HAVE_EVP_SHA256) && defined(USE_SHA2)
268         case LDNS_RSASHA256:
269 #endif
270 #if defined(HAVE_EVP_SHA512) && defined(USE_SHA2)
271         case LDNS_RSASHA512:
272 #endif
273 #ifdef USE_ECDSA
274         case LDNS_ECDSAP256SHA256:
275         case LDNS_ECDSAP384SHA384:
276 #endif
277 #ifdef USE_ED25519
278         case LDNS_ED25519:
279 #endif
280 #ifdef USE_ED448
281         case LDNS_ED448:
282 #endif
283 #if (defined(HAVE_EVP_SHA256) && defined(USE_SHA2)) || (defined(HAVE_EVP_SHA512) && defined(USE_SHA2)) || defined(USE_ECDSA) || defined(USE_ED25519) || defined(USE_ED448)
284                 return 1;
285 #endif
286
287 #ifdef USE_GOST
288         case LDNS_ECC_GOST:
289                 /* we support GOST if it can be loaded */
290                 return sldns_key_EVP_load_gost_id();
291 #endif
292         default:
293                 return 0;
294         }
295 }
296
297 #ifdef USE_DSA
298 /**
299  * Setup DSA key digest in DER encoding ... 
300  * @param sig: input is signature output alloced ptr (unless failure).
301  *      caller must free alloced ptr if this routine returns true.
302  * @param len: input is initial siglen, output is output len.
303  * @return false on failure.
304  */
305 static int
306 setup_dsa_sig(unsigned char** sig, unsigned int* len)
307 {
308         unsigned char* orig = *sig;
309         unsigned int origlen = *len;
310         int newlen;
311         BIGNUM *R, *S;
312         DSA_SIG *dsasig;
313
314         /* extract the R and S field from the sig buffer */
315         if(origlen < 1 + 2*SHA_DIGEST_LENGTH)
316                 return 0;
317         R = BN_new();
318         if(!R) return 0;
319         (void) BN_bin2bn(orig + 1, SHA_DIGEST_LENGTH, R);
320         S = BN_new();
321         if(!S) return 0;
322         (void) BN_bin2bn(orig + 21, SHA_DIGEST_LENGTH, S);
323         dsasig = DSA_SIG_new();
324         if(!dsasig) return 0;
325
326 #ifdef HAVE_DSA_SIG_SET0
327         if(!DSA_SIG_set0(dsasig, R, S)) return 0;
328 #else
329         dsasig->r = R;
330         dsasig->s = S;
331 #endif
332         *sig = NULL;
333         newlen = i2d_DSA_SIG(dsasig, sig);
334         if(newlen < 0) {
335                 DSA_SIG_free(dsasig);
336                 free(*sig);
337                 return 0;
338         }
339         *len = (unsigned int)newlen;
340         DSA_SIG_free(dsasig);
341         return 1;
342 }
343 #endif /* USE_DSA */
344
345 #ifdef USE_ECDSA
346 /**
347  * Setup the ECDSA signature in its encoding that the library wants.
348  * Converts from plain numbers to ASN formatted.
349  * @param sig: input is signature, output alloced ptr (unless failure).
350  *      caller must free alloced ptr if this routine returns true.
351  * @param len: input is initial siglen, output is output len.
352  * @return false on failure.
353  */
354 static int
355 setup_ecdsa_sig(unsigned char** sig, unsigned int* len)
356 {
357         /* convert from two BIGNUMs in the rdata buffer, to ASN notation.
358          * ASN preamble: 30440220 <R 32bytefor256> 0220 <S 32bytefor256>
359          * the '20' is the length of that field (=bnsize).
360 i        * the '44' is the total remaining length.
361          * if negative, start with leading zero.
362          * if starts with 00s, remove them from the number.
363          */
364         uint8_t pre[] = {0x30, 0x44, 0x02, 0x20};
365         int pre_len = 4;
366         uint8_t mid[] = {0x02, 0x20};
367         int mid_len = 2;
368         int raw_sig_len, r_high, s_high, r_rem=0, s_rem=0;
369         int bnsize = (int)((*len)/2);
370         unsigned char* d = *sig;
371         uint8_t* p;
372         /* if too short or not even length, fails */
373         if(*len < 16 || bnsize*2 != (int)*len)
374                 return 0;
375
376         /* strip leading zeroes from r (but not last one) */
377         while(r_rem < bnsize-1 && d[r_rem] == 0)
378                 r_rem++;
379         /* strip leading zeroes from s (but not last one) */
380         while(s_rem < bnsize-1 && d[bnsize+s_rem] == 0)
381                 s_rem++;
382
383         r_high = ((d[0+r_rem]&0x80)?1:0);
384         s_high = ((d[bnsize+s_rem]&0x80)?1:0);
385         raw_sig_len = pre_len + r_high + bnsize - r_rem + mid_len +
386                 s_high + bnsize - s_rem;
387         *sig = (unsigned char*)malloc((size_t)raw_sig_len);
388         if(!*sig)
389                 return 0;
390         p = (uint8_t*)*sig;
391         p[0] = pre[0];
392         p[1] = (uint8_t)(raw_sig_len-2);
393         p[2] = pre[2];
394         p[3] = (uint8_t)(bnsize + r_high - r_rem);
395         p += 4;
396         if(r_high) {
397                 *p = 0;
398                 p += 1;
399         }
400         memmove(p, d+r_rem, (size_t)bnsize-r_rem);
401         p += bnsize-r_rem;
402         memmove(p, mid, (size_t)mid_len-1);
403         p += mid_len-1;
404         *p = (uint8_t)(bnsize + s_high - s_rem);
405         p += 1;
406         if(s_high) {
407                 *p = 0;
408                 p += 1;
409         }
410         memmove(p, d+bnsize+s_rem, (size_t)bnsize-s_rem);
411         *len = (unsigned int)raw_sig_len;
412         return 1;
413 }
414 #endif /* USE_ECDSA */
415
416 #ifdef USE_ECDSA_EVP_WORKAROUND
417 static EVP_MD ecdsa_evp_256_md;
418 static EVP_MD ecdsa_evp_384_md;
419 void ecdsa_evp_workaround_init(void)
420 {
421         /* openssl before 1.0.0 fixes RSA with the SHA256
422          * hash in EVP.  We create one for ecdsa_sha256 */
423         ecdsa_evp_256_md = *EVP_sha256();
424         ecdsa_evp_256_md.required_pkey_type[0] = EVP_PKEY_EC;
425         ecdsa_evp_256_md.verify = (void*)ECDSA_verify;
426
427         ecdsa_evp_384_md = *EVP_sha384();
428         ecdsa_evp_384_md.required_pkey_type[0] = EVP_PKEY_EC;
429         ecdsa_evp_384_md.verify = (void*)ECDSA_verify;
430 }
431 #endif /* USE_ECDSA_EVP_WORKAROUND */
432
433 /**
434  * Setup key and digest for verification. Adjust sig if necessary.
435  *
436  * @param algo: key algorithm
437  * @param evp_key: EVP PKEY public key to create.
438  * @param digest_type: digest type to use
439  * @param key: key to setup for.
440  * @param keylen: length of key.
441  * @return false on failure.
442  */
443 static int
444 setup_key_digest(int algo, EVP_PKEY** evp_key, const EVP_MD** digest_type, 
445         unsigned char* key, size_t keylen)
446 {
447 #if defined(USE_DSA) && defined(USE_SHA1)
448         DSA* dsa;
449 #endif
450         RSA* rsa;
451
452         switch(algo) {
453 #if defined(USE_DSA) && defined(USE_SHA1)
454                 case LDNS_DSA:
455                 case LDNS_DSA_NSEC3:
456                         *evp_key = EVP_PKEY_new();
457                         if(!*evp_key) {
458                                 log_err("verify: malloc failure in crypto");
459                                 return 0;
460                         }
461                         dsa = sldns_key_buf2dsa_raw(key, keylen);
462                         if(!dsa) {
463                                 verbose(VERB_QUERY, "verify: "
464                                         "sldns_key_buf2dsa_raw failed");
465                                 return 0;
466                         }
467                         if(EVP_PKEY_assign_DSA(*evp_key, dsa) == 0) {
468                                 verbose(VERB_QUERY, "verify: "
469                                         "EVP_PKEY_assign_DSA failed");
470                                 return 0;
471                         }
472 #ifdef HAVE_EVP_DSS1
473                         *digest_type = EVP_dss1();
474 #else
475                         *digest_type = EVP_sha1();
476 #endif
477
478                         break;
479 #endif /* USE_DSA && USE_SHA1 */
480
481 #if defined(USE_SHA1) || (defined(HAVE_EVP_SHA256) && defined(USE_SHA2)) || (defined(HAVE_EVP_SHA512) && defined(USE_SHA2))
482 #ifdef USE_SHA1
483                 case LDNS_RSASHA1:
484                 case LDNS_RSASHA1_NSEC3:
485 #endif
486 #if defined(HAVE_EVP_SHA256) && defined(USE_SHA2)
487                 case LDNS_RSASHA256:
488 #endif
489 #if defined(HAVE_EVP_SHA512) && defined(USE_SHA2)
490                 case LDNS_RSASHA512:
491 #endif
492                         *evp_key = EVP_PKEY_new();
493                         if(!*evp_key) {
494                                 log_err("verify: malloc failure in crypto");
495                                 return 0;
496                         }
497                         rsa = sldns_key_buf2rsa_raw(key, keylen);
498                         if(!rsa) {
499                                 verbose(VERB_QUERY, "verify: "
500                                         "sldns_key_buf2rsa_raw SHA failed");
501                                 return 0;
502                         }
503                         if(EVP_PKEY_assign_RSA(*evp_key, rsa) == 0) {
504                                 verbose(VERB_QUERY, "verify: "
505                                         "EVP_PKEY_assign_RSA SHA failed");
506                                 return 0;
507                         }
508
509                         /* select SHA version */
510 #if defined(HAVE_EVP_SHA256) && defined(USE_SHA2)
511                         if(algo == LDNS_RSASHA256)
512                                 *digest_type = EVP_sha256();
513                         else
514 #endif
515 #if defined(HAVE_EVP_SHA512) && defined(USE_SHA2)
516                                 if(algo == LDNS_RSASHA512)
517                                 *digest_type = EVP_sha512();
518                         else
519 #endif
520 #ifdef USE_SHA1
521                                 *digest_type = EVP_sha1();
522 #else
523                                 { verbose(VERB_QUERY, "no digest available"); return 0; }
524 #endif
525                         break;
526 #endif /* defined(USE_SHA1) || (defined(HAVE_EVP_SHA256) && defined(USE_SHA2)) || (defined(HAVE_EVP_SHA512) && defined(USE_SHA2)) */
527
528                 case LDNS_RSAMD5:
529                         *evp_key = EVP_PKEY_new();
530                         if(!*evp_key) {
531                                 log_err("verify: malloc failure in crypto");
532                                 return 0;
533                         }
534                         rsa = sldns_key_buf2rsa_raw(key, keylen);
535                         if(!rsa) {
536                                 verbose(VERB_QUERY, "verify: "
537                                         "sldns_key_buf2rsa_raw MD5 failed");
538                                 return 0;
539                         }
540                         if(EVP_PKEY_assign_RSA(*evp_key, rsa) == 0) {
541                                 verbose(VERB_QUERY, "verify: "
542                                         "EVP_PKEY_assign_RSA MD5 failed");
543                                 return 0;
544                         }
545                         *digest_type = EVP_md5();
546
547                         break;
548 #ifdef USE_GOST
549                 case LDNS_ECC_GOST:
550                         *evp_key = sldns_gost2pkey_raw(key, keylen);
551                         if(!*evp_key) {
552                                 verbose(VERB_QUERY, "verify: "
553                                         "sldns_gost2pkey_raw failed");
554                                 return 0;
555                         }
556                         *digest_type = EVP_get_digestbyname("md_gost94");
557                         if(!*digest_type) {
558                                 verbose(VERB_QUERY, "verify: "
559                                         "EVP_getdigest md_gost94 failed");
560                                 return 0;
561                         }
562                         break;
563 #endif
564 #ifdef USE_ECDSA
565                 case LDNS_ECDSAP256SHA256:
566                         *evp_key = sldns_ecdsa2pkey_raw(key, keylen,
567                                 LDNS_ECDSAP256SHA256);
568                         if(!*evp_key) {
569                                 verbose(VERB_QUERY, "verify: "
570                                         "sldns_ecdsa2pkey_raw failed");
571                                 return 0;
572                         }
573 #ifdef USE_ECDSA_EVP_WORKAROUND
574                         *digest_type = &ecdsa_evp_256_md;
575 #else
576                         *digest_type = EVP_sha256();
577 #endif
578                         break;
579                 case LDNS_ECDSAP384SHA384:
580                         *evp_key = sldns_ecdsa2pkey_raw(key, keylen,
581                                 LDNS_ECDSAP384SHA384);
582                         if(!*evp_key) {
583                                 verbose(VERB_QUERY, "verify: "
584                                         "sldns_ecdsa2pkey_raw failed");
585                                 return 0;
586                         }
587 #ifdef USE_ECDSA_EVP_WORKAROUND
588                         *digest_type = &ecdsa_evp_384_md;
589 #else
590                         *digest_type = EVP_sha384();
591 #endif
592                         break;
593 #endif /* USE_ECDSA */
594 #ifdef USE_ED25519
595                 case LDNS_ED25519:
596                         *evp_key = sldns_ed255192pkey_raw(key, keylen);
597                         if(!*evp_key) {
598                                 verbose(VERB_QUERY, "verify: "
599                                         "sldns_ed255192pkey_raw failed");
600                                 return 0;
601                         }
602                         *digest_type = NULL;
603                         break;
604 #endif /* USE_ED25519 */
605 #ifdef USE_ED448
606                 case LDNS_ED448:
607                         *evp_key = sldns_ed4482pkey_raw(key, keylen);
608                         if(!*evp_key) {
609                                 verbose(VERB_QUERY, "verify: "
610                                         "sldns_ed4482pkey_raw failed");
611                                 return 0;
612                         }
613                         *digest_type = NULL;
614                         break;
615 #endif /* USE_ED448 */
616                 default:
617                         verbose(VERB_QUERY, "verify: unknown algorithm %d", 
618                                 algo);
619                         return 0;
620         }
621         return 1;
622 }
623
624 /**
625  * Check a canonical sig+rrset and signature against a dnskey
626  * @param buf: buffer with data to verify, the first rrsig part and the
627  *      canonicalized rrset.
628  * @param algo: DNSKEY algorithm.
629  * @param sigblock: signature rdata field from RRSIG
630  * @param sigblock_len: length of sigblock data.
631  * @param key: public key data from DNSKEY RR.
632  * @param keylen: length of keydata.
633  * @param reason: bogus reason in more detail.
634  * @return secure if verification succeeded, bogus on crypto failure,
635  *      unchecked on format errors and alloc failures.
636  */
637 enum sec_status
638 verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock, 
639         unsigned int sigblock_len, unsigned char* key, unsigned int keylen,
640         char** reason)
641 {
642         const EVP_MD *digest_type;
643         EVP_MD_CTX* ctx;
644         int res, dofree = 0, docrypto_free = 0;
645         EVP_PKEY *evp_key = NULL;
646
647 #ifndef USE_DSA
648         if((algo == LDNS_DSA || algo == LDNS_DSA_NSEC3) &&(fake_dsa||fake_sha1))
649                 return sec_status_secure;
650 #endif
651 #ifndef USE_SHA1
652         if(fake_sha1 && (algo == LDNS_DSA || algo == LDNS_DSA_NSEC3 || algo == LDNS_RSASHA1 || algo == LDNS_RSASHA1_NSEC3))
653                 return sec_status_secure;
654 #endif
655         
656         if(!setup_key_digest(algo, &evp_key, &digest_type, key, keylen)) {
657                 verbose(VERB_QUERY, "verify: failed to setup key");
658                 *reason = "use of key for crypto failed";
659                 EVP_PKEY_free(evp_key);
660                 return sec_status_bogus;
661         }
662 #ifdef USE_DSA
663         /* if it is a DSA signature in bind format, convert to DER format */
664         if((algo == LDNS_DSA || algo == LDNS_DSA_NSEC3) && 
665                 sigblock_len == 1+2*SHA_DIGEST_LENGTH) {
666                 if(!setup_dsa_sig(&sigblock, &sigblock_len)) {
667                         verbose(VERB_QUERY, "verify: failed to setup DSA sig");
668                         *reason = "use of key for DSA crypto failed";
669                         EVP_PKEY_free(evp_key);
670                         return sec_status_bogus;
671                 }
672                 docrypto_free = 1;
673         }
674 #endif
675 #if defined(USE_ECDSA) && defined(USE_DSA)
676         else 
677 #endif
678 #ifdef USE_ECDSA
679         if(algo == LDNS_ECDSAP256SHA256 || algo == LDNS_ECDSAP384SHA384) {
680                 /* EVP uses ASN prefix on sig, which is not in the wire data */
681                 if(!setup_ecdsa_sig(&sigblock, &sigblock_len)) {
682                         verbose(VERB_QUERY, "verify: failed to setup ECDSA sig");
683                         *reason = "use of signature for ECDSA crypto failed";
684                         EVP_PKEY_free(evp_key);
685                         return sec_status_bogus;
686                 }
687                 dofree = 1;
688         }
689 #endif /* USE_ECDSA */
690
691         /* do the signature cryptography work */
692 #ifdef HAVE_EVP_MD_CTX_NEW
693         ctx = EVP_MD_CTX_new();
694 #else
695         ctx = (EVP_MD_CTX*)malloc(sizeof(*ctx));
696         if(ctx) EVP_MD_CTX_init(ctx);
697 #endif
698         if(!ctx) {
699                 log_err("EVP_MD_CTX_new: malloc failure");
700                 EVP_PKEY_free(evp_key);
701                 if(dofree) free(sigblock);
702                 else if(docrypto_free) OPENSSL_free(sigblock);
703                 return sec_status_unchecked;
704         }
705 #ifndef HAVE_EVP_DIGESTVERIFY
706         if(EVP_DigestInit(ctx, digest_type) == 0) {
707                 verbose(VERB_QUERY, "verify: EVP_DigestInit failed");
708 #ifdef HAVE_EVP_MD_CTX_NEW
709                 EVP_MD_CTX_destroy(ctx);
710 #else
711                 EVP_MD_CTX_cleanup(ctx);
712                 free(ctx);
713 #endif
714                 EVP_PKEY_free(evp_key);
715                 if(dofree) free(sigblock);
716                 else if(docrypto_free) OPENSSL_free(sigblock);
717                 return sec_status_unchecked;
718         }
719         if(EVP_DigestUpdate(ctx, (unsigned char*)sldns_buffer_begin(buf), 
720                 (unsigned int)sldns_buffer_limit(buf)) == 0) {
721                 verbose(VERB_QUERY, "verify: EVP_DigestUpdate failed");
722 #ifdef HAVE_EVP_MD_CTX_NEW
723                 EVP_MD_CTX_destroy(ctx);
724 #else
725                 EVP_MD_CTX_cleanup(ctx);
726                 free(ctx);
727 #endif
728                 EVP_PKEY_free(evp_key);
729                 if(dofree) free(sigblock);
730                 else if(docrypto_free) OPENSSL_free(sigblock);
731                 return sec_status_unchecked;
732         }
733
734         res = EVP_VerifyFinal(ctx, sigblock, sigblock_len, evp_key);
735 #else /* HAVE_EVP_DIGESTVERIFY */
736         if(EVP_DigestVerifyInit(ctx, NULL, digest_type, NULL, evp_key) == 0) {
737                 verbose(VERB_QUERY, "verify: EVP_DigestVerifyInit failed");
738 #ifdef HAVE_EVP_MD_CTX_NEW
739                 EVP_MD_CTX_destroy(ctx);
740 #else
741                 EVP_MD_CTX_cleanup(ctx);
742                 free(ctx);
743 #endif
744                 EVP_PKEY_free(evp_key);
745                 if(dofree) free(sigblock);
746                 else if(docrypto_free) OPENSSL_free(sigblock);
747                 return sec_status_unchecked;
748         }
749         res = EVP_DigestVerify(ctx, sigblock, sigblock_len,
750                 (unsigned char*)sldns_buffer_begin(buf),
751                 sldns_buffer_limit(buf));
752 #endif
753 #ifdef HAVE_EVP_MD_CTX_NEW
754         EVP_MD_CTX_destroy(ctx);
755 #else
756         EVP_MD_CTX_cleanup(ctx);
757         free(ctx);
758 #endif
759         EVP_PKEY_free(evp_key);
760
761         if(dofree) free(sigblock);
762         else if(docrypto_free) OPENSSL_free(sigblock);
763
764         if(res == 1) {
765                 return sec_status_secure;
766         } else if(res == 0) {
767                 verbose(VERB_QUERY, "verify: signature mismatch");
768                 *reason = "signature crypto failed";
769                 return sec_status_bogus;
770         }
771
772         log_crypto_error("verify:", ERR_get_error());
773         return sec_status_unchecked;
774 }
775
776 /**************************************************/
777 #elif defined(HAVE_NSS)
778 /* libnss implementation */
779 /* nss3 */
780 #include "sechash.h"
781 #include "pk11pub.h"
782 #include "keyhi.h"
783 #include "secerr.h"
784 #include "cryptohi.h"
785 /* nspr4 */
786 #include "prerror.h"
787
788 /* return size of digest if supported, or 0 otherwise */
789 size_t
790 nsec3_hash_algo_size_supported(int id)
791 {
792         switch(id) {
793         case NSEC3_HASH_SHA1:
794                 return SHA1_LENGTH;
795         default:
796                 return 0;
797         }
798 }
799
800 /* perform nsec3 hash. return false on failure */
801 int
802 secalgo_nsec3_hash(int algo, unsigned char* buf, size_t len,
803         unsigned char* res)
804 {
805         switch(algo) {
806         case NSEC3_HASH_SHA1:
807                 (void)HASH_HashBuf(HASH_AlgSHA1, res, buf, (unsigned long)len);
808                 return 1;
809         default:
810                 return 0;
811         }
812 }
813
814 void
815 secalgo_hash_sha256(unsigned char* buf, size_t len, unsigned char* res)
816 {
817         (void)HASH_HashBuf(HASH_AlgSHA256, res, buf, (unsigned long)len);
818 }
819
820 size_t
821 ds_digest_size_supported(int algo)
822 {
823         /* uses libNSS */
824         switch(algo) {
825 #ifdef USE_SHA1
826                 case LDNS_SHA1:
827                         return SHA1_LENGTH;
828 #endif
829 #ifdef USE_SHA2
830                 case LDNS_SHA256:
831                         return SHA256_LENGTH;
832 #endif
833 #ifdef USE_ECDSA
834                 case LDNS_SHA384:
835                         return SHA384_LENGTH;
836 #endif
837                 /* GOST not supported in NSS */
838                 case LDNS_HASH_GOST:
839                 default: break;
840         }
841         return 0;
842 }
843
844 int
845 secalgo_ds_digest(int algo, unsigned char* buf, size_t len,
846         unsigned char* res)
847 {
848         /* uses libNSS */
849         switch(algo) {
850 #ifdef USE_SHA1
851                 case LDNS_SHA1:
852                         return HASH_HashBuf(HASH_AlgSHA1, res, buf, len)
853                                 == SECSuccess;
854 #endif
855 #if defined(USE_SHA2)
856                 case LDNS_SHA256:
857                         return HASH_HashBuf(HASH_AlgSHA256, res, buf, len)
858                                 == SECSuccess;
859 #endif
860 #ifdef USE_ECDSA
861                 case LDNS_SHA384:
862                         return HASH_HashBuf(HASH_AlgSHA384, res, buf, len)
863                                 == SECSuccess;
864 #endif
865                 case LDNS_HASH_GOST:
866                 default: 
867                         verbose(VERB_QUERY, "unknown DS digest algorithm %d", 
868                                 algo);
869                         break;
870         }
871         return 0;
872 }
873
874 int
875 dnskey_algo_id_is_supported(int id)
876 {
877         /* uses libNSS */
878         switch(id) {
879         case LDNS_RSAMD5:
880                 /* RFC 6725 deprecates RSAMD5 */
881                 return 0;
882 #if defined(USE_SHA1) || defined(USE_SHA2)
883 #if defined(USE_DSA) && defined(USE_SHA1)
884         case LDNS_DSA:
885         case LDNS_DSA_NSEC3:
886 #endif
887 #ifdef USE_SHA1
888         case LDNS_RSASHA1:
889         case LDNS_RSASHA1_NSEC3:
890 #endif
891 #ifdef USE_SHA2
892         case LDNS_RSASHA256:
893 #endif
894 #ifdef USE_SHA2
895         case LDNS_RSASHA512:
896 #endif
897                 return 1;
898 #endif /* SHA1 or SHA2 */
899
900 #ifdef USE_ECDSA
901         case LDNS_ECDSAP256SHA256:
902         case LDNS_ECDSAP384SHA384:
903                 return PK11_TokenExists(CKM_ECDSA);
904 #endif
905         case LDNS_ECC_GOST:
906         default:
907                 return 0;
908         }
909 }
910
911 /* return a new public key for NSS */
912 static SECKEYPublicKey* nss_key_create(KeyType ktype)
913 {
914         SECKEYPublicKey* key;
915         PLArenaPool* arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
916         if(!arena) {
917                 log_err("out of memory, PORT_NewArena failed");
918                 return NULL;
919         }
920         key = PORT_ArenaZNew(arena, SECKEYPublicKey);
921         if(!key) {
922                 log_err("out of memory, PORT_ArenaZNew failed");
923                 PORT_FreeArena(arena, PR_FALSE);
924                 return NULL;
925         }
926         key->arena = arena;
927         key->keyType = ktype;
928         key->pkcs11Slot = NULL;
929         key->pkcs11ID = CK_INVALID_HANDLE;
930         return key;
931 }
932
933 static SECKEYPublicKey* nss_buf2ecdsa(unsigned char* key, size_t len, int algo)
934 {
935         SECKEYPublicKey* pk;
936         SECItem pub = {siBuffer, NULL, 0};
937         SECItem params = {siBuffer, NULL, 0};
938         static unsigned char param256[] = {
939                 /* OBJECTIDENTIFIER 1.2.840.10045.3.1.7 (P-256)
940                  * {iso(1) member-body(2) us(840) ansi-x962(10045) curves(3) prime(1) prime256v1(7)} */
941                 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07
942         };
943         static unsigned char param384[] = {
944                 /* OBJECTIDENTIFIER 1.3.132.0.34 (P-384)
945                  * {iso(1) identified-organization(3) certicom(132) curve(0) ansip384r1(34)} */
946                 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x22
947         };
948         unsigned char buf[256+2]; /* sufficient for 2*384/8+1 */
949
950         /* check length, which uncompressed must be 2 bignums */
951         if(algo == LDNS_ECDSAP256SHA256) {
952                 if(len != 2*256/8) return NULL;
953                 /* ECCurve_X9_62_PRIME_256V1 */
954         } else if(algo == LDNS_ECDSAP384SHA384) {
955                 if(len != 2*384/8) return NULL;
956                 /* ECCurve_X9_62_PRIME_384R1 */
957         } else    return NULL;
958
959         buf[0] = 0x04; /* POINT_FORM_UNCOMPRESSED */
960         memmove(buf+1, key, len);
961         pub.data = buf;
962         pub.len = len+1;
963         if(algo == LDNS_ECDSAP256SHA256) {
964                 params.data = param256;
965                 params.len = sizeof(param256);
966         } else {
967                 params.data = param384;
968                 params.len = sizeof(param384);
969         }
970
971         pk = nss_key_create(ecKey);
972         if(!pk)
973                 return NULL;
974         pk->u.ec.size = (len/2)*8;
975         if(SECITEM_CopyItem(pk->arena, &pk->u.ec.publicValue, &pub)) {
976                 SECKEY_DestroyPublicKey(pk);
977                 return NULL;
978         }
979         if(SECITEM_CopyItem(pk->arena, &pk->u.ec.DEREncodedParams, &params)) {
980                 SECKEY_DestroyPublicKey(pk);
981                 return NULL;
982         }
983
984         return pk;
985 }
986
987 static SECKEYPublicKey* nss_buf2dsa(unsigned char* key, size_t len)
988 {
989         SECKEYPublicKey* pk;
990         uint8_t T;
991         uint16_t length;
992         uint16_t offset;
993         SECItem Q = {siBuffer, NULL, 0};
994         SECItem P = {siBuffer, NULL, 0};
995         SECItem G = {siBuffer, NULL, 0};
996         SECItem Y = {siBuffer, NULL, 0};
997
998         if(len == 0)
999                 return NULL;
1000         T = (uint8_t)key[0];
1001         length = (64 + T * 8);
1002         offset = 1;
1003
1004         if (T > 8) {
1005                 return NULL;
1006         }
1007         if(len < (size_t)1 + SHA1_LENGTH + 3*length)
1008                 return NULL;
1009
1010         Q.data = key+offset;
1011         Q.len = SHA1_LENGTH;
1012         offset += SHA1_LENGTH;
1013
1014         P.data = key+offset;
1015         P.len = length;
1016         offset += length;
1017
1018         G.data = key+offset;
1019         G.len = length;
1020         offset += length;
1021
1022         Y.data = key+offset;
1023         Y.len = length;
1024         offset += length;
1025
1026         pk = nss_key_create(dsaKey);
1027         if(!pk)
1028                 return NULL;
1029         if(SECITEM_CopyItem(pk->arena, &pk->u.dsa.params.prime, &P)) {
1030                 SECKEY_DestroyPublicKey(pk);
1031                 return NULL;
1032         }
1033         if(SECITEM_CopyItem(pk->arena, &pk->u.dsa.params.subPrime, &Q)) {
1034                 SECKEY_DestroyPublicKey(pk);
1035                 return NULL;
1036         }
1037         if(SECITEM_CopyItem(pk->arena, &pk->u.dsa.params.base, &G)) {
1038                 SECKEY_DestroyPublicKey(pk);
1039                 return NULL;
1040         }
1041         if(SECITEM_CopyItem(pk->arena, &pk->u.dsa.publicValue, &Y)) {
1042                 SECKEY_DestroyPublicKey(pk);
1043                 return NULL;
1044         }
1045         return pk;
1046 }
1047
1048 static SECKEYPublicKey* nss_buf2rsa(unsigned char* key, size_t len)
1049 {
1050         SECKEYPublicKey* pk;
1051         uint16_t exp;
1052         uint16_t offset;
1053         uint16_t int16;
1054         SECItem modulus = {siBuffer, NULL, 0};
1055         SECItem exponent = {siBuffer, NULL, 0};
1056         if(len == 0)
1057                 return NULL;
1058         if(key[0] == 0) {
1059                 if(len < 3)
1060                         return NULL;
1061                 /* the exponent is too large so it's places further */
1062                 memmove(&int16, key+1, 2);
1063                 exp = ntohs(int16);
1064                 offset = 3;
1065         } else {
1066                 exp = key[0];
1067                 offset = 1;
1068         }
1069
1070         /* key length at least one */
1071         if(len < (size_t)offset + exp + 1)
1072                 return NULL;
1073         
1074         exponent.data = key+offset;
1075         exponent.len = exp;
1076         offset += exp;
1077         modulus.data = key+offset;
1078         modulus.len = (len - offset);
1079
1080         pk = nss_key_create(rsaKey);
1081         if(!pk)
1082                 return NULL;
1083         if(SECITEM_CopyItem(pk->arena, &pk->u.rsa.modulus, &modulus)) {
1084                 SECKEY_DestroyPublicKey(pk);
1085                 return NULL;
1086         }
1087         if(SECITEM_CopyItem(pk->arena, &pk->u.rsa.publicExponent, &exponent)) {
1088                 SECKEY_DestroyPublicKey(pk);
1089                 return NULL;
1090         }
1091         return pk;
1092 }
1093
1094 /**
1095  * Setup key and digest for verification. Adjust sig if necessary.
1096  *
1097  * @param algo: key algorithm
1098  * @param evp_key: EVP PKEY public key to create.
1099  * @param digest_type: digest type to use
1100  * @param key: key to setup for.
1101  * @param keylen: length of key.
1102  * @param prefix: if returned, the ASN prefix for the hashblob.
1103  * @param prefixlen: length of the prefix.
1104  * @return false on failure.
1105  */
1106 static int
1107 nss_setup_key_digest(int algo, SECKEYPublicKey** pubkey, HASH_HashType* htype,
1108         unsigned char* key, size_t keylen, unsigned char** prefix,
1109         size_t* prefixlen)
1110 {
1111         /* uses libNSS */
1112
1113         /* hash prefix for md5, RFC2537 */
1114         static unsigned char p_md5[] = {0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a,
1115         0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10};
1116         /* hash prefix to prepend to hash output, from RFC3110 */
1117         static unsigned char p_sha1[] = {0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B,
1118                 0x0E, 0x03, 0x02, 0x1A, 0x05, 0x00, 0x04, 0x14};
1119         /* from RFC5702 */
1120         static unsigned char p_sha256[] = {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60,
1121         0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20};
1122         static unsigned char p_sha512[] = {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60,
1123         0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40};
1124         /* from RFC6234 */
1125         /* for future RSASHA384 .. 
1126         static unsigned char p_sha384[] = {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60,
1127         0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30};
1128         */
1129
1130         switch(algo) {
1131
1132 #if defined(USE_SHA1) || defined(USE_SHA2)
1133 #if defined(USE_DSA) && defined(USE_SHA1)
1134                 case LDNS_DSA:
1135                 case LDNS_DSA_NSEC3:
1136                         *pubkey = nss_buf2dsa(key, keylen);
1137                         if(!*pubkey) {
1138                                 log_err("verify: malloc failure in crypto");
1139                                 return 0;
1140                         }
1141                         *htype = HASH_AlgSHA1;
1142                         /* no prefix for DSA verification */
1143                         break;
1144 #endif
1145 #ifdef USE_SHA1
1146                 case LDNS_RSASHA1:
1147                 case LDNS_RSASHA1_NSEC3:
1148 #endif
1149 #ifdef USE_SHA2
1150                 case LDNS_RSASHA256:
1151 #endif
1152 #ifdef USE_SHA2
1153                 case LDNS_RSASHA512:
1154 #endif
1155                         *pubkey = nss_buf2rsa(key, keylen);
1156                         if(!*pubkey) {
1157                                 log_err("verify: malloc failure in crypto");
1158                                 return 0;
1159                         }
1160                         /* select SHA version */
1161 #ifdef USE_SHA2
1162                         if(algo == LDNS_RSASHA256) {
1163                                 *htype = HASH_AlgSHA256;
1164                                 *prefix = p_sha256;
1165                                 *prefixlen = sizeof(p_sha256);
1166                         } else
1167 #endif
1168 #ifdef USE_SHA2
1169                                 if(algo == LDNS_RSASHA512) {
1170                                 *htype = HASH_AlgSHA512;
1171                                 *prefix = p_sha512;
1172                                 *prefixlen = sizeof(p_sha512);
1173                         } else
1174 #endif
1175 #ifdef USE_SHA1
1176                         {
1177                                 *htype = HASH_AlgSHA1;
1178                                 *prefix = p_sha1;
1179                                 *prefixlen = sizeof(p_sha1);
1180                         }
1181 #else
1182                         {
1183                                 verbose(VERB_QUERY, "verify: no digest algo");
1184                                 return 0;
1185                         }
1186 #endif
1187
1188                         break;
1189 #endif /* SHA1 or SHA2 */
1190
1191                 case LDNS_RSAMD5:
1192                         *pubkey = nss_buf2rsa(key, keylen);
1193                         if(!*pubkey) {
1194                                 log_err("verify: malloc failure in crypto");
1195                                 return 0;
1196                         }
1197                         *htype = HASH_AlgMD5;
1198                         *prefix = p_md5;
1199                         *prefixlen = sizeof(p_md5);
1200
1201                         break;
1202 #ifdef USE_ECDSA
1203                 case LDNS_ECDSAP256SHA256:
1204                         *pubkey = nss_buf2ecdsa(key, keylen,
1205                                 LDNS_ECDSAP256SHA256);
1206                         if(!*pubkey) {
1207                                 log_err("verify: malloc failure in crypto");
1208                                 return 0;
1209                         }
1210                         *htype = HASH_AlgSHA256;
1211                         /* no prefix for DSA verification */
1212                         break;
1213                 case LDNS_ECDSAP384SHA384:
1214                         *pubkey = nss_buf2ecdsa(key, keylen,
1215                                 LDNS_ECDSAP384SHA384);
1216                         if(!*pubkey) {
1217                                 log_err("verify: malloc failure in crypto");
1218                                 return 0;
1219                         }
1220                         *htype = HASH_AlgSHA384;
1221                         /* no prefix for DSA verification */
1222                         break;
1223 #endif /* USE_ECDSA */
1224                 case LDNS_ECC_GOST:
1225                 default:
1226                         verbose(VERB_QUERY, "verify: unknown algorithm %d", 
1227                                 algo);
1228                         return 0;
1229         }
1230         return 1;
1231 }
1232
1233 /**
1234  * Check a canonical sig+rrset and signature against a dnskey
1235  * @param buf: buffer with data to verify, the first rrsig part and the
1236  *      canonicalized rrset.
1237  * @param algo: DNSKEY algorithm.
1238  * @param sigblock: signature rdata field from RRSIG
1239  * @param sigblock_len: length of sigblock data.
1240  * @param key: public key data from DNSKEY RR.
1241  * @param keylen: length of keydata.
1242  * @param reason: bogus reason in more detail.
1243  * @return secure if verification succeeded, bogus on crypto failure,
1244  *      unchecked on format errors and alloc failures.
1245  */
1246 enum sec_status
1247 verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock, 
1248         unsigned int sigblock_len, unsigned char* key, unsigned int keylen,
1249         char** reason)
1250 {
1251         /* uses libNSS */
1252         /* large enough for the different hashes */
1253         unsigned char hash[HASH_LENGTH_MAX];
1254         unsigned char hash2[HASH_LENGTH_MAX*2];
1255         HASH_HashType htype = 0;
1256         SECKEYPublicKey* pubkey = NULL;
1257         SECItem secsig = {siBuffer, sigblock, sigblock_len};
1258         SECItem sechash = {siBuffer, hash, 0};
1259         SECStatus res;
1260         unsigned char* prefix = NULL; /* prefix for hash, RFC3110, RFC5702 */
1261         size_t prefixlen = 0;
1262         int err;
1263
1264         if(!nss_setup_key_digest(algo, &pubkey, &htype, key, keylen,
1265                 &prefix, &prefixlen)) {
1266                 verbose(VERB_QUERY, "verify: failed to setup key");
1267                 *reason = "use of key for crypto failed";
1268                 SECKEY_DestroyPublicKey(pubkey);
1269                 return sec_status_bogus;
1270         }
1271
1272 #if defined(USE_DSA) && defined(USE_SHA1)
1273         /* need to convert DSA, ECDSA signatures? */
1274         if((algo == LDNS_DSA || algo == LDNS_DSA_NSEC3)) {
1275                 if(sigblock_len == 1+2*SHA1_LENGTH) {
1276                         secsig.data ++;
1277                         secsig.len --;
1278                 } else {
1279                         SECItem* p = DSAU_DecodeDerSig(&secsig);
1280                         if(!p) {
1281                                 verbose(VERB_QUERY, "verify: failed DER decode");
1282                                 *reason = "signature DER decode failed";
1283                                 SECKEY_DestroyPublicKey(pubkey);
1284                                 return sec_status_bogus;
1285                         }
1286                         if(SECITEM_CopyItem(pubkey->arena, &secsig, p)) {
1287                                 log_err("alloc failure in DER decode");
1288                                 SECKEY_DestroyPublicKey(pubkey);
1289                                 SECITEM_FreeItem(p, PR_TRUE);
1290                                 return sec_status_unchecked;
1291                         }
1292                         SECITEM_FreeItem(p, PR_TRUE);
1293                 }
1294         }
1295 #endif /* USE_DSA */
1296
1297         /* do the signature cryptography work */
1298         /* hash the data */
1299         sechash.len = HASH_ResultLen(htype);
1300         if(sechash.len > sizeof(hash)) {
1301                 verbose(VERB_QUERY, "verify: hash too large for buffer");
1302                 SECKEY_DestroyPublicKey(pubkey);
1303                 return sec_status_unchecked;
1304         }
1305         if(HASH_HashBuf(htype, hash, (unsigned char*)sldns_buffer_begin(buf),
1306                 (unsigned int)sldns_buffer_limit(buf)) != SECSuccess) {
1307                 verbose(VERB_QUERY, "verify: HASH_HashBuf failed");
1308                 SECKEY_DestroyPublicKey(pubkey);
1309                 return sec_status_unchecked;
1310         }
1311         if(prefix) {
1312                 int hashlen = sechash.len;
1313                 if(prefixlen+hashlen > sizeof(hash2)) {
1314                         verbose(VERB_QUERY, "verify: hashprefix too large");
1315                         SECKEY_DestroyPublicKey(pubkey);
1316                         return sec_status_unchecked;
1317                 }
1318                 sechash.data = hash2;
1319                 sechash.len = prefixlen+hashlen;
1320                 memcpy(sechash.data, prefix, prefixlen);
1321                 memmove(sechash.data+prefixlen, hash, hashlen);
1322         }
1323
1324         /* verify the signature */
1325         res = PK11_Verify(pubkey, &secsig, &sechash, NULL /*wincx*/);
1326         SECKEY_DestroyPublicKey(pubkey);
1327
1328         if(res == SECSuccess) {
1329                 return sec_status_secure;
1330         }
1331         err = PORT_GetError();
1332         if(err != SEC_ERROR_BAD_SIGNATURE) {
1333                 /* failed to verify */
1334                 verbose(VERB_QUERY, "verify: PK11_Verify failed: %s",
1335                         PORT_ErrorToString(err));
1336                 /* if it is not supported, like ECC is removed, we get,
1337                  * SEC_ERROR_NO_MODULE */
1338                 if(err == SEC_ERROR_NO_MODULE)
1339                         return sec_status_unchecked;
1340                 /* but other errors are commonly returned
1341                  * for a bad signature from NSS.  Thus we return bogus,
1342                  * not unchecked */
1343                 *reason = "signature crypto failed";
1344                 return sec_status_bogus;
1345         }
1346         verbose(VERB_QUERY, "verify: signature mismatch: %s",
1347                 PORT_ErrorToString(err));
1348         *reason = "signature crypto failed";
1349         return sec_status_bogus;
1350 }
1351
1352 #elif defined(HAVE_NETTLE)
1353
1354 #include "sha.h"
1355 #include "bignum.h"
1356 #include "macros.h"
1357 #include "rsa.h"
1358 #include "dsa.h"
1359 #ifdef HAVE_NETTLE_DSA_COMPAT_H
1360 #include "dsa-compat.h"
1361 #endif
1362 #include "asn1.h"
1363 #ifdef USE_ECDSA
1364 #include "ecdsa.h"
1365 #include "ecc-curve.h"
1366 #endif
1367 #ifdef HAVE_NETTLE_EDDSA_H
1368 #include "eddsa.h"
1369 #endif
1370
1371 static int
1372 _digest_nettle(int algo, uint8_t* buf, size_t len,
1373         unsigned char* res)
1374 {
1375         switch(algo) {
1376                 case SHA1_DIGEST_SIZE:
1377                 {
1378                         struct sha1_ctx ctx;
1379                         sha1_init(&ctx);
1380                         sha1_update(&ctx, len, buf);
1381                         sha1_digest(&ctx, SHA1_DIGEST_SIZE, res);
1382                         return 1;
1383                 }
1384                 case SHA256_DIGEST_SIZE:
1385                 {
1386                         struct sha256_ctx ctx;
1387                         sha256_init(&ctx);
1388                         sha256_update(&ctx, len, buf);
1389                         sha256_digest(&ctx, SHA256_DIGEST_SIZE, res);
1390                         return 1;
1391                 }
1392                 case SHA384_DIGEST_SIZE:
1393                 {
1394                         struct sha384_ctx ctx;
1395                         sha384_init(&ctx);
1396                         sha384_update(&ctx, len, buf);
1397                         sha384_digest(&ctx, SHA384_DIGEST_SIZE, res);
1398                         return 1;
1399                 }
1400                 case SHA512_DIGEST_SIZE:
1401                 {
1402                         struct sha512_ctx ctx;
1403                         sha512_init(&ctx);
1404                         sha512_update(&ctx, len, buf);
1405                         sha512_digest(&ctx, SHA512_DIGEST_SIZE, res);
1406                         return 1;
1407                 }
1408                 default:
1409                         break;
1410         }
1411         return 0;
1412 }
1413
1414 /* return size of digest if supported, or 0 otherwise */
1415 size_t
1416 nsec3_hash_algo_size_supported(int id)
1417 {
1418         switch(id) {
1419         case NSEC3_HASH_SHA1:
1420                 return SHA1_DIGEST_SIZE;
1421         default:
1422                 return 0;
1423         }
1424 }
1425
1426 /* perform nsec3 hash. return false on failure */
1427 int
1428 secalgo_nsec3_hash(int algo, unsigned char* buf, size_t len,
1429         unsigned char* res)
1430 {
1431         switch(algo) {
1432         case NSEC3_HASH_SHA1:
1433                 return _digest_nettle(SHA1_DIGEST_SIZE, (uint8_t*)buf, len,
1434                         res);
1435         default:
1436                 return 0;
1437         }
1438 }
1439
1440 void
1441 secalgo_hash_sha256(unsigned char* buf, size_t len, unsigned char* res)
1442 {
1443         _digest_nettle(SHA256_DIGEST_SIZE, (uint8_t*)buf, len, res);
1444 }
1445
1446 /**
1447  * Return size of DS digest according to its hash algorithm.
1448  * @param algo: DS digest algo.
1449  * @return size in bytes of digest, or 0 if not supported.
1450  */
1451 size_t
1452 ds_digest_size_supported(int algo)
1453 {
1454         switch(algo) {
1455                 case LDNS_SHA1:
1456 #ifdef USE_SHA1
1457                         return SHA1_DIGEST_SIZE;
1458 #else
1459                         if(fake_sha1) return 20;
1460                         return 0;
1461 #endif
1462 #ifdef USE_SHA2
1463                 case LDNS_SHA256:
1464                         return SHA256_DIGEST_SIZE;
1465 #endif
1466 #ifdef USE_ECDSA
1467                 case LDNS_SHA384:
1468                         return SHA384_DIGEST_SIZE;
1469 #endif
1470                 /* GOST not supported */
1471                 case LDNS_HASH_GOST:
1472                 default:
1473                         break;
1474         }
1475         return 0;
1476 }
1477
1478 int
1479 secalgo_ds_digest(int algo, unsigned char* buf, size_t len,
1480         unsigned char* res)
1481 {
1482         switch(algo) {
1483 #ifdef USE_SHA1
1484                 case LDNS_SHA1:
1485                         return _digest_nettle(SHA1_DIGEST_SIZE, buf, len, res);
1486 #endif
1487 #if defined(USE_SHA2)
1488                 case LDNS_SHA256:
1489                         return _digest_nettle(SHA256_DIGEST_SIZE, buf, len, res);
1490 #endif
1491 #ifdef USE_ECDSA
1492                 case LDNS_SHA384:
1493                         return _digest_nettle(SHA384_DIGEST_SIZE, buf, len, res);
1494
1495 #endif
1496                 case LDNS_HASH_GOST:
1497                 default:
1498                         verbose(VERB_QUERY, "unknown DS digest algorithm %d",
1499                                 algo);
1500                         break;
1501         }
1502         return 0;
1503 }
1504
1505 int
1506 dnskey_algo_id_is_supported(int id)
1507 {
1508         /* uses libnettle */
1509         switch(id) {
1510 #if defined(USE_DSA) && defined(USE_SHA1)
1511         case LDNS_DSA:
1512         case LDNS_DSA_NSEC3:
1513 #endif
1514 #ifdef USE_SHA1
1515         case LDNS_RSASHA1:
1516         case LDNS_RSASHA1_NSEC3:
1517 #endif
1518 #ifdef USE_SHA2
1519         case LDNS_RSASHA256:
1520         case LDNS_RSASHA512:
1521 #endif
1522 #ifdef USE_ECDSA
1523         case LDNS_ECDSAP256SHA256:
1524         case LDNS_ECDSAP384SHA384:
1525 #endif
1526                 return 1;
1527 #ifdef USE_ED25519
1528         case LDNS_ED25519:
1529                 return 1;
1530 #endif
1531         case LDNS_RSAMD5: /* RFC 6725 deprecates RSAMD5 */
1532         case LDNS_ECC_GOST:
1533         default:
1534                 return 0;
1535         }
1536 }
1537
1538 #if defined(USE_DSA) && defined(USE_SHA1)
1539 static char *
1540 _verify_nettle_dsa(sldns_buffer* buf, unsigned char* sigblock,
1541         unsigned int sigblock_len, unsigned char* key, unsigned int keylen)
1542 {
1543         uint8_t digest[SHA1_DIGEST_SIZE];
1544         uint8_t key_t_value;
1545         int res = 0;
1546         size_t offset;
1547         struct dsa_public_key pubkey;
1548         struct dsa_signature signature;
1549         unsigned int expected_len;
1550
1551         /* Extract DSA signature from the record */
1552         nettle_dsa_signature_init(&signature);
1553         /* Signature length: 41 bytes - RFC 2536 sec. 3 */
1554         if(sigblock_len == 41) {
1555                 if(key[0] != sigblock[0])
1556                         return "invalid T value in DSA signature or pubkey";
1557                 nettle_mpz_set_str_256_u(signature.r, 20, sigblock+1);
1558                 nettle_mpz_set_str_256_u(signature.s, 20, sigblock+1+20);
1559         } else {
1560                 /* DER encoded, decode the ASN1 notated R and S bignums */
1561                 /* SEQUENCE { r INTEGER, s INTEGER } */
1562                 struct asn1_der_iterator i, seq;
1563                 if(asn1_der_iterator_first(&i, sigblock_len,
1564                         (uint8_t*)sigblock) != ASN1_ITERATOR_CONSTRUCTED
1565                         || i.type != ASN1_SEQUENCE)
1566                         return "malformed DER encoded DSA signature";
1567                 /* decode this element of i using the seq iterator */
1568                 if(asn1_der_decode_constructed(&i, &seq) !=
1569                         ASN1_ITERATOR_PRIMITIVE || seq.type != ASN1_INTEGER)
1570                         return "malformed DER encoded DSA signature";
1571                 if(!asn1_der_get_bignum(&seq, signature.r, 20*8))
1572                         return "malformed DER encoded DSA signature";
1573                 if(asn1_der_iterator_next(&seq) != ASN1_ITERATOR_PRIMITIVE
1574                         || seq.type != ASN1_INTEGER)
1575                         return "malformed DER encoded DSA signature";
1576                 if(!asn1_der_get_bignum(&seq, signature.s, 20*8))
1577                         return "malformed DER encoded DSA signature";
1578                 if(asn1_der_iterator_next(&i) != ASN1_ITERATOR_END)
1579                         return "malformed DER encoded DSA signature";
1580         }
1581
1582         /* Validate T values constraints - RFC 2536 sec. 2 & sec. 3 */
1583         key_t_value = key[0];
1584         if (key_t_value > 8) {
1585                 return "invalid T value in DSA pubkey";
1586         }
1587
1588         /* Pubkey minimum length: 21 bytes - RFC 2536 sec. 2 */
1589         if (keylen < 21) {
1590                 return "DSA pubkey too short";
1591         }
1592
1593         expected_len =   1 +            /* T */
1594                         20 +            /* Q */
1595                        (64 + key_t_value*8) +   /* P */
1596                        (64 + key_t_value*8) +   /* G */
1597                        (64 + key_t_value*8);    /* Y */
1598         if (keylen != expected_len ) {
1599                 return "invalid DSA pubkey length";
1600         }
1601
1602         /* Extract DSA pubkey from the record */
1603         nettle_dsa_public_key_init(&pubkey);
1604         offset = 1;
1605         nettle_mpz_set_str_256_u(pubkey.q, 20, key+offset);
1606         offset += 20;
1607         nettle_mpz_set_str_256_u(pubkey.p, (64 + key_t_value*8), key+offset);
1608         offset += (64 + key_t_value*8);
1609         nettle_mpz_set_str_256_u(pubkey.g, (64 + key_t_value*8), key+offset);
1610         offset += (64 + key_t_value*8);
1611         nettle_mpz_set_str_256_u(pubkey.y, (64 + key_t_value*8), key+offset);
1612
1613         /* Digest content of "buf" and verify its DSA signature in "sigblock"*/
1614         res = _digest_nettle(SHA1_DIGEST_SIZE, (unsigned char*)sldns_buffer_begin(buf),
1615                                                 (unsigned int)sldns_buffer_limit(buf), (unsigned char*)digest);
1616         res &= dsa_sha1_verify_digest(&pubkey, digest, &signature);
1617
1618         /* Clear and return */
1619         nettle_dsa_signature_clear(&signature);
1620         nettle_dsa_public_key_clear(&pubkey);
1621         if (!res)
1622                 return "DSA signature verification failed";
1623         else
1624                 return NULL;
1625 }
1626 #endif /* USE_DSA */
1627
1628 static char *
1629 _verify_nettle_rsa(sldns_buffer* buf, unsigned int digest_size, char* sigblock,
1630         unsigned int sigblock_len, uint8_t* key, unsigned int keylen)
1631 {
1632         uint16_t exp_len = 0;
1633         size_t exp_offset = 0, mod_offset = 0;
1634         struct rsa_public_key pubkey;
1635         mpz_t signature;
1636         int res = 0;
1637
1638         /* RSA pubkey parsing as per RFC 3110 sec. 2 */
1639         if( keylen <= 1) {
1640                 return "null RSA key";
1641         }
1642         if (key[0] != 0) {
1643                 /* 1-byte length */
1644                 exp_len = key[0];
1645                 exp_offset = 1;
1646         } else {
1647                 /* 1-byte NUL + 2-bytes exponent length */
1648                 if (keylen < 3) {
1649                         return "incorrect RSA key length";
1650                 }
1651                 exp_len = READ_UINT16(key+1);
1652                 if (exp_len == 0)
1653                         return "null RSA exponent length";
1654                 exp_offset = 3;
1655         }
1656         /* Check that we are not over-running input length */
1657         if (keylen < exp_offset + exp_len + 1) {
1658                 return "RSA key content shorter than expected";
1659         }
1660         mod_offset = exp_offset + exp_len;
1661         nettle_rsa_public_key_init(&pubkey);
1662         pubkey.size = keylen - mod_offset;
1663         nettle_mpz_set_str_256_u(pubkey.e, exp_len, &key[exp_offset]);
1664         nettle_mpz_set_str_256_u(pubkey.n, pubkey.size, &key[mod_offset]);
1665
1666         /* Digest content of "buf" and verify its RSA signature in "sigblock"*/
1667         nettle_mpz_init_set_str_256_u(signature, sigblock_len, (uint8_t*)sigblock);
1668         switch (digest_size) {
1669                 case SHA1_DIGEST_SIZE:
1670                 {
1671                         uint8_t digest[SHA1_DIGEST_SIZE];
1672                         res = _digest_nettle(SHA1_DIGEST_SIZE, (unsigned char*)sldns_buffer_begin(buf),
1673                                                 (unsigned int)sldns_buffer_limit(buf), (unsigned char*)digest);
1674                         res &= rsa_sha1_verify_digest(&pubkey, digest, signature);
1675                         break;
1676                 }
1677                 case SHA256_DIGEST_SIZE:
1678                 {
1679                         uint8_t digest[SHA256_DIGEST_SIZE];
1680                         res = _digest_nettle(SHA256_DIGEST_SIZE, (unsigned char*)sldns_buffer_begin(buf),
1681                                                 (unsigned int)sldns_buffer_limit(buf), (unsigned char*)digest);
1682                         res &= rsa_sha256_verify_digest(&pubkey, digest, signature);
1683                         break;
1684                 }
1685                 case SHA512_DIGEST_SIZE:
1686                 {
1687                         uint8_t digest[SHA512_DIGEST_SIZE];
1688                         res = _digest_nettle(SHA512_DIGEST_SIZE, (unsigned char*)sldns_buffer_begin(buf),
1689                                                 (unsigned int)sldns_buffer_limit(buf), (unsigned char*)digest);
1690                         res &= rsa_sha512_verify_digest(&pubkey, digest, signature);
1691                         break;
1692                 }
1693                 default:
1694                         break;
1695         }
1696
1697         /* Clear and return */
1698         nettle_rsa_public_key_clear(&pubkey);
1699         mpz_clear(signature);
1700         if (!res) {
1701                 return "RSA signature verification failed";
1702         } else {
1703                 return NULL;
1704         }
1705 }
1706
1707 #ifdef USE_ECDSA
1708 static char *
1709 _verify_nettle_ecdsa(sldns_buffer* buf, unsigned int digest_size, unsigned char* sigblock,
1710         unsigned int sigblock_len, unsigned char* key, unsigned int keylen)
1711 {
1712         int res = 0;
1713         struct ecc_point pubkey;
1714         struct dsa_signature signature;
1715
1716         /* Always matched strength, as per RFC 6605 sec. 1 */
1717         if (sigblock_len != 2*digest_size || keylen != 2*digest_size) {
1718                 return "wrong ECDSA signature length";
1719         }
1720
1721         /* Parse ECDSA signature as per RFC 6605 sec. 4 */
1722         nettle_dsa_signature_init(&signature);
1723         switch (digest_size) {
1724                 case SHA256_DIGEST_SIZE:
1725                 {
1726                         uint8_t digest[SHA256_DIGEST_SIZE];
1727                         mpz_t x, y;
1728                         nettle_ecc_point_init(&pubkey, &nettle_secp_256r1);
1729                         nettle_mpz_init_set_str_256_u(x, SHA256_DIGEST_SIZE, key);
1730                         nettle_mpz_init_set_str_256_u(y, SHA256_DIGEST_SIZE, key+SHA256_DIGEST_SIZE);
1731                         nettle_mpz_set_str_256_u(signature.r, SHA256_DIGEST_SIZE, sigblock);
1732                         nettle_mpz_set_str_256_u(signature.s, SHA256_DIGEST_SIZE, sigblock+SHA256_DIGEST_SIZE);
1733                         res = _digest_nettle(SHA256_DIGEST_SIZE, (unsigned char*)sldns_buffer_begin(buf),
1734                                                 (unsigned int)sldns_buffer_limit(buf), (unsigned char*)digest);
1735                         res &= nettle_ecc_point_set(&pubkey, x, y);
1736                         res &= nettle_ecdsa_verify (&pubkey, SHA256_DIGEST_SIZE, digest, &signature);
1737                         mpz_clear(x);
1738                         mpz_clear(y);
1739                         break;
1740                 }
1741                 case SHA384_DIGEST_SIZE:
1742                 {
1743                         uint8_t digest[SHA384_DIGEST_SIZE];
1744                         mpz_t x, y;
1745                         nettle_ecc_point_init(&pubkey, &nettle_secp_384r1);
1746                         nettle_mpz_init_set_str_256_u(x, SHA384_DIGEST_SIZE, key);
1747                         nettle_mpz_init_set_str_256_u(y, SHA384_DIGEST_SIZE, key+SHA384_DIGEST_SIZE);
1748                         nettle_mpz_set_str_256_u(signature.r, SHA384_DIGEST_SIZE, sigblock);
1749                         nettle_mpz_set_str_256_u(signature.s, SHA384_DIGEST_SIZE, sigblock+SHA384_DIGEST_SIZE);
1750                         res = _digest_nettle(SHA384_DIGEST_SIZE, (unsigned char*)sldns_buffer_begin(buf),
1751                                                 (unsigned int)sldns_buffer_limit(buf), (unsigned char*)digest);
1752                         res &= nettle_ecc_point_set(&pubkey, x, y);
1753                         res &= nettle_ecdsa_verify (&pubkey, SHA384_DIGEST_SIZE, digest, &signature);
1754                         mpz_clear(x);
1755                         mpz_clear(y);
1756                         nettle_ecc_point_clear(&pubkey);
1757                         break;
1758                 }
1759                 default:
1760                         return "unknown ECDSA algorithm";
1761         }
1762
1763         /* Clear and return */
1764         nettle_dsa_signature_clear(&signature);
1765         if (!res)
1766                 return "ECDSA signature verification failed";
1767         else
1768                 return NULL;
1769 }
1770 #endif
1771
1772 #ifdef USE_ED25519
1773 static char *
1774 _verify_nettle_ed25519(sldns_buffer* buf, unsigned char* sigblock,
1775         unsigned int sigblock_len, unsigned char* key, unsigned int keylen)
1776 {
1777         int res = 0;
1778
1779         if(sigblock_len != ED25519_SIGNATURE_SIZE) {
1780                 return "wrong ED25519 signature length";
1781         }
1782         if(keylen != ED25519_KEY_SIZE) {
1783                 return "wrong ED25519 key length";
1784         }
1785
1786         res = ed25519_sha512_verify((uint8_t*)key, sldns_buffer_limit(buf),
1787                 sldns_buffer_begin(buf), (uint8_t*)sigblock);
1788
1789         if (!res)
1790                 return "ED25519 signature verification failed";
1791         else
1792                 return NULL;
1793 }
1794 #endif
1795
1796 /**
1797  * Check a canonical sig+rrset and signature against a dnskey
1798  * @param buf: buffer with data to verify, the first rrsig part and the
1799  *      canonicalized rrset.
1800  * @param algo: DNSKEY algorithm.
1801  * @param sigblock: signature rdata field from RRSIG
1802  * @param sigblock_len: length of sigblock data.
1803  * @param key: public key data from DNSKEY RR.
1804  * @param keylen: length of keydata.
1805  * @param reason: bogus reason in more detail.
1806  * @return secure if verification succeeded, bogus on crypto failure,
1807  *      unchecked on format errors and alloc failures.
1808  */
1809 enum sec_status
1810 verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock,
1811         unsigned int sigblock_len, unsigned char* key, unsigned int keylen,
1812         char** reason)
1813 {
1814         unsigned int digest_size = 0;
1815
1816         if (sigblock_len == 0 || keylen == 0) {
1817                 *reason = "null signature";
1818                 return sec_status_bogus;
1819         }
1820
1821         switch(algo) {
1822 #if defined(USE_DSA) && defined(USE_SHA1)
1823         case LDNS_DSA:
1824         case LDNS_DSA_NSEC3:
1825                 *reason = _verify_nettle_dsa(buf, sigblock, sigblock_len, key, keylen);
1826                 if (*reason != NULL)
1827                         return sec_status_bogus;
1828                 else
1829                         return sec_status_secure;
1830 #endif /* USE_DSA */
1831
1832 #ifdef USE_SHA1
1833         case LDNS_RSASHA1:
1834         case LDNS_RSASHA1_NSEC3:
1835                 digest_size = (digest_size ? digest_size : SHA1_DIGEST_SIZE);
1836 #endif
1837                 /* double fallthrough annotation to please gcc parser */
1838                 /* fallthrough */
1839 #ifdef USE_SHA2
1840                 /* fallthrough */
1841         case LDNS_RSASHA256:
1842                 digest_size = (digest_size ? digest_size : SHA256_DIGEST_SIZE);
1843                 /* fallthrough */
1844         case LDNS_RSASHA512:
1845                 digest_size = (digest_size ? digest_size : SHA512_DIGEST_SIZE);
1846
1847 #endif
1848                 *reason = _verify_nettle_rsa(buf, digest_size, (char*)sigblock,
1849                                                 sigblock_len, key, keylen);
1850                 if (*reason != NULL)
1851                         return sec_status_bogus;
1852                 else
1853                         return sec_status_secure;
1854
1855 #ifdef USE_ECDSA
1856         case LDNS_ECDSAP256SHA256:
1857                 digest_size = (digest_size ? digest_size : SHA256_DIGEST_SIZE);
1858                 /* fallthrough */
1859         case LDNS_ECDSAP384SHA384:
1860                 digest_size = (digest_size ? digest_size : SHA384_DIGEST_SIZE);
1861                 *reason = _verify_nettle_ecdsa(buf, digest_size, sigblock,
1862                                                 sigblock_len, key, keylen);
1863                 if (*reason != NULL)
1864                         return sec_status_bogus;
1865                 else
1866                         return sec_status_secure;
1867 #endif
1868 #ifdef USE_ED25519
1869         case LDNS_ED25519:
1870                 *reason = _verify_nettle_ed25519(buf, sigblock, sigblock_len,
1871                         key, keylen);
1872                 if (*reason != NULL)
1873                         return sec_status_bogus;
1874                 else
1875                         return sec_status_secure;
1876 #endif
1877         case LDNS_RSAMD5:
1878         case LDNS_ECC_GOST:
1879         default:
1880                 *reason = "unable to verify signature, unknown algorithm";
1881                 return sec_status_bogus;
1882         }
1883 }
1884
1885 #endif /* HAVE_SSL or HAVE_NSS or HAVE_NETTLE */