1ae8c6e27Sflorian /* 2ae8c6e27Sflorian * validator/val_secalgo.c - validator security algorithm functions. 3ae8c6e27Sflorian * 4ae8c6e27Sflorian * Copyright (c) 2012, NLnet Labs. All rights reserved. 5ae8c6e27Sflorian * 6ae8c6e27Sflorian * This software is open source. 7ae8c6e27Sflorian * 8ae8c6e27Sflorian * Redistribution and use in source and binary forms, with or without 9ae8c6e27Sflorian * modification, are permitted provided that the following conditions 10ae8c6e27Sflorian * are met: 11ae8c6e27Sflorian * 12ae8c6e27Sflorian * Redistributions of source code must retain the above copyright notice, 13ae8c6e27Sflorian * this list of conditions and the following disclaimer. 14ae8c6e27Sflorian * 15ae8c6e27Sflorian * Redistributions in binary form must reproduce the above copyright notice, 16ae8c6e27Sflorian * this list of conditions and the following disclaimer in the documentation 17ae8c6e27Sflorian * and/or other materials provided with the distribution. 18ae8c6e27Sflorian * 19ae8c6e27Sflorian * Neither the name of the NLNET LABS nor the names of its contributors may 20ae8c6e27Sflorian * be used to endorse or promote products derived from this software without 21ae8c6e27Sflorian * specific prior written permission. 22ae8c6e27Sflorian * 23ae8c6e27Sflorian * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24ae8c6e27Sflorian * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25ae8c6e27Sflorian * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 26ae8c6e27Sflorian * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 27ae8c6e27Sflorian * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 28ae8c6e27Sflorian * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 29ae8c6e27Sflorian * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 30ae8c6e27Sflorian * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 31ae8c6e27Sflorian * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32ae8c6e27Sflorian * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33ae8c6e27Sflorian * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34ae8c6e27Sflorian */ 35ae8c6e27Sflorian 36ae8c6e27Sflorian /** 37ae8c6e27Sflorian * \file 38ae8c6e27Sflorian * 39ae8c6e27Sflorian * This file contains helper functions for the validator module. 40ae8c6e27Sflorian * These functions take raw data buffers, formatted for crypto verification, 41ae8c6e27Sflorian * and do the library calls (for the crypto library in use). 42ae8c6e27Sflorian */ 43ae8c6e27Sflorian #include "config.h" 44ae8c6e27Sflorian /* packed_rrset on top to define enum types (forced by c99 standard) */ 45ae8c6e27Sflorian #include "util/data/packed_rrset.h" 46ae8c6e27Sflorian #include "validator/val_secalgo.h" 47ae8c6e27Sflorian #include "validator/val_nsec3.h" 48ae8c6e27Sflorian #include "util/log.h" 49ae8c6e27Sflorian #include "sldns/rrdef.h" 50ae8c6e27Sflorian #include "sldns/keyraw.h" 51ae8c6e27Sflorian #include "sldns/sbuffer.h" 52ae8c6e27Sflorian 53ae8c6e27Sflorian #if !defined(HAVE_SSL) && !defined(HAVE_NSS) && !defined(HAVE_NETTLE) 54ae8c6e27Sflorian #error "Need crypto library to do digital signature cryptography" 55ae8c6e27Sflorian #endif 56ae8c6e27Sflorian 57d32eb43cSflorian /** fake DSA support for unit tests */ 58d32eb43cSflorian int fake_dsa = 0; 59d32eb43cSflorian /** fake SHA1 support for unit tests */ 60d32eb43cSflorian int fake_sha1 = 0; 61d32eb43cSflorian 62ae8c6e27Sflorian /* OpenSSL implementation */ 63ae8c6e27Sflorian #ifdef HAVE_SSL 64ae8c6e27Sflorian #ifdef HAVE_OPENSSL_ERR_H 65ae8c6e27Sflorian #include <openssl/err.h> 66ae8c6e27Sflorian #endif 67ae8c6e27Sflorian 68ae8c6e27Sflorian #ifdef HAVE_OPENSSL_RAND_H 69ae8c6e27Sflorian #include <openssl/rand.h> 70ae8c6e27Sflorian #endif 71ae8c6e27Sflorian 72ae8c6e27Sflorian #ifdef HAVE_OPENSSL_CONF_H 73ae8c6e27Sflorian #include <openssl/conf.h> 74ae8c6e27Sflorian #endif 75ae8c6e27Sflorian 76ae8c6e27Sflorian #ifdef HAVE_OPENSSL_ENGINE_H 77ae8c6e27Sflorian #include <openssl/engine.h> 78ae8c6e27Sflorian #endif 79ae8c6e27Sflorian 80e47fef9eSflorian #if defined(HAVE_OPENSSL_DSA_H) && defined(USE_DSA) 81e47fef9eSflorian #include <openssl/dsa.h> 82e47fef9eSflorian #endif 83e47fef9eSflorian 84ae8c6e27Sflorian /** 85ae8c6e27Sflorian * Output a libcrypto openssl error to the logfile. 86ae8c6e27Sflorian * @param str: string to add to it. 87ae8c6e27Sflorian * @param e: the error to output, error number from ERR_get_error(). 88ae8c6e27Sflorian */ 89ae8c6e27Sflorian static void 90ae8c6e27Sflorian log_crypto_error(const char* str, unsigned long e) 91ae8c6e27Sflorian { 92ae8c6e27Sflorian char buf[128]; 93ae8c6e27Sflorian /* or use ERR_error_string if ERR_error_string_n is not avail TODO */ 94ae8c6e27Sflorian ERR_error_string_n(e, buf, sizeof(buf)); 95ae8c6e27Sflorian /* buf now contains */ 96ae8c6e27Sflorian /* error:[error code]:[library name]:[function name]:[reason string] */ 97ae8c6e27Sflorian log_err("%s crypto %s", str, buf); 98ae8c6e27Sflorian } 99ae8c6e27Sflorian 1006d08cb1bSflorian /** 1016d08cb1bSflorian * Output a libcrypto openssl error to the logfile as a debug message. 1026d08cb1bSflorian * @param level: debug level to use in verbose() call 1036d08cb1bSflorian * @param str: string to add to it. 1046d08cb1bSflorian * @param e: the error to output, error number from ERR_get_error(). 1056d08cb1bSflorian */ 1066d08cb1bSflorian static void 1076d08cb1bSflorian log_crypto_verbose(enum verbosity_value level, const char* str, unsigned long e) 1086d08cb1bSflorian { 1096d08cb1bSflorian char buf[128]; 1106d08cb1bSflorian /* or use ERR_error_string if ERR_error_string_n is not avail TODO */ 1116d08cb1bSflorian ERR_error_string_n(e, buf, sizeof(buf)); 1126d08cb1bSflorian /* buf now contains */ 1136d08cb1bSflorian /* error:[error code]:[library name]:[function name]:[reason string] */ 1146d08cb1bSflorian verbose(level, "%s crypto %s", str, buf); 1156d08cb1bSflorian } 1166d08cb1bSflorian 117ae8c6e27Sflorian /* return size of digest if supported, or 0 otherwise */ 118ae8c6e27Sflorian size_t 119ae8c6e27Sflorian nsec3_hash_algo_size_supported(int id) 120ae8c6e27Sflorian { 121ae8c6e27Sflorian switch(id) { 122ae8c6e27Sflorian case NSEC3_HASH_SHA1: 123ae8c6e27Sflorian return SHA_DIGEST_LENGTH; 124ae8c6e27Sflorian default: 125ae8c6e27Sflorian return 0; 126ae8c6e27Sflorian } 127ae8c6e27Sflorian } 128ae8c6e27Sflorian 129ae8c6e27Sflorian /* perform nsec3 hash. return false on failure */ 130ae8c6e27Sflorian int 131ae8c6e27Sflorian secalgo_nsec3_hash(int algo, unsigned char* buf, size_t len, 132ae8c6e27Sflorian unsigned char* res) 133ae8c6e27Sflorian { 134ae8c6e27Sflorian switch(algo) { 135ae8c6e27Sflorian case NSEC3_HASH_SHA1: 136ae8c6e27Sflorian #ifdef OPENSSL_FIPS 137ae8c6e27Sflorian if(!sldns_digest_evp(buf, len, res, EVP_sha1())) 138ae8c6e27Sflorian log_crypto_error("could not digest with EVP_sha1", 139ae8c6e27Sflorian ERR_get_error()); 140ae8c6e27Sflorian #else 141ae8c6e27Sflorian (void)SHA1(buf, len, res); 142ae8c6e27Sflorian #endif 143ae8c6e27Sflorian return 1; 144ae8c6e27Sflorian default: 145ae8c6e27Sflorian return 0; 146ae8c6e27Sflorian } 147ae8c6e27Sflorian } 148ae8c6e27Sflorian 149ae8c6e27Sflorian void 150ae8c6e27Sflorian secalgo_hash_sha256(unsigned char* buf, size_t len, unsigned char* res) 151ae8c6e27Sflorian { 152ae8c6e27Sflorian #ifdef OPENSSL_FIPS 153ae8c6e27Sflorian if(!sldns_digest_evp(buf, len, res, EVP_sha256())) 154ae8c6e27Sflorian log_crypto_error("could not digest with EVP_sha256", 155ae8c6e27Sflorian ERR_get_error()); 156ae8c6e27Sflorian #else 157ae8c6e27Sflorian (void)SHA256(buf, len, res); 158ae8c6e27Sflorian #endif 159ae8c6e27Sflorian } 160ae8c6e27Sflorian 161411c5950Sflorian /** hash structure for keeping track of running hashes */ 162411c5950Sflorian struct secalgo_hash { 163411c5950Sflorian /** the openssl message digest context */ 164411c5950Sflorian EVP_MD_CTX* ctx; 165411c5950Sflorian }; 166411c5950Sflorian 167411c5950Sflorian /** create secalgo hash with hash type */ 168411c5950Sflorian static struct secalgo_hash* secalgo_hash_create_md(const EVP_MD* md) 169411c5950Sflorian { 170411c5950Sflorian struct secalgo_hash* h; 171411c5950Sflorian if(!md) 172411c5950Sflorian return NULL; 173411c5950Sflorian h = calloc(1, sizeof(*h)); 174411c5950Sflorian if(!h) 175411c5950Sflorian return NULL; 176411c5950Sflorian h->ctx = EVP_MD_CTX_create(); 177411c5950Sflorian if(!h->ctx) { 178411c5950Sflorian free(h); 179411c5950Sflorian return NULL; 180411c5950Sflorian } 181411c5950Sflorian if(!EVP_DigestInit_ex(h->ctx, md, NULL)) { 182411c5950Sflorian EVP_MD_CTX_destroy(h->ctx); 183411c5950Sflorian free(h); 184411c5950Sflorian return NULL; 185411c5950Sflorian } 186411c5950Sflorian return h; 187411c5950Sflorian } 188411c5950Sflorian 189411c5950Sflorian struct secalgo_hash* secalgo_hash_create_sha384(void) 190411c5950Sflorian { 191411c5950Sflorian return secalgo_hash_create_md(EVP_sha384()); 192411c5950Sflorian } 193411c5950Sflorian 194411c5950Sflorian struct secalgo_hash* secalgo_hash_create_sha512(void) 195411c5950Sflorian { 196411c5950Sflorian return secalgo_hash_create_md(EVP_sha512()); 197411c5950Sflorian } 198411c5950Sflorian 199411c5950Sflorian int secalgo_hash_update(struct secalgo_hash* hash, uint8_t* data, size_t len) 200411c5950Sflorian { 201411c5950Sflorian return EVP_DigestUpdate(hash->ctx, (unsigned char*)data, 202411c5950Sflorian (unsigned int)len); 203411c5950Sflorian } 204411c5950Sflorian 205411c5950Sflorian int secalgo_hash_final(struct secalgo_hash* hash, uint8_t* result, 206411c5950Sflorian size_t maxlen, size_t* resultlen) 207411c5950Sflorian { 208411c5950Sflorian if(EVP_MD_CTX_size(hash->ctx) > (int)maxlen) { 209411c5950Sflorian *resultlen = 0; 210411c5950Sflorian log_err("secalgo_hash_final: hash buffer too small"); 211411c5950Sflorian return 0; 212411c5950Sflorian } 213411c5950Sflorian *resultlen = EVP_MD_CTX_size(hash->ctx); 214411c5950Sflorian return EVP_DigestFinal_ex(hash->ctx, result, NULL); 215411c5950Sflorian } 216411c5950Sflorian 217411c5950Sflorian void secalgo_hash_delete(struct secalgo_hash* hash) 218411c5950Sflorian { 219411c5950Sflorian if(!hash) return; 220411c5950Sflorian EVP_MD_CTX_destroy(hash->ctx); 221411c5950Sflorian free(hash); 222411c5950Sflorian } 223411c5950Sflorian 224ae8c6e27Sflorian /** 225ae8c6e27Sflorian * Return size of DS digest according to its hash algorithm. 226ae8c6e27Sflorian * @param algo: DS digest algo. 227ae8c6e27Sflorian * @return size in bytes of digest, or 0 if not supported. 228ae8c6e27Sflorian */ 229ae8c6e27Sflorian size_t 230ae8c6e27Sflorian ds_digest_size_supported(int algo) 231ae8c6e27Sflorian { 232ae8c6e27Sflorian switch(algo) { 233ae8c6e27Sflorian case LDNS_SHA1: 234ae8c6e27Sflorian #if defined(HAVE_EVP_SHA1) && defined(USE_SHA1) 2356d08cb1bSflorian #ifdef HAVE_EVP_DEFAULT_PROPERTIES_IS_FIPS_ENABLED 2366d08cb1bSflorian if (EVP_default_properties_is_fips_enabled(NULL)) 2376d08cb1bSflorian return 0; 2386d08cb1bSflorian #endif 239ae8c6e27Sflorian return SHA_DIGEST_LENGTH; 240ae8c6e27Sflorian #else 241ae8c6e27Sflorian if(fake_sha1) return 20; 242ae8c6e27Sflorian return 0; 243ae8c6e27Sflorian #endif 244ae8c6e27Sflorian #ifdef HAVE_EVP_SHA256 245ae8c6e27Sflorian case LDNS_SHA256: 246ae8c6e27Sflorian return SHA256_DIGEST_LENGTH; 247ae8c6e27Sflorian #endif 248ae8c6e27Sflorian #ifdef USE_GOST 249ae8c6e27Sflorian case LDNS_HASH_GOST: 250ae8c6e27Sflorian /* we support GOST if it can be loaded */ 251ae8c6e27Sflorian (void)sldns_key_EVP_load_gost_id(); 252ae8c6e27Sflorian if(EVP_get_digestbyname("md_gost94")) 253ae8c6e27Sflorian return 32; 254ae8c6e27Sflorian else return 0; 255ae8c6e27Sflorian #endif 256ae8c6e27Sflorian #ifdef USE_ECDSA 257ae8c6e27Sflorian case LDNS_SHA384: 258ae8c6e27Sflorian return SHA384_DIGEST_LENGTH; 259ae8c6e27Sflorian #endif 260ae8c6e27Sflorian default: break; 261ae8c6e27Sflorian } 262ae8c6e27Sflorian return 0; 263ae8c6e27Sflorian } 264ae8c6e27Sflorian 265ae8c6e27Sflorian #ifdef USE_GOST 266ae8c6e27Sflorian /** Perform GOST hash */ 267ae8c6e27Sflorian static int 268ae8c6e27Sflorian do_gost94(unsigned char* data, size_t len, unsigned char* dest) 269ae8c6e27Sflorian { 270ae8c6e27Sflorian const EVP_MD* md = EVP_get_digestbyname("md_gost94"); 271ae8c6e27Sflorian if(!md) 272ae8c6e27Sflorian return 0; 273ae8c6e27Sflorian return sldns_digest_evp(data, (unsigned int)len, dest, md); 274ae8c6e27Sflorian } 275ae8c6e27Sflorian #endif 276ae8c6e27Sflorian 277ae8c6e27Sflorian int 278ae8c6e27Sflorian secalgo_ds_digest(int algo, unsigned char* buf, size_t len, 279ae8c6e27Sflorian unsigned char* res) 280ae8c6e27Sflorian { 281ae8c6e27Sflorian switch(algo) { 282ae8c6e27Sflorian #if defined(HAVE_EVP_SHA1) && defined(USE_SHA1) 283ae8c6e27Sflorian case LDNS_SHA1: 284ae8c6e27Sflorian #ifdef OPENSSL_FIPS 285ae8c6e27Sflorian if(!sldns_digest_evp(buf, len, res, EVP_sha1())) 286ae8c6e27Sflorian log_crypto_error("could not digest with EVP_sha1", 287ae8c6e27Sflorian ERR_get_error()); 288ae8c6e27Sflorian #else 289ae8c6e27Sflorian (void)SHA1(buf, len, res); 290ae8c6e27Sflorian #endif 291ae8c6e27Sflorian return 1; 292ae8c6e27Sflorian #endif 293ae8c6e27Sflorian #ifdef HAVE_EVP_SHA256 294ae8c6e27Sflorian case LDNS_SHA256: 295ae8c6e27Sflorian #ifdef OPENSSL_FIPS 296ae8c6e27Sflorian if(!sldns_digest_evp(buf, len, res, EVP_sha256())) 297ae8c6e27Sflorian log_crypto_error("could not digest with EVP_sha256", 298ae8c6e27Sflorian ERR_get_error()); 299ae8c6e27Sflorian #else 300ae8c6e27Sflorian (void)SHA256(buf, len, res); 301ae8c6e27Sflorian #endif 302ae8c6e27Sflorian return 1; 303ae8c6e27Sflorian #endif 304ae8c6e27Sflorian #ifdef USE_GOST 305ae8c6e27Sflorian case LDNS_HASH_GOST: 306ae8c6e27Sflorian if(do_gost94(buf, len, res)) 307ae8c6e27Sflorian return 1; 308ae8c6e27Sflorian break; 309ae8c6e27Sflorian #endif 310ae8c6e27Sflorian #ifdef USE_ECDSA 311ae8c6e27Sflorian case LDNS_SHA384: 312ae8c6e27Sflorian #ifdef OPENSSL_FIPS 313ae8c6e27Sflorian if(!sldns_digest_evp(buf, len, res, EVP_sha384())) 314ae8c6e27Sflorian log_crypto_error("could not digest with EVP_sha384", 315ae8c6e27Sflorian ERR_get_error()); 316ae8c6e27Sflorian #else 317ae8c6e27Sflorian (void)SHA384(buf, len, res); 318ae8c6e27Sflorian #endif 319ae8c6e27Sflorian return 1; 320ae8c6e27Sflorian #endif 321ae8c6e27Sflorian default: 322ae8c6e27Sflorian verbose(VERB_QUERY, "unknown DS digest algorithm %d", 323ae8c6e27Sflorian algo); 324ae8c6e27Sflorian break; 325ae8c6e27Sflorian } 326ae8c6e27Sflorian return 0; 327ae8c6e27Sflorian } 328ae8c6e27Sflorian 329ae8c6e27Sflorian /** return true if DNSKEY algorithm id is supported */ 330ae8c6e27Sflorian int 331ae8c6e27Sflorian dnskey_algo_id_is_supported(int id) 332ae8c6e27Sflorian { 333ae8c6e27Sflorian switch(id) { 334ae8c6e27Sflorian case LDNS_RSAMD5: 335ae8c6e27Sflorian /* RFC 6725 deprecates RSAMD5 */ 336ae8c6e27Sflorian return 0; 337ae8c6e27Sflorian case LDNS_DSA: 338ae8c6e27Sflorian case LDNS_DSA_NSEC3: 339ae8c6e27Sflorian #if defined(USE_DSA) && defined(USE_SHA1) 340ae8c6e27Sflorian return 1; 341ae8c6e27Sflorian #else 342ae8c6e27Sflorian if(fake_dsa || fake_sha1) return 1; 343ae8c6e27Sflorian return 0; 344ae8c6e27Sflorian #endif 345ae8c6e27Sflorian 346ae8c6e27Sflorian case LDNS_RSASHA1: 347ae8c6e27Sflorian case LDNS_RSASHA1_NSEC3: 348ae8c6e27Sflorian #ifdef USE_SHA1 3496d08cb1bSflorian #ifdef HAVE_EVP_DEFAULT_PROPERTIES_IS_FIPS_ENABLED 3506d08cb1bSflorian return !EVP_default_properties_is_fips_enabled(NULL); 3516d08cb1bSflorian #else 352ae8c6e27Sflorian return 1; 3536d08cb1bSflorian #endif 354ae8c6e27Sflorian #else 355ae8c6e27Sflorian if(fake_sha1) return 1; 356ae8c6e27Sflorian return 0; 357ae8c6e27Sflorian #endif 358ae8c6e27Sflorian 359ae8c6e27Sflorian #if defined(HAVE_EVP_SHA256) && defined(USE_SHA2) 360ae8c6e27Sflorian case LDNS_RSASHA256: 361ae8c6e27Sflorian #endif 362ae8c6e27Sflorian #if defined(HAVE_EVP_SHA512) && defined(USE_SHA2) 363ae8c6e27Sflorian case LDNS_RSASHA512: 364ae8c6e27Sflorian #endif 365ae8c6e27Sflorian #ifdef USE_ECDSA 366ae8c6e27Sflorian case LDNS_ECDSAP256SHA256: 367ae8c6e27Sflorian case LDNS_ECDSAP384SHA384: 368ae8c6e27Sflorian #endif 3696d08cb1bSflorian #if (defined(HAVE_EVP_SHA256) && defined(USE_SHA2)) || (defined(HAVE_EVP_SHA512) && defined(USE_SHA2)) || defined(USE_ECDSA) 3706d08cb1bSflorian return 1; 3716d08cb1bSflorian #endif 372ae8c6e27Sflorian #ifdef USE_ED25519 373ae8c6e27Sflorian case LDNS_ED25519: 374ae8c6e27Sflorian #endif 375ae8c6e27Sflorian #ifdef USE_ED448 376ae8c6e27Sflorian case LDNS_ED448: 377ae8c6e27Sflorian #endif 3786d08cb1bSflorian #if defined(USE_ED25519) || defined(USE_ED448) 3796d08cb1bSflorian #ifdef HAVE_EVP_DEFAULT_PROPERTIES_IS_FIPS_ENABLED 3806d08cb1bSflorian return !EVP_default_properties_is_fips_enabled(NULL); 3816d08cb1bSflorian #else 382ae8c6e27Sflorian return 1; 383ae8c6e27Sflorian #endif 3846d08cb1bSflorian #endif 385ae8c6e27Sflorian 386ae8c6e27Sflorian #ifdef USE_GOST 387ae8c6e27Sflorian case LDNS_ECC_GOST: 388ae8c6e27Sflorian /* we support GOST if it can be loaded */ 389ae8c6e27Sflorian return sldns_key_EVP_load_gost_id(); 390ae8c6e27Sflorian #endif 391ae8c6e27Sflorian default: 392ae8c6e27Sflorian return 0; 393ae8c6e27Sflorian } 394ae8c6e27Sflorian } 395ae8c6e27Sflorian 396ae8c6e27Sflorian #ifdef USE_DSA 397ae8c6e27Sflorian /** 398ae8c6e27Sflorian * Setup DSA key digest in DER encoding ... 399ae8c6e27Sflorian * @param sig: input is signature output alloced ptr (unless failure). 400ae8c6e27Sflorian * caller must free alloced ptr if this routine returns true. 401ae8c6e27Sflorian * @param len: input is initial siglen, output is output len. 402ae8c6e27Sflorian * @return false on failure. 403ae8c6e27Sflorian */ 404ae8c6e27Sflorian static int 405ae8c6e27Sflorian setup_dsa_sig(unsigned char** sig, unsigned int* len) 406ae8c6e27Sflorian { 407ae8c6e27Sflorian unsigned char* orig = *sig; 408ae8c6e27Sflorian unsigned int origlen = *len; 409ae8c6e27Sflorian int newlen; 410ae8c6e27Sflorian BIGNUM *R, *S; 411ae8c6e27Sflorian DSA_SIG *dsasig; 412ae8c6e27Sflorian 413ae8c6e27Sflorian /* extract the R and S field from the sig buffer */ 414ae8c6e27Sflorian if(origlen < 1 + 2*SHA_DIGEST_LENGTH) 415ae8c6e27Sflorian return 0; 416ae8c6e27Sflorian R = BN_new(); 417ae8c6e27Sflorian if(!R) return 0; 418ae8c6e27Sflorian (void) BN_bin2bn(orig + 1, SHA_DIGEST_LENGTH, R); 419ae8c6e27Sflorian S = BN_new(); 420ae8c6e27Sflorian if(!S) return 0; 421ae8c6e27Sflorian (void) BN_bin2bn(orig + 21, SHA_DIGEST_LENGTH, S); 422ae8c6e27Sflorian dsasig = DSA_SIG_new(); 423ae8c6e27Sflorian if(!dsasig) return 0; 424ae8c6e27Sflorian 425ae8c6e27Sflorian #ifdef HAVE_DSA_SIG_SET0 426*7037e34cSflorian if(!DSA_SIG_set0(dsasig, R, S)) { 427*7037e34cSflorian DSA_SIG_free(dsasig); 428*7037e34cSflorian return 0; 429*7037e34cSflorian } 430ae8c6e27Sflorian #else 43157403691Sflorian # ifndef S_SPLINT_S 432ae8c6e27Sflorian dsasig->r = R; 433ae8c6e27Sflorian dsasig->s = S; 43457403691Sflorian # endif /* S_SPLINT_S */ 435ae8c6e27Sflorian #endif 436ae8c6e27Sflorian *sig = NULL; 437ae8c6e27Sflorian newlen = i2d_DSA_SIG(dsasig, sig); 438ae8c6e27Sflorian if(newlen < 0) { 439ae8c6e27Sflorian DSA_SIG_free(dsasig); 440ae8c6e27Sflorian free(*sig); 441ae8c6e27Sflorian return 0; 442ae8c6e27Sflorian } 443ae8c6e27Sflorian *len = (unsigned int)newlen; 444ae8c6e27Sflorian DSA_SIG_free(dsasig); 445ae8c6e27Sflorian return 1; 446ae8c6e27Sflorian } 447ae8c6e27Sflorian #endif /* USE_DSA */ 448ae8c6e27Sflorian 449ae8c6e27Sflorian #ifdef USE_ECDSA 450ae8c6e27Sflorian /** 451ae8c6e27Sflorian * Setup the ECDSA signature in its encoding that the library wants. 452ae8c6e27Sflorian * Converts from plain numbers to ASN formatted. 453ae8c6e27Sflorian * @param sig: input is signature, output alloced ptr (unless failure). 454ae8c6e27Sflorian * caller must free alloced ptr if this routine returns true. 455ae8c6e27Sflorian * @param len: input is initial siglen, output is output len. 456ae8c6e27Sflorian * @return false on failure. 457ae8c6e27Sflorian */ 458ae8c6e27Sflorian static int 459ae8c6e27Sflorian setup_ecdsa_sig(unsigned char** sig, unsigned int* len) 460ae8c6e27Sflorian { 461ae8c6e27Sflorian /* convert from two BIGNUMs in the rdata buffer, to ASN notation. 462ae8c6e27Sflorian * ASN preamble: 30440220 <R 32bytefor256> 0220 <S 32bytefor256> 463ae8c6e27Sflorian * the '20' is the length of that field (=bnsize). 464ae8c6e27Sflorian i * the '44' is the total remaining length. 465ae8c6e27Sflorian * if negative, start with leading zero. 466ae8c6e27Sflorian * if starts with 00s, remove them from the number. 467ae8c6e27Sflorian */ 468ae8c6e27Sflorian uint8_t pre[] = {0x30, 0x44, 0x02, 0x20}; 469ae8c6e27Sflorian int pre_len = 4; 470ae8c6e27Sflorian uint8_t mid[] = {0x02, 0x20}; 471ae8c6e27Sflorian int mid_len = 2; 472ae8c6e27Sflorian int raw_sig_len, r_high, s_high, r_rem=0, s_rem=0; 473ae8c6e27Sflorian int bnsize = (int)((*len)/2); 474ae8c6e27Sflorian unsigned char* d = *sig; 475ae8c6e27Sflorian uint8_t* p; 476ae8c6e27Sflorian /* if too short or not even length, fails */ 477ae8c6e27Sflorian if(*len < 16 || bnsize*2 != (int)*len) 478ae8c6e27Sflorian return 0; 479ae8c6e27Sflorian 480ae8c6e27Sflorian /* strip leading zeroes from r (but not last one) */ 481ae8c6e27Sflorian while(r_rem < bnsize-1 && d[r_rem] == 0) 482ae8c6e27Sflorian r_rem++; 483ae8c6e27Sflorian /* strip leading zeroes from s (but not last one) */ 484ae8c6e27Sflorian while(s_rem < bnsize-1 && d[bnsize+s_rem] == 0) 485ae8c6e27Sflorian s_rem++; 486ae8c6e27Sflorian 487ae8c6e27Sflorian r_high = ((d[0+r_rem]&0x80)?1:0); 488ae8c6e27Sflorian s_high = ((d[bnsize+s_rem]&0x80)?1:0); 489ae8c6e27Sflorian raw_sig_len = pre_len + r_high + bnsize - r_rem + mid_len + 490ae8c6e27Sflorian s_high + bnsize - s_rem; 491ae8c6e27Sflorian *sig = (unsigned char*)malloc((size_t)raw_sig_len); 492ae8c6e27Sflorian if(!*sig) 493ae8c6e27Sflorian return 0; 494ae8c6e27Sflorian p = (uint8_t*)*sig; 495ae8c6e27Sflorian p[0] = pre[0]; 496ae8c6e27Sflorian p[1] = (uint8_t)(raw_sig_len-2); 497ae8c6e27Sflorian p[2] = pre[2]; 498ae8c6e27Sflorian p[3] = (uint8_t)(bnsize + r_high - r_rem); 499ae8c6e27Sflorian p += 4; 500ae8c6e27Sflorian if(r_high) { 501ae8c6e27Sflorian *p = 0; 502ae8c6e27Sflorian p += 1; 503ae8c6e27Sflorian } 504ae8c6e27Sflorian memmove(p, d+r_rem, (size_t)bnsize-r_rem); 505ae8c6e27Sflorian p += bnsize-r_rem; 506ae8c6e27Sflorian memmove(p, mid, (size_t)mid_len-1); 507ae8c6e27Sflorian p += mid_len-1; 508ae8c6e27Sflorian *p = (uint8_t)(bnsize + s_high - s_rem); 509ae8c6e27Sflorian p += 1; 510ae8c6e27Sflorian if(s_high) { 511ae8c6e27Sflorian *p = 0; 512ae8c6e27Sflorian p += 1; 513ae8c6e27Sflorian } 514ae8c6e27Sflorian memmove(p, d+bnsize+s_rem, (size_t)bnsize-s_rem); 515ae8c6e27Sflorian *len = (unsigned int)raw_sig_len; 516ae8c6e27Sflorian return 1; 517ae8c6e27Sflorian } 518ae8c6e27Sflorian #endif /* USE_ECDSA */ 519ae8c6e27Sflorian 520ae8c6e27Sflorian #ifdef USE_ECDSA_EVP_WORKAROUND 521ae8c6e27Sflorian static EVP_MD ecdsa_evp_256_md; 522ae8c6e27Sflorian static EVP_MD ecdsa_evp_384_md; 523ae8c6e27Sflorian void ecdsa_evp_workaround_init(void) 524ae8c6e27Sflorian { 525ae8c6e27Sflorian /* openssl before 1.0.0 fixes RSA with the SHA256 526ae8c6e27Sflorian * hash in EVP. We create one for ecdsa_sha256 */ 527ae8c6e27Sflorian ecdsa_evp_256_md = *EVP_sha256(); 528ae8c6e27Sflorian ecdsa_evp_256_md.required_pkey_type[0] = EVP_PKEY_EC; 529ae8c6e27Sflorian ecdsa_evp_256_md.verify = (void*)ECDSA_verify; 530ae8c6e27Sflorian 531ae8c6e27Sflorian ecdsa_evp_384_md = *EVP_sha384(); 532ae8c6e27Sflorian ecdsa_evp_384_md.required_pkey_type[0] = EVP_PKEY_EC; 533ae8c6e27Sflorian ecdsa_evp_384_md.verify = (void*)ECDSA_verify; 534ae8c6e27Sflorian } 535ae8c6e27Sflorian #endif /* USE_ECDSA_EVP_WORKAROUND */ 536ae8c6e27Sflorian 537ae8c6e27Sflorian /** 538ae8c6e27Sflorian * Setup key and digest for verification. Adjust sig if necessary. 539ae8c6e27Sflorian * 540ae8c6e27Sflorian * @param algo: key algorithm 541ae8c6e27Sflorian * @param evp_key: EVP PKEY public key to create. 542ae8c6e27Sflorian * @param digest_type: digest type to use 543ae8c6e27Sflorian * @param key: key to setup for. 544ae8c6e27Sflorian * @param keylen: length of key. 545ae8c6e27Sflorian * @return false on failure. 546ae8c6e27Sflorian */ 547ae8c6e27Sflorian static int 548ae8c6e27Sflorian setup_key_digest(int algo, EVP_PKEY** evp_key, const EVP_MD** digest_type, 549ae8c6e27Sflorian unsigned char* key, size_t keylen) 550ae8c6e27Sflorian { 551ae8c6e27Sflorian switch(algo) { 552ae8c6e27Sflorian #if defined(USE_DSA) && defined(USE_SHA1) 553ae8c6e27Sflorian case LDNS_DSA: 554ae8c6e27Sflorian case LDNS_DSA_NSEC3: 555411c5950Sflorian *evp_key = sldns_key_dsa2pkey_raw(key, keylen); 556ae8c6e27Sflorian if(!*evp_key) { 557411c5950Sflorian verbose(VERB_QUERY, "verify: sldns_key_dsa2pkey failed"); 558ae8c6e27Sflorian return 0; 559ae8c6e27Sflorian } 560ae8c6e27Sflorian #ifdef HAVE_EVP_DSS1 561ae8c6e27Sflorian *digest_type = EVP_dss1(); 562ae8c6e27Sflorian #else 563ae8c6e27Sflorian *digest_type = EVP_sha1(); 564ae8c6e27Sflorian #endif 565ae8c6e27Sflorian 566ae8c6e27Sflorian break; 567ae8c6e27Sflorian #endif /* USE_DSA && USE_SHA1 */ 568ae8c6e27Sflorian 569ae8c6e27Sflorian #if defined(USE_SHA1) || (defined(HAVE_EVP_SHA256) && defined(USE_SHA2)) || (defined(HAVE_EVP_SHA512) && defined(USE_SHA2)) 570ae8c6e27Sflorian #ifdef USE_SHA1 571ae8c6e27Sflorian case LDNS_RSASHA1: 572ae8c6e27Sflorian case LDNS_RSASHA1_NSEC3: 573ae8c6e27Sflorian #endif 574ae8c6e27Sflorian #if defined(HAVE_EVP_SHA256) && defined(USE_SHA2) 575ae8c6e27Sflorian case LDNS_RSASHA256: 576ae8c6e27Sflorian #endif 577ae8c6e27Sflorian #if defined(HAVE_EVP_SHA512) && defined(USE_SHA2) 578ae8c6e27Sflorian case LDNS_RSASHA512: 579ae8c6e27Sflorian #endif 580411c5950Sflorian *evp_key = sldns_key_rsa2pkey_raw(key, keylen); 581ae8c6e27Sflorian if(!*evp_key) { 582411c5950Sflorian verbose(VERB_QUERY, "verify: sldns_key_rsa2pkey SHA failed"); 583ae8c6e27Sflorian return 0; 584ae8c6e27Sflorian } 585ae8c6e27Sflorian 586ae8c6e27Sflorian /* select SHA version */ 587ae8c6e27Sflorian #if defined(HAVE_EVP_SHA256) && defined(USE_SHA2) 588ae8c6e27Sflorian if(algo == LDNS_RSASHA256) 589ae8c6e27Sflorian *digest_type = EVP_sha256(); 590ae8c6e27Sflorian else 591ae8c6e27Sflorian #endif 592ae8c6e27Sflorian #if defined(HAVE_EVP_SHA512) && defined(USE_SHA2) 593ae8c6e27Sflorian if(algo == LDNS_RSASHA512) 594ae8c6e27Sflorian *digest_type = EVP_sha512(); 595ae8c6e27Sflorian else 596ae8c6e27Sflorian #endif 597ae8c6e27Sflorian #ifdef USE_SHA1 598ae8c6e27Sflorian *digest_type = EVP_sha1(); 599ae8c6e27Sflorian #else 600ae8c6e27Sflorian { verbose(VERB_QUERY, "no digest available"); return 0; } 601ae8c6e27Sflorian #endif 602ae8c6e27Sflorian break; 603ae8c6e27Sflorian #endif /* defined(USE_SHA1) || (defined(HAVE_EVP_SHA256) && defined(USE_SHA2)) || (defined(HAVE_EVP_SHA512) && defined(USE_SHA2)) */ 604ae8c6e27Sflorian 605ae8c6e27Sflorian case LDNS_RSAMD5: 606411c5950Sflorian *evp_key = sldns_key_rsa2pkey_raw(key, keylen); 607ae8c6e27Sflorian if(!*evp_key) { 608411c5950Sflorian verbose(VERB_QUERY, "verify: sldns_key_rsa2pkey MD5 failed"); 609ae8c6e27Sflorian return 0; 610ae8c6e27Sflorian } 611ae8c6e27Sflorian *digest_type = EVP_md5(); 612ae8c6e27Sflorian 613ae8c6e27Sflorian break; 614ae8c6e27Sflorian #ifdef USE_GOST 615ae8c6e27Sflorian case LDNS_ECC_GOST: 616ae8c6e27Sflorian *evp_key = sldns_gost2pkey_raw(key, keylen); 617ae8c6e27Sflorian if(!*evp_key) { 618ae8c6e27Sflorian verbose(VERB_QUERY, "verify: " 619ae8c6e27Sflorian "sldns_gost2pkey_raw failed"); 620ae8c6e27Sflorian return 0; 621ae8c6e27Sflorian } 622ae8c6e27Sflorian *digest_type = EVP_get_digestbyname("md_gost94"); 623ae8c6e27Sflorian if(!*digest_type) { 624ae8c6e27Sflorian verbose(VERB_QUERY, "verify: " 625ae8c6e27Sflorian "EVP_getdigest md_gost94 failed"); 626ae8c6e27Sflorian return 0; 627ae8c6e27Sflorian } 628ae8c6e27Sflorian break; 629ae8c6e27Sflorian #endif 630ae8c6e27Sflorian #ifdef USE_ECDSA 631ae8c6e27Sflorian case LDNS_ECDSAP256SHA256: 632ae8c6e27Sflorian *evp_key = sldns_ecdsa2pkey_raw(key, keylen, 633ae8c6e27Sflorian LDNS_ECDSAP256SHA256); 634ae8c6e27Sflorian if(!*evp_key) { 635ae8c6e27Sflorian verbose(VERB_QUERY, "verify: " 636ae8c6e27Sflorian "sldns_ecdsa2pkey_raw failed"); 637ae8c6e27Sflorian return 0; 638ae8c6e27Sflorian } 639ae8c6e27Sflorian #ifdef USE_ECDSA_EVP_WORKAROUND 640ae8c6e27Sflorian *digest_type = &ecdsa_evp_256_md; 641ae8c6e27Sflorian #else 642ae8c6e27Sflorian *digest_type = EVP_sha256(); 643ae8c6e27Sflorian #endif 644ae8c6e27Sflorian break; 645ae8c6e27Sflorian case LDNS_ECDSAP384SHA384: 646ae8c6e27Sflorian *evp_key = sldns_ecdsa2pkey_raw(key, keylen, 647ae8c6e27Sflorian LDNS_ECDSAP384SHA384); 648ae8c6e27Sflorian if(!*evp_key) { 649ae8c6e27Sflorian verbose(VERB_QUERY, "verify: " 650ae8c6e27Sflorian "sldns_ecdsa2pkey_raw failed"); 651ae8c6e27Sflorian return 0; 652ae8c6e27Sflorian } 653ae8c6e27Sflorian #ifdef USE_ECDSA_EVP_WORKAROUND 654ae8c6e27Sflorian *digest_type = &ecdsa_evp_384_md; 655ae8c6e27Sflorian #else 656ae8c6e27Sflorian *digest_type = EVP_sha384(); 657ae8c6e27Sflorian #endif 658ae8c6e27Sflorian break; 659ae8c6e27Sflorian #endif /* USE_ECDSA */ 660ae8c6e27Sflorian #ifdef USE_ED25519 661ae8c6e27Sflorian case LDNS_ED25519: 662ae8c6e27Sflorian *evp_key = sldns_ed255192pkey_raw(key, keylen); 663ae8c6e27Sflorian if(!*evp_key) { 664ae8c6e27Sflorian verbose(VERB_QUERY, "verify: " 665ae8c6e27Sflorian "sldns_ed255192pkey_raw failed"); 666ae8c6e27Sflorian return 0; 667ae8c6e27Sflorian } 668ae8c6e27Sflorian *digest_type = NULL; 669ae8c6e27Sflorian break; 670ae8c6e27Sflorian #endif /* USE_ED25519 */ 671ae8c6e27Sflorian #ifdef USE_ED448 672ae8c6e27Sflorian case LDNS_ED448: 673ae8c6e27Sflorian *evp_key = sldns_ed4482pkey_raw(key, keylen); 674ae8c6e27Sflorian if(!*evp_key) { 675ae8c6e27Sflorian verbose(VERB_QUERY, "verify: " 676ae8c6e27Sflorian "sldns_ed4482pkey_raw failed"); 677ae8c6e27Sflorian return 0; 678ae8c6e27Sflorian } 679ae8c6e27Sflorian *digest_type = NULL; 680ae8c6e27Sflorian break; 681ae8c6e27Sflorian #endif /* USE_ED448 */ 682ae8c6e27Sflorian default: 683ae8c6e27Sflorian verbose(VERB_QUERY, "verify: unknown algorithm %d", 684ae8c6e27Sflorian algo); 685ae8c6e27Sflorian return 0; 686ae8c6e27Sflorian } 687ae8c6e27Sflorian return 1; 688ae8c6e27Sflorian } 689ae8c6e27Sflorian 6906d08cb1bSflorian static void 6916d08cb1bSflorian digest_ctx_free(EVP_MD_CTX* ctx, EVP_PKEY *evp_key, 6926d08cb1bSflorian unsigned char* sigblock, int dofree, int docrypto_free) 6936d08cb1bSflorian { 6946d08cb1bSflorian #ifdef HAVE_EVP_MD_CTX_NEW 6956d08cb1bSflorian EVP_MD_CTX_destroy(ctx); 6966d08cb1bSflorian #else 6976d08cb1bSflorian EVP_MD_CTX_cleanup(ctx); 6986d08cb1bSflorian free(ctx); 6996d08cb1bSflorian #endif 7006d08cb1bSflorian EVP_PKEY_free(evp_key); 7016d08cb1bSflorian if(dofree) free(sigblock); 7026d08cb1bSflorian else if(docrypto_free) OPENSSL_free(sigblock); 7036d08cb1bSflorian } 7046d08cb1bSflorian 7056d08cb1bSflorian static enum sec_status 7066d08cb1bSflorian digest_error_status(const char *str) 7076d08cb1bSflorian { 7086d08cb1bSflorian unsigned long e = ERR_get_error(); 7096d08cb1bSflorian #ifdef EVP_R_INVALID_DIGEST 7106d08cb1bSflorian if (ERR_GET_LIB(e) == ERR_LIB_EVP && 7116d08cb1bSflorian ERR_GET_REASON(e) == EVP_R_INVALID_DIGEST) { 7126d08cb1bSflorian log_crypto_verbose(VERB_ALGO, str, e); 7136d08cb1bSflorian return sec_status_indeterminate; 7146d08cb1bSflorian } 7156d08cb1bSflorian #endif 7166d08cb1bSflorian log_crypto_verbose(VERB_QUERY, str, e); 7176d08cb1bSflorian return sec_status_unchecked; 7186d08cb1bSflorian } 7196d08cb1bSflorian 720ae8c6e27Sflorian /** 721ae8c6e27Sflorian * Check a canonical sig+rrset and signature against a dnskey 722ae8c6e27Sflorian * @param buf: buffer with data to verify, the first rrsig part and the 723ae8c6e27Sflorian * canonicalized rrset. 724ae8c6e27Sflorian * @param algo: DNSKEY algorithm. 725ae8c6e27Sflorian * @param sigblock: signature rdata field from RRSIG 726ae8c6e27Sflorian * @param sigblock_len: length of sigblock data. 727ae8c6e27Sflorian * @param key: public key data from DNSKEY RR. 728ae8c6e27Sflorian * @param keylen: length of keydata. 729ae8c6e27Sflorian * @param reason: bogus reason in more detail. 730ae8c6e27Sflorian * @return secure if verification succeeded, bogus on crypto failure, 7316d08cb1bSflorian * unchecked on format errors and alloc failures, indeterminate 7326d08cb1bSflorian * if digest is not supported by the crypto library (openssl3+ only). 733ae8c6e27Sflorian */ 734ae8c6e27Sflorian enum sec_status 735ae8c6e27Sflorian verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock, 736ae8c6e27Sflorian unsigned int sigblock_len, unsigned char* key, unsigned int keylen, 737ae8c6e27Sflorian char** reason) 738ae8c6e27Sflorian { 739ae8c6e27Sflorian const EVP_MD *digest_type; 740ae8c6e27Sflorian EVP_MD_CTX* ctx; 741ae8c6e27Sflorian int res, dofree = 0, docrypto_free = 0; 742ae8c6e27Sflorian EVP_PKEY *evp_key = NULL; 743ae8c6e27Sflorian 744ae8c6e27Sflorian #ifndef USE_DSA 745ae8c6e27Sflorian if((algo == LDNS_DSA || algo == LDNS_DSA_NSEC3) &&(fake_dsa||fake_sha1)) 746ae8c6e27Sflorian return sec_status_secure; 747ae8c6e27Sflorian #endif 748ae8c6e27Sflorian #ifndef USE_SHA1 749ae8c6e27Sflorian if(fake_sha1 && (algo == LDNS_DSA || algo == LDNS_DSA_NSEC3 || algo == LDNS_RSASHA1 || algo == LDNS_RSASHA1_NSEC3)) 750ae8c6e27Sflorian return sec_status_secure; 751ae8c6e27Sflorian #endif 752ae8c6e27Sflorian 753ae8c6e27Sflorian if(!setup_key_digest(algo, &evp_key, &digest_type, key, keylen)) { 754ae8c6e27Sflorian verbose(VERB_QUERY, "verify: failed to setup key"); 755ae8c6e27Sflorian *reason = "use of key for crypto failed"; 756ae8c6e27Sflorian EVP_PKEY_free(evp_key); 757ae8c6e27Sflorian return sec_status_bogus; 758ae8c6e27Sflorian } 759ae8c6e27Sflorian #ifdef USE_DSA 760ae8c6e27Sflorian /* if it is a DSA signature in bind format, convert to DER format */ 761ae8c6e27Sflorian if((algo == LDNS_DSA || algo == LDNS_DSA_NSEC3) && 762ae8c6e27Sflorian sigblock_len == 1+2*SHA_DIGEST_LENGTH) { 763ae8c6e27Sflorian if(!setup_dsa_sig(&sigblock, &sigblock_len)) { 764ae8c6e27Sflorian verbose(VERB_QUERY, "verify: failed to setup DSA sig"); 765ae8c6e27Sflorian *reason = "use of key for DSA crypto failed"; 766ae8c6e27Sflorian EVP_PKEY_free(evp_key); 767ae8c6e27Sflorian return sec_status_bogus; 768ae8c6e27Sflorian } 769ae8c6e27Sflorian docrypto_free = 1; 770ae8c6e27Sflorian } 771ae8c6e27Sflorian #endif 772ae8c6e27Sflorian #if defined(USE_ECDSA) && defined(USE_DSA) 773ae8c6e27Sflorian else 774ae8c6e27Sflorian #endif 775ae8c6e27Sflorian #ifdef USE_ECDSA 776ae8c6e27Sflorian if(algo == LDNS_ECDSAP256SHA256 || algo == LDNS_ECDSAP384SHA384) { 777ae8c6e27Sflorian /* EVP uses ASN prefix on sig, which is not in the wire data */ 778ae8c6e27Sflorian if(!setup_ecdsa_sig(&sigblock, &sigblock_len)) { 779ae8c6e27Sflorian verbose(VERB_QUERY, "verify: failed to setup ECDSA sig"); 780ae8c6e27Sflorian *reason = "use of signature for ECDSA crypto failed"; 781ae8c6e27Sflorian EVP_PKEY_free(evp_key); 782ae8c6e27Sflorian return sec_status_bogus; 783ae8c6e27Sflorian } 784ae8c6e27Sflorian dofree = 1; 785ae8c6e27Sflorian } 786ae8c6e27Sflorian #endif /* USE_ECDSA */ 787ae8c6e27Sflorian 788ae8c6e27Sflorian /* do the signature cryptography work */ 789ae8c6e27Sflorian #ifdef HAVE_EVP_MD_CTX_NEW 790ae8c6e27Sflorian ctx = EVP_MD_CTX_new(); 791ae8c6e27Sflorian #else 792ae8c6e27Sflorian ctx = (EVP_MD_CTX*)malloc(sizeof(*ctx)); 793ae8c6e27Sflorian if(ctx) EVP_MD_CTX_init(ctx); 794ae8c6e27Sflorian #endif 795ae8c6e27Sflorian if(!ctx) { 796ae8c6e27Sflorian log_err("EVP_MD_CTX_new: malloc failure"); 797ae8c6e27Sflorian EVP_PKEY_free(evp_key); 798ae8c6e27Sflorian if(dofree) free(sigblock); 799ae8c6e27Sflorian else if(docrypto_free) OPENSSL_free(sigblock); 800ae8c6e27Sflorian return sec_status_unchecked; 801ae8c6e27Sflorian } 802ae8c6e27Sflorian #ifndef HAVE_EVP_DIGESTVERIFY 803ae8c6e27Sflorian if(EVP_DigestInit(ctx, digest_type) == 0) { 8046d08cb1bSflorian enum sec_status sec; 8056d08cb1bSflorian sec = digest_error_status("verify: EVP_DigestInit failed"); 8066d08cb1bSflorian digest_ctx_free(ctx, evp_key, sigblock, 8076d08cb1bSflorian dofree, docrypto_free); 8086d08cb1bSflorian return sec; 809ae8c6e27Sflorian } 810ae8c6e27Sflorian if(EVP_DigestUpdate(ctx, (unsigned char*)sldns_buffer_begin(buf), 811ae8c6e27Sflorian (unsigned int)sldns_buffer_limit(buf)) == 0) { 8126d08cb1bSflorian log_crypto_verbose(VERB_QUERY, "verify: EVP_DigestUpdate failed", 8136d08cb1bSflorian ERR_get_error()); 8146d08cb1bSflorian digest_ctx_free(ctx, evp_key, sigblock, 8156d08cb1bSflorian dofree, docrypto_free); 816ae8c6e27Sflorian return sec_status_unchecked; 817ae8c6e27Sflorian } 818ae8c6e27Sflorian 819ae8c6e27Sflorian res = EVP_VerifyFinal(ctx, sigblock, sigblock_len, evp_key); 820ae8c6e27Sflorian #else /* HAVE_EVP_DIGESTVERIFY */ 821ae8c6e27Sflorian if(EVP_DigestVerifyInit(ctx, NULL, digest_type, NULL, evp_key) == 0) { 8226d08cb1bSflorian enum sec_status sec; 8236d08cb1bSflorian sec = digest_error_status("verify: EVP_DigestVerifyInit failed"); 8246d08cb1bSflorian digest_ctx_free(ctx, evp_key, sigblock, 8256d08cb1bSflorian dofree, docrypto_free); 8266d08cb1bSflorian return sec; 827ae8c6e27Sflorian } 828ae8c6e27Sflorian res = EVP_DigestVerify(ctx, sigblock, sigblock_len, 829ae8c6e27Sflorian (unsigned char*)sldns_buffer_begin(buf), 830ae8c6e27Sflorian sldns_buffer_limit(buf)); 831ae8c6e27Sflorian #endif 8326d08cb1bSflorian digest_ctx_free(ctx, evp_key, sigblock, 8336d08cb1bSflorian dofree, docrypto_free); 834ae8c6e27Sflorian 835ae8c6e27Sflorian if(res == 1) { 836ae8c6e27Sflorian return sec_status_secure; 837ae8c6e27Sflorian } else if(res == 0) { 838ae8c6e27Sflorian verbose(VERB_QUERY, "verify: signature mismatch"); 839ae8c6e27Sflorian *reason = "signature crypto failed"; 840ae8c6e27Sflorian return sec_status_bogus; 841ae8c6e27Sflorian } 842ae8c6e27Sflorian 843ae8c6e27Sflorian log_crypto_error("verify:", ERR_get_error()); 844ae8c6e27Sflorian return sec_status_unchecked; 845ae8c6e27Sflorian } 846ae8c6e27Sflorian 847ae8c6e27Sflorian /**************************************************/ 848ae8c6e27Sflorian #elif defined(HAVE_NSS) 849ae8c6e27Sflorian /* libnss implementation */ 850ae8c6e27Sflorian /* nss3 */ 851ae8c6e27Sflorian #include "sechash.h" 852ae8c6e27Sflorian #include "pk11pub.h" 853ae8c6e27Sflorian #include "keyhi.h" 854ae8c6e27Sflorian #include "secerr.h" 855ae8c6e27Sflorian #include "cryptohi.h" 856ae8c6e27Sflorian /* nspr4 */ 857ae8c6e27Sflorian #include "prerror.h" 858ae8c6e27Sflorian 859ae8c6e27Sflorian /* return size of digest if supported, or 0 otherwise */ 860ae8c6e27Sflorian size_t 861ae8c6e27Sflorian nsec3_hash_algo_size_supported(int id) 862ae8c6e27Sflorian { 863ae8c6e27Sflorian switch(id) { 864ae8c6e27Sflorian case NSEC3_HASH_SHA1: 865ae8c6e27Sflorian return SHA1_LENGTH; 866ae8c6e27Sflorian default: 867ae8c6e27Sflorian return 0; 868ae8c6e27Sflorian } 869ae8c6e27Sflorian } 870ae8c6e27Sflorian 871ae8c6e27Sflorian /* perform nsec3 hash. return false on failure */ 872ae8c6e27Sflorian int 873ae8c6e27Sflorian secalgo_nsec3_hash(int algo, unsigned char* buf, size_t len, 874ae8c6e27Sflorian unsigned char* res) 875ae8c6e27Sflorian { 876ae8c6e27Sflorian switch(algo) { 877ae8c6e27Sflorian case NSEC3_HASH_SHA1: 878ae8c6e27Sflorian (void)HASH_HashBuf(HASH_AlgSHA1, res, buf, (unsigned long)len); 879ae8c6e27Sflorian return 1; 880ae8c6e27Sflorian default: 881ae8c6e27Sflorian return 0; 882ae8c6e27Sflorian } 883ae8c6e27Sflorian } 884ae8c6e27Sflorian 885ae8c6e27Sflorian void 886ae8c6e27Sflorian secalgo_hash_sha256(unsigned char* buf, size_t len, unsigned char* res) 887ae8c6e27Sflorian { 888ae8c6e27Sflorian (void)HASH_HashBuf(HASH_AlgSHA256, res, buf, (unsigned long)len); 889ae8c6e27Sflorian } 890ae8c6e27Sflorian 891411c5950Sflorian /** the secalgo hash structure */ 892411c5950Sflorian struct secalgo_hash { 893411c5950Sflorian /** hash context */ 894411c5950Sflorian HASHContext* ctx; 895411c5950Sflorian }; 896411c5950Sflorian 897411c5950Sflorian /** create hash struct of type */ 898411c5950Sflorian static struct secalgo_hash* secalgo_hash_create_type(HASH_HashType tp) 899411c5950Sflorian { 900411c5950Sflorian struct secalgo_hash* h = calloc(1, sizeof(*h)); 901411c5950Sflorian if(!h) 902411c5950Sflorian return NULL; 903411c5950Sflorian h->ctx = HASH_Create(tp); 904411c5950Sflorian if(!h->ctx) { 905411c5950Sflorian free(h); 906411c5950Sflorian return NULL; 907411c5950Sflorian } 908411c5950Sflorian return h; 909411c5950Sflorian } 910411c5950Sflorian 911411c5950Sflorian struct secalgo_hash* secalgo_hash_create_sha384(void) 912411c5950Sflorian { 913411c5950Sflorian return secalgo_hash_create_type(HASH_AlgSHA384); 914411c5950Sflorian } 915411c5950Sflorian 916411c5950Sflorian struct secalgo_hash* secalgo_hash_create_sha512(void) 917411c5950Sflorian { 918411c5950Sflorian return secalgo_hash_create_type(HASH_AlgSHA512); 919411c5950Sflorian } 920411c5950Sflorian 921411c5950Sflorian int secalgo_hash_update(struct secalgo_hash* hash, uint8_t* data, size_t len) 922411c5950Sflorian { 923411c5950Sflorian HASH_Update(hash->ctx, (unsigned char*)data, (unsigned int)len); 924411c5950Sflorian return 1; 925411c5950Sflorian } 926411c5950Sflorian 927411c5950Sflorian int secalgo_hash_final(struct secalgo_hash* hash, uint8_t* result, 928411c5950Sflorian size_t maxlen, size_t* resultlen) 929411c5950Sflorian { 930411c5950Sflorian unsigned int reslen = 0; 931411c5950Sflorian if(HASH_ResultLenContext(hash->ctx) > (unsigned int)maxlen) { 932411c5950Sflorian *resultlen = 0; 933411c5950Sflorian log_err("secalgo_hash_final: hash buffer too small"); 934411c5950Sflorian return 0; 935411c5950Sflorian } 936411c5950Sflorian HASH_End(hash->ctx, (unsigned char*)result, &reslen, 937411c5950Sflorian (unsigned int)maxlen); 938411c5950Sflorian *resultlen = (size_t)reslen; 939411c5950Sflorian return 1; 940411c5950Sflorian } 941411c5950Sflorian 942411c5950Sflorian void secalgo_hash_delete(struct secalgo_hash* hash) 943411c5950Sflorian { 944411c5950Sflorian if(!hash) return; 945411c5950Sflorian HASH_Destroy(hash->ctx); 946411c5950Sflorian free(hash); 947411c5950Sflorian } 948411c5950Sflorian 949ae8c6e27Sflorian size_t 950ae8c6e27Sflorian ds_digest_size_supported(int algo) 951ae8c6e27Sflorian { 952ae8c6e27Sflorian /* uses libNSS */ 953ae8c6e27Sflorian switch(algo) { 954ae8c6e27Sflorian #ifdef USE_SHA1 955ae8c6e27Sflorian case LDNS_SHA1: 956ae8c6e27Sflorian return SHA1_LENGTH; 957ae8c6e27Sflorian #endif 958ae8c6e27Sflorian #ifdef USE_SHA2 959ae8c6e27Sflorian case LDNS_SHA256: 960ae8c6e27Sflorian return SHA256_LENGTH; 961ae8c6e27Sflorian #endif 962ae8c6e27Sflorian #ifdef USE_ECDSA 963ae8c6e27Sflorian case LDNS_SHA384: 964ae8c6e27Sflorian return SHA384_LENGTH; 965ae8c6e27Sflorian #endif 966ae8c6e27Sflorian /* GOST not supported in NSS */ 967ae8c6e27Sflorian case LDNS_HASH_GOST: 968ae8c6e27Sflorian default: break; 969ae8c6e27Sflorian } 970ae8c6e27Sflorian return 0; 971ae8c6e27Sflorian } 972ae8c6e27Sflorian 973ae8c6e27Sflorian int 974ae8c6e27Sflorian secalgo_ds_digest(int algo, unsigned char* buf, size_t len, 975ae8c6e27Sflorian unsigned char* res) 976ae8c6e27Sflorian { 977ae8c6e27Sflorian /* uses libNSS */ 978ae8c6e27Sflorian switch(algo) { 979ae8c6e27Sflorian #ifdef USE_SHA1 980ae8c6e27Sflorian case LDNS_SHA1: 981ae8c6e27Sflorian return HASH_HashBuf(HASH_AlgSHA1, res, buf, len) 982ae8c6e27Sflorian == SECSuccess; 983ae8c6e27Sflorian #endif 984ae8c6e27Sflorian #if defined(USE_SHA2) 985ae8c6e27Sflorian case LDNS_SHA256: 986ae8c6e27Sflorian return HASH_HashBuf(HASH_AlgSHA256, res, buf, len) 987ae8c6e27Sflorian == SECSuccess; 988ae8c6e27Sflorian #endif 989ae8c6e27Sflorian #ifdef USE_ECDSA 990ae8c6e27Sflorian case LDNS_SHA384: 991ae8c6e27Sflorian return HASH_HashBuf(HASH_AlgSHA384, res, buf, len) 992ae8c6e27Sflorian == SECSuccess; 993ae8c6e27Sflorian #endif 994ae8c6e27Sflorian case LDNS_HASH_GOST: 995ae8c6e27Sflorian default: 996ae8c6e27Sflorian verbose(VERB_QUERY, "unknown DS digest algorithm %d", 997ae8c6e27Sflorian algo); 998ae8c6e27Sflorian break; 999ae8c6e27Sflorian } 1000ae8c6e27Sflorian return 0; 1001ae8c6e27Sflorian } 1002ae8c6e27Sflorian 1003ae8c6e27Sflorian int 1004ae8c6e27Sflorian dnskey_algo_id_is_supported(int id) 1005ae8c6e27Sflorian { 1006ae8c6e27Sflorian /* uses libNSS */ 1007ae8c6e27Sflorian switch(id) { 1008ae8c6e27Sflorian case LDNS_RSAMD5: 1009ae8c6e27Sflorian /* RFC 6725 deprecates RSAMD5 */ 1010ae8c6e27Sflorian return 0; 1011ae8c6e27Sflorian #if defined(USE_SHA1) || defined(USE_SHA2) 1012ae8c6e27Sflorian #if defined(USE_DSA) && defined(USE_SHA1) 1013ae8c6e27Sflorian case LDNS_DSA: 1014ae8c6e27Sflorian case LDNS_DSA_NSEC3: 1015ae8c6e27Sflorian #endif 1016ae8c6e27Sflorian #ifdef USE_SHA1 1017ae8c6e27Sflorian case LDNS_RSASHA1: 1018ae8c6e27Sflorian case LDNS_RSASHA1_NSEC3: 1019ae8c6e27Sflorian #endif 1020ae8c6e27Sflorian #ifdef USE_SHA2 1021ae8c6e27Sflorian case LDNS_RSASHA256: 1022ae8c6e27Sflorian #endif 1023ae8c6e27Sflorian #ifdef USE_SHA2 1024ae8c6e27Sflorian case LDNS_RSASHA512: 1025ae8c6e27Sflorian #endif 1026ae8c6e27Sflorian return 1; 1027ae8c6e27Sflorian #endif /* SHA1 or SHA2 */ 1028ae8c6e27Sflorian 1029ae8c6e27Sflorian #ifdef USE_ECDSA 1030ae8c6e27Sflorian case LDNS_ECDSAP256SHA256: 1031ae8c6e27Sflorian case LDNS_ECDSAP384SHA384: 1032ae8c6e27Sflorian return PK11_TokenExists(CKM_ECDSA); 1033ae8c6e27Sflorian #endif 1034ae8c6e27Sflorian case LDNS_ECC_GOST: 1035ae8c6e27Sflorian default: 1036ae8c6e27Sflorian return 0; 1037ae8c6e27Sflorian } 1038ae8c6e27Sflorian } 1039ae8c6e27Sflorian 1040ae8c6e27Sflorian /* return a new public key for NSS */ 1041ae8c6e27Sflorian static SECKEYPublicKey* nss_key_create(KeyType ktype) 1042ae8c6e27Sflorian { 1043ae8c6e27Sflorian SECKEYPublicKey* key; 1044ae8c6e27Sflorian PLArenaPool* arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); 1045ae8c6e27Sflorian if(!arena) { 1046ae8c6e27Sflorian log_err("out of memory, PORT_NewArena failed"); 1047ae8c6e27Sflorian return NULL; 1048ae8c6e27Sflorian } 1049ae8c6e27Sflorian key = PORT_ArenaZNew(arena, SECKEYPublicKey); 1050ae8c6e27Sflorian if(!key) { 1051ae8c6e27Sflorian log_err("out of memory, PORT_ArenaZNew failed"); 1052ae8c6e27Sflorian PORT_FreeArena(arena, PR_FALSE); 1053ae8c6e27Sflorian return NULL; 1054ae8c6e27Sflorian } 1055ae8c6e27Sflorian key->arena = arena; 1056ae8c6e27Sflorian key->keyType = ktype; 1057ae8c6e27Sflorian key->pkcs11Slot = NULL; 1058ae8c6e27Sflorian key->pkcs11ID = CK_INVALID_HANDLE; 1059ae8c6e27Sflorian return key; 1060ae8c6e27Sflorian } 1061ae8c6e27Sflorian 1062ae8c6e27Sflorian static SECKEYPublicKey* nss_buf2ecdsa(unsigned char* key, size_t len, int algo) 1063ae8c6e27Sflorian { 1064ae8c6e27Sflorian SECKEYPublicKey* pk; 1065ae8c6e27Sflorian SECItem pub = {siBuffer, NULL, 0}; 1066ae8c6e27Sflorian SECItem params = {siBuffer, NULL, 0}; 1067ae8c6e27Sflorian static unsigned char param256[] = { 1068ae8c6e27Sflorian /* OBJECTIDENTIFIER 1.2.840.10045.3.1.7 (P-256) 1069ae8c6e27Sflorian * {iso(1) member-body(2) us(840) ansi-x962(10045) curves(3) prime(1) prime256v1(7)} */ 1070ae8c6e27Sflorian 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07 1071ae8c6e27Sflorian }; 1072ae8c6e27Sflorian static unsigned char param384[] = { 1073ae8c6e27Sflorian /* OBJECTIDENTIFIER 1.3.132.0.34 (P-384) 1074ae8c6e27Sflorian * {iso(1) identified-organization(3) certicom(132) curve(0) ansip384r1(34)} */ 1075ae8c6e27Sflorian 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x22 1076ae8c6e27Sflorian }; 1077ae8c6e27Sflorian unsigned char buf[256+2]; /* sufficient for 2*384/8+1 */ 1078ae8c6e27Sflorian 1079ae8c6e27Sflorian /* check length, which uncompressed must be 2 bignums */ 1080ae8c6e27Sflorian if(algo == LDNS_ECDSAP256SHA256) { 1081ae8c6e27Sflorian if(len != 2*256/8) return NULL; 1082ae8c6e27Sflorian /* ECCurve_X9_62_PRIME_256V1 */ 1083ae8c6e27Sflorian } else if(algo == LDNS_ECDSAP384SHA384) { 1084ae8c6e27Sflorian if(len != 2*384/8) return NULL; 1085ae8c6e27Sflorian /* ECCurve_X9_62_PRIME_384R1 */ 1086ae8c6e27Sflorian } else return NULL; 1087ae8c6e27Sflorian 1088ae8c6e27Sflorian buf[0] = 0x04; /* POINT_FORM_UNCOMPRESSED */ 1089ae8c6e27Sflorian memmove(buf+1, key, len); 1090ae8c6e27Sflorian pub.data = buf; 1091ae8c6e27Sflorian pub.len = len+1; 1092ae8c6e27Sflorian if(algo == LDNS_ECDSAP256SHA256) { 1093ae8c6e27Sflorian params.data = param256; 1094ae8c6e27Sflorian params.len = sizeof(param256); 1095ae8c6e27Sflorian } else { 1096ae8c6e27Sflorian params.data = param384; 1097ae8c6e27Sflorian params.len = sizeof(param384); 1098ae8c6e27Sflorian } 1099ae8c6e27Sflorian 1100ae8c6e27Sflorian pk = nss_key_create(ecKey); 1101ae8c6e27Sflorian if(!pk) 1102ae8c6e27Sflorian return NULL; 1103ae8c6e27Sflorian pk->u.ec.size = (len/2)*8; 1104ae8c6e27Sflorian if(SECITEM_CopyItem(pk->arena, &pk->u.ec.publicValue, &pub)) { 1105ae8c6e27Sflorian SECKEY_DestroyPublicKey(pk); 1106ae8c6e27Sflorian return NULL; 1107ae8c6e27Sflorian } 1108ae8c6e27Sflorian if(SECITEM_CopyItem(pk->arena, &pk->u.ec.DEREncodedParams, ¶ms)) { 1109ae8c6e27Sflorian SECKEY_DestroyPublicKey(pk); 1110ae8c6e27Sflorian return NULL; 1111ae8c6e27Sflorian } 1112ae8c6e27Sflorian 1113ae8c6e27Sflorian return pk; 1114ae8c6e27Sflorian } 1115ae8c6e27Sflorian 1116853e076fSflorian #if defined(USE_DSA) && defined(USE_SHA1) 1117ae8c6e27Sflorian static SECKEYPublicKey* nss_buf2dsa(unsigned char* key, size_t len) 1118ae8c6e27Sflorian { 1119ae8c6e27Sflorian SECKEYPublicKey* pk; 1120ae8c6e27Sflorian uint8_t T; 1121ae8c6e27Sflorian uint16_t length; 1122ae8c6e27Sflorian uint16_t offset; 1123ae8c6e27Sflorian SECItem Q = {siBuffer, NULL, 0}; 1124ae8c6e27Sflorian SECItem P = {siBuffer, NULL, 0}; 1125ae8c6e27Sflorian SECItem G = {siBuffer, NULL, 0}; 1126ae8c6e27Sflorian SECItem Y = {siBuffer, NULL, 0}; 1127ae8c6e27Sflorian 1128ae8c6e27Sflorian if(len == 0) 1129ae8c6e27Sflorian return NULL; 1130ae8c6e27Sflorian T = (uint8_t)key[0]; 1131ae8c6e27Sflorian length = (64 + T * 8); 1132ae8c6e27Sflorian offset = 1; 1133ae8c6e27Sflorian 1134ae8c6e27Sflorian if (T > 8) { 1135ae8c6e27Sflorian return NULL; 1136ae8c6e27Sflorian } 1137ae8c6e27Sflorian if(len < (size_t)1 + SHA1_LENGTH + 3*length) 1138ae8c6e27Sflorian return NULL; 1139ae8c6e27Sflorian 1140ae8c6e27Sflorian Q.data = key+offset; 1141ae8c6e27Sflorian Q.len = SHA1_LENGTH; 1142ae8c6e27Sflorian offset += SHA1_LENGTH; 1143ae8c6e27Sflorian 1144ae8c6e27Sflorian P.data = key+offset; 1145ae8c6e27Sflorian P.len = length; 1146ae8c6e27Sflorian offset += length; 1147ae8c6e27Sflorian 1148ae8c6e27Sflorian G.data = key+offset; 1149ae8c6e27Sflorian G.len = length; 1150ae8c6e27Sflorian offset += length; 1151ae8c6e27Sflorian 1152ae8c6e27Sflorian Y.data = key+offset; 1153ae8c6e27Sflorian Y.len = length; 1154ae8c6e27Sflorian offset += length; 1155ae8c6e27Sflorian 1156ae8c6e27Sflorian pk = nss_key_create(dsaKey); 1157ae8c6e27Sflorian if(!pk) 1158ae8c6e27Sflorian return NULL; 1159ae8c6e27Sflorian if(SECITEM_CopyItem(pk->arena, &pk->u.dsa.params.prime, &P)) { 1160ae8c6e27Sflorian SECKEY_DestroyPublicKey(pk); 1161ae8c6e27Sflorian return NULL; 1162ae8c6e27Sflorian } 1163ae8c6e27Sflorian if(SECITEM_CopyItem(pk->arena, &pk->u.dsa.params.subPrime, &Q)) { 1164ae8c6e27Sflorian SECKEY_DestroyPublicKey(pk); 1165ae8c6e27Sflorian return NULL; 1166ae8c6e27Sflorian } 1167ae8c6e27Sflorian if(SECITEM_CopyItem(pk->arena, &pk->u.dsa.params.base, &G)) { 1168ae8c6e27Sflorian SECKEY_DestroyPublicKey(pk); 1169ae8c6e27Sflorian return NULL; 1170ae8c6e27Sflorian } 1171ae8c6e27Sflorian if(SECITEM_CopyItem(pk->arena, &pk->u.dsa.publicValue, &Y)) { 1172ae8c6e27Sflorian SECKEY_DestroyPublicKey(pk); 1173ae8c6e27Sflorian return NULL; 1174ae8c6e27Sflorian } 1175ae8c6e27Sflorian return pk; 1176ae8c6e27Sflorian } 1177853e076fSflorian #endif /* USE_DSA && USE_SHA1 */ 1178ae8c6e27Sflorian 1179ae8c6e27Sflorian static SECKEYPublicKey* nss_buf2rsa(unsigned char* key, size_t len) 1180ae8c6e27Sflorian { 1181ae8c6e27Sflorian SECKEYPublicKey* pk; 1182ae8c6e27Sflorian uint16_t exp; 1183ae8c6e27Sflorian uint16_t offset; 1184ae8c6e27Sflorian uint16_t int16; 1185ae8c6e27Sflorian SECItem modulus = {siBuffer, NULL, 0}; 1186ae8c6e27Sflorian SECItem exponent = {siBuffer, NULL, 0}; 1187ae8c6e27Sflorian if(len == 0) 1188ae8c6e27Sflorian return NULL; 1189ae8c6e27Sflorian if(key[0] == 0) { 1190ae8c6e27Sflorian if(len < 3) 1191ae8c6e27Sflorian return NULL; 1192ae8c6e27Sflorian /* the exponent is too large so it's places further */ 1193ae8c6e27Sflorian memmove(&int16, key+1, 2); 1194ae8c6e27Sflorian exp = ntohs(int16); 1195ae8c6e27Sflorian offset = 3; 1196ae8c6e27Sflorian } else { 1197ae8c6e27Sflorian exp = key[0]; 1198ae8c6e27Sflorian offset = 1; 1199ae8c6e27Sflorian } 1200ae8c6e27Sflorian 1201ae8c6e27Sflorian /* key length at least one */ 1202ae8c6e27Sflorian if(len < (size_t)offset + exp + 1) 1203ae8c6e27Sflorian return NULL; 1204ae8c6e27Sflorian 1205ae8c6e27Sflorian exponent.data = key+offset; 1206ae8c6e27Sflorian exponent.len = exp; 1207ae8c6e27Sflorian offset += exp; 1208ae8c6e27Sflorian modulus.data = key+offset; 1209ae8c6e27Sflorian modulus.len = (len - offset); 1210ae8c6e27Sflorian 1211ae8c6e27Sflorian pk = nss_key_create(rsaKey); 1212ae8c6e27Sflorian if(!pk) 1213ae8c6e27Sflorian return NULL; 1214ae8c6e27Sflorian if(SECITEM_CopyItem(pk->arena, &pk->u.rsa.modulus, &modulus)) { 1215ae8c6e27Sflorian SECKEY_DestroyPublicKey(pk); 1216ae8c6e27Sflorian return NULL; 1217ae8c6e27Sflorian } 1218ae8c6e27Sflorian if(SECITEM_CopyItem(pk->arena, &pk->u.rsa.publicExponent, &exponent)) { 1219ae8c6e27Sflorian SECKEY_DestroyPublicKey(pk); 1220ae8c6e27Sflorian return NULL; 1221ae8c6e27Sflorian } 1222ae8c6e27Sflorian return pk; 1223ae8c6e27Sflorian } 1224ae8c6e27Sflorian 1225ae8c6e27Sflorian /** 1226ae8c6e27Sflorian * Setup key and digest for verification. Adjust sig if necessary. 1227ae8c6e27Sflorian * 1228ae8c6e27Sflorian * @param algo: key algorithm 1229ae8c6e27Sflorian * @param evp_key: EVP PKEY public key to create. 1230ae8c6e27Sflorian * @param digest_type: digest type to use 1231ae8c6e27Sflorian * @param key: key to setup for. 1232ae8c6e27Sflorian * @param keylen: length of key. 1233ae8c6e27Sflorian * @param prefix: if returned, the ASN prefix for the hashblob. 1234ae8c6e27Sflorian * @param prefixlen: length of the prefix. 1235ae8c6e27Sflorian * @return false on failure. 1236ae8c6e27Sflorian */ 1237ae8c6e27Sflorian static int 1238ae8c6e27Sflorian nss_setup_key_digest(int algo, SECKEYPublicKey** pubkey, HASH_HashType* htype, 1239ae8c6e27Sflorian unsigned char* key, size_t keylen, unsigned char** prefix, 1240ae8c6e27Sflorian size_t* prefixlen) 1241ae8c6e27Sflorian { 1242ae8c6e27Sflorian /* uses libNSS */ 1243ae8c6e27Sflorian 1244ae8c6e27Sflorian /* hash prefix for md5, RFC2537 */ 1245ae8c6e27Sflorian static unsigned char p_md5[] = {0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 1246ae8c6e27Sflorian 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10}; 1247ae8c6e27Sflorian /* hash prefix to prepend to hash output, from RFC3110 */ 1248ae8c6e27Sflorian static unsigned char p_sha1[] = {0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 1249ae8c6e27Sflorian 0x0E, 0x03, 0x02, 0x1A, 0x05, 0x00, 0x04, 0x14}; 1250ae8c6e27Sflorian /* from RFC5702 */ 1251ae8c6e27Sflorian static unsigned char p_sha256[] = {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 1252ae8c6e27Sflorian 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20}; 1253ae8c6e27Sflorian static unsigned char p_sha512[] = {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 1254ae8c6e27Sflorian 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40}; 1255ae8c6e27Sflorian /* from RFC6234 */ 1256ae8c6e27Sflorian /* for future RSASHA384 .. 1257ae8c6e27Sflorian static unsigned char p_sha384[] = {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 1258ae8c6e27Sflorian 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30}; 1259ae8c6e27Sflorian */ 1260ae8c6e27Sflorian 1261ae8c6e27Sflorian switch(algo) { 1262ae8c6e27Sflorian 1263ae8c6e27Sflorian #if defined(USE_SHA1) || defined(USE_SHA2) 1264ae8c6e27Sflorian #if defined(USE_DSA) && defined(USE_SHA1) 1265ae8c6e27Sflorian case LDNS_DSA: 1266ae8c6e27Sflorian case LDNS_DSA_NSEC3: 1267ae8c6e27Sflorian *pubkey = nss_buf2dsa(key, keylen); 1268ae8c6e27Sflorian if(!*pubkey) { 1269ae8c6e27Sflorian log_err("verify: malloc failure in crypto"); 1270ae8c6e27Sflorian return 0; 1271ae8c6e27Sflorian } 1272ae8c6e27Sflorian *htype = HASH_AlgSHA1; 1273ae8c6e27Sflorian /* no prefix for DSA verification */ 1274ae8c6e27Sflorian break; 1275ae8c6e27Sflorian #endif 1276ae8c6e27Sflorian #ifdef USE_SHA1 1277ae8c6e27Sflorian case LDNS_RSASHA1: 1278ae8c6e27Sflorian case LDNS_RSASHA1_NSEC3: 1279ae8c6e27Sflorian #endif 1280ae8c6e27Sflorian #ifdef USE_SHA2 1281ae8c6e27Sflorian case LDNS_RSASHA256: 1282ae8c6e27Sflorian #endif 1283ae8c6e27Sflorian #ifdef USE_SHA2 1284ae8c6e27Sflorian case LDNS_RSASHA512: 1285ae8c6e27Sflorian #endif 1286ae8c6e27Sflorian *pubkey = nss_buf2rsa(key, keylen); 1287ae8c6e27Sflorian if(!*pubkey) { 1288ae8c6e27Sflorian log_err("verify: malloc failure in crypto"); 1289ae8c6e27Sflorian return 0; 1290ae8c6e27Sflorian } 1291ae8c6e27Sflorian /* select SHA version */ 1292ae8c6e27Sflorian #ifdef USE_SHA2 1293ae8c6e27Sflorian if(algo == LDNS_RSASHA256) { 1294ae8c6e27Sflorian *htype = HASH_AlgSHA256; 1295ae8c6e27Sflorian *prefix = p_sha256; 1296ae8c6e27Sflorian *prefixlen = sizeof(p_sha256); 1297ae8c6e27Sflorian } else 1298ae8c6e27Sflorian #endif 1299ae8c6e27Sflorian #ifdef USE_SHA2 1300ae8c6e27Sflorian if(algo == LDNS_RSASHA512) { 1301ae8c6e27Sflorian *htype = HASH_AlgSHA512; 1302ae8c6e27Sflorian *prefix = p_sha512; 1303ae8c6e27Sflorian *prefixlen = sizeof(p_sha512); 1304ae8c6e27Sflorian } else 1305ae8c6e27Sflorian #endif 1306ae8c6e27Sflorian #ifdef USE_SHA1 1307ae8c6e27Sflorian { 1308ae8c6e27Sflorian *htype = HASH_AlgSHA1; 1309ae8c6e27Sflorian *prefix = p_sha1; 1310ae8c6e27Sflorian *prefixlen = sizeof(p_sha1); 1311ae8c6e27Sflorian } 1312ae8c6e27Sflorian #else 1313ae8c6e27Sflorian { 1314ae8c6e27Sflorian verbose(VERB_QUERY, "verify: no digest algo"); 1315ae8c6e27Sflorian return 0; 1316ae8c6e27Sflorian } 1317ae8c6e27Sflorian #endif 1318ae8c6e27Sflorian 1319ae8c6e27Sflorian break; 1320ae8c6e27Sflorian #endif /* SHA1 or SHA2 */ 1321ae8c6e27Sflorian 1322ae8c6e27Sflorian case LDNS_RSAMD5: 1323ae8c6e27Sflorian *pubkey = nss_buf2rsa(key, keylen); 1324ae8c6e27Sflorian if(!*pubkey) { 1325ae8c6e27Sflorian log_err("verify: malloc failure in crypto"); 1326ae8c6e27Sflorian return 0; 1327ae8c6e27Sflorian } 1328ae8c6e27Sflorian *htype = HASH_AlgMD5; 1329ae8c6e27Sflorian *prefix = p_md5; 1330ae8c6e27Sflorian *prefixlen = sizeof(p_md5); 1331ae8c6e27Sflorian 1332ae8c6e27Sflorian break; 1333ae8c6e27Sflorian #ifdef USE_ECDSA 1334ae8c6e27Sflorian case LDNS_ECDSAP256SHA256: 1335ae8c6e27Sflorian *pubkey = nss_buf2ecdsa(key, keylen, 1336ae8c6e27Sflorian LDNS_ECDSAP256SHA256); 1337ae8c6e27Sflorian if(!*pubkey) { 1338ae8c6e27Sflorian log_err("verify: malloc failure in crypto"); 1339ae8c6e27Sflorian return 0; 1340ae8c6e27Sflorian } 1341ae8c6e27Sflorian *htype = HASH_AlgSHA256; 1342ae8c6e27Sflorian /* no prefix for DSA verification */ 1343ae8c6e27Sflorian break; 1344ae8c6e27Sflorian case LDNS_ECDSAP384SHA384: 1345ae8c6e27Sflorian *pubkey = nss_buf2ecdsa(key, keylen, 1346ae8c6e27Sflorian LDNS_ECDSAP384SHA384); 1347ae8c6e27Sflorian if(!*pubkey) { 1348ae8c6e27Sflorian log_err("verify: malloc failure in crypto"); 1349ae8c6e27Sflorian return 0; 1350ae8c6e27Sflorian } 1351ae8c6e27Sflorian *htype = HASH_AlgSHA384; 1352ae8c6e27Sflorian /* no prefix for DSA verification */ 1353ae8c6e27Sflorian break; 1354ae8c6e27Sflorian #endif /* USE_ECDSA */ 1355ae8c6e27Sflorian case LDNS_ECC_GOST: 1356ae8c6e27Sflorian default: 1357ae8c6e27Sflorian verbose(VERB_QUERY, "verify: unknown algorithm %d", 1358ae8c6e27Sflorian algo); 1359ae8c6e27Sflorian return 0; 1360ae8c6e27Sflorian } 1361ae8c6e27Sflorian return 1; 1362ae8c6e27Sflorian } 1363ae8c6e27Sflorian 1364ae8c6e27Sflorian /** 1365ae8c6e27Sflorian * Check a canonical sig+rrset and signature against a dnskey 1366ae8c6e27Sflorian * @param buf: buffer with data to verify, the first rrsig part and the 1367ae8c6e27Sflorian * canonicalized rrset. 1368ae8c6e27Sflorian * @param algo: DNSKEY algorithm. 1369ae8c6e27Sflorian * @param sigblock: signature rdata field from RRSIG 1370ae8c6e27Sflorian * @param sigblock_len: length of sigblock data. 1371ae8c6e27Sflorian * @param key: public key data from DNSKEY RR. 1372ae8c6e27Sflorian * @param keylen: length of keydata. 1373ae8c6e27Sflorian * @param reason: bogus reason in more detail. 1374ae8c6e27Sflorian * @return secure if verification succeeded, bogus on crypto failure, 1375ae8c6e27Sflorian * unchecked on format errors and alloc failures. 1376ae8c6e27Sflorian */ 1377ae8c6e27Sflorian enum sec_status 1378ae8c6e27Sflorian verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock, 1379ae8c6e27Sflorian unsigned int sigblock_len, unsigned char* key, unsigned int keylen, 1380ae8c6e27Sflorian char** reason) 1381ae8c6e27Sflorian { 1382ae8c6e27Sflorian /* uses libNSS */ 1383ae8c6e27Sflorian /* large enough for the different hashes */ 1384ae8c6e27Sflorian unsigned char hash[HASH_LENGTH_MAX]; 1385ae8c6e27Sflorian unsigned char hash2[HASH_LENGTH_MAX*2]; 1386ae8c6e27Sflorian HASH_HashType htype = 0; 1387ae8c6e27Sflorian SECKEYPublicKey* pubkey = NULL; 1388ae8c6e27Sflorian SECItem secsig = {siBuffer, sigblock, sigblock_len}; 1389ae8c6e27Sflorian SECItem sechash = {siBuffer, hash, 0}; 1390ae8c6e27Sflorian SECStatus res; 1391ae8c6e27Sflorian unsigned char* prefix = NULL; /* prefix for hash, RFC3110, RFC5702 */ 1392ae8c6e27Sflorian size_t prefixlen = 0; 1393ae8c6e27Sflorian int err; 1394ae8c6e27Sflorian 1395ae8c6e27Sflorian if(!nss_setup_key_digest(algo, &pubkey, &htype, key, keylen, 1396ae8c6e27Sflorian &prefix, &prefixlen)) { 1397ae8c6e27Sflorian verbose(VERB_QUERY, "verify: failed to setup key"); 1398ae8c6e27Sflorian *reason = "use of key for crypto failed"; 1399ae8c6e27Sflorian SECKEY_DestroyPublicKey(pubkey); 1400ae8c6e27Sflorian return sec_status_bogus; 1401ae8c6e27Sflorian } 1402ae8c6e27Sflorian 1403ae8c6e27Sflorian #if defined(USE_DSA) && defined(USE_SHA1) 1404ae8c6e27Sflorian /* need to convert DSA, ECDSA signatures? */ 1405ae8c6e27Sflorian if((algo == LDNS_DSA || algo == LDNS_DSA_NSEC3)) { 1406ae8c6e27Sflorian if(sigblock_len == 1+2*SHA1_LENGTH) { 1407ae8c6e27Sflorian secsig.data ++; 1408ae8c6e27Sflorian secsig.len --; 1409ae8c6e27Sflorian } else { 1410ae8c6e27Sflorian SECItem* p = DSAU_DecodeDerSig(&secsig); 1411ae8c6e27Sflorian if(!p) { 1412ae8c6e27Sflorian verbose(VERB_QUERY, "verify: failed DER decode"); 1413ae8c6e27Sflorian *reason = "signature DER decode failed"; 1414ae8c6e27Sflorian SECKEY_DestroyPublicKey(pubkey); 1415ae8c6e27Sflorian return sec_status_bogus; 1416ae8c6e27Sflorian } 1417ae8c6e27Sflorian if(SECITEM_CopyItem(pubkey->arena, &secsig, p)) { 1418ae8c6e27Sflorian log_err("alloc failure in DER decode"); 1419ae8c6e27Sflorian SECKEY_DestroyPublicKey(pubkey); 1420ae8c6e27Sflorian SECITEM_FreeItem(p, PR_TRUE); 1421ae8c6e27Sflorian return sec_status_unchecked; 1422ae8c6e27Sflorian } 1423ae8c6e27Sflorian SECITEM_FreeItem(p, PR_TRUE); 1424ae8c6e27Sflorian } 1425ae8c6e27Sflorian } 1426ae8c6e27Sflorian #endif /* USE_DSA */ 1427ae8c6e27Sflorian 1428ae8c6e27Sflorian /* do the signature cryptography work */ 1429ae8c6e27Sflorian /* hash the data */ 1430ae8c6e27Sflorian sechash.len = HASH_ResultLen(htype); 1431ae8c6e27Sflorian if(sechash.len > sizeof(hash)) { 1432ae8c6e27Sflorian verbose(VERB_QUERY, "verify: hash too large for buffer"); 1433ae8c6e27Sflorian SECKEY_DestroyPublicKey(pubkey); 1434ae8c6e27Sflorian return sec_status_unchecked; 1435ae8c6e27Sflorian } 1436ae8c6e27Sflorian if(HASH_HashBuf(htype, hash, (unsigned char*)sldns_buffer_begin(buf), 1437ae8c6e27Sflorian (unsigned int)sldns_buffer_limit(buf)) != SECSuccess) { 1438ae8c6e27Sflorian verbose(VERB_QUERY, "verify: HASH_HashBuf failed"); 1439ae8c6e27Sflorian SECKEY_DestroyPublicKey(pubkey); 1440ae8c6e27Sflorian return sec_status_unchecked; 1441ae8c6e27Sflorian } 1442ae8c6e27Sflorian if(prefix) { 1443ae8c6e27Sflorian int hashlen = sechash.len; 1444ae8c6e27Sflorian if(prefixlen+hashlen > sizeof(hash2)) { 1445ae8c6e27Sflorian verbose(VERB_QUERY, "verify: hashprefix too large"); 1446ae8c6e27Sflorian SECKEY_DestroyPublicKey(pubkey); 1447ae8c6e27Sflorian return sec_status_unchecked; 1448ae8c6e27Sflorian } 1449ae8c6e27Sflorian sechash.data = hash2; 1450ae8c6e27Sflorian sechash.len = prefixlen+hashlen; 1451ae8c6e27Sflorian memcpy(sechash.data, prefix, prefixlen); 1452ae8c6e27Sflorian memmove(sechash.data+prefixlen, hash, hashlen); 1453ae8c6e27Sflorian } 1454ae8c6e27Sflorian 1455ae8c6e27Sflorian /* verify the signature */ 1456ae8c6e27Sflorian res = PK11_Verify(pubkey, &secsig, &sechash, NULL /*wincx*/); 1457ae8c6e27Sflorian SECKEY_DestroyPublicKey(pubkey); 1458ae8c6e27Sflorian 1459ae8c6e27Sflorian if(res == SECSuccess) { 1460ae8c6e27Sflorian return sec_status_secure; 1461ae8c6e27Sflorian } 1462ae8c6e27Sflorian err = PORT_GetError(); 1463ae8c6e27Sflorian if(err != SEC_ERROR_BAD_SIGNATURE) { 1464ae8c6e27Sflorian /* failed to verify */ 1465ae8c6e27Sflorian verbose(VERB_QUERY, "verify: PK11_Verify failed: %s", 1466ae8c6e27Sflorian PORT_ErrorToString(err)); 1467ae8c6e27Sflorian /* if it is not supported, like ECC is removed, we get, 1468ae8c6e27Sflorian * SEC_ERROR_NO_MODULE */ 1469ae8c6e27Sflorian if(err == SEC_ERROR_NO_MODULE) 1470ae8c6e27Sflorian return sec_status_unchecked; 1471ae8c6e27Sflorian /* but other errors are commonly returned 1472ae8c6e27Sflorian * for a bad signature from NSS. Thus we return bogus, 1473ae8c6e27Sflorian * not unchecked */ 1474ae8c6e27Sflorian *reason = "signature crypto failed"; 1475ae8c6e27Sflorian return sec_status_bogus; 1476ae8c6e27Sflorian } 1477ae8c6e27Sflorian verbose(VERB_QUERY, "verify: signature mismatch: %s", 1478ae8c6e27Sflorian PORT_ErrorToString(err)); 1479ae8c6e27Sflorian *reason = "signature crypto failed"; 1480ae8c6e27Sflorian return sec_status_bogus; 1481ae8c6e27Sflorian } 1482ae8c6e27Sflorian 1483ae8c6e27Sflorian #elif defined(HAVE_NETTLE) 1484ae8c6e27Sflorian 1485ae8c6e27Sflorian #include "sha.h" 1486ae8c6e27Sflorian #include "bignum.h" 1487ae8c6e27Sflorian #include "macros.h" 1488ae8c6e27Sflorian #include "rsa.h" 1489ae8c6e27Sflorian #include "dsa.h" 1490ae8c6e27Sflorian #ifdef HAVE_NETTLE_DSA_COMPAT_H 1491ae8c6e27Sflorian #include "dsa-compat.h" 1492ae8c6e27Sflorian #endif 1493ae8c6e27Sflorian #include "asn1.h" 1494ae8c6e27Sflorian #ifdef USE_ECDSA 1495ae8c6e27Sflorian #include "ecdsa.h" 1496ae8c6e27Sflorian #include "ecc-curve.h" 1497ae8c6e27Sflorian #endif 1498ae8c6e27Sflorian #ifdef HAVE_NETTLE_EDDSA_H 1499ae8c6e27Sflorian #include "eddsa.h" 1500ae8c6e27Sflorian #endif 1501ae8c6e27Sflorian 1502ae8c6e27Sflorian static int 1503ae8c6e27Sflorian _digest_nettle(int algo, uint8_t* buf, size_t len, 1504ae8c6e27Sflorian unsigned char* res) 1505ae8c6e27Sflorian { 1506ae8c6e27Sflorian switch(algo) { 1507ae8c6e27Sflorian case SHA1_DIGEST_SIZE: 1508ae8c6e27Sflorian { 1509ae8c6e27Sflorian struct sha1_ctx ctx; 1510ae8c6e27Sflorian sha1_init(&ctx); 1511ae8c6e27Sflorian sha1_update(&ctx, len, buf); 1512ae8c6e27Sflorian sha1_digest(&ctx, SHA1_DIGEST_SIZE, res); 1513ae8c6e27Sflorian return 1; 1514ae8c6e27Sflorian } 1515ae8c6e27Sflorian case SHA256_DIGEST_SIZE: 1516ae8c6e27Sflorian { 1517ae8c6e27Sflorian struct sha256_ctx ctx; 1518ae8c6e27Sflorian sha256_init(&ctx); 1519ae8c6e27Sflorian sha256_update(&ctx, len, buf); 1520ae8c6e27Sflorian sha256_digest(&ctx, SHA256_DIGEST_SIZE, res); 1521ae8c6e27Sflorian return 1; 1522ae8c6e27Sflorian } 1523ae8c6e27Sflorian case SHA384_DIGEST_SIZE: 1524ae8c6e27Sflorian { 1525ae8c6e27Sflorian struct sha384_ctx ctx; 1526ae8c6e27Sflorian sha384_init(&ctx); 1527ae8c6e27Sflorian sha384_update(&ctx, len, buf); 1528ae8c6e27Sflorian sha384_digest(&ctx, SHA384_DIGEST_SIZE, res); 1529ae8c6e27Sflorian return 1; 1530ae8c6e27Sflorian } 1531ae8c6e27Sflorian case SHA512_DIGEST_SIZE: 1532ae8c6e27Sflorian { 1533ae8c6e27Sflorian struct sha512_ctx ctx; 1534ae8c6e27Sflorian sha512_init(&ctx); 1535ae8c6e27Sflorian sha512_update(&ctx, len, buf); 1536ae8c6e27Sflorian sha512_digest(&ctx, SHA512_DIGEST_SIZE, res); 1537ae8c6e27Sflorian return 1; 1538ae8c6e27Sflorian } 1539ae8c6e27Sflorian default: 1540ae8c6e27Sflorian break; 1541ae8c6e27Sflorian } 1542ae8c6e27Sflorian return 0; 1543ae8c6e27Sflorian } 1544ae8c6e27Sflorian 1545ae8c6e27Sflorian /* return size of digest if supported, or 0 otherwise */ 1546ae8c6e27Sflorian size_t 1547ae8c6e27Sflorian nsec3_hash_algo_size_supported(int id) 1548ae8c6e27Sflorian { 1549ae8c6e27Sflorian switch(id) { 1550ae8c6e27Sflorian case NSEC3_HASH_SHA1: 1551ae8c6e27Sflorian return SHA1_DIGEST_SIZE; 1552ae8c6e27Sflorian default: 1553ae8c6e27Sflorian return 0; 1554ae8c6e27Sflorian } 1555ae8c6e27Sflorian } 1556ae8c6e27Sflorian 1557ae8c6e27Sflorian /* perform nsec3 hash. return false on failure */ 1558ae8c6e27Sflorian int 1559ae8c6e27Sflorian secalgo_nsec3_hash(int algo, unsigned char* buf, size_t len, 1560ae8c6e27Sflorian unsigned char* res) 1561ae8c6e27Sflorian { 1562ae8c6e27Sflorian switch(algo) { 1563ae8c6e27Sflorian case NSEC3_HASH_SHA1: 1564ae8c6e27Sflorian return _digest_nettle(SHA1_DIGEST_SIZE, (uint8_t*)buf, len, 1565ae8c6e27Sflorian res); 1566ae8c6e27Sflorian default: 1567ae8c6e27Sflorian return 0; 1568ae8c6e27Sflorian } 1569ae8c6e27Sflorian } 1570ae8c6e27Sflorian 1571ae8c6e27Sflorian void 1572ae8c6e27Sflorian secalgo_hash_sha256(unsigned char* buf, size_t len, unsigned char* res) 1573ae8c6e27Sflorian { 1574ae8c6e27Sflorian _digest_nettle(SHA256_DIGEST_SIZE, (uint8_t*)buf, len, res); 1575ae8c6e27Sflorian } 1576ae8c6e27Sflorian 1577411c5950Sflorian /** secalgo hash structure */ 1578411c5950Sflorian struct secalgo_hash { 1579411c5950Sflorian /** if it is 384 or 512 */ 1580411c5950Sflorian int active; 1581411c5950Sflorian /** context for sha384 */ 1582411c5950Sflorian struct sha384_ctx ctx384; 1583411c5950Sflorian /** context for sha512 */ 1584411c5950Sflorian struct sha512_ctx ctx512; 1585411c5950Sflorian }; 1586411c5950Sflorian 1587411c5950Sflorian struct secalgo_hash* secalgo_hash_create_sha384(void) 1588411c5950Sflorian { 1589411c5950Sflorian struct secalgo_hash* h = calloc(1, sizeof(*h)); 1590411c5950Sflorian if(!h) 1591411c5950Sflorian return NULL; 1592411c5950Sflorian h->active = 384; 1593411c5950Sflorian sha384_init(&h->ctx384); 1594411c5950Sflorian return h; 1595411c5950Sflorian } 1596411c5950Sflorian 1597411c5950Sflorian struct secalgo_hash* secalgo_hash_create_sha512(void) 1598411c5950Sflorian { 1599411c5950Sflorian struct secalgo_hash* h = calloc(1, sizeof(*h)); 1600411c5950Sflorian if(!h) 1601411c5950Sflorian return NULL; 1602411c5950Sflorian h->active = 512; 1603411c5950Sflorian sha512_init(&h->ctx512); 1604411c5950Sflorian return h; 1605411c5950Sflorian } 1606411c5950Sflorian 1607411c5950Sflorian int secalgo_hash_update(struct secalgo_hash* hash, uint8_t* data, size_t len) 1608411c5950Sflorian { 1609411c5950Sflorian if(hash->active == 384) { 1610411c5950Sflorian sha384_update(&hash->ctx384, len, data); 1611411c5950Sflorian } else if(hash->active == 512) { 1612411c5950Sflorian sha512_update(&hash->ctx512, len, data); 1613411c5950Sflorian } else { 1614411c5950Sflorian return 0; 1615411c5950Sflorian } 1616411c5950Sflorian return 1; 1617411c5950Sflorian } 1618411c5950Sflorian 1619411c5950Sflorian int secalgo_hash_final(struct secalgo_hash* hash, uint8_t* result, 1620411c5950Sflorian size_t maxlen, size_t* resultlen) 1621411c5950Sflorian { 1622411c5950Sflorian if(hash->active == 384) { 1623411c5950Sflorian if(SHA384_DIGEST_SIZE > maxlen) { 1624411c5950Sflorian *resultlen = 0; 1625411c5950Sflorian log_err("secalgo_hash_final: hash buffer too small"); 1626411c5950Sflorian return 0; 1627411c5950Sflorian } 1628411c5950Sflorian *resultlen = SHA384_DIGEST_SIZE; 1629411c5950Sflorian sha384_digest(&hash->ctx384, SHA384_DIGEST_SIZE, 1630411c5950Sflorian (unsigned char*)result); 1631411c5950Sflorian } else if(hash->active == 512) { 1632411c5950Sflorian if(SHA512_DIGEST_SIZE > maxlen) { 1633411c5950Sflorian *resultlen = 0; 1634411c5950Sflorian log_err("secalgo_hash_final: hash buffer too small"); 1635411c5950Sflorian return 0; 1636411c5950Sflorian } 1637411c5950Sflorian *resultlen = SHA512_DIGEST_SIZE; 1638411c5950Sflorian sha512_digest(&hash->ctx512, SHA512_DIGEST_SIZE, 1639411c5950Sflorian (unsigned char*)result); 1640411c5950Sflorian } else { 1641411c5950Sflorian *resultlen = 0; 1642411c5950Sflorian return 0; 1643411c5950Sflorian } 1644411c5950Sflorian return 1; 1645411c5950Sflorian } 1646411c5950Sflorian 1647411c5950Sflorian void secalgo_hash_delete(struct secalgo_hash* hash) 1648411c5950Sflorian { 1649411c5950Sflorian if(!hash) return; 1650411c5950Sflorian free(hash); 1651411c5950Sflorian } 1652411c5950Sflorian 1653ae8c6e27Sflorian /** 1654ae8c6e27Sflorian * Return size of DS digest according to its hash algorithm. 1655ae8c6e27Sflorian * @param algo: DS digest algo. 1656ae8c6e27Sflorian * @return size in bytes of digest, or 0 if not supported. 1657ae8c6e27Sflorian */ 1658ae8c6e27Sflorian size_t 1659ae8c6e27Sflorian ds_digest_size_supported(int algo) 1660ae8c6e27Sflorian { 1661ae8c6e27Sflorian switch(algo) { 1662ae8c6e27Sflorian case LDNS_SHA1: 1663ae8c6e27Sflorian #ifdef USE_SHA1 1664ae8c6e27Sflorian return SHA1_DIGEST_SIZE; 1665ae8c6e27Sflorian #else 1666ae8c6e27Sflorian if(fake_sha1) return 20; 1667ae8c6e27Sflorian return 0; 1668ae8c6e27Sflorian #endif 1669ae8c6e27Sflorian #ifdef USE_SHA2 1670ae8c6e27Sflorian case LDNS_SHA256: 1671ae8c6e27Sflorian return SHA256_DIGEST_SIZE; 1672ae8c6e27Sflorian #endif 1673ae8c6e27Sflorian #ifdef USE_ECDSA 1674ae8c6e27Sflorian case LDNS_SHA384: 1675ae8c6e27Sflorian return SHA384_DIGEST_SIZE; 1676ae8c6e27Sflorian #endif 1677ae8c6e27Sflorian /* GOST not supported */ 1678ae8c6e27Sflorian case LDNS_HASH_GOST: 1679ae8c6e27Sflorian default: 1680ae8c6e27Sflorian break; 1681ae8c6e27Sflorian } 1682ae8c6e27Sflorian return 0; 1683ae8c6e27Sflorian } 1684ae8c6e27Sflorian 1685ae8c6e27Sflorian int 1686ae8c6e27Sflorian secalgo_ds_digest(int algo, unsigned char* buf, size_t len, 1687ae8c6e27Sflorian unsigned char* res) 1688ae8c6e27Sflorian { 1689ae8c6e27Sflorian switch(algo) { 1690ae8c6e27Sflorian #ifdef USE_SHA1 1691ae8c6e27Sflorian case LDNS_SHA1: 1692ae8c6e27Sflorian return _digest_nettle(SHA1_DIGEST_SIZE, buf, len, res); 1693ae8c6e27Sflorian #endif 1694ae8c6e27Sflorian #if defined(USE_SHA2) 1695ae8c6e27Sflorian case LDNS_SHA256: 1696ae8c6e27Sflorian return _digest_nettle(SHA256_DIGEST_SIZE, buf, len, res); 1697ae8c6e27Sflorian #endif 1698ae8c6e27Sflorian #ifdef USE_ECDSA 1699ae8c6e27Sflorian case LDNS_SHA384: 1700ae8c6e27Sflorian return _digest_nettle(SHA384_DIGEST_SIZE, buf, len, res); 1701ae8c6e27Sflorian 1702ae8c6e27Sflorian #endif 1703ae8c6e27Sflorian case LDNS_HASH_GOST: 1704ae8c6e27Sflorian default: 1705ae8c6e27Sflorian verbose(VERB_QUERY, "unknown DS digest algorithm %d", 1706ae8c6e27Sflorian algo); 1707ae8c6e27Sflorian break; 1708ae8c6e27Sflorian } 1709ae8c6e27Sflorian return 0; 1710ae8c6e27Sflorian } 1711ae8c6e27Sflorian 1712ae8c6e27Sflorian int 1713ae8c6e27Sflorian dnskey_algo_id_is_supported(int id) 1714ae8c6e27Sflorian { 1715ae8c6e27Sflorian /* uses libnettle */ 1716ae8c6e27Sflorian switch(id) { 1717ae8c6e27Sflorian case LDNS_DSA: 1718ae8c6e27Sflorian case LDNS_DSA_NSEC3: 1719d32eb43cSflorian #if defined(USE_DSA) && defined(USE_SHA1) 1720d32eb43cSflorian return 1; 1721d32eb43cSflorian #else 1722d32eb43cSflorian if(fake_dsa || fake_sha1) return 1; 1723d32eb43cSflorian return 0; 1724ae8c6e27Sflorian #endif 1725ae8c6e27Sflorian case LDNS_RSASHA1: 1726ae8c6e27Sflorian case LDNS_RSASHA1_NSEC3: 1727d32eb43cSflorian #ifdef USE_SHA1 1728d32eb43cSflorian return 1; 1729d32eb43cSflorian #else 1730d32eb43cSflorian if(fake_sha1) return 1; 1731d32eb43cSflorian return 0; 1732ae8c6e27Sflorian #endif 1733ae8c6e27Sflorian #ifdef USE_SHA2 1734ae8c6e27Sflorian case LDNS_RSASHA256: 1735ae8c6e27Sflorian case LDNS_RSASHA512: 1736ae8c6e27Sflorian #endif 1737ae8c6e27Sflorian #ifdef USE_ECDSA 1738ae8c6e27Sflorian case LDNS_ECDSAP256SHA256: 1739ae8c6e27Sflorian case LDNS_ECDSAP384SHA384: 1740ae8c6e27Sflorian #endif 1741ae8c6e27Sflorian return 1; 1742ae8c6e27Sflorian #ifdef USE_ED25519 1743ae8c6e27Sflorian case LDNS_ED25519: 1744ae8c6e27Sflorian return 1; 1745ae8c6e27Sflorian #endif 1746ae8c6e27Sflorian case LDNS_RSAMD5: /* RFC 6725 deprecates RSAMD5 */ 1747ae8c6e27Sflorian case LDNS_ECC_GOST: 1748ae8c6e27Sflorian default: 1749ae8c6e27Sflorian return 0; 1750ae8c6e27Sflorian } 1751ae8c6e27Sflorian } 1752ae8c6e27Sflorian 1753ae8c6e27Sflorian #if defined(USE_DSA) && defined(USE_SHA1) 1754ae8c6e27Sflorian static char * 1755ae8c6e27Sflorian _verify_nettle_dsa(sldns_buffer* buf, unsigned char* sigblock, 1756ae8c6e27Sflorian unsigned int sigblock_len, unsigned char* key, unsigned int keylen) 1757ae8c6e27Sflorian { 1758ae8c6e27Sflorian uint8_t digest[SHA1_DIGEST_SIZE]; 1759ae8c6e27Sflorian uint8_t key_t_value; 1760ae8c6e27Sflorian int res = 0; 1761ae8c6e27Sflorian size_t offset; 1762ae8c6e27Sflorian struct dsa_public_key pubkey; 1763ae8c6e27Sflorian struct dsa_signature signature; 1764ae8c6e27Sflorian unsigned int expected_len; 1765ae8c6e27Sflorian 1766ae8c6e27Sflorian /* Extract DSA signature from the record */ 1767ae8c6e27Sflorian nettle_dsa_signature_init(&signature); 1768ae8c6e27Sflorian /* Signature length: 41 bytes - RFC 2536 sec. 3 */ 1769ae8c6e27Sflorian if(sigblock_len == 41) { 1770ae8c6e27Sflorian if(key[0] != sigblock[0]) 1771ae8c6e27Sflorian return "invalid T value in DSA signature or pubkey"; 1772ae8c6e27Sflorian nettle_mpz_set_str_256_u(signature.r, 20, sigblock+1); 1773ae8c6e27Sflorian nettle_mpz_set_str_256_u(signature.s, 20, sigblock+1+20); 1774ae8c6e27Sflorian } else { 1775ae8c6e27Sflorian /* DER encoded, decode the ASN1 notated R and S bignums */ 1776ae8c6e27Sflorian /* SEQUENCE { r INTEGER, s INTEGER } */ 1777ae8c6e27Sflorian struct asn1_der_iterator i, seq; 1778ae8c6e27Sflorian if(asn1_der_iterator_first(&i, sigblock_len, 1779ae8c6e27Sflorian (uint8_t*)sigblock) != ASN1_ITERATOR_CONSTRUCTED 1780ae8c6e27Sflorian || i.type != ASN1_SEQUENCE) 1781ae8c6e27Sflorian return "malformed DER encoded DSA signature"; 1782ae8c6e27Sflorian /* decode this element of i using the seq iterator */ 1783ae8c6e27Sflorian if(asn1_der_decode_constructed(&i, &seq) != 1784ae8c6e27Sflorian ASN1_ITERATOR_PRIMITIVE || seq.type != ASN1_INTEGER) 1785ae8c6e27Sflorian return "malformed DER encoded DSA signature"; 1786ae8c6e27Sflorian if(!asn1_der_get_bignum(&seq, signature.r, 20*8)) 1787ae8c6e27Sflorian return "malformed DER encoded DSA signature"; 1788ae8c6e27Sflorian if(asn1_der_iterator_next(&seq) != ASN1_ITERATOR_PRIMITIVE 1789ae8c6e27Sflorian || seq.type != ASN1_INTEGER) 1790ae8c6e27Sflorian return "malformed DER encoded DSA signature"; 1791ae8c6e27Sflorian if(!asn1_der_get_bignum(&seq, signature.s, 20*8)) 1792ae8c6e27Sflorian return "malformed DER encoded DSA signature"; 1793ae8c6e27Sflorian if(asn1_der_iterator_next(&i) != ASN1_ITERATOR_END) 1794ae8c6e27Sflorian return "malformed DER encoded DSA signature"; 1795ae8c6e27Sflorian } 1796ae8c6e27Sflorian 1797ae8c6e27Sflorian /* Validate T values constraints - RFC 2536 sec. 2 & sec. 3 */ 1798ae8c6e27Sflorian key_t_value = key[0]; 1799ae8c6e27Sflorian if (key_t_value > 8) { 1800ae8c6e27Sflorian return "invalid T value in DSA pubkey"; 1801ae8c6e27Sflorian } 1802ae8c6e27Sflorian 1803ae8c6e27Sflorian /* Pubkey minimum length: 21 bytes - RFC 2536 sec. 2 */ 1804ae8c6e27Sflorian if (keylen < 21) { 1805ae8c6e27Sflorian return "DSA pubkey too short"; 1806ae8c6e27Sflorian } 1807ae8c6e27Sflorian 1808ae8c6e27Sflorian expected_len = 1 + /* T */ 1809ae8c6e27Sflorian 20 + /* Q */ 1810ae8c6e27Sflorian (64 + key_t_value*8) + /* P */ 1811ae8c6e27Sflorian (64 + key_t_value*8) + /* G */ 1812ae8c6e27Sflorian (64 + key_t_value*8); /* Y */ 1813ae8c6e27Sflorian if (keylen != expected_len ) { 1814ae8c6e27Sflorian return "invalid DSA pubkey length"; 1815ae8c6e27Sflorian } 1816ae8c6e27Sflorian 1817ae8c6e27Sflorian /* Extract DSA pubkey from the record */ 1818ae8c6e27Sflorian nettle_dsa_public_key_init(&pubkey); 1819ae8c6e27Sflorian offset = 1; 1820ae8c6e27Sflorian nettle_mpz_set_str_256_u(pubkey.q, 20, key+offset); 1821ae8c6e27Sflorian offset += 20; 1822ae8c6e27Sflorian nettle_mpz_set_str_256_u(pubkey.p, (64 + key_t_value*8), key+offset); 1823ae8c6e27Sflorian offset += (64 + key_t_value*8); 1824ae8c6e27Sflorian nettle_mpz_set_str_256_u(pubkey.g, (64 + key_t_value*8), key+offset); 1825ae8c6e27Sflorian offset += (64 + key_t_value*8); 1826ae8c6e27Sflorian nettle_mpz_set_str_256_u(pubkey.y, (64 + key_t_value*8), key+offset); 1827ae8c6e27Sflorian 1828ae8c6e27Sflorian /* Digest content of "buf" and verify its DSA signature in "sigblock"*/ 1829ae8c6e27Sflorian res = _digest_nettle(SHA1_DIGEST_SIZE, (unsigned char*)sldns_buffer_begin(buf), 1830ae8c6e27Sflorian (unsigned int)sldns_buffer_limit(buf), (unsigned char*)digest); 1831ae8c6e27Sflorian res &= dsa_sha1_verify_digest(&pubkey, digest, &signature); 1832ae8c6e27Sflorian 1833ae8c6e27Sflorian /* Clear and return */ 1834ae8c6e27Sflorian nettle_dsa_signature_clear(&signature); 1835ae8c6e27Sflorian nettle_dsa_public_key_clear(&pubkey); 1836ae8c6e27Sflorian if (!res) 1837ae8c6e27Sflorian return "DSA signature verification failed"; 1838ae8c6e27Sflorian else 1839ae8c6e27Sflorian return NULL; 1840ae8c6e27Sflorian } 1841ae8c6e27Sflorian #endif /* USE_DSA */ 1842ae8c6e27Sflorian 1843ae8c6e27Sflorian static char * 1844ae8c6e27Sflorian _verify_nettle_rsa(sldns_buffer* buf, unsigned int digest_size, char* sigblock, 1845ae8c6e27Sflorian unsigned int sigblock_len, uint8_t* key, unsigned int keylen) 1846ae8c6e27Sflorian { 1847ae8c6e27Sflorian uint16_t exp_len = 0; 1848ae8c6e27Sflorian size_t exp_offset = 0, mod_offset = 0; 1849ae8c6e27Sflorian struct rsa_public_key pubkey; 1850ae8c6e27Sflorian mpz_t signature; 1851ae8c6e27Sflorian int res = 0; 1852ae8c6e27Sflorian 1853ae8c6e27Sflorian /* RSA pubkey parsing as per RFC 3110 sec. 2 */ 1854ae8c6e27Sflorian if( keylen <= 1) { 1855ae8c6e27Sflorian return "null RSA key"; 1856ae8c6e27Sflorian } 1857ae8c6e27Sflorian if (key[0] != 0) { 1858ae8c6e27Sflorian /* 1-byte length */ 1859ae8c6e27Sflorian exp_len = key[0]; 1860ae8c6e27Sflorian exp_offset = 1; 1861ae8c6e27Sflorian } else { 1862ae8c6e27Sflorian /* 1-byte NUL + 2-bytes exponent length */ 1863ae8c6e27Sflorian if (keylen < 3) { 1864ae8c6e27Sflorian return "incorrect RSA key length"; 1865ae8c6e27Sflorian } 1866ae8c6e27Sflorian exp_len = READ_UINT16(key+1); 1867ae8c6e27Sflorian if (exp_len == 0) 1868ae8c6e27Sflorian return "null RSA exponent length"; 1869ae8c6e27Sflorian exp_offset = 3; 1870ae8c6e27Sflorian } 1871ae8c6e27Sflorian /* Check that we are not over-running input length */ 1872ae8c6e27Sflorian if (keylen < exp_offset + exp_len + 1) { 1873ae8c6e27Sflorian return "RSA key content shorter than expected"; 1874ae8c6e27Sflorian } 1875ae8c6e27Sflorian mod_offset = exp_offset + exp_len; 1876ae8c6e27Sflorian nettle_rsa_public_key_init(&pubkey); 1877ae8c6e27Sflorian pubkey.size = keylen - mod_offset; 1878ae8c6e27Sflorian nettle_mpz_set_str_256_u(pubkey.e, exp_len, &key[exp_offset]); 1879ae8c6e27Sflorian nettle_mpz_set_str_256_u(pubkey.n, pubkey.size, &key[mod_offset]); 1880ae8c6e27Sflorian 1881ae8c6e27Sflorian /* Digest content of "buf" and verify its RSA signature in "sigblock"*/ 1882ae8c6e27Sflorian nettle_mpz_init_set_str_256_u(signature, sigblock_len, (uint8_t*)sigblock); 1883ae8c6e27Sflorian switch (digest_size) { 1884ae8c6e27Sflorian case SHA1_DIGEST_SIZE: 1885ae8c6e27Sflorian { 1886ae8c6e27Sflorian uint8_t digest[SHA1_DIGEST_SIZE]; 1887ae8c6e27Sflorian res = _digest_nettle(SHA1_DIGEST_SIZE, (unsigned char*)sldns_buffer_begin(buf), 1888ae8c6e27Sflorian (unsigned int)sldns_buffer_limit(buf), (unsigned char*)digest); 1889ae8c6e27Sflorian res &= rsa_sha1_verify_digest(&pubkey, digest, signature); 1890ae8c6e27Sflorian break; 1891ae8c6e27Sflorian } 1892ae8c6e27Sflorian case SHA256_DIGEST_SIZE: 1893ae8c6e27Sflorian { 1894ae8c6e27Sflorian uint8_t digest[SHA256_DIGEST_SIZE]; 1895ae8c6e27Sflorian res = _digest_nettle(SHA256_DIGEST_SIZE, (unsigned char*)sldns_buffer_begin(buf), 1896ae8c6e27Sflorian (unsigned int)sldns_buffer_limit(buf), (unsigned char*)digest); 1897ae8c6e27Sflorian res &= rsa_sha256_verify_digest(&pubkey, digest, signature); 1898ae8c6e27Sflorian break; 1899ae8c6e27Sflorian } 1900ae8c6e27Sflorian case SHA512_DIGEST_SIZE: 1901ae8c6e27Sflorian { 1902ae8c6e27Sflorian uint8_t digest[SHA512_DIGEST_SIZE]; 1903ae8c6e27Sflorian res = _digest_nettle(SHA512_DIGEST_SIZE, (unsigned char*)sldns_buffer_begin(buf), 1904ae8c6e27Sflorian (unsigned int)sldns_buffer_limit(buf), (unsigned char*)digest); 1905ae8c6e27Sflorian res &= rsa_sha512_verify_digest(&pubkey, digest, signature); 1906ae8c6e27Sflorian break; 1907ae8c6e27Sflorian } 1908ae8c6e27Sflorian default: 1909ae8c6e27Sflorian break; 1910ae8c6e27Sflorian } 1911ae8c6e27Sflorian 1912ae8c6e27Sflorian /* Clear and return */ 1913ae8c6e27Sflorian nettle_rsa_public_key_clear(&pubkey); 1914ae8c6e27Sflorian mpz_clear(signature); 1915ae8c6e27Sflorian if (!res) { 1916ae8c6e27Sflorian return "RSA signature verification failed"; 1917ae8c6e27Sflorian } else { 1918ae8c6e27Sflorian return NULL; 1919ae8c6e27Sflorian } 1920ae8c6e27Sflorian } 1921ae8c6e27Sflorian 1922ae8c6e27Sflorian #ifdef USE_ECDSA 1923ae8c6e27Sflorian static char * 1924ae8c6e27Sflorian _verify_nettle_ecdsa(sldns_buffer* buf, unsigned int digest_size, unsigned char* sigblock, 1925ae8c6e27Sflorian unsigned int sigblock_len, unsigned char* key, unsigned int keylen) 1926ae8c6e27Sflorian { 1927ae8c6e27Sflorian int res = 0; 1928ae8c6e27Sflorian struct ecc_point pubkey; 1929ae8c6e27Sflorian struct dsa_signature signature; 1930ae8c6e27Sflorian 1931ae8c6e27Sflorian /* Always matched strength, as per RFC 6605 sec. 1 */ 1932ae8c6e27Sflorian if (sigblock_len != 2*digest_size || keylen != 2*digest_size) { 1933ae8c6e27Sflorian return "wrong ECDSA signature length"; 1934ae8c6e27Sflorian } 1935ae8c6e27Sflorian 1936ae8c6e27Sflorian /* Parse ECDSA signature as per RFC 6605 sec. 4 */ 1937ae8c6e27Sflorian nettle_dsa_signature_init(&signature); 1938ae8c6e27Sflorian switch (digest_size) { 1939ae8c6e27Sflorian case SHA256_DIGEST_SIZE: 1940ae8c6e27Sflorian { 1941ae8c6e27Sflorian uint8_t digest[SHA256_DIGEST_SIZE]; 1942ae8c6e27Sflorian mpz_t x, y; 194357403691Sflorian nettle_ecc_point_init(&pubkey, nettle_get_secp_256r1()); 1944ae8c6e27Sflorian nettle_mpz_init_set_str_256_u(x, SHA256_DIGEST_SIZE, key); 1945ae8c6e27Sflorian nettle_mpz_init_set_str_256_u(y, SHA256_DIGEST_SIZE, key+SHA256_DIGEST_SIZE); 1946ae8c6e27Sflorian nettle_mpz_set_str_256_u(signature.r, SHA256_DIGEST_SIZE, sigblock); 1947ae8c6e27Sflorian nettle_mpz_set_str_256_u(signature.s, SHA256_DIGEST_SIZE, sigblock+SHA256_DIGEST_SIZE); 1948ae8c6e27Sflorian res = _digest_nettle(SHA256_DIGEST_SIZE, (unsigned char*)sldns_buffer_begin(buf), 1949ae8c6e27Sflorian (unsigned int)sldns_buffer_limit(buf), (unsigned char*)digest); 1950ae8c6e27Sflorian res &= nettle_ecc_point_set(&pubkey, x, y); 1951ae8c6e27Sflorian res &= nettle_ecdsa_verify (&pubkey, SHA256_DIGEST_SIZE, digest, &signature); 1952ae8c6e27Sflorian mpz_clear(x); 1953ae8c6e27Sflorian mpz_clear(y); 1954e47fef9eSflorian nettle_ecc_point_clear(&pubkey); 1955ae8c6e27Sflorian break; 1956ae8c6e27Sflorian } 1957ae8c6e27Sflorian case SHA384_DIGEST_SIZE: 1958ae8c6e27Sflorian { 1959ae8c6e27Sflorian uint8_t digest[SHA384_DIGEST_SIZE]; 1960ae8c6e27Sflorian mpz_t x, y; 196157403691Sflorian nettle_ecc_point_init(&pubkey, nettle_get_secp_384r1()); 1962ae8c6e27Sflorian nettle_mpz_init_set_str_256_u(x, SHA384_DIGEST_SIZE, key); 1963ae8c6e27Sflorian nettle_mpz_init_set_str_256_u(y, SHA384_DIGEST_SIZE, key+SHA384_DIGEST_SIZE); 1964ae8c6e27Sflorian nettle_mpz_set_str_256_u(signature.r, SHA384_DIGEST_SIZE, sigblock); 1965ae8c6e27Sflorian nettle_mpz_set_str_256_u(signature.s, SHA384_DIGEST_SIZE, sigblock+SHA384_DIGEST_SIZE); 1966ae8c6e27Sflorian res = _digest_nettle(SHA384_DIGEST_SIZE, (unsigned char*)sldns_buffer_begin(buf), 1967ae8c6e27Sflorian (unsigned int)sldns_buffer_limit(buf), (unsigned char*)digest); 1968ae8c6e27Sflorian res &= nettle_ecc_point_set(&pubkey, x, y); 1969ae8c6e27Sflorian res &= nettle_ecdsa_verify (&pubkey, SHA384_DIGEST_SIZE, digest, &signature); 1970ae8c6e27Sflorian mpz_clear(x); 1971ae8c6e27Sflorian mpz_clear(y); 1972ae8c6e27Sflorian nettle_ecc_point_clear(&pubkey); 1973ae8c6e27Sflorian break; 1974ae8c6e27Sflorian } 1975ae8c6e27Sflorian default: 1976ae8c6e27Sflorian return "unknown ECDSA algorithm"; 1977ae8c6e27Sflorian } 1978ae8c6e27Sflorian 1979ae8c6e27Sflorian /* Clear and return */ 1980ae8c6e27Sflorian nettle_dsa_signature_clear(&signature); 1981ae8c6e27Sflorian if (!res) 1982ae8c6e27Sflorian return "ECDSA signature verification failed"; 1983ae8c6e27Sflorian else 1984ae8c6e27Sflorian return NULL; 1985ae8c6e27Sflorian } 1986ae8c6e27Sflorian #endif 1987ae8c6e27Sflorian 1988ae8c6e27Sflorian #ifdef USE_ED25519 1989ae8c6e27Sflorian static char * 1990ae8c6e27Sflorian _verify_nettle_ed25519(sldns_buffer* buf, unsigned char* sigblock, 1991ae8c6e27Sflorian unsigned int sigblock_len, unsigned char* key, unsigned int keylen) 1992ae8c6e27Sflorian { 1993ae8c6e27Sflorian int res = 0; 1994ae8c6e27Sflorian 1995ae8c6e27Sflorian if(sigblock_len != ED25519_SIGNATURE_SIZE) { 1996ae8c6e27Sflorian return "wrong ED25519 signature length"; 1997ae8c6e27Sflorian } 1998ae8c6e27Sflorian if(keylen != ED25519_KEY_SIZE) { 1999ae8c6e27Sflorian return "wrong ED25519 key length"; 2000ae8c6e27Sflorian } 2001ae8c6e27Sflorian 2002ae8c6e27Sflorian res = ed25519_sha512_verify((uint8_t*)key, sldns_buffer_limit(buf), 2003ae8c6e27Sflorian sldns_buffer_begin(buf), (uint8_t*)sigblock); 2004ae8c6e27Sflorian 2005ae8c6e27Sflorian if (!res) 2006ae8c6e27Sflorian return "ED25519 signature verification failed"; 2007ae8c6e27Sflorian else 2008ae8c6e27Sflorian return NULL; 2009ae8c6e27Sflorian } 2010ae8c6e27Sflorian #endif 2011ae8c6e27Sflorian 2012ae8c6e27Sflorian /** 2013ae8c6e27Sflorian * Check a canonical sig+rrset and signature against a dnskey 2014ae8c6e27Sflorian * @param buf: buffer with data to verify, the first rrsig part and the 2015ae8c6e27Sflorian * canonicalized rrset. 2016ae8c6e27Sflorian * @param algo: DNSKEY algorithm. 2017ae8c6e27Sflorian * @param sigblock: signature rdata field from RRSIG 2018ae8c6e27Sflorian * @param sigblock_len: length of sigblock data. 2019ae8c6e27Sflorian * @param key: public key data from DNSKEY RR. 2020ae8c6e27Sflorian * @param keylen: length of keydata. 2021ae8c6e27Sflorian * @param reason: bogus reason in more detail. 2022ae8c6e27Sflorian * @return secure if verification succeeded, bogus on crypto failure, 2023ae8c6e27Sflorian * unchecked on format errors and alloc failures. 2024ae8c6e27Sflorian */ 2025ae8c6e27Sflorian enum sec_status 2026ae8c6e27Sflorian verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock, 2027ae8c6e27Sflorian unsigned int sigblock_len, unsigned char* key, unsigned int keylen, 2028ae8c6e27Sflorian char** reason) 2029ae8c6e27Sflorian { 2030ae8c6e27Sflorian unsigned int digest_size = 0; 2031ae8c6e27Sflorian 2032ae8c6e27Sflorian if (sigblock_len == 0 || keylen == 0) { 2033ae8c6e27Sflorian *reason = "null signature"; 2034ae8c6e27Sflorian return sec_status_bogus; 2035ae8c6e27Sflorian } 2036ae8c6e27Sflorian 2037d32eb43cSflorian #ifndef USE_DSA 2038d32eb43cSflorian if((algo == LDNS_DSA || algo == LDNS_DSA_NSEC3) &&(fake_dsa||fake_sha1)) 2039d32eb43cSflorian return sec_status_secure; 2040d32eb43cSflorian #endif 2041d32eb43cSflorian #ifndef USE_SHA1 2042d32eb43cSflorian if(fake_sha1 && (algo == LDNS_DSA || algo == LDNS_DSA_NSEC3 || algo == LDNS_RSASHA1 || algo == LDNS_RSASHA1_NSEC3)) 2043d32eb43cSflorian return sec_status_secure; 2044d32eb43cSflorian #endif 2045d32eb43cSflorian 2046ae8c6e27Sflorian switch(algo) { 2047ae8c6e27Sflorian #if defined(USE_DSA) && defined(USE_SHA1) 2048ae8c6e27Sflorian case LDNS_DSA: 2049ae8c6e27Sflorian case LDNS_DSA_NSEC3: 2050ae8c6e27Sflorian *reason = _verify_nettle_dsa(buf, sigblock, sigblock_len, key, keylen); 2051ae8c6e27Sflorian if (*reason != NULL) 2052ae8c6e27Sflorian return sec_status_bogus; 2053ae8c6e27Sflorian else 2054ae8c6e27Sflorian return sec_status_secure; 2055ae8c6e27Sflorian #endif /* USE_DSA */ 2056ae8c6e27Sflorian 2057ae8c6e27Sflorian #ifdef USE_SHA1 2058ae8c6e27Sflorian case LDNS_RSASHA1: 2059ae8c6e27Sflorian case LDNS_RSASHA1_NSEC3: 2060ae8c6e27Sflorian digest_size = (digest_size ? digest_size : SHA1_DIGEST_SIZE); 2061ae8c6e27Sflorian #endif 2062ae8c6e27Sflorian /* double fallthrough annotation to please gcc parser */ 2063*7037e34cSflorian ATTR_FALLTHROUGH 2064ae8c6e27Sflorian /* fallthrough */ 2065ae8c6e27Sflorian #ifdef USE_SHA2 2066ae8c6e27Sflorian /* fallthrough */ 2067ae8c6e27Sflorian case LDNS_RSASHA256: 2068ae8c6e27Sflorian digest_size = (digest_size ? digest_size : SHA256_DIGEST_SIZE); 2069*7037e34cSflorian ATTR_FALLTHROUGH 2070ae8c6e27Sflorian /* fallthrough */ 2071ae8c6e27Sflorian case LDNS_RSASHA512: 2072ae8c6e27Sflorian digest_size = (digest_size ? digest_size : SHA512_DIGEST_SIZE); 2073ae8c6e27Sflorian 2074ae8c6e27Sflorian #endif 2075ae8c6e27Sflorian *reason = _verify_nettle_rsa(buf, digest_size, (char*)sigblock, 2076ae8c6e27Sflorian sigblock_len, key, keylen); 2077ae8c6e27Sflorian if (*reason != NULL) 2078ae8c6e27Sflorian return sec_status_bogus; 2079ae8c6e27Sflorian else 2080ae8c6e27Sflorian return sec_status_secure; 2081ae8c6e27Sflorian 2082ae8c6e27Sflorian #ifdef USE_ECDSA 2083ae8c6e27Sflorian case LDNS_ECDSAP256SHA256: 2084ae8c6e27Sflorian digest_size = (digest_size ? digest_size : SHA256_DIGEST_SIZE); 2085*7037e34cSflorian ATTR_FALLTHROUGH 2086ae8c6e27Sflorian /* fallthrough */ 2087ae8c6e27Sflorian case LDNS_ECDSAP384SHA384: 2088ae8c6e27Sflorian digest_size = (digest_size ? digest_size : SHA384_DIGEST_SIZE); 2089ae8c6e27Sflorian *reason = _verify_nettle_ecdsa(buf, digest_size, sigblock, 2090ae8c6e27Sflorian sigblock_len, key, keylen); 2091ae8c6e27Sflorian if (*reason != NULL) 2092ae8c6e27Sflorian return sec_status_bogus; 2093ae8c6e27Sflorian else 2094ae8c6e27Sflorian return sec_status_secure; 2095ae8c6e27Sflorian #endif 2096ae8c6e27Sflorian #ifdef USE_ED25519 2097ae8c6e27Sflorian case LDNS_ED25519: 2098ae8c6e27Sflorian *reason = _verify_nettle_ed25519(buf, sigblock, sigblock_len, 2099ae8c6e27Sflorian key, keylen); 2100ae8c6e27Sflorian if (*reason != NULL) 2101ae8c6e27Sflorian return sec_status_bogus; 2102ae8c6e27Sflorian else 2103ae8c6e27Sflorian return sec_status_secure; 2104ae8c6e27Sflorian #endif 2105ae8c6e27Sflorian case LDNS_RSAMD5: 2106ae8c6e27Sflorian case LDNS_ECC_GOST: 2107ae8c6e27Sflorian default: 2108ae8c6e27Sflorian *reason = "unable to verify signature, unknown algorithm"; 2109ae8c6e27Sflorian return sec_status_bogus; 2110ae8c6e27Sflorian } 2111ae8c6e27Sflorian } 2112ae8c6e27Sflorian 2113ae8c6e27Sflorian #endif /* HAVE_SSL or HAVE_NSS or HAVE_NETTLE */ 2114