13dcb24b8Ssthen /* 23dcb24b8Ssthen * validator/val_secalgo.c - validator security algorithm functions. 33dcb24b8Ssthen * 43dcb24b8Ssthen * Copyright (c) 2012, NLnet Labs. All rights reserved. 53dcb24b8Ssthen * 63dcb24b8Ssthen * This software is open source. 73dcb24b8Ssthen * 83dcb24b8Ssthen * Redistribution and use in source and binary forms, with or without 93dcb24b8Ssthen * modification, are permitted provided that the following conditions 103dcb24b8Ssthen * are met: 113dcb24b8Ssthen * 123dcb24b8Ssthen * Redistributions of source code must retain the above copyright notice, 133dcb24b8Ssthen * this list of conditions and the following disclaimer. 143dcb24b8Ssthen * 153dcb24b8Ssthen * Redistributions in binary form must reproduce the above copyright notice, 163dcb24b8Ssthen * this list of conditions and the following disclaimer in the documentation 173dcb24b8Ssthen * and/or other materials provided with the distribution. 183dcb24b8Ssthen * 193dcb24b8Ssthen * Neither the name of the NLNET LABS nor the names of its contributors may 203dcb24b8Ssthen * be used to endorse or promote products derived from this software without 213dcb24b8Ssthen * specific prior written permission. 223dcb24b8Ssthen * 233dcb24b8Ssthen * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 245d76a658Ssthen * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 255d76a658Ssthen * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 265d76a658Ssthen * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 275d76a658Ssthen * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 285d76a658Ssthen * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 295d76a658Ssthen * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 305d76a658Ssthen * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 315d76a658Ssthen * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 325d76a658Ssthen * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 335d76a658Ssthen * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 343dcb24b8Ssthen */ 353dcb24b8Ssthen 363dcb24b8Ssthen /** 373dcb24b8Ssthen * \file 383dcb24b8Ssthen * 393dcb24b8Ssthen * This file contains helper functions for the validator module. 403dcb24b8Ssthen * These functions take raw data buffers, formatted for crypto verification, 413dcb24b8Ssthen * and do the library calls (for the crypto library in use). 423dcb24b8Ssthen */ 433dcb24b8Ssthen #include "config.h" 44b2cdf21fSsthen /* packed_rrset on top to define enum types (forced by c99 standard) */ 453dcb24b8Ssthen #include "util/data/packed_rrset.h" 46b2cdf21fSsthen #include "validator/val_secalgo.h" 4724893edcSsthen #include "validator/val_nsec3.h" 483dcb24b8Ssthen #include "util/log.h" 49fdfb4ba6Ssthen #include "sldns/rrdef.h" 50fdfb4ba6Ssthen #include "sldns/keyraw.h" 51fdfb4ba6Ssthen #include "sldns/sbuffer.h" 523dcb24b8Ssthen 5324893edcSsthen #if !defined(HAVE_SSL) && !defined(HAVE_NSS) && !defined(HAVE_NETTLE) 543dcb24b8Ssthen #error "Need crypto library to do digital signature cryptography" 553dcb24b8Ssthen #endif 563dcb24b8Ssthen 57eaf2578eSsthen /** fake DSA support for unit tests */ 58eaf2578eSsthen int fake_dsa = 0; 59eaf2578eSsthen /** fake SHA1 support for unit tests */ 60eaf2578eSsthen int fake_sha1 = 0; 61eaf2578eSsthen 623dcb24b8Ssthen /* OpenSSL implementation */ 633dcb24b8Ssthen #ifdef HAVE_SSL 643dcb24b8Ssthen #ifdef HAVE_OPENSSL_ERR_H 653dcb24b8Ssthen #include <openssl/err.h> 663dcb24b8Ssthen #endif 673dcb24b8Ssthen 683dcb24b8Ssthen #ifdef HAVE_OPENSSL_RAND_H 693dcb24b8Ssthen #include <openssl/rand.h> 703dcb24b8Ssthen #endif 713dcb24b8Ssthen 723dcb24b8Ssthen #ifdef HAVE_OPENSSL_CONF_H 733dcb24b8Ssthen #include <openssl/conf.h> 743dcb24b8Ssthen #endif 753dcb24b8Ssthen 763dcb24b8Ssthen #ifdef HAVE_OPENSSL_ENGINE_H 773dcb24b8Ssthen #include <openssl/engine.h> 783dcb24b8Ssthen #endif 793dcb24b8Ssthen 80a3167c07Ssthen #if defined(HAVE_OPENSSL_DSA_H) && defined(USE_DSA) 81a3167c07Ssthen #include <openssl/dsa.h> 82a3167c07Ssthen #endif 83a3167c07Ssthen 84452a1548Ssthen /** 85452a1548Ssthen * Output a libcrypto openssl error to the logfile. 86452a1548Ssthen * @param str: string to add to it. 87452a1548Ssthen * @param e: the error to output, error number from ERR_get_error(). 88452a1548Ssthen */ 89452a1548Ssthen static void 90452a1548Ssthen log_crypto_error(const char* str, unsigned long e) 91452a1548Ssthen { 92452a1548Ssthen char buf[128]; 93452a1548Ssthen /* or use ERR_error_string if ERR_error_string_n is not avail TODO */ 94452a1548Ssthen ERR_error_string_n(e, buf, sizeof(buf)); 95452a1548Ssthen /* buf now contains */ 96452a1548Ssthen /* error:[error code]:[library name]:[function name]:[reason string] */ 97452a1548Ssthen log_err("%s crypto %s", str, buf); 98452a1548Ssthen } 99452a1548Ssthen 100d1e2768aSsthen /** 101d1e2768aSsthen * Output a libcrypto openssl error to the logfile as a debug message. 102d1e2768aSsthen * @param level: debug level to use in verbose() call 103d1e2768aSsthen * @param str: string to add to it. 104d1e2768aSsthen * @param e: the error to output, error number from ERR_get_error(). 105d1e2768aSsthen */ 106d1e2768aSsthen static void 107d1e2768aSsthen log_crypto_verbose(enum verbosity_value level, const char* str, unsigned long e) 108d1e2768aSsthen { 109d1e2768aSsthen char buf[128]; 110d1e2768aSsthen /* or use ERR_error_string if ERR_error_string_n is not avail TODO */ 111d1e2768aSsthen ERR_error_string_n(e, buf, sizeof(buf)); 112d1e2768aSsthen /* buf now contains */ 113d1e2768aSsthen /* error:[error code]:[library name]:[function name]:[reason string] */ 114d1e2768aSsthen verbose(level, "%s crypto %s", str, buf); 115d1e2768aSsthen } 116d1e2768aSsthen 11724893edcSsthen /* return size of digest if supported, or 0 otherwise */ 11824893edcSsthen size_t 11924893edcSsthen nsec3_hash_algo_size_supported(int id) 12024893edcSsthen { 12124893edcSsthen switch(id) { 12224893edcSsthen case NSEC3_HASH_SHA1: 12324893edcSsthen return SHA_DIGEST_LENGTH; 12424893edcSsthen default: 12524893edcSsthen return 0; 12624893edcSsthen } 12724893edcSsthen } 12824893edcSsthen 12924893edcSsthen /* perform nsec3 hash. return false on failure */ 13024893edcSsthen int 13124893edcSsthen secalgo_nsec3_hash(int algo, unsigned char* buf, size_t len, 13224893edcSsthen unsigned char* res) 13324893edcSsthen { 13424893edcSsthen switch(algo) { 13524893edcSsthen case NSEC3_HASH_SHA1: 136452a1548Ssthen #ifdef OPENSSL_FIPS 137452a1548Ssthen if(!sldns_digest_evp(buf, len, res, EVP_sha1())) 138452a1548Ssthen log_crypto_error("could not digest with EVP_sha1", 139452a1548Ssthen ERR_get_error()); 140452a1548Ssthen #else 14124893edcSsthen (void)SHA1(buf, len, res); 142452a1548Ssthen #endif 14324893edcSsthen return 1; 14424893edcSsthen default: 14524893edcSsthen return 0; 14624893edcSsthen } 14724893edcSsthen } 14824893edcSsthen 1492ee382b6Ssthen void 1502ee382b6Ssthen secalgo_hash_sha256(unsigned char* buf, size_t len, unsigned char* res) 1512ee382b6Ssthen { 152452a1548Ssthen #ifdef OPENSSL_FIPS 153452a1548Ssthen if(!sldns_digest_evp(buf, len, res, EVP_sha256())) 154452a1548Ssthen log_crypto_error("could not digest with EVP_sha256", 155452a1548Ssthen ERR_get_error()); 156452a1548Ssthen #else 1572ee382b6Ssthen (void)SHA256(buf, len, res); 158452a1548Ssthen #endif 1592ee382b6Ssthen } 1602ee382b6Ssthen 161191f22c6Ssthen /** hash structure for keeping track of running hashes */ 162191f22c6Ssthen struct secalgo_hash { 163191f22c6Ssthen /** the openssl message digest context */ 164191f22c6Ssthen EVP_MD_CTX* ctx; 165191f22c6Ssthen }; 166191f22c6Ssthen 167191f22c6Ssthen /** create secalgo hash with hash type */ 168191f22c6Ssthen static struct secalgo_hash* secalgo_hash_create_md(const EVP_MD* md) 169191f22c6Ssthen { 170191f22c6Ssthen struct secalgo_hash* h; 171191f22c6Ssthen if(!md) 172191f22c6Ssthen return NULL; 173191f22c6Ssthen h = calloc(1, sizeof(*h)); 174191f22c6Ssthen if(!h) 175191f22c6Ssthen return NULL; 176191f22c6Ssthen h->ctx = EVP_MD_CTX_create(); 177191f22c6Ssthen if(!h->ctx) { 178191f22c6Ssthen free(h); 179191f22c6Ssthen return NULL; 180191f22c6Ssthen } 181191f22c6Ssthen if(!EVP_DigestInit_ex(h->ctx, md, NULL)) { 182191f22c6Ssthen EVP_MD_CTX_destroy(h->ctx); 183191f22c6Ssthen free(h); 184191f22c6Ssthen return NULL; 185191f22c6Ssthen } 186191f22c6Ssthen return h; 187191f22c6Ssthen } 188191f22c6Ssthen 189191f22c6Ssthen struct secalgo_hash* secalgo_hash_create_sha384(void) 190191f22c6Ssthen { 191191f22c6Ssthen return secalgo_hash_create_md(EVP_sha384()); 192191f22c6Ssthen } 193191f22c6Ssthen 194191f22c6Ssthen struct secalgo_hash* secalgo_hash_create_sha512(void) 195191f22c6Ssthen { 196191f22c6Ssthen return secalgo_hash_create_md(EVP_sha512()); 197191f22c6Ssthen } 198191f22c6Ssthen 199191f22c6Ssthen int secalgo_hash_update(struct secalgo_hash* hash, uint8_t* data, size_t len) 200191f22c6Ssthen { 201191f22c6Ssthen return EVP_DigestUpdate(hash->ctx, (unsigned char*)data, 202191f22c6Ssthen (unsigned int)len); 203191f22c6Ssthen } 204191f22c6Ssthen 205191f22c6Ssthen int secalgo_hash_final(struct secalgo_hash* hash, uint8_t* result, 206191f22c6Ssthen size_t maxlen, size_t* resultlen) 207191f22c6Ssthen { 208191f22c6Ssthen if(EVP_MD_CTX_size(hash->ctx) > (int)maxlen) { 209191f22c6Ssthen *resultlen = 0; 210191f22c6Ssthen log_err("secalgo_hash_final: hash buffer too small"); 211191f22c6Ssthen return 0; 212191f22c6Ssthen } 213191f22c6Ssthen *resultlen = EVP_MD_CTX_size(hash->ctx); 214191f22c6Ssthen return EVP_DigestFinal_ex(hash->ctx, result, NULL); 215191f22c6Ssthen } 216191f22c6Ssthen 217191f22c6Ssthen void secalgo_hash_delete(struct secalgo_hash* hash) 218191f22c6Ssthen { 219191f22c6Ssthen if(!hash) return; 220191f22c6Ssthen EVP_MD_CTX_destroy(hash->ctx); 221191f22c6Ssthen free(hash); 222191f22c6Ssthen } 223191f22c6Ssthen 2243dcb24b8Ssthen /** 2253dcb24b8Ssthen * Return size of DS digest according to its hash algorithm. 2263dcb24b8Ssthen * @param algo: DS digest algo. 2273dcb24b8Ssthen * @return size in bytes of digest, or 0 if not supported. 2283dcb24b8Ssthen */ 2293dcb24b8Ssthen size_t 2303dcb24b8Ssthen ds_digest_size_supported(int algo) 2313dcb24b8Ssthen { 2323dcb24b8Ssthen switch(algo) { 2333dcb24b8Ssthen case LDNS_SHA1: 2342be9e038Ssthen #if defined(HAVE_EVP_SHA1) && defined(USE_SHA1) 235d1e2768aSsthen #ifdef HAVE_EVP_DEFAULT_PROPERTIES_IS_FIPS_ENABLED 236d1e2768aSsthen if (EVP_default_properties_is_fips_enabled(NULL)) 237d1e2768aSsthen return 0; 238d1e2768aSsthen #endif 2393dcb24b8Ssthen return SHA_DIGEST_LENGTH; 2402be9e038Ssthen #else 2412be9e038Ssthen if(fake_sha1) return 20; 2422be9e038Ssthen return 0; 2433dcb24b8Ssthen #endif 2443dcb24b8Ssthen #ifdef HAVE_EVP_SHA256 2453dcb24b8Ssthen case LDNS_SHA256: 2463dcb24b8Ssthen return SHA256_DIGEST_LENGTH; 2473dcb24b8Ssthen #endif 2483dcb24b8Ssthen #ifdef USE_GOST 2493dcb24b8Ssthen case LDNS_HASH_GOST: 25032e31f52Ssthen /* we support GOST if it can be loaded */ 25132e31f52Ssthen (void)sldns_key_EVP_load_gost_id(); 2523dcb24b8Ssthen if(EVP_get_digestbyname("md_gost94")) 2533dcb24b8Ssthen return 32; 2543dcb24b8Ssthen else return 0; 2553dcb24b8Ssthen #endif 2563dcb24b8Ssthen #ifdef USE_ECDSA 2573dcb24b8Ssthen case LDNS_SHA384: 2583dcb24b8Ssthen return SHA384_DIGEST_LENGTH; 2593dcb24b8Ssthen #endif 2603dcb24b8Ssthen default: break; 2613dcb24b8Ssthen } 2623dcb24b8Ssthen return 0; 2633dcb24b8Ssthen } 2643dcb24b8Ssthen 2653dcb24b8Ssthen #ifdef USE_GOST 2663dcb24b8Ssthen /** Perform GOST hash */ 2673dcb24b8Ssthen static int 2683dcb24b8Ssthen do_gost94(unsigned char* data, size_t len, unsigned char* dest) 2693dcb24b8Ssthen { 2703dcb24b8Ssthen const EVP_MD* md = EVP_get_digestbyname("md_gost94"); 2713dcb24b8Ssthen if(!md) 2723dcb24b8Ssthen return 0; 2735d76a658Ssthen return sldns_digest_evp(data, (unsigned int)len, dest, md); 2743dcb24b8Ssthen } 2753dcb24b8Ssthen #endif 2763dcb24b8Ssthen 2773dcb24b8Ssthen int 2783dcb24b8Ssthen secalgo_ds_digest(int algo, unsigned char* buf, size_t len, 2793dcb24b8Ssthen unsigned char* res) 2803dcb24b8Ssthen { 2813dcb24b8Ssthen switch(algo) { 2822be9e038Ssthen #if defined(HAVE_EVP_SHA1) && defined(USE_SHA1) 2833dcb24b8Ssthen case LDNS_SHA1: 284452a1548Ssthen #ifdef OPENSSL_FIPS 285452a1548Ssthen if(!sldns_digest_evp(buf, len, res, EVP_sha1())) 286452a1548Ssthen log_crypto_error("could not digest with EVP_sha1", 287452a1548Ssthen ERR_get_error()); 288452a1548Ssthen #else 2893dcb24b8Ssthen (void)SHA1(buf, len, res); 290452a1548Ssthen #endif 2913dcb24b8Ssthen return 1; 2923dcb24b8Ssthen #endif 2933dcb24b8Ssthen #ifdef HAVE_EVP_SHA256 2943dcb24b8Ssthen case LDNS_SHA256: 295452a1548Ssthen #ifdef OPENSSL_FIPS 296452a1548Ssthen if(!sldns_digest_evp(buf, len, res, EVP_sha256())) 297452a1548Ssthen log_crypto_error("could not digest with EVP_sha256", 298452a1548Ssthen ERR_get_error()); 299452a1548Ssthen #else 3003dcb24b8Ssthen (void)SHA256(buf, len, res); 301452a1548Ssthen #endif 3023dcb24b8Ssthen return 1; 3033dcb24b8Ssthen #endif 3043dcb24b8Ssthen #ifdef USE_GOST 3053dcb24b8Ssthen case LDNS_HASH_GOST: 3063dcb24b8Ssthen if(do_gost94(buf, len, res)) 3073dcb24b8Ssthen return 1; 3083dcb24b8Ssthen break; 3093dcb24b8Ssthen #endif 3103dcb24b8Ssthen #ifdef USE_ECDSA 3113dcb24b8Ssthen case LDNS_SHA384: 312452a1548Ssthen #ifdef OPENSSL_FIPS 313452a1548Ssthen if(!sldns_digest_evp(buf, len, res, EVP_sha384())) 314452a1548Ssthen log_crypto_error("could not digest with EVP_sha384", 315452a1548Ssthen ERR_get_error()); 316452a1548Ssthen #else 3173dcb24b8Ssthen (void)SHA384(buf, len, res); 318452a1548Ssthen #endif 3193dcb24b8Ssthen return 1; 3203dcb24b8Ssthen #endif 3213dcb24b8Ssthen default: 3223dcb24b8Ssthen verbose(VERB_QUERY, "unknown DS digest algorithm %d", 3233dcb24b8Ssthen algo); 3243dcb24b8Ssthen break; 3253dcb24b8Ssthen } 3263dcb24b8Ssthen return 0; 3273dcb24b8Ssthen } 3283dcb24b8Ssthen 3293dcb24b8Ssthen /** return true if DNSKEY algorithm id is supported */ 3303dcb24b8Ssthen int 3313dcb24b8Ssthen dnskey_algo_id_is_supported(int id) 3323dcb24b8Ssthen { 3333dcb24b8Ssthen switch(id) { 3343dcb24b8Ssthen case LDNS_RSAMD5: 335229e174cSsthen /* RFC 6725 deprecates RSAMD5 */ 336229e174cSsthen return 0; 3373dcb24b8Ssthen case LDNS_DSA: 3383dcb24b8Ssthen case LDNS_DSA_NSEC3: 3392be9e038Ssthen #if defined(USE_DSA) && defined(USE_SHA1) 34077079be7Ssthen return 1; 34177079be7Ssthen #else 3422be9e038Ssthen if(fake_dsa || fake_sha1) return 1; 34377079be7Ssthen return 0; 3442ee382b6Ssthen #endif 3452be9e038Ssthen 3463dcb24b8Ssthen case LDNS_RSASHA1: 3473dcb24b8Ssthen case LDNS_RSASHA1_NSEC3: 3482be9e038Ssthen #ifdef USE_SHA1 349d1e2768aSsthen #ifdef HAVE_EVP_DEFAULT_PROPERTIES_IS_FIPS_ENABLED 350d1e2768aSsthen return !EVP_default_properties_is_fips_enabled(NULL); 351d1e2768aSsthen #else 3522be9e038Ssthen return 1; 353d1e2768aSsthen #endif 3542be9e038Ssthen #else 3552be9e038Ssthen if(fake_sha1) return 1; 3562be9e038Ssthen return 0; 3572be9e038Ssthen #endif 3582be9e038Ssthen 3593dcb24b8Ssthen #if defined(HAVE_EVP_SHA256) && defined(USE_SHA2) 3603dcb24b8Ssthen case LDNS_RSASHA256: 3613dcb24b8Ssthen #endif 3623dcb24b8Ssthen #if defined(HAVE_EVP_SHA512) && defined(USE_SHA2) 3633dcb24b8Ssthen case LDNS_RSASHA512: 3643dcb24b8Ssthen #endif 3653dcb24b8Ssthen #ifdef USE_ECDSA 3663dcb24b8Ssthen case LDNS_ECDSAP256SHA256: 3673dcb24b8Ssthen case LDNS_ECDSAP384SHA384: 3683dcb24b8Ssthen #endif 369d1e2768aSsthen #if (defined(HAVE_EVP_SHA256) && defined(USE_SHA2)) || (defined(HAVE_EVP_SHA512) && defined(USE_SHA2)) || defined(USE_ECDSA) 370d1e2768aSsthen return 1; 371d1e2768aSsthen #endif 3722be9e038Ssthen #ifdef USE_ED25519 3732be9e038Ssthen case LDNS_ED25519: 3742be9e038Ssthen #endif 37520237c55Ssthen #ifdef USE_ED448 37620237c55Ssthen case LDNS_ED448: 37720237c55Ssthen #endif 378d1e2768aSsthen #if defined(USE_ED25519) || defined(USE_ED448) 379d1e2768aSsthen #ifdef HAVE_EVP_DEFAULT_PROPERTIES_IS_FIPS_ENABLED 380d1e2768aSsthen return !EVP_default_properties_is_fips_enabled(NULL); 381d1e2768aSsthen #else 3823dcb24b8Ssthen return 1; 3832be9e038Ssthen #endif 384d1e2768aSsthen #endif 3852be9e038Ssthen 3863dcb24b8Ssthen #ifdef USE_GOST 3873dcb24b8Ssthen case LDNS_ECC_GOST: 3883dcb24b8Ssthen /* we support GOST if it can be loaded */ 3895d76a658Ssthen return sldns_key_EVP_load_gost_id(); 3903dcb24b8Ssthen #endif 3913dcb24b8Ssthen default: 3923dcb24b8Ssthen return 0; 3933dcb24b8Ssthen } 3943dcb24b8Ssthen } 3953dcb24b8Ssthen 3962ee382b6Ssthen #ifdef USE_DSA 3973dcb24b8Ssthen /** 3983dcb24b8Ssthen * Setup DSA key digest in DER encoding ... 3993dcb24b8Ssthen * @param sig: input is signature output alloced ptr (unless failure). 4003dcb24b8Ssthen * caller must free alloced ptr if this routine returns true. 4013dcb24b8Ssthen * @param len: input is initial siglen, output is output len. 4023dcb24b8Ssthen * @return false on failure. 4033dcb24b8Ssthen */ 4043dcb24b8Ssthen static int 4053dcb24b8Ssthen setup_dsa_sig(unsigned char** sig, unsigned int* len) 4063dcb24b8Ssthen { 4073dcb24b8Ssthen unsigned char* orig = *sig; 4083dcb24b8Ssthen unsigned int origlen = *len; 4093dcb24b8Ssthen int newlen; 4103dcb24b8Ssthen BIGNUM *R, *S; 4113dcb24b8Ssthen DSA_SIG *dsasig; 4123dcb24b8Ssthen 4133dcb24b8Ssthen /* extract the R and S field from the sig buffer */ 4143dcb24b8Ssthen if(origlen < 1 + 2*SHA_DIGEST_LENGTH) 4153dcb24b8Ssthen return 0; 4163dcb24b8Ssthen R = BN_new(); 4173dcb24b8Ssthen if(!R) return 0; 4183dcb24b8Ssthen (void) BN_bin2bn(orig + 1, SHA_DIGEST_LENGTH, R); 4193dcb24b8Ssthen S = BN_new(); 4203dcb24b8Ssthen if(!S) return 0; 4213dcb24b8Ssthen (void) BN_bin2bn(orig + 21, SHA_DIGEST_LENGTH, S); 4223dcb24b8Ssthen dsasig = DSA_SIG_new(); 4233dcb24b8Ssthen if(!dsasig) return 0; 4243dcb24b8Ssthen 42577079be7Ssthen #ifdef HAVE_DSA_SIG_SET0 426*98bc733bSsthen if(!DSA_SIG_set0(dsasig, R, S)) { 427*98bc733bSsthen DSA_SIG_free(dsasig); 428*98bc733bSsthen return 0; 429*98bc733bSsthen } 43077079be7Ssthen #else 431ebf5bb73Ssthen # ifndef S_SPLINT_S 4323dcb24b8Ssthen dsasig->r = R; 4333dcb24b8Ssthen dsasig->s = S; 434ebf5bb73Ssthen # endif /* S_SPLINT_S */ 43577079be7Ssthen #endif 4363dcb24b8Ssthen *sig = NULL; 4373dcb24b8Ssthen newlen = i2d_DSA_SIG(dsasig, sig); 4383dcb24b8Ssthen if(newlen < 0) { 4393dcb24b8Ssthen DSA_SIG_free(dsasig); 4403dcb24b8Ssthen free(*sig); 4413dcb24b8Ssthen return 0; 4423dcb24b8Ssthen } 4433dcb24b8Ssthen *len = (unsigned int)newlen; 4443dcb24b8Ssthen DSA_SIG_free(dsasig); 4453dcb24b8Ssthen return 1; 4463dcb24b8Ssthen } 4472ee382b6Ssthen #endif /* USE_DSA */ 4483dcb24b8Ssthen 4493dcb24b8Ssthen #ifdef USE_ECDSA 4503dcb24b8Ssthen /** 4513dcb24b8Ssthen * Setup the ECDSA signature in its encoding that the library wants. 4523dcb24b8Ssthen * Converts from plain numbers to ASN formatted. 4533dcb24b8Ssthen * @param sig: input is signature, output alloced ptr (unless failure). 4543dcb24b8Ssthen * caller must free alloced ptr if this routine returns true. 4553dcb24b8Ssthen * @param len: input is initial siglen, output is output len. 4563dcb24b8Ssthen * @return false on failure. 4573dcb24b8Ssthen */ 4583dcb24b8Ssthen static int 4593dcb24b8Ssthen setup_ecdsa_sig(unsigned char** sig, unsigned int* len) 4603dcb24b8Ssthen { 4612ee382b6Ssthen /* convert from two BIGNUMs in the rdata buffer, to ASN notation. 462bdfc4d55Sflorian * ASN preamble: 30440220 <R 32bytefor256> 0220 <S 32bytefor256> 4632ee382b6Ssthen * the '20' is the length of that field (=bnsize). 4642ee382b6Ssthen i * the '44' is the total remaining length. 4652ee382b6Ssthen * if negative, start with leading zero. 4662ee382b6Ssthen * if starts with 00s, remove them from the number. 4672ee382b6Ssthen */ 4682ee382b6Ssthen uint8_t pre[] = {0x30, 0x44, 0x02, 0x20}; 4692ee382b6Ssthen int pre_len = 4; 4702ee382b6Ssthen uint8_t mid[] = {0x02, 0x20}; 4712ee382b6Ssthen int mid_len = 2; 4722ee382b6Ssthen int raw_sig_len, r_high, s_high, r_rem=0, s_rem=0; 4733dcb24b8Ssthen int bnsize = (int)((*len)/2); 4742ee382b6Ssthen unsigned char* d = *sig; 4752ee382b6Ssthen uint8_t* p; 4763dcb24b8Ssthen /* if too short or not even length, fails */ 4773dcb24b8Ssthen if(*len < 16 || bnsize*2 != (int)*len) 4783dcb24b8Ssthen return 0; 4793dcb24b8Ssthen 4802ee382b6Ssthen /* strip leading zeroes from r (but not last one) */ 4812ee382b6Ssthen while(r_rem < bnsize-1 && d[r_rem] == 0) 4822ee382b6Ssthen r_rem++; 4832ee382b6Ssthen /* strip leading zeroes from s (but not last one) */ 4842ee382b6Ssthen while(s_rem < bnsize-1 && d[bnsize+s_rem] == 0) 4852ee382b6Ssthen s_rem++; 4862ee382b6Ssthen 4872ee382b6Ssthen r_high = ((d[0+r_rem]&0x80)?1:0); 4882ee382b6Ssthen s_high = ((d[bnsize+s_rem]&0x80)?1:0); 4892ee382b6Ssthen raw_sig_len = pre_len + r_high + bnsize - r_rem + mid_len + 4902ee382b6Ssthen s_high + bnsize - s_rem; 4912ee382b6Ssthen *sig = (unsigned char*)malloc((size_t)raw_sig_len); 4922ee382b6Ssthen if(!*sig) 4933dcb24b8Ssthen return 0; 4942ee382b6Ssthen p = (uint8_t*)*sig; 4952ee382b6Ssthen p[0] = pre[0]; 4962ee382b6Ssthen p[1] = (uint8_t)(raw_sig_len-2); 4972ee382b6Ssthen p[2] = pre[2]; 4982ee382b6Ssthen p[3] = (uint8_t)(bnsize + r_high - r_rem); 4992ee382b6Ssthen p += 4; 5002ee382b6Ssthen if(r_high) { 5012ee382b6Ssthen *p = 0; 5022ee382b6Ssthen p += 1; 5033dcb24b8Ssthen } 5042ee382b6Ssthen memmove(p, d+r_rem, (size_t)bnsize-r_rem); 5052ee382b6Ssthen p += bnsize-r_rem; 5062ee382b6Ssthen memmove(p, mid, (size_t)mid_len-1); 5072ee382b6Ssthen p += mid_len-1; 5082ee382b6Ssthen *p = (uint8_t)(bnsize + s_high - s_rem); 5092ee382b6Ssthen p += 1; 5102ee382b6Ssthen if(s_high) { 5112ee382b6Ssthen *p = 0; 5122ee382b6Ssthen p += 1; 5132ee382b6Ssthen } 5142ee382b6Ssthen memmove(p, d+bnsize+s_rem, (size_t)bnsize-s_rem); 5152ee382b6Ssthen *len = (unsigned int)raw_sig_len; 5163dcb24b8Ssthen return 1; 5173dcb24b8Ssthen } 5183dcb24b8Ssthen #endif /* USE_ECDSA */ 5193dcb24b8Ssthen 52077079be7Ssthen #ifdef USE_ECDSA_EVP_WORKAROUND 52177079be7Ssthen static EVP_MD ecdsa_evp_256_md; 52277079be7Ssthen static EVP_MD ecdsa_evp_384_md; 52377079be7Ssthen void ecdsa_evp_workaround_init(void) 52477079be7Ssthen { 52577079be7Ssthen /* openssl before 1.0.0 fixes RSA with the SHA256 52677079be7Ssthen * hash in EVP. We create one for ecdsa_sha256 */ 52777079be7Ssthen ecdsa_evp_256_md = *EVP_sha256(); 52877079be7Ssthen ecdsa_evp_256_md.required_pkey_type[0] = EVP_PKEY_EC; 52977079be7Ssthen ecdsa_evp_256_md.verify = (void*)ECDSA_verify; 53077079be7Ssthen 53177079be7Ssthen ecdsa_evp_384_md = *EVP_sha384(); 53277079be7Ssthen ecdsa_evp_384_md.required_pkey_type[0] = EVP_PKEY_EC; 53377079be7Ssthen ecdsa_evp_384_md.verify = (void*)ECDSA_verify; 53477079be7Ssthen } 53577079be7Ssthen #endif /* USE_ECDSA_EVP_WORKAROUND */ 53677079be7Ssthen 5373dcb24b8Ssthen /** 5383dcb24b8Ssthen * Setup key and digest for verification. Adjust sig if necessary. 5393dcb24b8Ssthen * 5403dcb24b8Ssthen * @param algo: key algorithm 5413dcb24b8Ssthen * @param evp_key: EVP PKEY public key to create. 5423dcb24b8Ssthen * @param digest_type: digest type to use 5433dcb24b8Ssthen * @param key: key to setup for. 5443dcb24b8Ssthen * @param keylen: length of key. 5453dcb24b8Ssthen * @return false on failure. 5463dcb24b8Ssthen */ 5473dcb24b8Ssthen static int 5483dcb24b8Ssthen setup_key_digest(int algo, EVP_PKEY** evp_key, const EVP_MD** digest_type, 5493dcb24b8Ssthen unsigned char* key, size_t keylen) 5503dcb24b8Ssthen { 5513dcb24b8Ssthen switch(algo) { 5522be9e038Ssthen #if defined(USE_DSA) && defined(USE_SHA1) 5533dcb24b8Ssthen case LDNS_DSA: 5543dcb24b8Ssthen case LDNS_DSA_NSEC3: 555191f22c6Ssthen *evp_key = sldns_key_dsa2pkey_raw(key, keylen); 5563dcb24b8Ssthen if(!*evp_key) { 557191f22c6Ssthen verbose(VERB_QUERY, "verify: sldns_key_dsa2pkey failed"); 5583dcb24b8Ssthen return 0; 5593dcb24b8Ssthen } 56077079be7Ssthen #ifdef HAVE_EVP_DSS1 5613dcb24b8Ssthen *digest_type = EVP_dss1(); 56277079be7Ssthen #else 56377079be7Ssthen *digest_type = EVP_sha1(); 56477079be7Ssthen #endif 5653dcb24b8Ssthen 5663dcb24b8Ssthen break; 5672be9e038Ssthen #endif /* USE_DSA && USE_SHA1 */ 5682be9e038Ssthen 5692be9e038Ssthen #if defined(USE_SHA1) || (defined(HAVE_EVP_SHA256) && defined(USE_SHA2)) || (defined(HAVE_EVP_SHA512) && defined(USE_SHA2)) 5702be9e038Ssthen #ifdef USE_SHA1 5713dcb24b8Ssthen case LDNS_RSASHA1: 5723dcb24b8Ssthen case LDNS_RSASHA1_NSEC3: 5732be9e038Ssthen #endif 5743dcb24b8Ssthen #if defined(HAVE_EVP_SHA256) && defined(USE_SHA2) 5753dcb24b8Ssthen case LDNS_RSASHA256: 5763dcb24b8Ssthen #endif 5773dcb24b8Ssthen #if defined(HAVE_EVP_SHA512) && defined(USE_SHA2) 5783dcb24b8Ssthen case LDNS_RSASHA512: 5793dcb24b8Ssthen #endif 580191f22c6Ssthen *evp_key = sldns_key_rsa2pkey_raw(key, keylen); 5813dcb24b8Ssthen if(!*evp_key) { 582191f22c6Ssthen verbose(VERB_QUERY, "verify: sldns_key_rsa2pkey SHA failed"); 5833dcb24b8Ssthen return 0; 5843dcb24b8Ssthen } 5853dcb24b8Ssthen 5863dcb24b8Ssthen /* select SHA version */ 5873dcb24b8Ssthen #if defined(HAVE_EVP_SHA256) && defined(USE_SHA2) 5883dcb24b8Ssthen if(algo == LDNS_RSASHA256) 5893dcb24b8Ssthen *digest_type = EVP_sha256(); 5903dcb24b8Ssthen else 5913dcb24b8Ssthen #endif 5923dcb24b8Ssthen #if defined(HAVE_EVP_SHA512) && defined(USE_SHA2) 5933dcb24b8Ssthen if(algo == LDNS_RSASHA512) 5943dcb24b8Ssthen *digest_type = EVP_sha512(); 5953dcb24b8Ssthen else 5963dcb24b8Ssthen #endif 5972be9e038Ssthen #ifdef USE_SHA1 5983dcb24b8Ssthen *digest_type = EVP_sha1(); 5992be9e038Ssthen #else 6002be9e038Ssthen { verbose(VERB_QUERY, "no digest available"); return 0; } 6012be9e038Ssthen #endif 6023dcb24b8Ssthen break; 6032be9e038Ssthen #endif /* defined(USE_SHA1) || (defined(HAVE_EVP_SHA256) && defined(USE_SHA2)) || (defined(HAVE_EVP_SHA512) && defined(USE_SHA2)) */ 6042be9e038Ssthen 6053dcb24b8Ssthen case LDNS_RSAMD5: 606191f22c6Ssthen *evp_key = sldns_key_rsa2pkey_raw(key, keylen); 6073dcb24b8Ssthen if(!*evp_key) { 608191f22c6Ssthen verbose(VERB_QUERY, "verify: sldns_key_rsa2pkey MD5 failed"); 6093dcb24b8Ssthen return 0; 6103dcb24b8Ssthen } 6113dcb24b8Ssthen *digest_type = EVP_md5(); 6123dcb24b8Ssthen 6133dcb24b8Ssthen break; 6143dcb24b8Ssthen #ifdef USE_GOST 6153dcb24b8Ssthen case LDNS_ECC_GOST: 6165d76a658Ssthen *evp_key = sldns_gost2pkey_raw(key, keylen); 6173dcb24b8Ssthen if(!*evp_key) { 6183dcb24b8Ssthen verbose(VERB_QUERY, "verify: " 6195d76a658Ssthen "sldns_gost2pkey_raw failed"); 6203dcb24b8Ssthen return 0; 6213dcb24b8Ssthen } 6223dcb24b8Ssthen *digest_type = EVP_get_digestbyname("md_gost94"); 6233dcb24b8Ssthen if(!*digest_type) { 6243dcb24b8Ssthen verbose(VERB_QUERY, "verify: " 6253dcb24b8Ssthen "EVP_getdigest md_gost94 failed"); 6263dcb24b8Ssthen return 0; 6273dcb24b8Ssthen } 6283dcb24b8Ssthen break; 6293dcb24b8Ssthen #endif 6303dcb24b8Ssthen #ifdef USE_ECDSA 6313dcb24b8Ssthen case LDNS_ECDSAP256SHA256: 6325d76a658Ssthen *evp_key = sldns_ecdsa2pkey_raw(key, keylen, 6333dcb24b8Ssthen LDNS_ECDSAP256SHA256); 6343dcb24b8Ssthen if(!*evp_key) { 6353dcb24b8Ssthen verbose(VERB_QUERY, "verify: " 6365d76a658Ssthen "sldns_ecdsa2pkey_raw failed"); 6373dcb24b8Ssthen return 0; 6383dcb24b8Ssthen } 6393dcb24b8Ssthen #ifdef USE_ECDSA_EVP_WORKAROUND 64077079be7Ssthen *digest_type = &ecdsa_evp_256_md; 6413dcb24b8Ssthen #else 6423dcb24b8Ssthen *digest_type = EVP_sha256(); 6433dcb24b8Ssthen #endif 6443dcb24b8Ssthen break; 6453dcb24b8Ssthen case LDNS_ECDSAP384SHA384: 6465d76a658Ssthen *evp_key = sldns_ecdsa2pkey_raw(key, keylen, 6473dcb24b8Ssthen LDNS_ECDSAP384SHA384); 6483dcb24b8Ssthen if(!*evp_key) { 6493dcb24b8Ssthen verbose(VERB_QUERY, "verify: " 6505d76a658Ssthen "sldns_ecdsa2pkey_raw failed"); 6513dcb24b8Ssthen return 0; 6523dcb24b8Ssthen } 6533dcb24b8Ssthen #ifdef USE_ECDSA_EVP_WORKAROUND 65477079be7Ssthen *digest_type = &ecdsa_evp_384_md; 6553dcb24b8Ssthen #else 6563dcb24b8Ssthen *digest_type = EVP_sha384(); 6573dcb24b8Ssthen #endif 6583dcb24b8Ssthen break; 6593dcb24b8Ssthen #endif /* USE_ECDSA */ 6602be9e038Ssthen #ifdef USE_ED25519 6612be9e038Ssthen case LDNS_ED25519: 6622be9e038Ssthen *evp_key = sldns_ed255192pkey_raw(key, keylen); 6632be9e038Ssthen if(!*evp_key) { 6642be9e038Ssthen verbose(VERB_QUERY, "verify: " 6652be9e038Ssthen "sldns_ed255192pkey_raw failed"); 6662be9e038Ssthen return 0; 6672be9e038Ssthen } 6682be9e038Ssthen *digest_type = NULL; 6692be9e038Ssthen break; 6702be9e038Ssthen #endif /* USE_ED25519 */ 67120237c55Ssthen #ifdef USE_ED448 67220237c55Ssthen case LDNS_ED448: 67320237c55Ssthen *evp_key = sldns_ed4482pkey_raw(key, keylen); 67420237c55Ssthen if(!*evp_key) { 67520237c55Ssthen verbose(VERB_QUERY, "verify: " 67620237c55Ssthen "sldns_ed4482pkey_raw failed"); 67720237c55Ssthen return 0; 67820237c55Ssthen } 67920237c55Ssthen *digest_type = NULL; 68020237c55Ssthen break; 68120237c55Ssthen #endif /* USE_ED448 */ 6823dcb24b8Ssthen default: 6833dcb24b8Ssthen verbose(VERB_QUERY, "verify: unknown algorithm %d", 6843dcb24b8Ssthen algo); 6853dcb24b8Ssthen return 0; 6863dcb24b8Ssthen } 6873dcb24b8Ssthen return 1; 6883dcb24b8Ssthen } 6893dcb24b8Ssthen 690d1e2768aSsthen static void 691d1e2768aSsthen digest_ctx_free(EVP_MD_CTX* ctx, EVP_PKEY *evp_key, 692d1e2768aSsthen unsigned char* sigblock, int dofree, int docrypto_free) 693d1e2768aSsthen { 694d1e2768aSsthen #ifdef HAVE_EVP_MD_CTX_NEW 695d1e2768aSsthen EVP_MD_CTX_destroy(ctx); 696d1e2768aSsthen #else 697d1e2768aSsthen EVP_MD_CTX_cleanup(ctx); 698d1e2768aSsthen free(ctx); 699d1e2768aSsthen #endif 700d1e2768aSsthen EVP_PKEY_free(evp_key); 701d1e2768aSsthen if(dofree) free(sigblock); 702d1e2768aSsthen else if(docrypto_free) OPENSSL_free(sigblock); 703d1e2768aSsthen } 704d1e2768aSsthen 705d1e2768aSsthen static enum sec_status 706d1e2768aSsthen digest_error_status(const char *str) 707d1e2768aSsthen { 708d1e2768aSsthen unsigned long e = ERR_get_error(); 709d1e2768aSsthen #ifdef EVP_R_INVALID_DIGEST 710d1e2768aSsthen if (ERR_GET_LIB(e) == ERR_LIB_EVP && 711d1e2768aSsthen ERR_GET_REASON(e) == EVP_R_INVALID_DIGEST) { 712d1e2768aSsthen log_crypto_verbose(VERB_ALGO, str, e); 713d1e2768aSsthen return sec_status_indeterminate; 714d1e2768aSsthen } 715d1e2768aSsthen #endif 716d1e2768aSsthen log_crypto_verbose(VERB_QUERY, str, e); 717d1e2768aSsthen return sec_status_unchecked; 718d1e2768aSsthen } 719d1e2768aSsthen 7203dcb24b8Ssthen /** 7213dcb24b8Ssthen * Check a canonical sig+rrset and signature against a dnskey 7223dcb24b8Ssthen * @param buf: buffer with data to verify, the first rrsig part and the 7233dcb24b8Ssthen * canonicalized rrset. 7243dcb24b8Ssthen * @param algo: DNSKEY algorithm. 7253dcb24b8Ssthen * @param sigblock: signature rdata field from RRSIG 7263dcb24b8Ssthen * @param sigblock_len: length of sigblock data. 7273dcb24b8Ssthen * @param key: public key data from DNSKEY RR. 7283dcb24b8Ssthen * @param keylen: length of keydata. 7293dcb24b8Ssthen * @param reason: bogus reason in more detail. 7303dcb24b8Ssthen * @return secure if verification succeeded, bogus on crypto failure, 731d1e2768aSsthen * unchecked on format errors and alloc failures, indeterminate 732d1e2768aSsthen * if digest is not supported by the crypto library (openssl3+ only). 7333dcb24b8Ssthen */ 7343dcb24b8Ssthen enum sec_status 7355d76a658Ssthen verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock, 7363dcb24b8Ssthen unsigned int sigblock_len, unsigned char* key, unsigned int keylen, 7373dcb24b8Ssthen char** reason) 7383dcb24b8Ssthen { 7393dcb24b8Ssthen const EVP_MD *digest_type; 7402ee382b6Ssthen EVP_MD_CTX* ctx; 7412ee382b6Ssthen int res, dofree = 0, docrypto_free = 0; 7423dcb24b8Ssthen EVP_PKEY *evp_key = NULL; 7433dcb24b8Ssthen 74477079be7Ssthen #ifndef USE_DSA 7452be9e038Ssthen if((algo == LDNS_DSA || algo == LDNS_DSA_NSEC3) &&(fake_dsa||fake_sha1)) 7462be9e038Ssthen return sec_status_secure; 7472be9e038Ssthen #endif 7482be9e038Ssthen #ifndef USE_SHA1 7492be9e038Ssthen if(fake_sha1 && (algo == LDNS_DSA || algo == LDNS_DSA_NSEC3 || algo == LDNS_RSASHA1 || algo == LDNS_RSASHA1_NSEC3)) 75077079be7Ssthen return sec_status_secure; 75177079be7Ssthen #endif 75277079be7Ssthen 7533dcb24b8Ssthen if(!setup_key_digest(algo, &evp_key, &digest_type, key, keylen)) { 7543dcb24b8Ssthen verbose(VERB_QUERY, "verify: failed to setup key"); 7553dcb24b8Ssthen *reason = "use of key for crypto failed"; 7563dcb24b8Ssthen EVP_PKEY_free(evp_key); 7573dcb24b8Ssthen return sec_status_bogus; 7583dcb24b8Ssthen } 7592ee382b6Ssthen #ifdef USE_DSA 7603dcb24b8Ssthen /* if it is a DSA signature in bind format, convert to DER format */ 7613dcb24b8Ssthen if((algo == LDNS_DSA || algo == LDNS_DSA_NSEC3) && 7623dcb24b8Ssthen sigblock_len == 1+2*SHA_DIGEST_LENGTH) { 7633dcb24b8Ssthen if(!setup_dsa_sig(&sigblock, &sigblock_len)) { 7643dcb24b8Ssthen verbose(VERB_QUERY, "verify: failed to setup DSA sig"); 7653dcb24b8Ssthen *reason = "use of key for DSA crypto failed"; 7663dcb24b8Ssthen EVP_PKEY_free(evp_key); 7673dcb24b8Ssthen return sec_status_bogus; 7683dcb24b8Ssthen } 7692ee382b6Ssthen docrypto_free = 1; 7703dcb24b8Ssthen } 7712ee382b6Ssthen #endif 7722ee382b6Ssthen #if defined(USE_ECDSA) && defined(USE_DSA) 7732ee382b6Ssthen else 7742ee382b6Ssthen #endif 7753dcb24b8Ssthen #ifdef USE_ECDSA 7762ee382b6Ssthen if(algo == LDNS_ECDSAP256SHA256 || algo == LDNS_ECDSAP384SHA384) { 7773dcb24b8Ssthen /* EVP uses ASN prefix on sig, which is not in the wire data */ 7783dcb24b8Ssthen if(!setup_ecdsa_sig(&sigblock, &sigblock_len)) { 7793dcb24b8Ssthen verbose(VERB_QUERY, "verify: failed to setup ECDSA sig"); 7803dcb24b8Ssthen *reason = "use of signature for ECDSA crypto failed"; 7813dcb24b8Ssthen EVP_PKEY_free(evp_key); 7823dcb24b8Ssthen return sec_status_bogus; 7833dcb24b8Ssthen } 7843dcb24b8Ssthen dofree = 1; 7853dcb24b8Ssthen } 7863dcb24b8Ssthen #endif /* USE_ECDSA */ 7873dcb24b8Ssthen 7883dcb24b8Ssthen /* do the signature cryptography work */ 7892ee382b6Ssthen #ifdef HAVE_EVP_MD_CTX_NEW 7902ee382b6Ssthen ctx = EVP_MD_CTX_new(); 7912ee382b6Ssthen #else 7922ee382b6Ssthen ctx = (EVP_MD_CTX*)malloc(sizeof(*ctx)); 7932ee382b6Ssthen if(ctx) EVP_MD_CTX_init(ctx); 7942ee382b6Ssthen #endif 7952ee382b6Ssthen if(!ctx) { 7962ee382b6Ssthen log_err("EVP_MD_CTX_new: malloc failure"); 7973dcb24b8Ssthen EVP_PKEY_free(evp_key); 7983dcb24b8Ssthen if(dofree) free(sigblock); 79977079be7Ssthen else if(docrypto_free) OPENSSL_free(sigblock); 8003dcb24b8Ssthen return sec_status_unchecked; 8013dcb24b8Ssthen } 8022be9e038Ssthen #ifndef HAVE_EVP_DIGESTVERIFY 8032be9e038Ssthen if(EVP_DigestInit(ctx, digest_type) == 0) { 804d1e2768aSsthen enum sec_status sec; 805d1e2768aSsthen sec = digest_error_status("verify: EVP_DigestInit failed"); 806d1e2768aSsthen digest_ctx_free(ctx, evp_key, sigblock, 807d1e2768aSsthen dofree, docrypto_free); 808d1e2768aSsthen return sec; 8092ee382b6Ssthen } 8102be9e038Ssthen if(EVP_DigestUpdate(ctx, (unsigned char*)sldns_buffer_begin(buf), 8115d76a658Ssthen (unsigned int)sldns_buffer_limit(buf)) == 0) { 812d1e2768aSsthen log_crypto_verbose(VERB_QUERY, "verify: EVP_DigestUpdate failed", 813d1e2768aSsthen ERR_get_error()); 814d1e2768aSsthen digest_ctx_free(ctx, evp_key, sigblock, 815d1e2768aSsthen dofree, docrypto_free); 8163dcb24b8Ssthen return sec_status_unchecked; 8173dcb24b8Ssthen } 8183dcb24b8Ssthen 8192ee382b6Ssthen res = EVP_VerifyFinal(ctx, sigblock, sigblock_len, evp_key); 8202be9e038Ssthen #else /* HAVE_EVP_DIGESTVERIFY */ 8212be9e038Ssthen if(EVP_DigestVerifyInit(ctx, NULL, digest_type, NULL, evp_key) == 0) { 822d1e2768aSsthen enum sec_status sec; 823d1e2768aSsthen sec = digest_error_status("verify: EVP_DigestVerifyInit failed"); 824d1e2768aSsthen digest_ctx_free(ctx, evp_key, sigblock, 825d1e2768aSsthen dofree, docrypto_free); 826d1e2768aSsthen return sec; 8272be9e038Ssthen } 8282be9e038Ssthen res = EVP_DigestVerify(ctx, sigblock, sigblock_len, 8292be9e038Ssthen (unsigned char*)sldns_buffer_begin(buf), 8302be9e038Ssthen sldns_buffer_limit(buf)); 8312be9e038Ssthen #endif 832d1e2768aSsthen digest_ctx_free(ctx, evp_key, sigblock, 833d1e2768aSsthen dofree, docrypto_free); 8343dcb24b8Ssthen 8353dcb24b8Ssthen if(res == 1) { 8363dcb24b8Ssthen return sec_status_secure; 8373dcb24b8Ssthen } else if(res == 0) { 8383dcb24b8Ssthen verbose(VERB_QUERY, "verify: signature mismatch"); 8393dcb24b8Ssthen *reason = "signature crypto failed"; 8403dcb24b8Ssthen return sec_status_bogus; 8413dcb24b8Ssthen } 8423dcb24b8Ssthen 8433dcb24b8Ssthen log_crypto_error("verify:", ERR_get_error()); 8443dcb24b8Ssthen return sec_status_unchecked; 8453dcb24b8Ssthen } 8463dcb24b8Ssthen 8473dcb24b8Ssthen /**************************************************/ 8483dcb24b8Ssthen #elif defined(HAVE_NSS) 8493dcb24b8Ssthen /* libnss implementation */ 850229e174cSsthen /* nss3 */ 851229e174cSsthen #include "sechash.h" 852229e174cSsthen #include "pk11pub.h" 853229e174cSsthen #include "keyhi.h" 854229e174cSsthen #include "secerr.h" 855229e174cSsthen #include "cryptohi.h" 856229e174cSsthen /* nspr4 */ 857229e174cSsthen #include "prerror.h" 8583dcb24b8Ssthen 85924893edcSsthen /* return size of digest if supported, or 0 otherwise */ 86024893edcSsthen size_t 86124893edcSsthen nsec3_hash_algo_size_supported(int id) 86224893edcSsthen { 86324893edcSsthen switch(id) { 86424893edcSsthen case NSEC3_HASH_SHA1: 86524893edcSsthen return SHA1_LENGTH; 86624893edcSsthen default: 86724893edcSsthen return 0; 86824893edcSsthen } 86924893edcSsthen } 87024893edcSsthen 87124893edcSsthen /* perform nsec3 hash. return false on failure */ 87224893edcSsthen int 87324893edcSsthen secalgo_nsec3_hash(int algo, unsigned char* buf, size_t len, 87424893edcSsthen unsigned char* res) 87524893edcSsthen { 87624893edcSsthen switch(algo) { 87724893edcSsthen case NSEC3_HASH_SHA1: 87824893edcSsthen (void)HASH_HashBuf(HASH_AlgSHA1, res, buf, (unsigned long)len); 87924893edcSsthen return 1; 88024893edcSsthen default: 88124893edcSsthen return 0; 88224893edcSsthen } 88324893edcSsthen } 88424893edcSsthen 8852ee382b6Ssthen void 8862ee382b6Ssthen secalgo_hash_sha256(unsigned char* buf, size_t len, unsigned char* res) 8872ee382b6Ssthen { 8882ee382b6Ssthen (void)HASH_HashBuf(HASH_AlgSHA256, res, buf, (unsigned long)len); 8892ee382b6Ssthen } 8902ee382b6Ssthen 891191f22c6Ssthen /** the secalgo hash structure */ 892191f22c6Ssthen struct secalgo_hash { 893191f22c6Ssthen /** hash context */ 894191f22c6Ssthen HASHContext* ctx; 895191f22c6Ssthen }; 896191f22c6Ssthen 897191f22c6Ssthen /** create hash struct of type */ 898191f22c6Ssthen static struct secalgo_hash* secalgo_hash_create_type(HASH_HashType tp) 899191f22c6Ssthen { 900191f22c6Ssthen struct secalgo_hash* h = calloc(1, sizeof(*h)); 901191f22c6Ssthen if(!h) 902191f22c6Ssthen return NULL; 903191f22c6Ssthen h->ctx = HASH_Create(tp); 904191f22c6Ssthen if(!h->ctx) { 905191f22c6Ssthen free(h); 906191f22c6Ssthen return NULL; 907191f22c6Ssthen } 908191f22c6Ssthen return h; 909191f22c6Ssthen } 910191f22c6Ssthen 911191f22c6Ssthen struct secalgo_hash* secalgo_hash_create_sha384(void) 912191f22c6Ssthen { 913191f22c6Ssthen return secalgo_hash_create_type(HASH_AlgSHA384); 914191f22c6Ssthen } 915191f22c6Ssthen 916191f22c6Ssthen struct secalgo_hash* secalgo_hash_create_sha512(void) 917191f22c6Ssthen { 918191f22c6Ssthen return secalgo_hash_create_type(HASH_AlgSHA512); 919191f22c6Ssthen } 920191f22c6Ssthen 921191f22c6Ssthen int secalgo_hash_update(struct secalgo_hash* hash, uint8_t* data, size_t len) 922191f22c6Ssthen { 923191f22c6Ssthen HASH_Update(hash->ctx, (unsigned char*)data, (unsigned int)len); 924191f22c6Ssthen return 1; 925191f22c6Ssthen } 926191f22c6Ssthen 927191f22c6Ssthen int secalgo_hash_final(struct secalgo_hash* hash, uint8_t* result, 928191f22c6Ssthen size_t maxlen, size_t* resultlen) 929191f22c6Ssthen { 930191f22c6Ssthen unsigned int reslen = 0; 931191f22c6Ssthen if(HASH_ResultLenContext(hash->ctx) > (unsigned int)maxlen) { 932191f22c6Ssthen *resultlen = 0; 933191f22c6Ssthen log_err("secalgo_hash_final: hash buffer too small"); 934191f22c6Ssthen return 0; 935191f22c6Ssthen } 936191f22c6Ssthen HASH_End(hash->ctx, (unsigned char*)result, &reslen, 937191f22c6Ssthen (unsigned int)maxlen); 938191f22c6Ssthen *resultlen = (size_t)reslen; 939191f22c6Ssthen return 1; 940191f22c6Ssthen } 941191f22c6Ssthen 942191f22c6Ssthen void secalgo_hash_delete(struct secalgo_hash* hash) 943191f22c6Ssthen { 944191f22c6Ssthen if(!hash) return; 945191f22c6Ssthen HASH_Destroy(hash->ctx); 946191f22c6Ssthen free(hash); 947191f22c6Ssthen } 948191f22c6Ssthen 9493dcb24b8Ssthen size_t 9503dcb24b8Ssthen ds_digest_size_supported(int algo) 9513dcb24b8Ssthen { 9523dcb24b8Ssthen /* uses libNSS */ 9533dcb24b8Ssthen switch(algo) { 9542be9e038Ssthen #ifdef USE_SHA1 9553dcb24b8Ssthen case LDNS_SHA1: 9563dcb24b8Ssthen return SHA1_LENGTH; 9572be9e038Ssthen #endif 9583dcb24b8Ssthen #ifdef USE_SHA2 9593dcb24b8Ssthen case LDNS_SHA256: 9603dcb24b8Ssthen return SHA256_LENGTH; 9613dcb24b8Ssthen #endif 9623dcb24b8Ssthen #ifdef USE_ECDSA 9633dcb24b8Ssthen case LDNS_SHA384: 9643dcb24b8Ssthen return SHA384_LENGTH; 9653dcb24b8Ssthen #endif 9663dcb24b8Ssthen /* GOST not supported in NSS */ 9673dcb24b8Ssthen case LDNS_HASH_GOST: 9683dcb24b8Ssthen default: break; 9693dcb24b8Ssthen } 9703dcb24b8Ssthen return 0; 9713dcb24b8Ssthen } 9723dcb24b8Ssthen 9733dcb24b8Ssthen int 9743dcb24b8Ssthen secalgo_ds_digest(int algo, unsigned char* buf, size_t len, 9753dcb24b8Ssthen unsigned char* res) 9763dcb24b8Ssthen { 9773dcb24b8Ssthen /* uses libNSS */ 9783dcb24b8Ssthen switch(algo) { 9792be9e038Ssthen #ifdef USE_SHA1 9803dcb24b8Ssthen case LDNS_SHA1: 9813dcb24b8Ssthen return HASH_HashBuf(HASH_AlgSHA1, res, buf, len) 9823dcb24b8Ssthen == SECSuccess; 9832be9e038Ssthen #endif 9843dcb24b8Ssthen #if defined(USE_SHA2) 9853dcb24b8Ssthen case LDNS_SHA256: 9863dcb24b8Ssthen return HASH_HashBuf(HASH_AlgSHA256, res, buf, len) 9873dcb24b8Ssthen == SECSuccess; 9883dcb24b8Ssthen #endif 9893dcb24b8Ssthen #ifdef USE_ECDSA 9903dcb24b8Ssthen case LDNS_SHA384: 9913dcb24b8Ssthen return HASH_HashBuf(HASH_AlgSHA384, res, buf, len) 9923dcb24b8Ssthen == SECSuccess; 9933dcb24b8Ssthen #endif 9943dcb24b8Ssthen case LDNS_HASH_GOST: 9953dcb24b8Ssthen default: 9963dcb24b8Ssthen verbose(VERB_QUERY, "unknown DS digest algorithm %d", 9973dcb24b8Ssthen algo); 9983dcb24b8Ssthen break; 9993dcb24b8Ssthen } 10003dcb24b8Ssthen return 0; 10013dcb24b8Ssthen } 10023dcb24b8Ssthen 10033dcb24b8Ssthen int 10043dcb24b8Ssthen dnskey_algo_id_is_supported(int id) 10053dcb24b8Ssthen { 10063dcb24b8Ssthen /* uses libNSS */ 10073dcb24b8Ssthen switch(id) { 10083dcb24b8Ssthen case LDNS_RSAMD5: 1009229e174cSsthen /* RFC 6725 deprecates RSAMD5 */ 1010229e174cSsthen return 0; 10112be9e038Ssthen #if defined(USE_SHA1) || defined(USE_SHA2) 10122be9e038Ssthen #if defined(USE_DSA) && defined(USE_SHA1) 10133dcb24b8Ssthen case LDNS_DSA: 10143dcb24b8Ssthen case LDNS_DSA_NSEC3: 10152ee382b6Ssthen #endif 10162be9e038Ssthen #ifdef USE_SHA1 10173dcb24b8Ssthen case LDNS_RSASHA1: 10183dcb24b8Ssthen case LDNS_RSASHA1_NSEC3: 10192be9e038Ssthen #endif 10203dcb24b8Ssthen #ifdef USE_SHA2 10213dcb24b8Ssthen case LDNS_RSASHA256: 10223dcb24b8Ssthen #endif 10233dcb24b8Ssthen #ifdef USE_SHA2 10243dcb24b8Ssthen case LDNS_RSASHA512: 10253dcb24b8Ssthen #endif 10263dcb24b8Ssthen return 1; 10272be9e038Ssthen #endif /* SHA1 or SHA2 */ 10282be9e038Ssthen 10293dcb24b8Ssthen #ifdef USE_ECDSA 10303dcb24b8Ssthen case LDNS_ECDSAP256SHA256: 10313dcb24b8Ssthen case LDNS_ECDSAP384SHA384: 10323dcb24b8Ssthen return PK11_TokenExists(CKM_ECDSA); 10333dcb24b8Ssthen #endif 10343dcb24b8Ssthen case LDNS_ECC_GOST: 10353dcb24b8Ssthen default: 10363dcb24b8Ssthen return 0; 10373dcb24b8Ssthen } 10383dcb24b8Ssthen } 10393dcb24b8Ssthen 10403dcb24b8Ssthen /* return a new public key for NSS */ 10413dcb24b8Ssthen static SECKEYPublicKey* nss_key_create(KeyType ktype) 10423dcb24b8Ssthen { 10433dcb24b8Ssthen SECKEYPublicKey* key; 10443dcb24b8Ssthen PLArenaPool* arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); 10453dcb24b8Ssthen if(!arena) { 10463dcb24b8Ssthen log_err("out of memory, PORT_NewArena failed"); 10473dcb24b8Ssthen return NULL; 10483dcb24b8Ssthen } 10493dcb24b8Ssthen key = PORT_ArenaZNew(arena, SECKEYPublicKey); 10503dcb24b8Ssthen if(!key) { 10513dcb24b8Ssthen log_err("out of memory, PORT_ArenaZNew failed"); 10523dcb24b8Ssthen PORT_FreeArena(arena, PR_FALSE); 10533dcb24b8Ssthen return NULL; 10543dcb24b8Ssthen } 10553dcb24b8Ssthen key->arena = arena; 10563dcb24b8Ssthen key->keyType = ktype; 10573dcb24b8Ssthen key->pkcs11Slot = NULL; 10583dcb24b8Ssthen key->pkcs11ID = CK_INVALID_HANDLE; 10593dcb24b8Ssthen return key; 10603dcb24b8Ssthen } 10613dcb24b8Ssthen 10623dcb24b8Ssthen static SECKEYPublicKey* nss_buf2ecdsa(unsigned char* key, size_t len, int algo) 10633dcb24b8Ssthen { 10643dcb24b8Ssthen SECKEYPublicKey* pk; 10653dcb24b8Ssthen SECItem pub = {siBuffer, NULL, 0}; 10663dcb24b8Ssthen SECItem params = {siBuffer, NULL, 0}; 1067229e174cSsthen static unsigned char param256[] = { 10683dcb24b8Ssthen /* OBJECTIDENTIFIER 1.2.840.10045.3.1.7 (P-256) 10693dcb24b8Ssthen * {iso(1) member-body(2) us(840) ansi-x962(10045) curves(3) prime(1) prime256v1(7)} */ 10703dcb24b8Ssthen 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07 10713dcb24b8Ssthen }; 1072229e174cSsthen static unsigned char param384[] = { 10733dcb24b8Ssthen /* OBJECTIDENTIFIER 1.3.132.0.34 (P-384) 10743dcb24b8Ssthen * {iso(1) identified-organization(3) certicom(132) curve(0) ansip384r1(34)} */ 10753dcb24b8Ssthen 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x22 10763dcb24b8Ssthen }; 10773dcb24b8Ssthen unsigned char buf[256+2]; /* sufficient for 2*384/8+1 */ 10783dcb24b8Ssthen 10793dcb24b8Ssthen /* check length, which uncompressed must be 2 bignums */ 10803dcb24b8Ssthen if(algo == LDNS_ECDSAP256SHA256) { 10813dcb24b8Ssthen if(len != 2*256/8) return NULL; 10823dcb24b8Ssthen /* ECCurve_X9_62_PRIME_256V1 */ 10833dcb24b8Ssthen } else if(algo == LDNS_ECDSAP384SHA384) { 10843dcb24b8Ssthen if(len != 2*384/8) return NULL; 10853dcb24b8Ssthen /* ECCurve_X9_62_PRIME_384R1 */ 10863dcb24b8Ssthen } else return NULL; 10873dcb24b8Ssthen 10883dcb24b8Ssthen buf[0] = 0x04; /* POINT_FORM_UNCOMPRESSED */ 10893dcb24b8Ssthen memmove(buf+1, key, len); 10903dcb24b8Ssthen pub.data = buf; 10913dcb24b8Ssthen pub.len = len+1; 10923dcb24b8Ssthen if(algo == LDNS_ECDSAP256SHA256) { 10933dcb24b8Ssthen params.data = param256; 10943dcb24b8Ssthen params.len = sizeof(param256); 10953dcb24b8Ssthen } else { 10963dcb24b8Ssthen params.data = param384; 10973dcb24b8Ssthen params.len = sizeof(param384); 10983dcb24b8Ssthen } 10993dcb24b8Ssthen 11003dcb24b8Ssthen pk = nss_key_create(ecKey); 11013dcb24b8Ssthen if(!pk) 11023dcb24b8Ssthen return NULL; 11033dcb24b8Ssthen pk->u.ec.size = (len/2)*8; 11043dcb24b8Ssthen if(SECITEM_CopyItem(pk->arena, &pk->u.ec.publicValue, &pub)) { 11053dcb24b8Ssthen SECKEY_DestroyPublicKey(pk); 11063dcb24b8Ssthen return NULL; 11073dcb24b8Ssthen } 11083dcb24b8Ssthen if(SECITEM_CopyItem(pk->arena, &pk->u.ec.DEREncodedParams, ¶ms)) { 11093dcb24b8Ssthen SECKEY_DestroyPublicKey(pk); 11103dcb24b8Ssthen return NULL; 11113dcb24b8Ssthen } 11123dcb24b8Ssthen 11133dcb24b8Ssthen return pk; 11143dcb24b8Ssthen } 11153dcb24b8Ssthen 1116eba819a2Ssthen #if defined(USE_DSA) && defined(USE_SHA1) 11173dcb24b8Ssthen static SECKEYPublicKey* nss_buf2dsa(unsigned char* key, size_t len) 11183dcb24b8Ssthen { 11193dcb24b8Ssthen SECKEYPublicKey* pk; 11203dcb24b8Ssthen uint8_t T; 11213dcb24b8Ssthen uint16_t length; 11223dcb24b8Ssthen uint16_t offset; 11233dcb24b8Ssthen SECItem Q = {siBuffer, NULL, 0}; 11243dcb24b8Ssthen SECItem P = {siBuffer, NULL, 0}; 11253dcb24b8Ssthen SECItem G = {siBuffer, NULL, 0}; 11263dcb24b8Ssthen SECItem Y = {siBuffer, NULL, 0}; 11273dcb24b8Ssthen 11283dcb24b8Ssthen if(len == 0) 11293dcb24b8Ssthen return NULL; 11303dcb24b8Ssthen T = (uint8_t)key[0]; 11313dcb24b8Ssthen length = (64 + T * 8); 11323dcb24b8Ssthen offset = 1; 11333dcb24b8Ssthen 11343dcb24b8Ssthen if (T > 8) { 11353dcb24b8Ssthen return NULL; 11363dcb24b8Ssthen } 11373dcb24b8Ssthen if(len < (size_t)1 + SHA1_LENGTH + 3*length) 11383dcb24b8Ssthen return NULL; 11393dcb24b8Ssthen 11403dcb24b8Ssthen Q.data = key+offset; 11413dcb24b8Ssthen Q.len = SHA1_LENGTH; 11423dcb24b8Ssthen offset += SHA1_LENGTH; 11433dcb24b8Ssthen 11443dcb24b8Ssthen P.data = key+offset; 11453dcb24b8Ssthen P.len = length; 11463dcb24b8Ssthen offset += length; 11473dcb24b8Ssthen 11483dcb24b8Ssthen G.data = key+offset; 11493dcb24b8Ssthen G.len = length; 11503dcb24b8Ssthen offset += length; 11513dcb24b8Ssthen 11523dcb24b8Ssthen Y.data = key+offset; 11533dcb24b8Ssthen Y.len = length; 11543dcb24b8Ssthen offset += length; 11553dcb24b8Ssthen 11563dcb24b8Ssthen pk = nss_key_create(dsaKey); 11573dcb24b8Ssthen if(!pk) 11583dcb24b8Ssthen return NULL; 11593dcb24b8Ssthen if(SECITEM_CopyItem(pk->arena, &pk->u.dsa.params.prime, &P)) { 11603dcb24b8Ssthen SECKEY_DestroyPublicKey(pk); 11613dcb24b8Ssthen return NULL; 11623dcb24b8Ssthen } 11633dcb24b8Ssthen if(SECITEM_CopyItem(pk->arena, &pk->u.dsa.params.subPrime, &Q)) { 11643dcb24b8Ssthen SECKEY_DestroyPublicKey(pk); 11653dcb24b8Ssthen return NULL; 11663dcb24b8Ssthen } 11673dcb24b8Ssthen if(SECITEM_CopyItem(pk->arena, &pk->u.dsa.params.base, &G)) { 11683dcb24b8Ssthen SECKEY_DestroyPublicKey(pk); 11693dcb24b8Ssthen return NULL; 11703dcb24b8Ssthen } 11713dcb24b8Ssthen if(SECITEM_CopyItem(pk->arena, &pk->u.dsa.publicValue, &Y)) { 11723dcb24b8Ssthen SECKEY_DestroyPublicKey(pk); 11733dcb24b8Ssthen return NULL; 11743dcb24b8Ssthen } 11753dcb24b8Ssthen return pk; 11763dcb24b8Ssthen } 1177eba819a2Ssthen #endif /* USE_DSA && USE_SHA1 */ 11783dcb24b8Ssthen 11793dcb24b8Ssthen static SECKEYPublicKey* nss_buf2rsa(unsigned char* key, size_t len) 11803dcb24b8Ssthen { 11813dcb24b8Ssthen SECKEYPublicKey* pk; 11823dcb24b8Ssthen uint16_t exp; 11833dcb24b8Ssthen uint16_t offset; 11843dcb24b8Ssthen uint16_t int16; 11853dcb24b8Ssthen SECItem modulus = {siBuffer, NULL, 0}; 11863dcb24b8Ssthen SECItem exponent = {siBuffer, NULL, 0}; 11873dcb24b8Ssthen if(len == 0) 11883dcb24b8Ssthen return NULL; 11893dcb24b8Ssthen if(key[0] == 0) { 11903dcb24b8Ssthen if(len < 3) 11913dcb24b8Ssthen return NULL; 11923dcb24b8Ssthen /* the exponent is too large so it's places further */ 11933dcb24b8Ssthen memmove(&int16, key+1, 2); 11943dcb24b8Ssthen exp = ntohs(int16); 11953dcb24b8Ssthen offset = 3; 11963dcb24b8Ssthen } else { 11973dcb24b8Ssthen exp = key[0]; 11983dcb24b8Ssthen offset = 1; 11993dcb24b8Ssthen } 12003dcb24b8Ssthen 12013dcb24b8Ssthen /* key length at least one */ 12023dcb24b8Ssthen if(len < (size_t)offset + exp + 1) 12033dcb24b8Ssthen return NULL; 12043dcb24b8Ssthen 12053dcb24b8Ssthen exponent.data = key+offset; 12063dcb24b8Ssthen exponent.len = exp; 12073dcb24b8Ssthen offset += exp; 12083dcb24b8Ssthen modulus.data = key+offset; 12093dcb24b8Ssthen modulus.len = (len - offset); 12103dcb24b8Ssthen 12113dcb24b8Ssthen pk = nss_key_create(rsaKey); 12123dcb24b8Ssthen if(!pk) 12133dcb24b8Ssthen return NULL; 12143dcb24b8Ssthen if(SECITEM_CopyItem(pk->arena, &pk->u.rsa.modulus, &modulus)) { 12153dcb24b8Ssthen SECKEY_DestroyPublicKey(pk); 12163dcb24b8Ssthen return NULL; 12173dcb24b8Ssthen } 12183dcb24b8Ssthen if(SECITEM_CopyItem(pk->arena, &pk->u.rsa.publicExponent, &exponent)) { 12193dcb24b8Ssthen SECKEY_DestroyPublicKey(pk); 12203dcb24b8Ssthen return NULL; 12213dcb24b8Ssthen } 12223dcb24b8Ssthen return pk; 12233dcb24b8Ssthen } 12243dcb24b8Ssthen 12253dcb24b8Ssthen /** 12263dcb24b8Ssthen * Setup key and digest for verification. Adjust sig if necessary. 12273dcb24b8Ssthen * 12283dcb24b8Ssthen * @param algo: key algorithm 12293dcb24b8Ssthen * @param evp_key: EVP PKEY public key to create. 12303dcb24b8Ssthen * @param digest_type: digest type to use 12313dcb24b8Ssthen * @param key: key to setup for. 12323dcb24b8Ssthen * @param keylen: length of key. 12333dcb24b8Ssthen * @param prefix: if returned, the ASN prefix for the hashblob. 12343dcb24b8Ssthen * @param prefixlen: length of the prefix. 12353dcb24b8Ssthen * @return false on failure. 12363dcb24b8Ssthen */ 12373dcb24b8Ssthen static int 12383dcb24b8Ssthen nss_setup_key_digest(int algo, SECKEYPublicKey** pubkey, HASH_HashType* htype, 12393dcb24b8Ssthen unsigned char* key, size_t keylen, unsigned char** prefix, 12403dcb24b8Ssthen size_t* prefixlen) 12413dcb24b8Ssthen { 12423dcb24b8Ssthen /* uses libNSS */ 12433dcb24b8Ssthen 12443dcb24b8Ssthen /* hash prefix for md5, RFC2537 */ 1245229e174cSsthen static unsigned char p_md5[] = {0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 12463dcb24b8Ssthen 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10}; 12473dcb24b8Ssthen /* hash prefix to prepend to hash output, from RFC3110 */ 1248229e174cSsthen static unsigned char p_sha1[] = {0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 12493dcb24b8Ssthen 0x0E, 0x03, 0x02, 0x1A, 0x05, 0x00, 0x04, 0x14}; 12503dcb24b8Ssthen /* from RFC5702 */ 1251229e174cSsthen static unsigned char p_sha256[] = {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 12523dcb24b8Ssthen 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20}; 1253229e174cSsthen static unsigned char p_sha512[] = {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 12543dcb24b8Ssthen 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40}; 12553dcb24b8Ssthen /* from RFC6234 */ 12563dcb24b8Ssthen /* for future RSASHA384 .. 1257229e174cSsthen static unsigned char p_sha384[] = {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 12583dcb24b8Ssthen 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30}; 12593dcb24b8Ssthen */ 12603dcb24b8Ssthen 12613dcb24b8Ssthen switch(algo) { 12622be9e038Ssthen 12632be9e038Ssthen #if defined(USE_SHA1) || defined(USE_SHA2) 12642be9e038Ssthen #if defined(USE_DSA) && defined(USE_SHA1) 12653dcb24b8Ssthen case LDNS_DSA: 12663dcb24b8Ssthen case LDNS_DSA_NSEC3: 12673dcb24b8Ssthen *pubkey = nss_buf2dsa(key, keylen); 12683dcb24b8Ssthen if(!*pubkey) { 12693dcb24b8Ssthen log_err("verify: malloc failure in crypto"); 12703dcb24b8Ssthen return 0; 12713dcb24b8Ssthen } 12723dcb24b8Ssthen *htype = HASH_AlgSHA1; 12733dcb24b8Ssthen /* no prefix for DSA verification */ 12743dcb24b8Ssthen break; 12752ee382b6Ssthen #endif 12762be9e038Ssthen #ifdef USE_SHA1 12773dcb24b8Ssthen case LDNS_RSASHA1: 12783dcb24b8Ssthen case LDNS_RSASHA1_NSEC3: 12792be9e038Ssthen #endif 12803dcb24b8Ssthen #ifdef USE_SHA2 12813dcb24b8Ssthen case LDNS_RSASHA256: 12823dcb24b8Ssthen #endif 12833dcb24b8Ssthen #ifdef USE_SHA2 12843dcb24b8Ssthen case LDNS_RSASHA512: 12853dcb24b8Ssthen #endif 12863dcb24b8Ssthen *pubkey = nss_buf2rsa(key, keylen); 12873dcb24b8Ssthen if(!*pubkey) { 12883dcb24b8Ssthen log_err("verify: malloc failure in crypto"); 12893dcb24b8Ssthen return 0; 12903dcb24b8Ssthen } 12913dcb24b8Ssthen /* select SHA version */ 12923dcb24b8Ssthen #ifdef USE_SHA2 12933dcb24b8Ssthen if(algo == LDNS_RSASHA256) { 12943dcb24b8Ssthen *htype = HASH_AlgSHA256; 12953dcb24b8Ssthen *prefix = p_sha256; 12963dcb24b8Ssthen *prefixlen = sizeof(p_sha256); 12973dcb24b8Ssthen } else 12983dcb24b8Ssthen #endif 12993dcb24b8Ssthen #ifdef USE_SHA2 13003dcb24b8Ssthen if(algo == LDNS_RSASHA512) { 13013dcb24b8Ssthen *htype = HASH_AlgSHA512; 13023dcb24b8Ssthen *prefix = p_sha512; 13033dcb24b8Ssthen *prefixlen = sizeof(p_sha512); 13043dcb24b8Ssthen } else 13053dcb24b8Ssthen #endif 13062be9e038Ssthen #ifdef USE_SHA1 13073dcb24b8Ssthen { 13083dcb24b8Ssthen *htype = HASH_AlgSHA1; 13093dcb24b8Ssthen *prefix = p_sha1; 13103dcb24b8Ssthen *prefixlen = sizeof(p_sha1); 13113dcb24b8Ssthen } 13122be9e038Ssthen #else 13132be9e038Ssthen { 13142be9e038Ssthen verbose(VERB_QUERY, "verify: no digest algo"); 13152be9e038Ssthen return 0; 13162be9e038Ssthen } 13172be9e038Ssthen #endif 13183dcb24b8Ssthen 13193dcb24b8Ssthen break; 13202be9e038Ssthen #endif /* SHA1 or SHA2 */ 13212be9e038Ssthen 13223dcb24b8Ssthen case LDNS_RSAMD5: 13233dcb24b8Ssthen *pubkey = nss_buf2rsa(key, keylen); 13243dcb24b8Ssthen if(!*pubkey) { 13253dcb24b8Ssthen log_err("verify: malloc failure in crypto"); 13263dcb24b8Ssthen return 0; 13273dcb24b8Ssthen } 13283dcb24b8Ssthen *htype = HASH_AlgMD5; 13293dcb24b8Ssthen *prefix = p_md5; 13303dcb24b8Ssthen *prefixlen = sizeof(p_md5); 13313dcb24b8Ssthen 13323dcb24b8Ssthen break; 13333dcb24b8Ssthen #ifdef USE_ECDSA 13343dcb24b8Ssthen case LDNS_ECDSAP256SHA256: 13353dcb24b8Ssthen *pubkey = nss_buf2ecdsa(key, keylen, 13363dcb24b8Ssthen LDNS_ECDSAP256SHA256); 13373dcb24b8Ssthen if(!*pubkey) { 13383dcb24b8Ssthen log_err("verify: malloc failure in crypto"); 13393dcb24b8Ssthen return 0; 13403dcb24b8Ssthen } 13413dcb24b8Ssthen *htype = HASH_AlgSHA256; 13423dcb24b8Ssthen /* no prefix for DSA verification */ 13433dcb24b8Ssthen break; 13443dcb24b8Ssthen case LDNS_ECDSAP384SHA384: 13453dcb24b8Ssthen *pubkey = nss_buf2ecdsa(key, keylen, 13463dcb24b8Ssthen LDNS_ECDSAP384SHA384); 13473dcb24b8Ssthen if(!*pubkey) { 13483dcb24b8Ssthen log_err("verify: malloc failure in crypto"); 13493dcb24b8Ssthen return 0; 13503dcb24b8Ssthen } 13513dcb24b8Ssthen *htype = HASH_AlgSHA384; 13523dcb24b8Ssthen /* no prefix for DSA verification */ 13533dcb24b8Ssthen break; 13543dcb24b8Ssthen #endif /* USE_ECDSA */ 13553dcb24b8Ssthen case LDNS_ECC_GOST: 13563dcb24b8Ssthen default: 13573dcb24b8Ssthen verbose(VERB_QUERY, "verify: unknown algorithm %d", 13583dcb24b8Ssthen algo); 13593dcb24b8Ssthen return 0; 13603dcb24b8Ssthen } 13613dcb24b8Ssthen return 1; 13623dcb24b8Ssthen } 13633dcb24b8Ssthen 13643dcb24b8Ssthen /** 13653dcb24b8Ssthen * Check a canonical sig+rrset and signature against a dnskey 13663dcb24b8Ssthen * @param buf: buffer with data to verify, the first rrsig part and the 13673dcb24b8Ssthen * canonicalized rrset. 13683dcb24b8Ssthen * @param algo: DNSKEY algorithm. 13693dcb24b8Ssthen * @param sigblock: signature rdata field from RRSIG 13703dcb24b8Ssthen * @param sigblock_len: length of sigblock data. 13713dcb24b8Ssthen * @param key: public key data from DNSKEY RR. 13723dcb24b8Ssthen * @param keylen: length of keydata. 13733dcb24b8Ssthen * @param reason: bogus reason in more detail. 13743dcb24b8Ssthen * @return secure if verification succeeded, bogus on crypto failure, 13753dcb24b8Ssthen * unchecked on format errors and alloc failures. 13763dcb24b8Ssthen */ 13773dcb24b8Ssthen enum sec_status 13785d76a658Ssthen verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock, 13793dcb24b8Ssthen unsigned int sigblock_len, unsigned char* key, unsigned int keylen, 13803dcb24b8Ssthen char** reason) 13813dcb24b8Ssthen { 13823dcb24b8Ssthen /* uses libNSS */ 13833dcb24b8Ssthen /* large enough for the different hashes */ 13843dcb24b8Ssthen unsigned char hash[HASH_LENGTH_MAX]; 13853dcb24b8Ssthen unsigned char hash2[HASH_LENGTH_MAX*2]; 13863dcb24b8Ssthen HASH_HashType htype = 0; 13873dcb24b8Ssthen SECKEYPublicKey* pubkey = NULL; 13883dcb24b8Ssthen SECItem secsig = {siBuffer, sigblock, sigblock_len}; 13893dcb24b8Ssthen SECItem sechash = {siBuffer, hash, 0}; 13903dcb24b8Ssthen SECStatus res; 13913dcb24b8Ssthen unsigned char* prefix = NULL; /* prefix for hash, RFC3110, RFC5702 */ 13923dcb24b8Ssthen size_t prefixlen = 0; 13933dcb24b8Ssthen int err; 13943dcb24b8Ssthen 13953dcb24b8Ssthen if(!nss_setup_key_digest(algo, &pubkey, &htype, key, keylen, 13963dcb24b8Ssthen &prefix, &prefixlen)) { 13973dcb24b8Ssthen verbose(VERB_QUERY, "verify: failed to setup key"); 13983dcb24b8Ssthen *reason = "use of key for crypto failed"; 13993dcb24b8Ssthen SECKEY_DestroyPublicKey(pubkey); 14003dcb24b8Ssthen return sec_status_bogus; 14013dcb24b8Ssthen } 14023dcb24b8Ssthen 14032be9e038Ssthen #if defined(USE_DSA) && defined(USE_SHA1) 14043dcb24b8Ssthen /* need to convert DSA, ECDSA signatures? */ 14053dcb24b8Ssthen if((algo == LDNS_DSA || algo == LDNS_DSA_NSEC3)) { 14063dcb24b8Ssthen if(sigblock_len == 1+2*SHA1_LENGTH) { 14073dcb24b8Ssthen secsig.data ++; 14083dcb24b8Ssthen secsig.len --; 14093dcb24b8Ssthen } else { 14103dcb24b8Ssthen SECItem* p = DSAU_DecodeDerSig(&secsig); 14113dcb24b8Ssthen if(!p) { 14123dcb24b8Ssthen verbose(VERB_QUERY, "verify: failed DER decode"); 14133dcb24b8Ssthen *reason = "signature DER decode failed"; 14143dcb24b8Ssthen SECKEY_DestroyPublicKey(pubkey); 14153dcb24b8Ssthen return sec_status_bogus; 14163dcb24b8Ssthen } 14173dcb24b8Ssthen if(SECITEM_CopyItem(pubkey->arena, &secsig, p)) { 14183dcb24b8Ssthen log_err("alloc failure in DER decode"); 14193dcb24b8Ssthen SECKEY_DestroyPublicKey(pubkey); 14203dcb24b8Ssthen SECITEM_FreeItem(p, PR_TRUE); 14213dcb24b8Ssthen return sec_status_unchecked; 14223dcb24b8Ssthen } 14233dcb24b8Ssthen SECITEM_FreeItem(p, PR_TRUE); 14243dcb24b8Ssthen } 14253dcb24b8Ssthen } 14262ee382b6Ssthen #endif /* USE_DSA */ 14273dcb24b8Ssthen 14283dcb24b8Ssthen /* do the signature cryptography work */ 14293dcb24b8Ssthen /* hash the data */ 14303dcb24b8Ssthen sechash.len = HASH_ResultLen(htype); 14313dcb24b8Ssthen if(sechash.len > sizeof(hash)) { 14323dcb24b8Ssthen verbose(VERB_QUERY, "verify: hash too large for buffer"); 14333dcb24b8Ssthen SECKEY_DestroyPublicKey(pubkey); 14343dcb24b8Ssthen return sec_status_unchecked; 14353dcb24b8Ssthen } 14365d76a658Ssthen if(HASH_HashBuf(htype, hash, (unsigned char*)sldns_buffer_begin(buf), 14375d76a658Ssthen (unsigned int)sldns_buffer_limit(buf)) != SECSuccess) { 14383dcb24b8Ssthen verbose(VERB_QUERY, "verify: HASH_HashBuf failed"); 14393dcb24b8Ssthen SECKEY_DestroyPublicKey(pubkey); 14403dcb24b8Ssthen return sec_status_unchecked; 14413dcb24b8Ssthen } 14423dcb24b8Ssthen if(prefix) { 14433dcb24b8Ssthen int hashlen = sechash.len; 14443dcb24b8Ssthen if(prefixlen+hashlen > sizeof(hash2)) { 14453dcb24b8Ssthen verbose(VERB_QUERY, "verify: hashprefix too large"); 14463dcb24b8Ssthen SECKEY_DestroyPublicKey(pubkey); 14473dcb24b8Ssthen return sec_status_unchecked; 14483dcb24b8Ssthen } 14493dcb24b8Ssthen sechash.data = hash2; 14503dcb24b8Ssthen sechash.len = prefixlen+hashlen; 14513dcb24b8Ssthen memcpy(sechash.data, prefix, prefixlen); 14523dcb24b8Ssthen memmove(sechash.data+prefixlen, hash, hashlen); 14533dcb24b8Ssthen } 14543dcb24b8Ssthen 14553dcb24b8Ssthen /* verify the signature */ 14563dcb24b8Ssthen res = PK11_Verify(pubkey, &secsig, &sechash, NULL /*wincx*/); 14573dcb24b8Ssthen SECKEY_DestroyPublicKey(pubkey); 14583dcb24b8Ssthen 14593dcb24b8Ssthen if(res == SECSuccess) { 14603dcb24b8Ssthen return sec_status_secure; 14613dcb24b8Ssthen } 14623dcb24b8Ssthen err = PORT_GetError(); 14633dcb24b8Ssthen if(err != SEC_ERROR_BAD_SIGNATURE) { 14643dcb24b8Ssthen /* failed to verify */ 14653dcb24b8Ssthen verbose(VERB_QUERY, "verify: PK11_Verify failed: %s", 14663dcb24b8Ssthen PORT_ErrorToString(err)); 14673dcb24b8Ssthen /* if it is not supported, like ECC is removed, we get, 14683dcb24b8Ssthen * SEC_ERROR_NO_MODULE */ 14693dcb24b8Ssthen if(err == SEC_ERROR_NO_MODULE) 14703dcb24b8Ssthen return sec_status_unchecked; 14713dcb24b8Ssthen /* but other errors are commonly returned 14723dcb24b8Ssthen * for a bad signature from NSS. Thus we return bogus, 14733dcb24b8Ssthen * not unchecked */ 14743dcb24b8Ssthen *reason = "signature crypto failed"; 14753dcb24b8Ssthen return sec_status_bogus; 14763dcb24b8Ssthen } 14773dcb24b8Ssthen verbose(VERB_QUERY, "verify: signature mismatch: %s", 14783dcb24b8Ssthen PORT_ErrorToString(err)); 14793dcb24b8Ssthen *reason = "signature crypto failed"; 14803dcb24b8Ssthen return sec_status_bogus; 14813dcb24b8Ssthen } 14823dcb24b8Ssthen 148324893edcSsthen #elif defined(HAVE_NETTLE) 14843dcb24b8Ssthen 148524893edcSsthen #include "sha.h" 148624893edcSsthen #include "bignum.h" 148724893edcSsthen #include "macros.h" 148824893edcSsthen #include "rsa.h" 148924893edcSsthen #include "dsa.h" 149077079be7Ssthen #ifdef HAVE_NETTLE_DSA_COMPAT_H 149177079be7Ssthen #include "dsa-compat.h" 149277079be7Ssthen #endif 149324893edcSsthen #include "asn1.h" 149424893edcSsthen #ifdef USE_ECDSA 149524893edcSsthen #include "ecdsa.h" 149624893edcSsthen #include "ecc-curve.h" 149724893edcSsthen #endif 14987191de28Ssthen #ifdef HAVE_NETTLE_EDDSA_H 14997191de28Ssthen #include "eddsa.h" 15007191de28Ssthen #endif 150124893edcSsthen 150224893edcSsthen static int 150324893edcSsthen _digest_nettle(int algo, uint8_t* buf, size_t len, 150424893edcSsthen unsigned char* res) 150524893edcSsthen { 150624893edcSsthen switch(algo) { 150724893edcSsthen case SHA1_DIGEST_SIZE: 150824893edcSsthen { 150924893edcSsthen struct sha1_ctx ctx; 151024893edcSsthen sha1_init(&ctx); 151124893edcSsthen sha1_update(&ctx, len, buf); 151224893edcSsthen sha1_digest(&ctx, SHA1_DIGEST_SIZE, res); 151324893edcSsthen return 1; 151424893edcSsthen } 151524893edcSsthen case SHA256_DIGEST_SIZE: 151624893edcSsthen { 151724893edcSsthen struct sha256_ctx ctx; 151824893edcSsthen sha256_init(&ctx); 151924893edcSsthen sha256_update(&ctx, len, buf); 152024893edcSsthen sha256_digest(&ctx, SHA256_DIGEST_SIZE, res); 152124893edcSsthen return 1; 152224893edcSsthen } 152324893edcSsthen case SHA384_DIGEST_SIZE: 152424893edcSsthen { 152524893edcSsthen struct sha384_ctx ctx; 152624893edcSsthen sha384_init(&ctx); 152724893edcSsthen sha384_update(&ctx, len, buf); 152824893edcSsthen sha384_digest(&ctx, SHA384_DIGEST_SIZE, res); 152924893edcSsthen return 1; 153024893edcSsthen } 153124893edcSsthen case SHA512_DIGEST_SIZE: 153224893edcSsthen { 153324893edcSsthen struct sha512_ctx ctx; 153424893edcSsthen sha512_init(&ctx); 153524893edcSsthen sha512_update(&ctx, len, buf); 153624893edcSsthen sha512_digest(&ctx, SHA512_DIGEST_SIZE, res); 153724893edcSsthen return 1; 153824893edcSsthen } 153924893edcSsthen default: 154024893edcSsthen break; 154124893edcSsthen } 154224893edcSsthen return 0; 154324893edcSsthen } 154424893edcSsthen 154524893edcSsthen /* return size of digest if supported, or 0 otherwise */ 154624893edcSsthen size_t 154724893edcSsthen nsec3_hash_algo_size_supported(int id) 154824893edcSsthen { 154924893edcSsthen switch(id) { 155024893edcSsthen case NSEC3_HASH_SHA1: 155124893edcSsthen return SHA1_DIGEST_SIZE; 155224893edcSsthen default: 155324893edcSsthen return 0; 155424893edcSsthen } 155524893edcSsthen } 155624893edcSsthen 155724893edcSsthen /* perform nsec3 hash. return false on failure */ 155824893edcSsthen int 155924893edcSsthen secalgo_nsec3_hash(int algo, unsigned char* buf, size_t len, 156024893edcSsthen unsigned char* res) 156124893edcSsthen { 156224893edcSsthen switch(algo) { 156324893edcSsthen case NSEC3_HASH_SHA1: 156424893edcSsthen return _digest_nettle(SHA1_DIGEST_SIZE, (uint8_t*)buf, len, 156524893edcSsthen res); 156624893edcSsthen default: 156724893edcSsthen return 0; 156824893edcSsthen } 156924893edcSsthen } 157024893edcSsthen 15712ee382b6Ssthen void 15722ee382b6Ssthen secalgo_hash_sha256(unsigned char* buf, size_t len, unsigned char* res) 15732ee382b6Ssthen { 15742ee382b6Ssthen _digest_nettle(SHA256_DIGEST_SIZE, (uint8_t*)buf, len, res); 15752ee382b6Ssthen } 15762ee382b6Ssthen 1577191f22c6Ssthen /** secalgo hash structure */ 1578191f22c6Ssthen struct secalgo_hash { 1579191f22c6Ssthen /** if it is 384 or 512 */ 1580191f22c6Ssthen int active; 1581191f22c6Ssthen /** context for sha384 */ 1582191f22c6Ssthen struct sha384_ctx ctx384; 1583191f22c6Ssthen /** context for sha512 */ 1584191f22c6Ssthen struct sha512_ctx ctx512; 1585191f22c6Ssthen }; 1586191f22c6Ssthen 1587191f22c6Ssthen struct secalgo_hash* secalgo_hash_create_sha384(void) 1588191f22c6Ssthen { 1589191f22c6Ssthen struct secalgo_hash* h = calloc(1, sizeof(*h)); 1590191f22c6Ssthen if(!h) 1591191f22c6Ssthen return NULL; 1592191f22c6Ssthen h->active = 384; 1593191f22c6Ssthen sha384_init(&h->ctx384); 1594191f22c6Ssthen return h; 1595191f22c6Ssthen } 1596191f22c6Ssthen 1597191f22c6Ssthen struct secalgo_hash* secalgo_hash_create_sha512(void) 1598191f22c6Ssthen { 1599191f22c6Ssthen struct secalgo_hash* h = calloc(1, sizeof(*h)); 1600191f22c6Ssthen if(!h) 1601191f22c6Ssthen return NULL; 1602191f22c6Ssthen h->active = 512; 1603191f22c6Ssthen sha512_init(&h->ctx512); 1604191f22c6Ssthen return h; 1605191f22c6Ssthen } 1606191f22c6Ssthen 1607191f22c6Ssthen int secalgo_hash_update(struct secalgo_hash* hash, uint8_t* data, size_t len) 1608191f22c6Ssthen { 1609191f22c6Ssthen if(hash->active == 384) { 1610191f22c6Ssthen sha384_update(&hash->ctx384, len, data); 1611191f22c6Ssthen } else if(hash->active == 512) { 1612191f22c6Ssthen sha512_update(&hash->ctx512, len, data); 1613191f22c6Ssthen } else { 1614191f22c6Ssthen return 0; 1615191f22c6Ssthen } 1616191f22c6Ssthen return 1; 1617191f22c6Ssthen } 1618191f22c6Ssthen 1619191f22c6Ssthen int secalgo_hash_final(struct secalgo_hash* hash, uint8_t* result, 1620191f22c6Ssthen size_t maxlen, size_t* resultlen) 1621191f22c6Ssthen { 1622191f22c6Ssthen if(hash->active == 384) { 1623191f22c6Ssthen if(SHA384_DIGEST_SIZE > maxlen) { 1624191f22c6Ssthen *resultlen = 0; 1625191f22c6Ssthen log_err("secalgo_hash_final: hash buffer too small"); 1626191f22c6Ssthen return 0; 1627191f22c6Ssthen } 1628191f22c6Ssthen *resultlen = SHA384_DIGEST_SIZE; 1629191f22c6Ssthen sha384_digest(&hash->ctx384, SHA384_DIGEST_SIZE, 1630191f22c6Ssthen (unsigned char*)result); 1631191f22c6Ssthen } else if(hash->active == 512) { 1632191f22c6Ssthen if(SHA512_DIGEST_SIZE > maxlen) { 1633191f22c6Ssthen *resultlen = 0; 1634191f22c6Ssthen log_err("secalgo_hash_final: hash buffer too small"); 1635191f22c6Ssthen return 0; 1636191f22c6Ssthen } 1637191f22c6Ssthen *resultlen = SHA512_DIGEST_SIZE; 1638191f22c6Ssthen sha512_digest(&hash->ctx512, SHA512_DIGEST_SIZE, 1639191f22c6Ssthen (unsigned char*)result); 1640191f22c6Ssthen } else { 1641191f22c6Ssthen *resultlen = 0; 1642191f22c6Ssthen return 0; 1643191f22c6Ssthen } 1644191f22c6Ssthen return 1; 1645191f22c6Ssthen } 1646191f22c6Ssthen 1647191f22c6Ssthen void secalgo_hash_delete(struct secalgo_hash* hash) 1648191f22c6Ssthen { 1649191f22c6Ssthen if(!hash) return; 1650191f22c6Ssthen free(hash); 1651191f22c6Ssthen } 1652191f22c6Ssthen 165324893edcSsthen /** 165424893edcSsthen * Return size of DS digest according to its hash algorithm. 165524893edcSsthen * @param algo: DS digest algo. 165624893edcSsthen * @return size in bytes of digest, or 0 if not supported. 165724893edcSsthen */ 165824893edcSsthen size_t 165924893edcSsthen ds_digest_size_supported(int algo) 166024893edcSsthen { 166124893edcSsthen switch(algo) { 166224893edcSsthen case LDNS_SHA1: 16632be9e038Ssthen #ifdef USE_SHA1 166424893edcSsthen return SHA1_DIGEST_SIZE; 16652be9e038Ssthen #else 16662be9e038Ssthen if(fake_sha1) return 20; 16672be9e038Ssthen return 0; 16682be9e038Ssthen #endif 166924893edcSsthen #ifdef USE_SHA2 167024893edcSsthen case LDNS_SHA256: 167124893edcSsthen return SHA256_DIGEST_SIZE; 167224893edcSsthen #endif 167324893edcSsthen #ifdef USE_ECDSA 167424893edcSsthen case LDNS_SHA384: 167524893edcSsthen return SHA384_DIGEST_SIZE; 167624893edcSsthen #endif 167724893edcSsthen /* GOST not supported */ 167824893edcSsthen case LDNS_HASH_GOST: 167924893edcSsthen default: 168024893edcSsthen break; 168124893edcSsthen } 168224893edcSsthen return 0; 168324893edcSsthen } 168424893edcSsthen 168524893edcSsthen int 168624893edcSsthen secalgo_ds_digest(int algo, unsigned char* buf, size_t len, 168724893edcSsthen unsigned char* res) 168824893edcSsthen { 168924893edcSsthen switch(algo) { 16902be9e038Ssthen #ifdef USE_SHA1 169124893edcSsthen case LDNS_SHA1: 169224893edcSsthen return _digest_nettle(SHA1_DIGEST_SIZE, buf, len, res); 16932be9e038Ssthen #endif 169424893edcSsthen #if defined(USE_SHA2) 169524893edcSsthen case LDNS_SHA256: 169624893edcSsthen return _digest_nettle(SHA256_DIGEST_SIZE, buf, len, res); 169724893edcSsthen #endif 169824893edcSsthen #ifdef USE_ECDSA 169924893edcSsthen case LDNS_SHA384: 170024893edcSsthen return _digest_nettle(SHA384_DIGEST_SIZE, buf, len, res); 170124893edcSsthen 170224893edcSsthen #endif 170324893edcSsthen case LDNS_HASH_GOST: 170424893edcSsthen default: 170524893edcSsthen verbose(VERB_QUERY, "unknown DS digest algorithm %d", 170624893edcSsthen algo); 170724893edcSsthen break; 170824893edcSsthen } 170924893edcSsthen return 0; 171024893edcSsthen } 171124893edcSsthen 171224893edcSsthen int 171324893edcSsthen dnskey_algo_id_is_supported(int id) 171424893edcSsthen { 171524893edcSsthen /* uses libnettle */ 171624893edcSsthen switch(id) { 171724893edcSsthen case LDNS_DSA: 171824893edcSsthen case LDNS_DSA_NSEC3: 1719eaf2578eSsthen #if defined(USE_DSA) && defined(USE_SHA1) 1720eaf2578eSsthen return 1; 1721eaf2578eSsthen #else 1722eaf2578eSsthen if(fake_dsa || fake_sha1) return 1; 1723eaf2578eSsthen return 0; 17242ee382b6Ssthen #endif 172524893edcSsthen case LDNS_RSASHA1: 172624893edcSsthen case LDNS_RSASHA1_NSEC3: 1727eaf2578eSsthen #ifdef USE_SHA1 1728eaf2578eSsthen return 1; 1729eaf2578eSsthen #else 1730eaf2578eSsthen if(fake_sha1) return 1; 1731eaf2578eSsthen return 0; 17322be9e038Ssthen #endif 173324893edcSsthen #ifdef USE_SHA2 173424893edcSsthen case LDNS_RSASHA256: 173524893edcSsthen case LDNS_RSASHA512: 173624893edcSsthen #endif 173724893edcSsthen #ifdef USE_ECDSA 173824893edcSsthen case LDNS_ECDSAP256SHA256: 173924893edcSsthen case LDNS_ECDSAP384SHA384: 174024893edcSsthen #endif 174124893edcSsthen return 1; 17427191de28Ssthen #ifdef USE_ED25519 17437191de28Ssthen case LDNS_ED25519: 17447191de28Ssthen return 1; 17457191de28Ssthen #endif 174624893edcSsthen case LDNS_RSAMD5: /* RFC 6725 deprecates RSAMD5 */ 174724893edcSsthen case LDNS_ECC_GOST: 174824893edcSsthen default: 174924893edcSsthen return 0; 175024893edcSsthen } 175124893edcSsthen } 175224893edcSsthen 17532be9e038Ssthen #if defined(USE_DSA) && defined(USE_SHA1) 175424893edcSsthen static char * 175524893edcSsthen _verify_nettle_dsa(sldns_buffer* buf, unsigned char* sigblock, 175624893edcSsthen unsigned int sigblock_len, unsigned char* key, unsigned int keylen) 175724893edcSsthen { 175824893edcSsthen uint8_t digest[SHA1_DIGEST_SIZE]; 175977079be7Ssthen uint8_t key_t_value; 176024893edcSsthen int res = 0; 176124893edcSsthen size_t offset; 176224893edcSsthen struct dsa_public_key pubkey; 176324893edcSsthen struct dsa_signature signature; 176424893edcSsthen unsigned int expected_len; 176524893edcSsthen 176624893edcSsthen /* Extract DSA signature from the record */ 176724893edcSsthen nettle_dsa_signature_init(&signature); 176824893edcSsthen /* Signature length: 41 bytes - RFC 2536 sec. 3 */ 176924893edcSsthen if(sigblock_len == 41) { 177024893edcSsthen if(key[0] != sigblock[0]) 177124893edcSsthen return "invalid T value in DSA signature or pubkey"; 177224893edcSsthen nettle_mpz_set_str_256_u(signature.r, 20, sigblock+1); 177324893edcSsthen nettle_mpz_set_str_256_u(signature.s, 20, sigblock+1+20); 177424893edcSsthen } else { 177524893edcSsthen /* DER encoded, decode the ASN1 notated R and S bignums */ 177624893edcSsthen /* SEQUENCE { r INTEGER, s INTEGER } */ 177724893edcSsthen struct asn1_der_iterator i, seq; 177824893edcSsthen if(asn1_der_iterator_first(&i, sigblock_len, 177924893edcSsthen (uint8_t*)sigblock) != ASN1_ITERATOR_CONSTRUCTED 178024893edcSsthen || i.type != ASN1_SEQUENCE) 178124893edcSsthen return "malformed DER encoded DSA signature"; 178224893edcSsthen /* decode this element of i using the seq iterator */ 178324893edcSsthen if(asn1_der_decode_constructed(&i, &seq) != 178424893edcSsthen ASN1_ITERATOR_PRIMITIVE || seq.type != ASN1_INTEGER) 178524893edcSsthen return "malformed DER encoded DSA signature"; 178624893edcSsthen if(!asn1_der_get_bignum(&seq, signature.r, 20*8)) 178724893edcSsthen return "malformed DER encoded DSA signature"; 178824893edcSsthen if(asn1_der_iterator_next(&seq) != ASN1_ITERATOR_PRIMITIVE 178924893edcSsthen || seq.type != ASN1_INTEGER) 179024893edcSsthen return "malformed DER encoded DSA signature"; 179124893edcSsthen if(!asn1_der_get_bignum(&seq, signature.s, 20*8)) 179224893edcSsthen return "malformed DER encoded DSA signature"; 179324893edcSsthen if(asn1_der_iterator_next(&i) != ASN1_ITERATOR_END) 179424893edcSsthen return "malformed DER encoded DSA signature"; 179524893edcSsthen } 179624893edcSsthen 179724893edcSsthen /* Validate T values constraints - RFC 2536 sec. 2 & sec. 3 */ 179877079be7Ssthen key_t_value = key[0]; 179977079be7Ssthen if (key_t_value > 8) { 180024893edcSsthen return "invalid T value in DSA pubkey"; 180124893edcSsthen } 180224893edcSsthen 180324893edcSsthen /* Pubkey minimum length: 21 bytes - RFC 2536 sec. 2 */ 180424893edcSsthen if (keylen < 21) { 180524893edcSsthen return "DSA pubkey too short"; 180624893edcSsthen } 180724893edcSsthen 180824893edcSsthen expected_len = 1 + /* T */ 180924893edcSsthen 20 + /* Q */ 181077079be7Ssthen (64 + key_t_value*8) + /* P */ 181177079be7Ssthen (64 + key_t_value*8) + /* G */ 181277079be7Ssthen (64 + key_t_value*8); /* Y */ 181324893edcSsthen if (keylen != expected_len ) { 181424893edcSsthen return "invalid DSA pubkey length"; 181524893edcSsthen } 181624893edcSsthen 181724893edcSsthen /* Extract DSA pubkey from the record */ 181824893edcSsthen nettle_dsa_public_key_init(&pubkey); 181924893edcSsthen offset = 1; 182024893edcSsthen nettle_mpz_set_str_256_u(pubkey.q, 20, key+offset); 182124893edcSsthen offset += 20; 182277079be7Ssthen nettle_mpz_set_str_256_u(pubkey.p, (64 + key_t_value*8), key+offset); 182377079be7Ssthen offset += (64 + key_t_value*8); 182477079be7Ssthen nettle_mpz_set_str_256_u(pubkey.g, (64 + key_t_value*8), key+offset); 182577079be7Ssthen offset += (64 + key_t_value*8); 182677079be7Ssthen nettle_mpz_set_str_256_u(pubkey.y, (64 + key_t_value*8), key+offset); 182724893edcSsthen 182824893edcSsthen /* Digest content of "buf" and verify its DSA signature in "sigblock"*/ 182924893edcSsthen res = _digest_nettle(SHA1_DIGEST_SIZE, (unsigned char*)sldns_buffer_begin(buf), 183024893edcSsthen (unsigned int)sldns_buffer_limit(buf), (unsigned char*)digest); 183124893edcSsthen res &= dsa_sha1_verify_digest(&pubkey, digest, &signature); 183224893edcSsthen 183324893edcSsthen /* Clear and return */ 183424893edcSsthen nettle_dsa_signature_clear(&signature); 183524893edcSsthen nettle_dsa_public_key_clear(&pubkey); 183624893edcSsthen if (!res) 183724893edcSsthen return "DSA signature verification failed"; 183824893edcSsthen else 183924893edcSsthen return NULL; 184024893edcSsthen } 184177079be7Ssthen #endif /* USE_DSA */ 184224893edcSsthen 184324893edcSsthen static char * 184424893edcSsthen _verify_nettle_rsa(sldns_buffer* buf, unsigned int digest_size, char* sigblock, 184524893edcSsthen unsigned int sigblock_len, uint8_t* key, unsigned int keylen) 184624893edcSsthen { 184724893edcSsthen uint16_t exp_len = 0; 184824893edcSsthen size_t exp_offset = 0, mod_offset = 0; 184924893edcSsthen struct rsa_public_key pubkey; 185024893edcSsthen mpz_t signature; 185124893edcSsthen int res = 0; 185224893edcSsthen 185324893edcSsthen /* RSA pubkey parsing as per RFC 3110 sec. 2 */ 185424893edcSsthen if( keylen <= 1) { 185524893edcSsthen return "null RSA key"; 185624893edcSsthen } 185724893edcSsthen if (key[0] != 0) { 185824893edcSsthen /* 1-byte length */ 185924893edcSsthen exp_len = key[0]; 186024893edcSsthen exp_offset = 1; 186124893edcSsthen } else { 186224893edcSsthen /* 1-byte NUL + 2-bytes exponent length */ 186324893edcSsthen if (keylen < 3) { 186424893edcSsthen return "incorrect RSA key length"; 186524893edcSsthen } 186624893edcSsthen exp_len = READ_UINT16(key+1); 186724893edcSsthen if (exp_len == 0) 186824893edcSsthen return "null RSA exponent length"; 186924893edcSsthen exp_offset = 3; 187024893edcSsthen } 187124893edcSsthen /* Check that we are not over-running input length */ 187224893edcSsthen if (keylen < exp_offset + exp_len + 1) { 187324893edcSsthen return "RSA key content shorter than expected"; 187424893edcSsthen } 187524893edcSsthen mod_offset = exp_offset + exp_len; 187624893edcSsthen nettle_rsa_public_key_init(&pubkey); 187724893edcSsthen pubkey.size = keylen - mod_offset; 187824893edcSsthen nettle_mpz_set_str_256_u(pubkey.e, exp_len, &key[exp_offset]); 187924893edcSsthen nettle_mpz_set_str_256_u(pubkey.n, pubkey.size, &key[mod_offset]); 188024893edcSsthen 188124893edcSsthen /* Digest content of "buf" and verify its RSA signature in "sigblock"*/ 188224893edcSsthen nettle_mpz_init_set_str_256_u(signature, sigblock_len, (uint8_t*)sigblock); 188324893edcSsthen switch (digest_size) { 188424893edcSsthen case SHA1_DIGEST_SIZE: 188524893edcSsthen { 188624893edcSsthen uint8_t digest[SHA1_DIGEST_SIZE]; 188724893edcSsthen res = _digest_nettle(SHA1_DIGEST_SIZE, (unsigned char*)sldns_buffer_begin(buf), 188824893edcSsthen (unsigned int)sldns_buffer_limit(buf), (unsigned char*)digest); 188924893edcSsthen res &= rsa_sha1_verify_digest(&pubkey, digest, signature); 189024893edcSsthen break; 189124893edcSsthen } 189224893edcSsthen case SHA256_DIGEST_SIZE: 189324893edcSsthen { 189424893edcSsthen uint8_t digest[SHA256_DIGEST_SIZE]; 189524893edcSsthen res = _digest_nettle(SHA256_DIGEST_SIZE, (unsigned char*)sldns_buffer_begin(buf), 189624893edcSsthen (unsigned int)sldns_buffer_limit(buf), (unsigned char*)digest); 189724893edcSsthen res &= rsa_sha256_verify_digest(&pubkey, digest, signature); 189824893edcSsthen break; 189924893edcSsthen } 190024893edcSsthen case SHA512_DIGEST_SIZE: 190124893edcSsthen { 190224893edcSsthen uint8_t digest[SHA512_DIGEST_SIZE]; 190324893edcSsthen res = _digest_nettle(SHA512_DIGEST_SIZE, (unsigned char*)sldns_buffer_begin(buf), 190424893edcSsthen (unsigned int)sldns_buffer_limit(buf), (unsigned char*)digest); 190524893edcSsthen res &= rsa_sha512_verify_digest(&pubkey, digest, signature); 190624893edcSsthen break; 190724893edcSsthen } 190824893edcSsthen default: 190924893edcSsthen break; 191024893edcSsthen } 191124893edcSsthen 191224893edcSsthen /* Clear and return */ 191324893edcSsthen nettle_rsa_public_key_clear(&pubkey); 191424893edcSsthen mpz_clear(signature); 191524893edcSsthen if (!res) { 191624893edcSsthen return "RSA signature verification failed"; 191724893edcSsthen } else { 191824893edcSsthen return NULL; 191924893edcSsthen } 192024893edcSsthen } 192124893edcSsthen 192224893edcSsthen #ifdef USE_ECDSA 192324893edcSsthen static char * 192424893edcSsthen _verify_nettle_ecdsa(sldns_buffer* buf, unsigned int digest_size, unsigned char* sigblock, 192524893edcSsthen unsigned int sigblock_len, unsigned char* key, unsigned int keylen) 192624893edcSsthen { 192724893edcSsthen int res = 0; 192824893edcSsthen struct ecc_point pubkey; 192924893edcSsthen struct dsa_signature signature; 193024893edcSsthen 193124893edcSsthen /* Always matched strength, as per RFC 6605 sec. 1 */ 193224893edcSsthen if (sigblock_len != 2*digest_size || keylen != 2*digest_size) { 193324893edcSsthen return "wrong ECDSA signature length"; 193424893edcSsthen } 193524893edcSsthen 193624893edcSsthen /* Parse ECDSA signature as per RFC 6605 sec. 4 */ 193724893edcSsthen nettle_dsa_signature_init(&signature); 193824893edcSsthen switch (digest_size) { 193924893edcSsthen case SHA256_DIGEST_SIZE: 194024893edcSsthen { 194124893edcSsthen uint8_t digest[SHA256_DIGEST_SIZE]; 194224893edcSsthen mpz_t x, y; 1943ebf5bb73Ssthen nettle_ecc_point_init(&pubkey, nettle_get_secp_256r1()); 194424893edcSsthen nettle_mpz_init_set_str_256_u(x, SHA256_DIGEST_SIZE, key); 194524893edcSsthen nettle_mpz_init_set_str_256_u(y, SHA256_DIGEST_SIZE, key+SHA256_DIGEST_SIZE); 194624893edcSsthen nettle_mpz_set_str_256_u(signature.r, SHA256_DIGEST_SIZE, sigblock); 194724893edcSsthen nettle_mpz_set_str_256_u(signature.s, SHA256_DIGEST_SIZE, sigblock+SHA256_DIGEST_SIZE); 194824893edcSsthen res = _digest_nettle(SHA256_DIGEST_SIZE, (unsigned char*)sldns_buffer_begin(buf), 194924893edcSsthen (unsigned int)sldns_buffer_limit(buf), (unsigned char*)digest); 195024893edcSsthen res &= nettle_ecc_point_set(&pubkey, x, y); 195124893edcSsthen res &= nettle_ecdsa_verify (&pubkey, SHA256_DIGEST_SIZE, digest, &signature); 195224893edcSsthen mpz_clear(x); 195324893edcSsthen mpz_clear(y); 1954a3167c07Ssthen nettle_ecc_point_clear(&pubkey); 195524893edcSsthen break; 195624893edcSsthen } 195724893edcSsthen case SHA384_DIGEST_SIZE: 195824893edcSsthen { 195924893edcSsthen uint8_t digest[SHA384_DIGEST_SIZE]; 196024893edcSsthen mpz_t x, y; 1961ebf5bb73Ssthen nettle_ecc_point_init(&pubkey, nettle_get_secp_384r1()); 196224893edcSsthen nettle_mpz_init_set_str_256_u(x, SHA384_DIGEST_SIZE, key); 196324893edcSsthen nettle_mpz_init_set_str_256_u(y, SHA384_DIGEST_SIZE, key+SHA384_DIGEST_SIZE); 196424893edcSsthen nettle_mpz_set_str_256_u(signature.r, SHA384_DIGEST_SIZE, sigblock); 196524893edcSsthen nettle_mpz_set_str_256_u(signature.s, SHA384_DIGEST_SIZE, sigblock+SHA384_DIGEST_SIZE); 196624893edcSsthen res = _digest_nettle(SHA384_DIGEST_SIZE, (unsigned char*)sldns_buffer_begin(buf), 196724893edcSsthen (unsigned int)sldns_buffer_limit(buf), (unsigned char*)digest); 196824893edcSsthen res &= nettle_ecc_point_set(&pubkey, x, y); 196924893edcSsthen res &= nettle_ecdsa_verify (&pubkey, SHA384_DIGEST_SIZE, digest, &signature); 197024893edcSsthen mpz_clear(x); 197124893edcSsthen mpz_clear(y); 197224893edcSsthen nettle_ecc_point_clear(&pubkey); 197324893edcSsthen break; 197424893edcSsthen } 197524893edcSsthen default: 197624893edcSsthen return "unknown ECDSA algorithm"; 197724893edcSsthen } 197824893edcSsthen 197924893edcSsthen /* Clear and return */ 198024893edcSsthen nettle_dsa_signature_clear(&signature); 198124893edcSsthen if (!res) 198224893edcSsthen return "ECDSA signature verification failed"; 198324893edcSsthen else 198424893edcSsthen return NULL; 198524893edcSsthen } 198624893edcSsthen #endif 198724893edcSsthen 19887191de28Ssthen #ifdef USE_ED25519 19897191de28Ssthen static char * 19907191de28Ssthen _verify_nettle_ed25519(sldns_buffer* buf, unsigned char* sigblock, 19917191de28Ssthen unsigned int sigblock_len, unsigned char* key, unsigned int keylen) 19927191de28Ssthen { 19937191de28Ssthen int res = 0; 19947191de28Ssthen 19957191de28Ssthen if(sigblock_len != ED25519_SIGNATURE_SIZE) { 19967191de28Ssthen return "wrong ED25519 signature length"; 19977191de28Ssthen } 19987191de28Ssthen if(keylen != ED25519_KEY_SIZE) { 19997191de28Ssthen return "wrong ED25519 key length"; 20007191de28Ssthen } 20017191de28Ssthen 20027191de28Ssthen res = ed25519_sha512_verify((uint8_t*)key, sldns_buffer_limit(buf), 20037191de28Ssthen sldns_buffer_begin(buf), (uint8_t*)sigblock); 20047191de28Ssthen 20057191de28Ssthen if (!res) 20067191de28Ssthen return "ED25519 signature verification failed"; 20077191de28Ssthen else 20087191de28Ssthen return NULL; 20097191de28Ssthen } 20107191de28Ssthen #endif 20117191de28Ssthen 201224893edcSsthen /** 201324893edcSsthen * Check a canonical sig+rrset and signature against a dnskey 201424893edcSsthen * @param buf: buffer with data to verify, the first rrsig part and the 201524893edcSsthen * canonicalized rrset. 201624893edcSsthen * @param algo: DNSKEY algorithm. 201724893edcSsthen * @param sigblock: signature rdata field from RRSIG 201824893edcSsthen * @param sigblock_len: length of sigblock data. 201924893edcSsthen * @param key: public key data from DNSKEY RR. 202024893edcSsthen * @param keylen: length of keydata. 202124893edcSsthen * @param reason: bogus reason in more detail. 202224893edcSsthen * @return secure if verification succeeded, bogus on crypto failure, 202324893edcSsthen * unchecked on format errors and alloc failures. 202424893edcSsthen */ 202524893edcSsthen enum sec_status 202624893edcSsthen verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock, 202724893edcSsthen unsigned int sigblock_len, unsigned char* key, unsigned int keylen, 202824893edcSsthen char** reason) 202924893edcSsthen { 203024893edcSsthen unsigned int digest_size = 0; 203124893edcSsthen 203224893edcSsthen if (sigblock_len == 0 || keylen == 0) { 203324893edcSsthen *reason = "null signature"; 203424893edcSsthen return sec_status_bogus; 203524893edcSsthen } 203624893edcSsthen 2037eaf2578eSsthen #ifndef USE_DSA 2038eaf2578eSsthen if((algo == LDNS_DSA || algo == LDNS_DSA_NSEC3) &&(fake_dsa||fake_sha1)) 2039eaf2578eSsthen return sec_status_secure; 2040eaf2578eSsthen #endif 2041eaf2578eSsthen #ifndef USE_SHA1 2042eaf2578eSsthen if(fake_sha1 && (algo == LDNS_DSA || algo == LDNS_DSA_NSEC3 || algo == LDNS_RSASHA1 || algo == LDNS_RSASHA1_NSEC3)) 2043eaf2578eSsthen return sec_status_secure; 2044eaf2578eSsthen #endif 2045eaf2578eSsthen 204624893edcSsthen switch(algo) { 20472be9e038Ssthen #if defined(USE_DSA) && defined(USE_SHA1) 204824893edcSsthen case LDNS_DSA: 204924893edcSsthen case LDNS_DSA_NSEC3: 205024893edcSsthen *reason = _verify_nettle_dsa(buf, sigblock, sigblock_len, key, keylen); 205124893edcSsthen if (*reason != NULL) 205224893edcSsthen return sec_status_bogus; 205324893edcSsthen else 205424893edcSsthen return sec_status_secure; 20552ee382b6Ssthen #endif /* USE_DSA */ 205624893edcSsthen 20572be9e038Ssthen #ifdef USE_SHA1 205824893edcSsthen case LDNS_RSASHA1: 205924893edcSsthen case LDNS_RSASHA1_NSEC3: 206024893edcSsthen digest_size = (digest_size ? digest_size : SHA1_DIGEST_SIZE); 20612be9e038Ssthen #endif 20627191de28Ssthen /* double fallthrough annotation to please gcc parser */ 2063*98bc733bSsthen ATTR_FALLTHROUGH 20647191de28Ssthen /* fallthrough */ 206524893edcSsthen #ifdef USE_SHA2 20667191de28Ssthen /* fallthrough */ 206724893edcSsthen case LDNS_RSASHA256: 206824893edcSsthen digest_size = (digest_size ? digest_size : SHA256_DIGEST_SIZE); 2069*98bc733bSsthen ATTR_FALLTHROUGH 20707191de28Ssthen /* fallthrough */ 207124893edcSsthen case LDNS_RSASHA512: 207224893edcSsthen digest_size = (digest_size ? digest_size : SHA512_DIGEST_SIZE); 207324893edcSsthen 207424893edcSsthen #endif 207524893edcSsthen *reason = _verify_nettle_rsa(buf, digest_size, (char*)sigblock, 207624893edcSsthen sigblock_len, key, keylen); 207724893edcSsthen if (*reason != NULL) 207824893edcSsthen return sec_status_bogus; 207924893edcSsthen else 208024893edcSsthen return sec_status_secure; 208124893edcSsthen 208224893edcSsthen #ifdef USE_ECDSA 208324893edcSsthen case LDNS_ECDSAP256SHA256: 208424893edcSsthen digest_size = (digest_size ? digest_size : SHA256_DIGEST_SIZE); 2085*98bc733bSsthen ATTR_FALLTHROUGH 20867191de28Ssthen /* fallthrough */ 208724893edcSsthen case LDNS_ECDSAP384SHA384: 208824893edcSsthen digest_size = (digest_size ? digest_size : SHA384_DIGEST_SIZE); 208924893edcSsthen *reason = _verify_nettle_ecdsa(buf, digest_size, sigblock, 209024893edcSsthen sigblock_len, key, keylen); 209124893edcSsthen if (*reason != NULL) 209224893edcSsthen return sec_status_bogus; 209324893edcSsthen else 209424893edcSsthen return sec_status_secure; 209524893edcSsthen #endif 20967191de28Ssthen #ifdef USE_ED25519 20977191de28Ssthen case LDNS_ED25519: 20987191de28Ssthen *reason = _verify_nettle_ed25519(buf, sigblock, sigblock_len, 20997191de28Ssthen key, keylen); 21007191de28Ssthen if (*reason != NULL) 21017191de28Ssthen return sec_status_bogus; 21027191de28Ssthen else 21037191de28Ssthen return sec_status_secure; 21047191de28Ssthen #endif 210524893edcSsthen case LDNS_RSAMD5: 210624893edcSsthen case LDNS_ECC_GOST: 210724893edcSsthen default: 210824893edcSsthen *reason = "unable to verify signature, unknown algorithm"; 210924893edcSsthen return sec_status_bogus; 211024893edcSsthen } 211124893edcSsthen } 211224893edcSsthen 211324893edcSsthen #endif /* HAVE_SSL or HAVE_NSS or HAVE_NETTLE */ 2114