18ed2b524SDag-Erling Smørgrav /* 28ed2b524SDag-Erling Smørgrav * validator/val_secalgo.c - validator security algorithm functions. 38ed2b524SDag-Erling Smørgrav * 48ed2b524SDag-Erling Smørgrav * Copyright (c) 2012, NLnet Labs. All rights reserved. 58ed2b524SDag-Erling Smørgrav * 68ed2b524SDag-Erling Smørgrav * This software is open source. 78ed2b524SDag-Erling Smørgrav * 88ed2b524SDag-Erling Smørgrav * Redistribution and use in source and binary forms, with or without 98ed2b524SDag-Erling Smørgrav * modification, are permitted provided that the following conditions 108ed2b524SDag-Erling Smørgrav * are met: 118ed2b524SDag-Erling Smørgrav * 128ed2b524SDag-Erling Smørgrav * Redistributions of source code must retain the above copyright notice, 138ed2b524SDag-Erling Smørgrav * this list of conditions and the following disclaimer. 148ed2b524SDag-Erling Smørgrav * 158ed2b524SDag-Erling Smørgrav * Redistributions in binary form must reproduce the above copyright notice, 168ed2b524SDag-Erling Smørgrav * this list of conditions and the following disclaimer in the documentation 178ed2b524SDag-Erling Smørgrav * and/or other materials provided with the distribution. 188ed2b524SDag-Erling Smørgrav * 198ed2b524SDag-Erling Smørgrav * Neither the name of the NLNET LABS nor the names of its contributors may 208ed2b524SDag-Erling Smørgrav * be used to endorse or promote products derived from this software without 218ed2b524SDag-Erling Smørgrav * specific prior written permission. 228ed2b524SDag-Erling Smørgrav * 238ed2b524SDag-Erling Smørgrav * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2417d15b25SDag-Erling Smørgrav * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2517d15b25SDag-Erling Smørgrav * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2617d15b25SDag-Erling Smørgrav * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2717d15b25SDag-Erling Smørgrav * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2817d15b25SDag-Erling Smørgrav * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 2917d15b25SDag-Erling Smørgrav * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 3017d15b25SDag-Erling Smørgrav * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 3117d15b25SDag-Erling Smørgrav * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 3217d15b25SDag-Erling Smørgrav * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 3317d15b25SDag-Erling Smørgrav * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 348ed2b524SDag-Erling Smørgrav */ 358ed2b524SDag-Erling Smørgrav 368ed2b524SDag-Erling Smørgrav /** 378ed2b524SDag-Erling Smørgrav * \file 388ed2b524SDag-Erling Smørgrav * 398ed2b524SDag-Erling Smørgrav * This file contains helper functions for the validator module. 408ed2b524SDag-Erling Smørgrav * These functions take raw data buffers, formatted for crypto verification, 418ed2b524SDag-Erling Smørgrav * and do the library calls (for the crypto library in use). 428ed2b524SDag-Erling Smørgrav */ 438ed2b524SDag-Erling Smørgrav #include "config.h" 446480faa8SDag-Erling Smørgrav /* packed_rrset on top to define enum types (forced by c99 standard) */ 458ed2b524SDag-Erling Smørgrav #include "util/data/packed_rrset.h" 466480faa8SDag-Erling Smørgrav #include "validator/val_secalgo.h" 4705ab2901SDag-Erling Smørgrav #include "validator/val_nsec3.h" 488ed2b524SDag-Erling Smørgrav #include "util/log.h" 4909a3aaf3SDag-Erling Smørgrav #include "sldns/rrdef.h" 5009a3aaf3SDag-Erling Smørgrav #include "sldns/keyraw.h" 5109a3aaf3SDag-Erling Smørgrav #include "sldns/sbuffer.h" 528ed2b524SDag-Erling Smørgrav 5305ab2901SDag-Erling Smørgrav #if !defined(HAVE_SSL) && !defined(HAVE_NSS) && !defined(HAVE_NETTLE) 548ed2b524SDag-Erling Smørgrav #error "Need crypto library to do digital signature cryptography" 558ed2b524SDag-Erling Smørgrav #endif 568ed2b524SDag-Erling Smørgrav 578ed2b524SDag-Erling Smørgrav /* OpenSSL implementation */ 588ed2b524SDag-Erling Smørgrav #ifdef HAVE_SSL 598ed2b524SDag-Erling Smørgrav #ifdef HAVE_OPENSSL_ERR_H 608ed2b524SDag-Erling Smørgrav #include <openssl/err.h> 618ed2b524SDag-Erling Smørgrav #endif 628ed2b524SDag-Erling Smørgrav 638ed2b524SDag-Erling Smørgrav #ifdef HAVE_OPENSSL_RAND_H 648ed2b524SDag-Erling Smørgrav #include <openssl/rand.h> 658ed2b524SDag-Erling Smørgrav #endif 668ed2b524SDag-Erling Smørgrav 678ed2b524SDag-Erling Smørgrav #ifdef HAVE_OPENSSL_CONF_H 688ed2b524SDag-Erling Smørgrav #include <openssl/conf.h> 698ed2b524SDag-Erling Smørgrav #endif 708ed2b524SDag-Erling Smørgrav 718ed2b524SDag-Erling Smørgrav #ifdef HAVE_OPENSSL_ENGINE_H 728ed2b524SDag-Erling Smørgrav #include <openssl/engine.h> 738ed2b524SDag-Erling Smørgrav #endif 748ed2b524SDag-Erling Smørgrav 75bc892140SDag-Erling Smørgrav /** fake DSA support for unit tests */ 76bc892140SDag-Erling Smørgrav int fake_dsa = 0; 7765b390aaSDag-Erling Smørgrav /** fake SHA1 support for unit tests */ 7865b390aaSDag-Erling Smørgrav int fake_sha1 = 0; 79bc892140SDag-Erling Smørgrav 80a755b6f6SDag-Erling Smørgrav /** 81a755b6f6SDag-Erling Smørgrav * Output a libcrypto openssl error to the logfile. 82a755b6f6SDag-Erling Smørgrav * @param str: string to add to it. 83a755b6f6SDag-Erling Smørgrav * @param e: the error to output, error number from ERR_get_error(). 84a755b6f6SDag-Erling Smørgrav */ 85a755b6f6SDag-Erling Smørgrav static void 86a755b6f6SDag-Erling Smørgrav log_crypto_error(const char* str, unsigned long e) 87a755b6f6SDag-Erling Smørgrav { 88a755b6f6SDag-Erling Smørgrav char buf[128]; 89a755b6f6SDag-Erling Smørgrav /* or use ERR_error_string if ERR_error_string_n is not avail TODO */ 90a755b6f6SDag-Erling Smørgrav ERR_error_string_n(e, buf, sizeof(buf)); 91a755b6f6SDag-Erling Smørgrav /* buf now contains */ 92a755b6f6SDag-Erling Smørgrav /* error:[error code]:[library name]:[function name]:[reason string] */ 93a755b6f6SDag-Erling Smørgrav log_err("%s crypto %s", str, buf); 94a755b6f6SDag-Erling Smørgrav } 95a755b6f6SDag-Erling Smørgrav 9605ab2901SDag-Erling Smørgrav /* return size of digest if supported, or 0 otherwise */ 9705ab2901SDag-Erling Smørgrav size_t 9805ab2901SDag-Erling Smørgrav nsec3_hash_algo_size_supported(int id) 9905ab2901SDag-Erling Smørgrav { 10005ab2901SDag-Erling Smørgrav switch(id) { 10105ab2901SDag-Erling Smørgrav case NSEC3_HASH_SHA1: 10205ab2901SDag-Erling Smørgrav return SHA_DIGEST_LENGTH; 10305ab2901SDag-Erling Smørgrav default: 10405ab2901SDag-Erling Smørgrav return 0; 10505ab2901SDag-Erling Smørgrav } 10605ab2901SDag-Erling Smørgrav } 10705ab2901SDag-Erling Smørgrav 10805ab2901SDag-Erling Smørgrav /* perform nsec3 hash. return false on failure */ 10905ab2901SDag-Erling Smørgrav int 11005ab2901SDag-Erling Smørgrav secalgo_nsec3_hash(int algo, unsigned char* buf, size_t len, 11105ab2901SDag-Erling Smørgrav unsigned char* res) 11205ab2901SDag-Erling Smørgrav { 11305ab2901SDag-Erling Smørgrav switch(algo) { 11405ab2901SDag-Erling Smørgrav case NSEC3_HASH_SHA1: 115a755b6f6SDag-Erling Smørgrav #ifdef OPENSSL_FIPS 116a755b6f6SDag-Erling Smørgrav if(!sldns_digest_evp(buf, len, res, EVP_sha1())) 117a755b6f6SDag-Erling Smørgrav log_crypto_error("could not digest with EVP_sha1", 118a755b6f6SDag-Erling Smørgrav ERR_get_error()); 119a755b6f6SDag-Erling Smørgrav #else 12005ab2901SDag-Erling Smørgrav (void)SHA1(buf, len, res); 121a755b6f6SDag-Erling Smørgrav #endif 12205ab2901SDag-Erling Smørgrav return 1; 12305ab2901SDag-Erling Smørgrav default: 12405ab2901SDag-Erling Smørgrav return 0; 12505ab2901SDag-Erling Smørgrav } 12605ab2901SDag-Erling Smørgrav } 12705ab2901SDag-Erling Smørgrav 128e2d15004SDag-Erling Smørgrav void 129e2d15004SDag-Erling Smørgrav secalgo_hash_sha256(unsigned char* buf, size_t len, unsigned char* res) 130e2d15004SDag-Erling Smørgrav { 131a755b6f6SDag-Erling Smørgrav #ifdef OPENSSL_FIPS 132a755b6f6SDag-Erling Smørgrav if(!sldns_digest_evp(buf, len, res, EVP_sha256())) 133a755b6f6SDag-Erling Smørgrav log_crypto_error("could not digest with EVP_sha256", 134a755b6f6SDag-Erling Smørgrav ERR_get_error()); 135a755b6f6SDag-Erling Smørgrav #else 136e2d15004SDag-Erling Smørgrav (void)SHA256(buf, len, res); 137a755b6f6SDag-Erling Smørgrav #endif 138e2d15004SDag-Erling Smørgrav } 139e2d15004SDag-Erling Smørgrav 1408ed2b524SDag-Erling Smørgrav /** 1418ed2b524SDag-Erling Smørgrav * Return size of DS digest according to its hash algorithm. 1428ed2b524SDag-Erling Smørgrav * @param algo: DS digest algo. 1438ed2b524SDag-Erling Smørgrav * @return size in bytes of digest, or 0 if not supported. 1448ed2b524SDag-Erling Smørgrav */ 1458ed2b524SDag-Erling Smørgrav size_t 1468ed2b524SDag-Erling Smørgrav ds_digest_size_supported(int algo) 1478ed2b524SDag-Erling Smørgrav { 1488ed2b524SDag-Erling Smørgrav switch(algo) { 1498ed2b524SDag-Erling Smørgrav case LDNS_SHA1: 15065b390aaSDag-Erling Smørgrav #if defined(HAVE_EVP_SHA1) && defined(USE_SHA1) 1518ed2b524SDag-Erling Smørgrav return SHA_DIGEST_LENGTH; 15265b390aaSDag-Erling Smørgrav #else 15365b390aaSDag-Erling Smørgrav if(fake_sha1) return 20; 15465b390aaSDag-Erling Smørgrav return 0; 1558ed2b524SDag-Erling Smørgrav #endif 1568ed2b524SDag-Erling Smørgrav #ifdef HAVE_EVP_SHA256 1578ed2b524SDag-Erling Smørgrav case LDNS_SHA256: 1588ed2b524SDag-Erling Smørgrav return SHA256_DIGEST_LENGTH; 1598ed2b524SDag-Erling Smørgrav #endif 1608ed2b524SDag-Erling Smørgrav #ifdef USE_GOST 1618ed2b524SDag-Erling Smørgrav case LDNS_HASH_GOST: 162f61ef7f6SDag-Erling Smørgrav /* we support GOST if it can be loaded */ 163f61ef7f6SDag-Erling Smørgrav (void)sldns_key_EVP_load_gost_id(); 1648ed2b524SDag-Erling Smørgrav if(EVP_get_digestbyname("md_gost94")) 1658ed2b524SDag-Erling Smørgrav return 32; 1668ed2b524SDag-Erling Smørgrav else return 0; 1678ed2b524SDag-Erling Smørgrav #endif 1688ed2b524SDag-Erling Smørgrav #ifdef USE_ECDSA 1698ed2b524SDag-Erling Smørgrav case LDNS_SHA384: 1708ed2b524SDag-Erling Smørgrav return SHA384_DIGEST_LENGTH; 1718ed2b524SDag-Erling Smørgrav #endif 1728ed2b524SDag-Erling Smørgrav default: break; 1738ed2b524SDag-Erling Smørgrav } 1748ed2b524SDag-Erling Smørgrav return 0; 1758ed2b524SDag-Erling Smørgrav } 1768ed2b524SDag-Erling Smørgrav 1778ed2b524SDag-Erling Smørgrav #ifdef USE_GOST 1788ed2b524SDag-Erling Smørgrav /** Perform GOST hash */ 1798ed2b524SDag-Erling Smørgrav static int 1808ed2b524SDag-Erling Smørgrav do_gost94(unsigned char* data, size_t len, unsigned char* dest) 1818ed2b524SDag-Erling Smørgrav { 1828ed2b524SDag-Erling Smørgrav const EVP_MD* md = EVP_get_digestbyname("md_gost94"); 1838ed2b524SDag-Erling Smørgrav if(!md) 1848ed2b524SDag-Erling Smørgrav return 0; 18517d15b25SDag-Erling Smørgrav return sldns_digest_evp(data, (unsigned int)len, dest, md); 1868ed2b524SDag-Erling Smørgrav } 1878ed2b524SDag-Erling Smørgrav #endif 1888ed2b524SDag-Erling Smørgrav 1898ed2b524SDag-Erling Smørgrav int 1908ed2b524SDag-Erling Smørgrav secalgo_ds_digest(int algo, unsigned char* buf, size_t len, 1918ed2b524SDag-Erling Smørgrav unsigned char* res) 1928ed2b524SDag-Erling Smørgrav { 1938ed2b524SDag-Erling Smørgrav switch(algo) { 19465b390aaSDag-Erling Smørgrav #if defined(HAVE_EVP_SHA1) && defined(USE_SHA1) 1958ed2b524SDag-Erling Smørgrav case LDNS_SHA1: 196a755b6f6SDag-Erling Smørgrav #ifdef OPENSSL_FIPS 197a755b6f6SDag-Erling Smørgrav if(!sldns_digest_evp(buf, len, res, EVP_sha1())) 198a755b6f6SDag-Erling Smørgrav log_crypto_error("could not digest with EVP_sha1", 199a755b6f6SDag-Erling Smørgrav ERR_get_error()); 200a755b6f6SDag-Erling Smørgrav #else 2018ed2b524SDag-Erling Smørgrav (void)SHA1(buf, len, res); 202a755b6f6SDag-Erling Smørgrav #endif 2038ed2b524SDag-Erling Smørgrav return 1; 2048ed2b524SDag-Erling Smørgrav #endif 2058ed2b524SDag-Erling Smørgrav #ifdef HAVE_EVP_SHA256 2068ed2b524SDag-Erling Smørgrav case LDNS_SHA256: 207a755b6f6SDag-Erling Smørgrav #ifdef OPENSSL_FIPS 208a755b6f6SDag-Erling Smørgrav if(!sldns_digest_evp(buf, len, res, EVP_sha256())) 209a755b6f6SDag-Erling Smørgrav log_crypto_error("could not digest with EVP_sha256", 210a755b6f6SDag-Erling Smørgrav ERR_get_error()); 211a755b6f6SDag-Erling Smørgrav #else 2128ed2b524SDag-Erling Smørgrav (void)SHA256(buf, len, res); 213a755b6f6SDag-Erling Smørgrav #endif 2148ed2b524SDag-Erling Smørgrav return 1; 2158ed2b524SDag-Erling Smørgrav #endif 2168ed2b524SDag-Erling Smørgrav #ifdef USE_GOST 2178ed2b524SDag-Erling Smørgrav case LDNS_HASH_GOST: 2188ed2b524SDag-Erling Smørgrav if(do_gost94(buf, len, res)) 2198ed2b524SDag-Erling Smørgrav return 1; 2208ed2b524SDag-Erling Smørgrav break; 2218ed2b524SDag-Erling Smørgrav #endif 2228ed2b524SDag-Erling Smørgrav #ifdef USE_ECDSA 2238ed2b524SDag-Erling Smørgrav case LDNS_SHA384: 224a755b6f6SDag-Erling Smørgrav #ifdef OPENSSL_FIPS 225a755b6f6SDag-Erling Smørgrav if(!sldns_digest_evp(buf, len, res, EVP_sha384())) 226a755b6f6SDag-Erling Smørgrav log_crypto_error("could not digest with EVP_sha384", 227a755b6f6SDag-Erling Smørgrav ERR_get_error()); 228a755b6f6SDag-Erling Smørgrav #else 2298ed2b524SDag-Erling Smørgrav (void)SHA384(buf, len, res); 230a755b6f6SDag-Erling Smørgrav #endif 2318ed2b524SDag-Erling Smørgrav return 1; 2328ed2b524SDag-Erling Smørgrav #endif 2338ed2b524SDag-Erling Smørgrav default: 2348ed2b524SDag-Erling Smørgrav verbose(VERB_QUERY, "unknown DS digest algorithm %d", 2358ed2b524SDag-Erling Smørgrav algo); 2368ed2b524SDag-Erling Smørgrav break; 2378ed2b524SDag-Erling Smørgrav } 2388ed2b524SDag-Erling Smørgrav return 0; 2398ed2b524SDag-Erling Smørgrav } 2408ed2b524SDag-Erling Smørgrav 2418ed2b524SDag-Erling Smørgrav /** return true if DNSKEY algorithm id is supported */ 2428ed2b524SDag-Erling Smørgrav int 2438ed2b524SDag-Erling Smørgrav dnskey_algo_id_is_supported(int id) 2448ed2b524SDag-Erling Smørgrav { 2458ed2b524SDag-Erling Smørgrav switch(id) { 2468ed2b524SDag-Erling Smørgrav case LDNS_RSAMD5: 2478ed2b524SDag-Erling Smørgrav /* RFC 6725 deprecates RSAMD5 */ 2488ed2b524SDag-Erling Smørgrav return 0; 2498ed2b524SDag-Erling Smørgrav case LDNS_DSA: 2508ed2b524SDag-Erling Smørgrav case LDNS_DSA_NSEC3: 25165b390aaSDag-Erling Smørgrav #if defined(USE_DSA) && defined(USE_SHA1) 252bc892140SDag-Erling Smørgrav return 1; 253bc892140SDag-Erling Smørgrav #else 25465b390aaSDag-Erling Smørgrav if(fake_dsa || fake_sha1) return 1; 255bc892140SDag-Erling Smørgrav return 0; 256e2d15004SDag-Erling Smørgrav #endif 25765b390aaSDag-Erling Smørgrav 2588ed2b524SDag-Erling Smørgrav case LDNS_RSASHA1: 2598ed2b524SDag-Erling Smørgrav case LDNS_RSASHA1_NSEC3: 26065b390aaSDag-Erling Smørgrav #ifdef USE_SHA1 26165b390aaSDag-Erling Smørgrav return 1; 26265b390aaSDag-Erling Smørgrav #else 26365b390aaSDag-Erling Smørgrav if(fake_sha1) return 1; 26465b390aaSDag-Erling Smørgrav return 0; 26565b390aaSDag-Erling Smørgrav #endif 26665b390aaSDag-Erling Smørgrav 2678ed2b524SDag-Erling Smørgrav #if defined(HAVE_EVP_SHA256) && defined(USE_SHA2) 2688ed2b524SDag-Erling Smørgrav case LDNS_RSASHA256: 2698ed2b524SDag-Erling Smørgrav #endif 2708ed2b524SDag-Erling Smørgrav #if defined(HAVE_EVP_SHA512) && defined(USE_SHA2) 2718ed2b524SDag-Erling Smørgrav case LDNS_RSASHA512: 2728ed2b524SDag-Erling Smørgrav #endif 2738ed2b524SDag-Erling Smørgrav #ifdef USE_ECDSA 2748ed2b524SDag-Erling Smørgrav case LDNS_ECDSAP256SHA256: 2758ed2b524SDag-Erling Smørgrav case LDNS_ECDSAP384SHA384: 2768ed2b524SDag-Erling Smørgrav #endif 277c7f4d7adSDag-Erling Smørgrav #ifdef USE_ED25519 278c7f4d7adSDag-Erling Smørgrav case LDNS_ED25519: 279c7f4d7adSDag-Erling Smørgrav #endif 2800fb34990SDag-Erling Smørgrav #ifdef USE_ED448 2810fb34990SDag-Erling Smørgrav case LDNS_ED448: 2820fb34990SDag-Erling Smørgrav #endif 2830fb34990SDag-Erling Smørgrav #if (defined(HAVE_EVP_SHA256) && defined(USE_SHA2)) || (defined(HAVE_EVP_SHA512) && defined(USE_SHA2)) || defined(USE_ECDSA) || defined(USE_ED25519) || defined(USE_ED448) 2848ed2b524SDag-Erling Smørgrav return 1; 28565b390aaSDag-Erling Smørgrav #endif 28665b390aaSDag-Erling Smørgrav 2878ed2b524SDag-Erling Smørgrav #ifdef USE_GOST 2888ed2b524SDag-Erling Smørgrav case LDNS_ECC_GOST: 2898ed2b524SDag-Erling Smørgrav /* we support GOST if it can be loaded */ 29017d15b25SDag-Erling Smørgrav return sldns_key_EVP_load_gost_id(); 2918ed2b524SDag-Erling Smørgrav #endif 2928ed2b524SDag-Erling Smørgrav default: 2938ed2b524SDag-Erling Smørgrav return 0; 2948ed2b524SDag-Erling Smørgrav } 2958ed2b524SDag-Erling Smørgrav } 2968ed2b524SDag-Erling Smørgrav 297e2d15004SDag-Erling Smørgrav #ifdef USE_DSA 2988ed2b524SDag-Erling Smørgrav /** 2998ed2b524SDag-Erling Smørgrav * Setup DSA key digest in DER encoding ... 3008ed2b524SDag-Erling Smørgrav * @param sig: input is signature output alloced ptr (unless failure). 3018ed2b524SDag-Erling Smørgrav * caller must free alloced ptr if this routine returns true. 3028ed2b524SDag-Erling Smørgrav * @param len: input is initial siglen, output is output len. 3038ed2b524SDag-Erling Smørgrav * @return false on failure. 3048ed2b524SDag-Erling Smørgrav */ 3058ed2b524SDag-Erling Smørgrav static int 3068ed2b524SDag-Erling Smørgrav setup_dsa_sig(unsigned char** sig, unsigned int* len) 3078ed2b524SDag-Erling Smørgrav { 3088ed2b524SDag-Erling Smørgrav unsigned char* orig = *sig; 3098ed2b524SDag-Erling Smørgrav unsigned int origlen = *len; 3108ed2b524SDag-Erling Smørgrav int newlen; 3118ed2b524SDag-Erling Smørgrav BIGNUM *R, *S; 3128ed2b524SDag-Erling Smørgrav DSA_SIG *dsasig; 3138ed2b524SDag-Erling Smørgrav 3148ed2b524SDag-Erling Smørgrav /* extract the R and S field from the sig buffer */ 3158ed2b524SDag-Erling Smørgrav if(origlen < 1 + 2*SHA_DIGEST_LENGTH) 3168ed2b524SDag-Erling Smørgrav return 0; 3178ed2b524SDag-Erling Smørgrav R = BN_new(); 3188ed2b524SDag-Erling Smørgrav if(!R) return 0; 3198ed2b524SDag-Erling Smørgrav (void) BN_bin2bn(orig + 1, SHA_DIGEST_LENGTH, R); 3208ed2b524SDag-Erling Smørgrav S = BN_new(); 3218ed2b524SDag-Erling Smørgrav if(!S) return 0; 3228ed2b524SDag-Erling Smørgrav (void) BN_bin2bn(orig + 21, SHA_DIGEST_LENGTH, S); 3238ed2b524SDag-Erling Smørgrav dsasig = DSA_SIG_new(); 3248ed2b524SDag-Erling Smørgrav if(!dsasig) return 0; 3258ed2b524SDag-Erling Smørgrav 326bc892140SDag-Erling Smørgrav #ifdef HAVE_DSA_SIG_SET0 327bc892140SDag-Erling Smørgrav if(!DSA_SIG_set0(dsasig, R, S)) return 0; 328bc892140SDag-Erling Smørgrav #else 329*0eefd307SCy Schubert # ifndef S_SPLINT_S 3308ed2b524SDag-Erling Smørgrav dsasig->r = R; 3318ed2b524SDag-Erling Smørgrav dsasig->s = S; 332*0eefd307SCy Schubert # endif /* S_SPLINT_S */ 333bc892140SDag-Erling Smørgrav #endif 3348ed2b524SDag-Erling Smørgrav *sig = NULL; 3358ed2b524SDag-Erling Smørgrav newlen = i2d_DSA_SIG(dsasig, sig); 3368ed2b524SDag-Erling Smørgrav if(newlen < 0) { 3378ed2b524SDag-Erling Smørgrav DSA_SIG_free(dsasig); 3388ed2b524SDag-Erling Smørgrav free(*sig); 3398ed2b524SDag-Erling Smørgrav return 0; 3408ed2b524SDag-Erling Smørgrav } 3418ed2b524SDag-Erling Smørgrav *len = (unsigned int)newlen; 3428ed2b524SDag-Erling Smørgrav DSA_SIG_free(dsasig); 3438ed2b524SDag-Erling Smørgrav return 1; 3448ed2b524SDag-Erling Smørgrav } 345e2d15004SDag-Erling Smørgrav #endif /* USE_DSA */ 3468ed2b524SDag-Erling Smørgrav 3478ed2b524SDag-Erling Smørgrav #ifdef USE_ECDSA 3488ed2b524SDag-Erling Smørgrav /** 3498ed2b524SDag-Erling Smørgrav * Setup the ECDSA signature in its encoding that the library wants. 3508ed2b524SDag-Erling Smørgrav * Converts from plain numbers to ASN formatted. 3518ed2b524SDag-Erling Smørgrav * @param sig: input is signature, output alloced ptr (unless failure). 3528ed2b524SDag-Erling Smørgrav * caller must free alloced ptr if this routine returns true. 3538ed2b524SDag-Erling Smørgrav * @param len: input is initial siglen, output is output len. 3548ed2b524SDag-Erling Smørgrav * @return false on failure. 3558ed2b524SDag-Erling Smørgrav */ 3568ed2b524SDag-Erling Smørgrav static int 3578ed2b524SDag-Erling Smørgrav setup_ecdsa_sig(unsigned char** sig, unsigned int* len) 3588ed2b524SDag-Erling Smørgrav { 359e2d15004SDag-Erling Smørgrav /* convert from two BIGNUMs in the rdata buffer, to ASN notation. 3608a384985SDag-Erling Smørgrav * ASN preamble: 30440220 <R 32bytefor256> 0220 <S 32bytefor256> 361e2d15004SDag-Erling Smørgrav * the '20' is the length of that field (=bnsize). 362e2d15004SDag-Erling Smørgrav i * the '44' is the total remaining length. 363e2d15004SDag-Erling Smørgrav * if negative, start with leading zero. 364e2d15004SDag-Erling Smørgrav * if starts with 00s, remove them from the number. 365e2d15004SDag-Erling Smørgrav */ 366e2d15004SDag-Erling Smørgrav uint8_t pre[] = {0x30, 0x44, 0x02, 0x20}; 367e2d15004SDag-Erling Smørgrav int pre_len = 4; 368e2d15004SDag-Erling Smørgrav uint8_t mid[] = {0x02, 0x20}; 369e2d15004SDag-Erling Smørgrav int mid_len = 2; 370e2d15004SDag-Erling Smørgrav int raw_sig_len, r_high, s_high, r_rem=0, s_rem=0; 3718ed2b524SDag-Erling Smørgrav int bnsize = (int)((*len)/2); 372e2d15004SDag-Erling Smørgrav unsigned char* d = *sig; 373e2d15004SDag-Erling Smørgrav uint8_t* p; 3748ed2b524SDag-Erling Smørgrav /* if too short or not even length, fails */ 3758ed2b524SDag-Erling Smørgrav if(*len < 16 || bnsize*2 != (int)*len) 3768ed2b524SDag-Erling Smørgrav return 0; 3778ed2b524SDag-Erling Smørgrav 378e2d15004SDag-Erling Smørgrav /* strip leading zeroes from r (but not last one) */ 379e2d15004SDag-Erling Smørgrav while(r_rem < bnsize-1 && d[r_rem] == 0) 380e2d15004SDag-Erling Smørgrav r_rem++; 381e2d15004SDag-Erling Smørgrav /* strip leading zeroes from s (but not last one) */ 382e2d15004SDag-Erling Smørgrav while(s_rem < bnsize-1 && d[bnsize+s_rem] == 0) 383e2d15004SDag-Erling Smørgrav s_rem++; 384e2d15004SDag-Erling Smørgrav 385e2d15004SDag-Erling Smørgrav r_high = ((d[0+r_rem]&0x80)?1:0); 386e2d15004SDag-Erling Smørgrav s_high = ((d[bnsize+s_rem]&0x80)?1:0); 387e2d15004SDag-Erling Smørgrav raw_sig_len = pre_len + r_high + bnsize - r_rem + mid_len + 388e2d15004SDag-Erling Smørgrav s_high + bnsize - s_rem; 389e2d15004SDag-Erling Smørgrav *sig = (unsigned char*)malloc((size_t)raw_sig_len); 390e2d15004SDag-Erling Smørgrav if(!*sig) 3918ed2b524SDag-Erling Smørgrav return 0; 392e2d15004SDag-Erling Smørgrav p = (uint8_t*)*sig; 393e2d15004SDag-Erling Smørgrav p[0] = pre[0]; 394e2d15004SDag-Erling Smørgrav p[1] = (uint8_t)(raw_sig_len-2); 395e2d15004SDag-Erling Smørgrav p[2] = pre[2]; 396e2d15004SDag-Erling Smørgrav p[3] = (uint8_t)(bnsize + r_high - r_rem); 397e2d15004SDag-Erling Smørgrav p += 4; 398e2d15004SDag-Erling Smørgrav if(r_high) { 399e2d15004SDag-Erling Smørgrav *p = 0; 400e2d15004SDag-Erling Smørgrav p += 1; 4018ed2b524SDag-Erling Smørgrav } 402e2d15004SDag-Erling Smørgrav memmove(p, d+r_rem, (size_t)bnsize-r_rem); 403e2d15004SDag-Erling Smørgrav p += bnsize-r_rem; 404e2d15004SDag-Erling Smørgrav memmove(p, mid, (size_t)mid_len-1); 405e2d15004SDag-Erling Smørgrav p += mid_len-1; 406e2d15004SDag-Erling Smørgrav *p = (uint8_t)(bnsize + s_high - s_rem); 407e2d15004SDag-Erling Smørgrav p += 1; 408e2d15004SDag-Erling Smørgrav if(s_high) { 409e2d15004SDag-Erling Smørgrav *p = 0; 410e2d15004SDag-Erling Smørgrav p += 1; 411e2d15004SDag-Erling Smørgrav } 412e2d15004SDag-Erling Smørgrav memmove(p, d+bnsize+s_rem, (size_t)bnsize-s_rem); 413e2d15004SDag-Erling Smørgrav *len = (unsigned int)raw_sig_len; 4148ed2b524SDag-Erling Smørgrav return 1; 4158ed2b524SDag-Erling Smørgrav } 4168ed2b524SDag-Erling Smørgrav #endif /* USE_ECDSA */ 4178ed2b524SDag-Erling Smørgrav 418b5663de9SDag-Erling Smørgrav #ifdef USE_ECDSA_EVP_WORKAROUND 419b5663de9SDag-Erling Smørgrav static EVP_MD ecdsa_evp_256_md; 420b5663de9SDag-Erling Smørgrav static EVP_MD ecdsa_evp_384_md; 421b5663de9SDag-Erling Smørgrav void ecdsa_evp_workaround_init(void) 422b5663de9SDag-Erling Smørgrav { 423b5663de9SDag-Erling Smørgrav /* openssl before 1.0.0 fixes RSA with the SHA256 424b5663de9SDag-Erling Smørgrav * hash in EVP. We create one for ecdsa_sha256 */ 425b5663de9SDag-Erling Smørgrav ecdsa_evp_256_md = *EVP_sha256(); 426b5663de9SDag-Erling Smørgrav ecdsa_evp_256_md.required_pkey_type[0] = EVP_PKEY_EC; 427b5663de9SDag-Erling Smørgrav ecdsa_evp_256_md.verify = (void*)ECDSA_verify; 428b5663de9SDag-Erling Smørgrav 429b5663de9SDag-Erling Smørgrav ecdsa_evp_384_md = *EVP_sha384(); 430b5663de9SDag-Erling Smørgrav ecdsa_evp_384_md.required_pkey_type[0] = EVP_PKEY_EC; 431b5663de9SDag-Erling Smørgrav ecdsa_evp_384_md.verify = (void*)ECDSA_verify; 432b5663de9SDag-Erling Smørgrav } 433b5663de9SDag-Erling Smørgrav #endif /* USE_ECDSA_EVP_WORKAROUND */ 434b5663de9SDag-Erling Smørgrav 4358ed2b524SDag-Erling Smørgrav /** 4368ed2b524SDag-Erling Smørgrav * Setup key and digest for verification. Adjust sig if necessary. 4378ed2b524SDag-Erling Smørgrav * 4388ed2b524SDag-Erling Smørgrav * @param algo: key algorithm 4398ed2b524SDag-Erling Smørgrav * @param evp_key: EVP PKEY public key to create. 4408ed2b524SDag-Erling Smørgrav * @param digest_type: digest type to use 4418ed2b524SDag-Erling Smørgrav * @param key: key to setup for. 4428ed2b524SDag-Erling Smørgrav * @param keylen: length of key. 4438ed2b524SDag-Erling Smørgrav * @return false on failure. 4448ed2b524SDag-Erling Smørgrav */ 4458ed2b524SDag-Erling Smørgrav static int 4468ed2b524SDag-Erling Smørgrav setup_key_digest(int algo, EVP_PKEY** evp_key, const EVP_MD** digest_type, 4478ed2b524SDag-Erling Smørgrav unsigned char* key, size_t keylen) 4488ed2b524SDag-Erling Smørgrav { 44965b390aaSDag-Erling Smørgrav #if defined(USE_DSA) && defined(USE_SHA1) 4508ed2b524SDag-Erling Smørgrav DSA* dsa; 451e2d15004SDag-Erling Smørgrav #endif 4528ed2b524SDag-Erling Smørgrav RSA* rsa; 4538ed2b524SDag-Erling Smørgrav 4548ed2b524SDag-Erling Smørgrav switch(algo) { 45565b390aaSDag-Erling Smørgrav #if defined(USE_DSA) && defined(USE_SHA1) 4568ed2b524SDag-Erling Smørgrav case LDNS_DSA: 4578ed2b524SDag-Erling Smørgrav case LDNS_DSA_NSEC3: 4588ed2b524SDag-Erling Smørgrav *evp_key = EVP_PKEY_new(); 4598ed2b524SDag-Erling Smørgrav if(!*evp_key) { 4608ed2b524SDag-Erling Smørgrav log_err("verify: malloc failure in crypto"); 4618ed2b524SDag-Erling Smørgrav return 0; 4628ed2b524SDag-Erling Smørgrav } 46317d15b25SDag-Erling Smørgrav dsa = sldns_key_buf2dsa_raw(key, keylen); 4648ed2b524SDag-Erling Smørgrav if(!dsa) { 4658ed2b524SDag-Erling Smørgrav verbose(VERB_QUERY, "verify: " 46617d15b25SDag-Erling Smørgrav "sldns_key_buf2dsa_raw failed"); 4678ed2b524SDag-Erling Smørgrav return 0; 4688ed2b524SDag-Erling Smørgrav } 4698ed2b524SDag-Erling Smørgrav if(EVP_PKEY_assign_DSA(*evp_key, dsa) == 0) { 4708ed2b524SDag-Erling Smørgrav verbose(VERB_QUERY, "verify: " 4718ed2b524SDag-Erling Smørgrav "EVP_PKEY_assign_DSA failed"); 4728ed2b524SDag-Erling Smørgrav return 0; 4738ed2b524SDag-Erling Smørgrav } 474bc892140SDag-Erling Smørgrav #ifdef HAVE_EVP_DSS1 4758ed2b524SDag-Erling Smørgrav *digest_type = EVP_dss1(); 476bc892140SDag-Erling Smørgrav #else 477bc892140SDag-Erling Smørgrav *digest_type = EVP_sha1(); 478bc892140SDag-Erling Smørgrav #endif 4798ed2b524SDag-Erling Smørgrav 4808ed2b524SDag-Erling Smørgrav break; 48165b390aaSDag-Erling Smørgrav #endif /* USE_DSA && USE_SHA1 */ 48265b390aaSDag-Erling Smørgrav 48365b390aaSDag-Erling Smørgrav #if defined(USE_SHA1) || (defined(HAVE_EVP_SHA256) && defined(USE_SHA2)) || (defined(HAVE_EVP_SHA512) && defined(USE_SHA2)) 48465b390aaSDag-Erling Smørgrav #ifdef USE_SHA1 4858ed2b524SDag-Erling Smørgrav case LDNS_RSASHA1: 4868ed2b524SDag-Erling Smørgrav case LDNS_RSASHA1_NSEC3: 48765b390aaSDag-Erling Smørgrav #endif 4888ed2b524SDag-Erling Smørgrav #if defined(HAVE_EVP_SHA256) && defined(USE_SHA2) 4898ed2b524SDag-Erling Smørgrav case LDNS_RSASHA256: 4908ed2b524SDag-Erling Smørgrav #endif 4918ed2b524SDag-Erling Smørgrav #if defined(HAVE_EVP_SHA512) && defined(USE_SHA2) 4928ed2b524SDag-Erling Smørgrav case LDNS_RSASHA512: 4938ed2b524SDag-Erling Smørgrav #endif 4948ed2b524SDag-Erling Smørgrav *evp_key = EVP_PKEY_new(); 4958ed2b524SDag-Erling Smørgrav if(!*evp_key) { 4968ed2b524SDag-Erling Smørgrav log_err("verify: malloc failure in crypto"); 4978ed2b524SDag-Erling Smørgrav return 0; 4988ed2b524SDag-Erling Smørgrav } 49917d15b25SDag-Erling Smørgrav rsa = sldns_key_buf2rsa_raw(key, keylen); 5008ed2b524SDag-Erling Smørgrav if(!rsa) { 5018ed2b524SDag-Erling Smørgrav verbose(VERB_QUERY, "verify: " 50217d15b25SDag-Erling Smørgrav "sldns_key_buf2rsa_raw SHA failed"); 5038ed2b524SDag-Erling Smørgrav return 0; 5048ed2b524SDag-Erling Smørgrav } 5058ed2b524SDag-Erling Smørgrav if(EVP_PKEY_assign_RSA(*evp_key, rsa) == 0) { 5068ed2b524SDag-Erling Smørgrav verbose(VERB_QUERY, "verify: " 5078ed2b524SDag-Erling Smørgrav "EVP_PKEY_assign_RSA SHA failed"); 5088ed2b524SDag-Erling Smørgrav return 0; 5098ed2b524SDag-Erling Smørgrav } 5108ed2b524SDag-Erling Smørgrav 5118ed2b524SDag-Erling Smørgrav /* select SHA version */ 5128ed2b524SDag-Erling Smørgrav #if defined(HAVE_EVP_SHA256) && defined(USE_SHA2) 5138ed2b524SDag-Erling Smørgrav if(algo == LDNS_RSASHA256) 5148ed2b524SDag-Erling Smørgrav *digest_type = EVP_sha256(); 5158ed2b524SDag-Erling Smørgrav else 5168ed2b524SDag-Erling Smørgrav #endif 5178ed2b524SDag-Erling Smørgrav #if defined(HAVE_EVP_SHA512) && defined(USE_SHA2) 5188ed2b524SDag-Erling Smørgrav if(algo == LDNS_RSASHA512) 5198ed2b524SDag-Erling Smørgrav *digest_type = EVP_sha512(); 5208ed2b524SDag-Erling Smørgrav else 5218ed2b524SDag-Erling Smørgrav #endif 52265b390aaSDag-Erling Smørgrav #ifdef USE_SHA1 5238ed2b524SDag-Erling Smørgrav *digest_type = EVP_sha1(); 52465b390aaSDag-Erling Smørgrav #else 52565b390aaSDag-Erling Smørgrav { verbose(VERB_QUERY, "no digest available"); return 0; } 52665b390aaSDag-Erling Smørgrav #endif 5278ed2b524SDag-Erling Smørgrav break; 52865b390aaSDag-Erling Smørgrav #endif /* defined(USE_SHA1) || (defined(HAVE_EVP_SHA256) && defined(USE_SHA2)) || (defined(HAVE_EVP_SHA512) && defined(USE_SHA2)) */ 52965b390aaSDag-Erling Smørgrav 5308ed2b524SDag-Erling Smørgrav case LDNS_RSAMD5: 5318ed2b524SDag-Erling Smørgrav *evp_key = EVP_PKEY_new(); 5328ed2b524SDag-Erling Smørgrav if(!*evp_key) { 5338ed2b524SDag-Erling Smørgrav log_err("verify: malloc failure in crypto"); 5348ed2b524SDag-Erling Smørgrav return 0; 5358ed2b524SDag-Erling Smørgrav } 53617d15b25SDag-Erling Smørgrav rsa = sldns_key_buf2rsa_raw(key, keylen); 5378ed2b524SDag-Erling Smørgrav if(!rsa) { 5388ed2b524SDag-Erling Smørgrav verbose(VERB_QUERY, "verify: " 53917d15b25SDag-Erling Smørgrav "sldns_key_buf2rsa_raw MD5 failed"); 5408ed2b524SDag-Erling Smørgrav return 0; 5418ed2b524SDag-Erling Smørgrav } 5428ed2b524SDag-Erling Smørgrav if(EVP_PKEY_assign_RSA(*evp_key, rsa) == 0) { 5438ed2b524SDag-Erling Smørgrav verbose(VERB_QUERY, "verify: " 5448ed2b524SDag-Erling Smørgrav "EVP_PKEY_assign_RSA MD5 failed"); 5458ed2b524SDag-Erling Smørgrav return 0; 5468ed2b524SDag-Erling Smørgrav } 5478ed2b524SDag-Erling Smørgrav *digest_type = EVP_md5(); 5488ed2b524SDag-Erling Smørgrav 5498ed2b524SDag-Erling Smørgrav break; 5508ed2b524SDag-Erling Smørgrav #ifdef USE_GOST 5518ed2b524SDag-Erling Smørgrav case LDNS_ECC_GOST: 55217d15b25SDag-Erling Smørgrav *evp_key = sldns_gost2pkey_raw(key, keylen); 5538ed2b524SDag-Erling Smørgrav if(!*evp_key) { 5548ed2b524SDag-Erling Smørgrav verbose(VERB_QUERY, "verify: " 55517d15b25SDag-Erling Smørgrav "sldns_gost2pkey_raw failed"); 5568ed2b524SDag-Erling Smørgrav return 0; 5578ed2b524SDag-Erling Smørgrav } 5588ed2b524SDag-Erling Smørgrav *digest_type = EVP_get_digestbyname("md_gost94"); 5598ed2b524SDag-Erling Smørgrav if(!*digest_type) { 5608ed2b524SDag-Erling Smørgrav verbose(VERB_QUERY, "verify: " 5618ed2b524SDag-Erling Smørgrav "EVP_getdigest md_gost94 failed"); 5628ed2b524SDag-Erling Smørgrav return 0; 5638ed2b524SDag-Erling Smørgrav } 5648ed2b524SDag-Erling Smørgrav break; 5658ed2b524SDag-Erling Smørgrav #endif 5668ed2b524SDag-Erling Smørgrav #ifdef USE_ECDSA 5678ed2b524SDag-Erling Smørgrav case LDNS_ECDSAP256SHA256: 56817d15b25SDag-Erling Smørgrav *evp_key = sldns_ecdsa2pkey_raw(key, keylen, 5698ed2b524SDag-Erling Smørgrav LDNS_ECDSAP256SHA256); 5708ed2b524SDag-Erling Smørgrav if(!*evp_key) { 5718ed2b524SDag-Erling Smørgrav verbose(VERB_QUERY, "verify: " 57217d15b25SDag-Erling Smørgrav "sldns_ecdsa2pkey_raw failed"); 5738ed2b524SDag-Erling Smørgrav return 0; 5748ed2b524SDag-Erling Smørgrav } 5758ed2b524SDag-Erling Smørgrav #ifdef USE_ECDSA_EVP_WORKAROUND 576b5663de9SDag-Erling Smørgrav *digest_type = &ecdsa_evp_256_md; 5778ed2b524SDag-Erling Smørgrav #else 5788ed2b524SDag-Erling Smørgrav *digest_type = EVP_sha256(); 5798ed2b524SDag-Erling Smørgrav #endif 5808ed2b524SDag-Erling Smørgrav break; 5818ed2b524SDag-Erling Smørgrav case LDNS_ECDSAP384SHA384: 58217d15b25SDag-Erling Smørgrav *evp_key = sldns_ecdsa2pkey_raw(key, keylen, 5838ed2b524SDag-Erling Smørgrav LDNS_ECDSAP384SHA384); 5848ed2b524SDag-Erling Smørgrav if(!*evp_key) { 5858ed2b524SDag-Erling Smørgrav verbose(VERB_QUERY, "verify: " 58617d15b25SDag-Erling Smørgrav "sldns_ecdsa2pkey_raw failed"); 5878ed2b524SDag-Erling Smørgrav return 0; 5888ed2b524SDag-Erling Smørgrav } 5898ed2b524SDag-Erling Smørgrav #ifdef USE_ECDSA_EVP_WORKAROUND 590b5663de9SDag-Erling Smørgrav *digest_type = &ecdsa_evp_384_md; 5918ed2b524SDag-Erling Smørgrav #else 5928ed2b524SDag-Erling Smørgrav *digest_type = EVP_sha384(); 5938ed2b524SDag-Erling Smørgrav #endif 5948ed2b524SDag-Erling Smørgrav break; 5958ed2b524SDag-Erling Smørgrav #endif /* USE_ECDSA */ 596c7f4d7adSDag-Erling Smørgrav #ifdef USE_ED25519 597c7f4d7adSDag-Erling Smørgrav case LDNS_ED25519: 598c7f4d7adSDag-Erling Smørgrav *evp_key = sldns_ed255192pkey_raw(key, keylen); 599c7f4d7adSDag-Erling Smørgrav if(!*evp_key) { 600c7f4d7adSDag-Erling Smørgrav verbose(VERB_QUERY, "verify: " 601c7f4d7adSDag-Erling Smørgrav "sldns_ed255192pkey_raw failed"); 602c7f4d7adSDag-Erling Smørgrav return 0; 603c7f4d7adSDag-Erling Smørgrav } 604c7f4d7adSDag-Erling Smørgrav *digest_type = NULL; 605c7f4d7adSDag-Erling Smørgrav break; 606c7f4d7adSDag-Erling Smørgrav #endif /* USE_ED25519 */ 6070fb34990SDag-Erling Smørgrav #ifdef USE_ED448 6080fb34990SDag-Erling Smørgrav case LDNS_ED448: 6090fb34990SDag-Erling Smørgrav *evp_key = sldns_ed4482pkey_raw(key, keylen); 6100fb34990SDag-Erling Smørgrav if(!*evp_key) { 6110fb34990SDag-Erling Smørgrav verbose(VERB_QUERY, "verify: " 6120fb34990SDag-Erling Smørgrav "sldns_ed4482pkey_raw failed"); 6130fb34990SDag-Erling Smørgrav return 0; 6140fb34990SDag-Erling Smørgrav } 6150fb34990SDag-Erling Smørgrav *digest_type = NULL; 6160fb34990SDag-Erling Smørgrav break; 6170fb34990SDag-Erling Smørgrav #endif /* USE_ED448 */ 6188ed2b524SDag-Erling Smørgrav default: 6198ed2b524SDag-Erling Smørgrav verbose(VERB_QUERY, "verify: unknown algorithm %d", 6208ed2b524SDag-Erling Smørgrav algo); 6218ed2b524SDag-Erling Smørgrav return 0; 6228ed2b524SDag-Erling Smørgrav } 6238ed2b524SDag-Erling Smørgrav return 1; 6248ed2b524SDag-Erling Smørgrav } 6258ed2b524SDag-Erling Smørgrav 6268ed2b524SDag-Erling Smørgrav /** 6278ed2b524SDag-Erling Smørgrav * Check a canonical sig+rrset and signature against a dnskey 6288ed2b524SDag-Erling Smørgrav * @param buf: buffer with data to verify, the first rrsig part and the 6298ed2b524SDag-Erling Smørgrav * canonicalized rrset. 6308ed2b524SDag-Erling Smørgrav * @param algo: DNSKEY algorithm. 6318ed2b524SDag-Erling Smørgrav * @param sigblock: signature rdata field from RRSIG 6328ed2b524SDag-Erling Smørgrav * @param sigblock_len: length of sigblock data. 6338ed2b524SDag-Erling Smørgrav * @param key: public key data from DNSKEY RR. 6348ed2b524SDag-Erling Smørgrav * @param keylen: length of keydata. 6358ed2b524SDag-Erling Smørgrav * @param reason: bogus reason in more detail. 6368ed2b524SDag-Erling Smørgrav * @return secure if verification succeeded, bogus on crypto failure, 6378ed2b524SDag-Erling Smørgrav * unchecked on format errors and alloc failures. 6388ed2b524SDag-Erling Smørgrav */ 6398ed2b524SDag-Erling Smørgrav enum sec_status 64017d15b25SDag-Erling Smørgrav verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock, 6418ed2b524SDag-Erling Smørgrav unsigned int sigblock_len, unsigned char* key, unsigned int keylen, 6428ed2b524SDag-Erling Smørgrav char** reason) 6438ed2b524SDag-Erling Smørgrav { 6448ed2b524SDag-Erling Smørgrav const EVP_MD *digest_type; 645e2d15004SDag-Erling Smørgrav EVP_MD_CTX* ctx; 646e2d15004SDag-Erling Smørgrav int res, dofree = 0, docrypto_free = 0; 6478ed2b524SDag-Erling Smørgrav EVP_PKEY *evp_key = NULL; 6488ed2b524SDag-Erling Smørgrav 649bc892140SDag-Erling Smørgrav #ifndef USE_DSA 65065b390aaSDag-Erling Smørgrav if((algo == LDNS_DSA || algo == LDNS_DSA_NSEC3) &&(fake_dsa||fake_sha1)) 65165b390aaSDag-Erling Smørgrav return sec_status_secure; 65265b390aaSDag-Erling Smørgrav #endif 65365b390aaSDag-Erling Smørgrav #ifndef USE_SHA1 65465b390aaSDag-Erling Smørgrav if(fake_sha1 && (algo == LDNS_DSA || algo == LDNS_DSA_NSEC3 || algo == LDNS_RSASHA1 || algo == LDNS_RSASHA1_NSEC3)) 655bc892140SDag-Erling Smørgrav return sec_status_secure; 656bc892140SDag-Erling Smørgrav #endif 657bc892140SDag-Erling Smørgrav 6588ed2b524SDag-Erling Smørgrav if(!setup_key_digest(algo, &evp_key, &digest_type, key, keylen)) { 6598ed2b524SDag-Erling Smørgrav verbose(VERB_QUERY, "verify: failed to setup key"); 6608ed2b524SDag-Erling Smørgrav *reason = "use of key for crypto failed"; 6618ed2b524SDag-Erling Smørgrav EVP_PKEY_free(evp_key); 6628ed2b524SDag-Erling Smørgrav return sec_status_bogus; 6638ed2b524SDag-Erling Smørgrav } 664e2d15004SDag-Erling Smørgrav #ifdef USE_DSA 6658ed2b524SDag-Erling Smørgrav /* if it is a DSA signature in bind format, convert to DER format */ 6668ed2b524SDag-Erling Smørgrav if((algo == LDNS_DSA || algo == LDNS_DSA_NSEC3) && 6678ed2b524SDag-Erling Smørgrav sigblock_len == 1+2*SHA_DIGEST_LENGTH) { 6688ed2b524SDag-Erling Smørgrav if(!setup_dsa_sig(&sigblock, &sigblock_len)) { 6698ed2b524SDag-Erling Smørgrav verbose(VERB_QUERY, "verify: failed to setup DSA sig"); 6708ed2b524SDag-Erling Smørgrav *reason = "use of key for DSA crypto failed"; 6718ed2b524SDag-Erling Smørgrav EVP_PKEY_free(evp_key); 6728ed2b524SDag-Erling Smørgrav return sec_status_bogus; 6738ed2b524SDag-Erling Smørgrav } 674e2d15004SDag-Erling Smørgrav docrypto_free = 1; 6758ed2b524SDag-Erling Smørgrav } 676e2d15004SDag-Erling Smørgrav #endif 677e2d15004SDag-Erling Smørgrav #if defined(USE_ECDSA) && defined(USE_DSA) 678e2d15004SDag-Erling Smørgrav else 679e2d15004SDag-Erling Smørgrav #endif 6808ed2b524SDag-Erling Smørgrav #ifdef USE_ECDSA 681e2d15004SDag-Erling Smørgrav if(algo == LDNS_ECDSAP256SHA256 || algo == LDNS_ECDSAP384SHA384) { 6828ed2b524SDag-Erling Smørgrav /* EVP uses ASN prefix on sig, which is not in the wire data */ 6838ed2b524SDag-Erling Smørgrav if(!setup_ecdsa_sig(&sigblock, &sigblock_len)) { 6848ed2b524SDag-Erling Smørgrav verbose(VERB_QUERY, "verify: failed to setup ECDSA sig"); 6858ed2b524SDag-Erling Smørgrav *reason = "use of signature for ECDSA crypto failed"; 6868ed2b524SDag-Erling Smørgrav EVP_PKEY_free(evp_key); 6878ed2b524SDag-Erling Smørgrav return sec_status_bogus; 6888ed2b524SDag-Erling Smørgrav } 6898ed2b524SDag-Erling Smørgrav dofree = 1; 6908ed2b524SDag-Erling Smørgrav } 6918ed2b524SDag-Erling Smørgrav #endif /* USE_ECDSA */ 6928ed2b524SDag-Erling Smørgrav 6938ed2b524SDag-Erling Smørgrav /* do the signature cryptography work */ 694e2d15004SDag-Erling Smørgrav #ifdef HAVE_EVP_MD_CTX_NEW 695e2d15004SDag-Erling Smørgrav ctx = EVP_MD_CTX_new(); 696e2d15004SDag-Erling Smørgrav #else 697e2d15004SDag-Erling Smørgrav ctx = (EVP_MD_CTX*)malloc(sizeof(*ctx)); 698e2d15004SDag-Erling Smørgrav if(ctx) EVP_MD_CTX_init(ctx); 699e2d15004SDag-Erling Smørgrav #endif 700e2d15004SDag-Erling Smørgrav if(!ctx) { 701e2d15004SDag-Erling Smørgrav log_err("EVP_MD_CTX_new: malloc failure"); 7028ed2b524SDag-Erling Smørgrav EVP_PKEY_free(evp_key); 7038ed2b524SDag-Erling Smørgrav if(dofree) free(sigblock); 704b5663de9SDag-Erling Smørgrav else if(docrypto_free) OPENSSL_free(sigblock); 7058ed2b524SDag-Erling Smørgrav return sec_status_unchecked; 7068ed2b524SDag-Erling Smørgrav } 707c7f4d7adSDag-Erling Smørgrav #ifndef HAVE_EVP_DIGESTVERIFY 708c7f4d7adSDag-Erling Smørgrav if(EVP_DigestInit(ctx, digest_type) == 0) { 709c7f4d7adSDag-Erling Smørgrav verbose(VERB_QUERY, "verify: EVP_DigestInit failed"); 710c7f4d7adSDag-Erling Smørgrav #ifdef HAVE_EVP_MD_CTX_NEW 711e2d15004SDag-Erling Smørgrav EVP_MD_CTX_destroy(ctx); 712c7f4d7adSDag-Erling Smørgrav #else 713c7f4d7adSDag-Erling Smørgrav EVP_MD_CTX_cleanup(ctx); 714c7f4d7adSDag-Erling Smørgrav free(ctx); 715c7f4d7adSDag-Erling Smørgrav #endif 716e2d15004SDag-Erling Smørgrav EVP_PKEY_free(evp_key); 717e2d15004SDag-Erling Smørgrav if(dofree) free(sigblock); 718b5663de9SDag-Erling Smørgrav else if(docrypto_free) OPENSSL_free(sigblock); 719e2d15004SDag-Erling Smørgrav return sec_status_unchecked; 720e2d15004SDag-Erling Smørgrav } 721c7f4d7adSDag-Erling Smørgrav if(EVP_DigestUpdate(ctx, (unsigned char*)sldns_buffer_begin(buf), 72217d15b25SDag-Erling Smørgrav (unsigned int)sldns_buffer_limit(buf)) == 0) { 723c7f4d7adSDag-Erling Smørgrav verbose(VERB_QUERY, "verify: EVP_DigestUpdate failed"); 724c7f4d7adSDag-Erling Smørgrav #ifdef HAVE_EVP_MD_CTX_NEW 725e2d15004SDag-Erling Smørgrav EVP_MD_CTX_destroy(ctx); 726c7f4d7adSDag-Erling Smørgrav #else 727c7f4d7adSDag-Erling Smørgrav EVP_MD_CTX_cleanup(ctx); 728c7f4d7adSDag-Erling Smørgrav free(ctx); 729c7f4d7adSDag-Erling Smørgrav #endif 7308ed2b524SDag-Erling Smørgrav EVP_PKEY_free(evp_key); 7318ed2b524SDag-Erling Smørgrav if(dofree) free(sigblock); 732b5663de9SDag-Erling Smørgrav else if(docrypto_free) OPENSSL_free(sigblock); 7338ed2b524SDag-Erling Smørgrav return sec_status_unchecked; 7348ed2b524SDag-Erling Smørgrav } 7358ed2b524SDag-Erling Smørgrav 736e2d15004SDag-Erling Smørgrav res = EVP_VerifyFinal(ctx, sigblock, sigblock_len, evp_key); 737c7f4d7adSDag-Erling Smørgrav #else /* HAVE_EVP_DIGESTVERIFY */ 738c7f4d7adSDag-Erling Smørgrav if(EVP_DigestVerifyInit(ctx, NULL, digest_type, NULL, evp_key) == 0) { 739c7f4d7adSDag-Erling Smørgrav verbose(VERB_QUERY, "verify: EVP_DigestVerifyInit failed"); 740c7f4d7adSDag-Erling Smørgrav #ifdef HAVE_EVP_MD_CTX_NEW 741c7f4d7adSDag-Erling Smørgrav EVP_MD_CTX_destroy(ctx); 742c7f4d7adSDag-Erling Smørgrav #else 743c7f4d7adSDag-Erling Smørgrav EVP_MD_CTX_cleanup(ctx); 744c7f4d7adSDag-Erling Smørgrav free(ctx); 745c7f4d7adSDag-Erling Smørgrav #endif 746c7f4d7adSDag-Erling Smørgrav EVP_PKEY_free(evp_key); 747c7f4d7adSDag-Erling Smørgrav if(dofree) free(sigblock); 748c7f4d7adSDag-Erling Smørgrav else if(docrypto_free) OPENSSL_free(sigblock); 749c7f4d7adSDag-Erling Smørgrav return sec_status_unchecked; 750c7f4d7adSDag-Erling Smørgrav } 751c7f4d7adSDag-Erling Smørgrav res = EVP_DigestVerify(ctx, sigblock, sigblock_len, 752c7f4d7adSDag-Erling Smørgrav (unsigned char*)sldns_buffer_begin(buf), 753c7f4d7adSDag-Erling Smørgrav sldns_buffer_limit(buf)); 754c7f4d7adSDag-Erling Smørgrav #endif 755e2d15004SDag-Erling Smørgrav #ifdef HAVE_EVP_MD_CTX_NEW 756e2d15004SDag-Erling Smørgrav EVP_MD_CTX_destroy(ctx); 757e2d15004SDag-Erling Smørgrav #else 758e2d15004SDag-Erling Smørgrav EVP_MD_CTX_cleanup(ctx); 759e2d15004SDag-Erling Smørgrav free(ctx); 760e2d15004SDag-Erling Smørgrav #endif 7618ed2b524SDag-Erling Smørgrav EVP_PKEY_free(evp_key); 7628ed2b524SDag-Erling Smørgrav 763e2d15004SDag-Erling Smørgrav if(dofree) free(sigblock); 764b5663de9SDag-Erling Smørgrav else if(docrypto_free) OPENSSL_free(sigblock); 7658ed2b524SDag-Erling Smørgrav 7668ed2b524SDag-Erling Smørgrav if(res == 1) { 7678ed2b524SDag-Erling Smørgrav return sec_status_secure; 7688ed2b524SDag-Erling Smørgrav } else if(res == 0) { 7698ed2b524SDag-Erling Smørgrav verbose(VERB_QUERY, "verify: signature mismatch"); 7708ed2b524SDag-Erling Smørgrav *reason = "signature crypto failed"; 7718ed2b524SDag-Erling Smørgrav return sec_status_bogus; 7728ed2b524SDag-Erling Smørgrav } 7738ed2b524SDag-Erling Smørgrav 7748ed2b524SDag-Erling Smørgrav log_crypto_error("verify:", ERR_get_error()); 7758ed2b524SDag-Erling Smørgrav return sec_status_unchecked; 7768ed2b524SDag-Erling Smørgrav } 7778ed2b524SDag-Erling Smørgrav 7788ed2b524SDag-Erling Smørgrav /**************************************************/ 7798ed2b524SDag-Erling Smørgrav #elif defined(HAVE_NSS) 7808ed2b524SDag-Erling Smørgrav /* libnss implementation */ 7818ed2b524SDag-Erling Smørgrav /* nss3 */ 7828ed2b524SDag-Erling Smørgrav #include "sechash.h" 7838ed2b524SDag-Erling Smørgrav #include "pk11pub.h" 7848ed2b524SDag-Erling Smørgrav #include "keyhi.h" 7858ed2b524SDag-Erling Smørgrav #include "secerr.h" 7868ed2b524SDag-Erling Smørgrav #include "cryptohi.h" 7878ed2b524SDag-Erling Smørgrav /* nspr4 */ 7888ed2b524SDag-Erling Smørgrav #include "prerror.h" 7898ed2b524SDag-Erling Smørgrav 79005ab2901SDag-Erling Smørgrav /* return size of digest if supported, or 0 otherwise */ 79105ab2901SDag-Erling Smørgrav size_t 79205ab2901SDag-Erling Smørgrav nsec3_hash_algo_size_supported(int id) 79305ab2901SDag-Erling Smørgrav { 79405ab2901SDag-Erling Smørgrav switch(id) { 79505ab2901SDag-Erling Smørgrav case NSEC3_HASH_SHA1: 79605ab2901SDag-Erling Smørgrav return SHA1_LENGTH; 79705ab2901SDag-Erling Smørgrav default: 79805ab2901SDag-Erling Smørgrav return 0; 79905ab2901SDag-Erling Smørgrav } 80005ab2901SDag-Erling Smørgrav } 80105ab2901SDag-Erling Smørgrav 80205ab2901SDag-Erling Smørgrav /* perform nsec3 hash. return false on failure */ 80305ab2901SDag-Erling Smørgrav int 80405ab2901SDag-Erling Smørgrav secalgo_nsec3_hash(int algo, unsigned char* buf, size_t len, 80505ab2901SDag-Erling Smørgrav unsigned char* res) 80605ab2901SDag-Erling Smørgrav { 80705ab2901SDag-Erling Smørgrav switch(algo) { 80805ab2901SDag-Erling Smørgrav case NSEC3_HASH_SHA1: 80905ab2901SDag-Erling Smørgrav (void)HASH_HashBuf(HASH_AlgSHA1, res, buf, (unsigned long)len); 81005ab2901SDag-Erling Smørgrav return 1; 81105ab2901SDag-Erling Smørgrav default: 81205ab2901SDag-Erling Smørgrav return 0; 81305ab2901SDag-Erling Smørgrav } 81405ab2901SDag-Erling Smørgrav } 81505ab2901SDag-Erling Smørgrav 816e2d15004SDag-Erling Smørgrav void 817e2d15004SDag-Erling Smørgrav secalgo_hash_sha256(unsigned char* buf, size_t len, unsigned char* res) 818e2d15004SDag-Erling Smørgrav { 819e2d15004SDag-Erling Smørgrav (void)HASH_HashBuf(HASH_AlgSHA256, res, buf, (unsigned long)len); 820e2d15004SDag-Erling Smørgrav } 821e2d15004SDag-Erling Smørgrav 8228ed2b524SDag-Erling Smørgrav size_t 8238ed2b524SDag-Erling Smørgrav ds_digest_size_supported(int algo) 8248ed2b524SDag-Erling Smørgrav { 8258ed2b524SDag-Erling Smørgrav /* uses libNSS */ 8268ed2b524SDag-Erling Smørgrav switch(algo) { 82765b390aaSDag-Erling Smørgrav #ifdef USE_SHA1 8288ed2b524SDag-Erling Smørgrav case LDNS_SHA1: 8298ed2b524SDag-Erling Smørgrav return SHA1_LENGTH; 83065b390aaSDag-Erling Smørgrav #endif 8318ed2b524SDag-Erling Smørgrav #ifdef USE_SHA2 8328ed2b524SDag-Erling Smørgrav case LDNS_SHA256: 8338ed2b524SDag-Erling Smørgrav return SHA256_LENGTH; 8348ed2b524SDag-Erling Smørgrav #endif 8358ed2b524SDag-Erling Smørgrav #ifdef USE_ECDSA 8368ed2b524SDag-Erling Smørgrav case LDNS_SHA384: 8378ed2b524SDag-Erling Smørgrav return SHA384_LENGTH; 8388ed2b524SDag-Erling Smørgrav #endif 8398ed2b524SDag-Erling Smørgrav /* GOST not supported in NSS */ 8408ed2b524SDag-Erling Smørgrav case LDNS_HASH_GOST: 8418ed2b524SDag-Erling Smørgrav default: break; 8428ed2b524SDag-Erling Smørgrav } 8438ed2b524SDag-Erling Smørgrav return 0; 8448ed2b524SDag-Erling Smørgrav } 8458ed2b524SDag-Erling Smørgrav 8468ed2b524SDag-Erling Smørgrav int 8478ed2b524SDag-Erling Smørgrav secalgo_ds_digest(int algo, unsigned char* buf, size_t len, 8488ed2b524SDag-Erling Smørgrav unsigned char* res) 8498ed2b524SDag-Erling Smørgrav { 8508ed2b524SDag-Erling Smørgrav /* uses libNSS */ 8518ed2b524SDag-Erling Smørgrav switch(algo) { 85265b390aaSDag-Erling Smørgrav #ifdef USE_SHA1 8538ed2b524SDag-Erling Smørgrav case LDNS_SHA1: 8548ed2b524SDag-Erling Smørgrav return HASH_HashBuf(HASH_AlgSHA1, res, buf, len) 8558ed2b524SDag-Erling Smørgrav == SECSuccess; 85665b390aaSDag-Erling Smørgrav #endif 8578ed2b524SDag-Erling Smørgrav #if defined(USE_SHA2) 8588ed2b524SDag-Erling Smørgrav case LDNS_SHA256: 8598ed2b524SDag-Erling Smørgrav return HASH_HashBuf(HASH_AlgSHA256, res, buf, len) 8608ed2b524SDag-Erling Smørgrav == SECSuccess; 8618ed2b524SDag-Erling Smørgrav #endif 8628ed2b524SDag-Erling Smørgrav #ifdef USE_ECDSA 8638ed2b524SDag-Erling Smørgrav case LDNS_SHA384: 8648ed2b524SDag-Erling Smørgrav return HASH_HashBuf(HASH_AlgSHA384, res, buf, len) 8658ed2b524SDag-Erling Smørgrav == SECSuccess; 8668ed2b524SDag-Erling Smørgrav #endif 8678ed2b524SDag-Erling Smørgrav case LDNS_HASH_GOST: 8688ed2b524SDag-Erling Smørgrav default: 8698ed2b524SDag-Erling Smørgrav verbose(VERB_QUERY, "unknown DS digest algorithm %d", 8708ed2b524SDag-Erling Smørgrav algo); 8718ed2b524SDag-Erling Smørgrav break; 8728ed2b524SDag-Erling Smørgrav } 8738ed2b524SDag-Erling Smørgrav return 0; 8748ed2b524SDag-Erling Smørgrav } 8758ed2b524SDag-Erling Smørgrav 8768ed2b524SDag-Erling Smørgrav int 8778ed2b524SDag-Erling Smørgrav dnskey_algo_id_is_supported(int id) 8788ed2b524SDag-Erling Smørgrav { 8798ed2b524SDag-Erling Smørgrav /* uses libNSS */ 8808ed2b524SDag-Erling Smørgrav switch(id) { 8818ed2b524SDag-Erling Smørgrav case LDNS_RSAMD5: 8828ed2b524SDag-Erling Smørgrav /* RFC 6725 deprecates RSAMD5 */ 8838ed2b524SDag-Erling Smørgrav return 0; 88465b390aaSDag-Erling Smørgrav #if defined(USE_SHA1) || defined(USE_SHA2) 88565b390aaSDag-Erling Smørgrav #if defined(USE_DSA) && defined(USE_SHA1) 8868ed2b524SDag-Erling Smørgrav case LDNS_DSA: 8878ed2b524SDag-Erling Smørgrav case LDNS_DSA_NSEC3: 888e2d15004SDag-Erling Smørgrav #endif 88965b390aaSDag-Erling Smørgrav #ifdef USE_SHA1 8908ed2b524SDag-Erling Smørgrav case LDNS_RSASHA1: 8918ed2b524SDag-Erling Smørgrav case LDNS_RSASHA1_NSEC3: 89265b390aaSDag-Erling Smørgrav #endif 8938ed2b524SDag-Erling Smørgrav #ifdef USE_SHA2 8948ed2b524SDag-Erling Smørgrav case LDNS_RSASHA256: 8958ed2b524SDag-Erling Smørgrav #endif 8968ed2b524SDag-Erling Smørgrav #ifdef USE_SHA2 8978ed2b524SDag-Erling Smørgrav case LDNS_RSASHA512: 8988ed2b524SDag-Erling Smørgrav #endif 8998ed2b524SDag-Erling Smørgrav return 1; 90065b390aaSDag-Erling Smørgrav #endif /* SHA1 or SHA2 */ 90165b390aaSDag-Erling Smørgrav 9028ed2b524SDag-Erling Smørgrav #ifdef USE_ECDSA 9038ed2b524SDag-Erling Smørgrav case LDNS_ECDSAP256SHA256: 9048ed2b524SDag-Erling Smørgrav case LDNS_ECDSAP384SHA384: 9058ed2b524SDag-Erling Smørgrav return PK11_TokenExists(CKM_ECDSA); 9068ed2b524SDag-Erling Smørgrav #endif 9078ed2b524SDag-Erling Smørgrav case LDNS_ECC_GOST: 9088ed2b524SDag-Erling Smørgrav default: 9098ed2b524SDag-Erling Smørgrav return 0; 9108ed2b524SDag-Erling Smørgrav } 9118ed2b524SDag-Erling Smørgrav } 9128ed2b524SDag-Erling Smørgrav 9138ed2b524SDag-Erling Smørgrav /* return a new public key for NSS */ 9148ed2b524SDag-Erling Smørgrav static SECKEYPublicKey* nss_key_create(KeyType ktype) 9158ed2b524SDag-Erling Smørgrav { 9168ed2b524SDag-Erling Smørgrav SECKEYPublicKey* key; 9178ed2b524SDag-Erling Smørgrav PLArenaPool* arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); 9188ed2b524SDag-Erling Smørgrav if(!arena) { 9198ed2b524SDag-Erling Smørgrav log_err("out of memory, PORT_NewArena failed"); 9208ed2b524SDag-Erling Smørgrav return NULL; 9218ed2b524SDag-Erling Smørgrav } 9228ed2b524SDag-Erling Smørgrav key = PORT_ArenaZNew(arena, SECKEYPublicKey); 9238ed2b524SDag-Erling Smørgrav if(!key) { 9248ed2b524SDag-Erling Smørgrav log_err("out of memory, PORT_ArenaZNew failed"); 9258ed2b524SDag-Erling Smørgrav PORT_FreeArena(arena, PR_FALSE); 9268ed2b524SDag-Erling Smørgrav return NULL; 9278ed2b524SDag-Erling Smørgrav } 9288ed2b524SDag-Erling Smørgrav key->arena = arena; 9298ed2b524SDag-Erling Smørgrav key->keyType = ktype; 9308ed2b524SDag-Erling Smørgrav key->pkcs11Slot = NULL; 9318ed2b524SDag-Erling Smørgrav key->pkcs11ID = CK_INVALID_HANDLE; 9328ed2b524SDag-Erling Smørgrav return key; 9338ed2b524SDag-Erling Smørgrav } 9348ed2b524SDag-Erling Smørgrav 9358ed2b524SDag-Erling Smørgrav static SECKEYPublicKey* nss_buf2ecdsa(unsigned char* key, size_t len, int algo) 9368ed2b524SDag-Erling Smørgrav { 9378ed2b524SDag-Erling Smørgrav SECKEYPublicKey* pk; 9388ed2b524SDag-Erling Smørgrav SECItem pub = {siBuffer, NULL, 0}; 9398ed2b524SDag-Erling Smørgrav SECItem params = {siBuffer, NULL, 0}; 94017d15b25SDag-Erling Smørgrav static unsigned char param256[] = { 9418ed2b524SDag-Erling Smørgrav /* OBJECTIDENTIFIER 1.2.840.10045.3.1.7 (P-256) 9428ed2b524SDag-Erling Smørgrav * {iso(1) member-body(2) us(840) ansi-x962(10045) curves(3) prime(1) prime256v1(7)} */ 9438ed2b524SDag-Erling Smørgrav 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07 9448ed2b524SDag-Erling Smørgrav }; 94517d15b25SDag-Erling Smørgrav static unsigned char param384[] = { 9468ed2b524SDag-Erling Smørgrav /* OBJECTIDENTIFIER 1.3.132.0.34 (P-384) 9478ed2b524SDag-Erling Smørgrav * {iso(1) identified-organization(3) certicom(132) curve(0) ansip384r1(34)} */ 9488ed2b524SDag-Erling Smørgrav 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x22 9498ed2b524SDag-Erling Smørgrav }; 9508ed2b524SDag-Erling Smørgrav unsigned char buf[256+2]; /* sufficient for 2*384/8+1 */ 9518ed2b524SDag-Erling Smørgrav 9528ed2b524SDag-Erling Smørgrav /* check length, which uncompressed must be 2 bignums */ 9538ed2b524SDag-Erling Smørgrav if(algo == LDNS_ECDSAP256SHA256) { 9548ed2b524SDag-Erling Smørgrav if(len != 2*256/8) return NULL; 9558ed2b524SDag-Erling Smørgrav /* ECCurve_X9_62_PRIME_256V1 */ 9568ed2b524SDag-Erling Smørgrav } else if(algo == LDNS_ECDSAP384SHA384) { 9578ed2b524SDag-Erling Smørgrav if(len != 2*384/8) return NULL; 9588ed2b524SDag-Erling Smørgrav /* ECCurve_X9_62_PRIME_384R1 */ 9598ed2b524SDag-Erling Smørgrav } else return NULL; 9608ed2b524SDag-Erling Smørgrav 9618ed2b524SDag-Erling Smørgrav buf[0] = 0x04; /* POINT_FORM_UNCOMPRESSED */ 9628ed2b524SDag-Erling Smørgrav memmove(buf+1, key, len); 9638ed2b524SDag-Erling Smørgrav pub.data = buf; 9648ed2b524SDag-Erling Smørgrav pub.len = len+1; 9658ed2b524SDag-Erling Smørgrav if(algo == LDNS_ECDSAP256SHA256) { 9668ed2b524SDag-Erling Smørgrav params.data = param256; 9678ed2b524SDag-Erling Smørgrav params.len = sizeof(param256); 9688ed2b524SDag-Erling Smørgrav } else { 9698ed2b524SDag-Erling Smørgrav params.data = param384; 9708ed2b524SDag-Erling Smørgrav params.len = sizeof(param384); 9718ed2b524SDag-Erling Smørgrav } 9728ed2b524SDag-Erling Smørgrav 9738ed2b524SDag-Erling Smørgrav pk = nss_key_create(ecKey); 9748ed2b524SDag-Erling Smørgrav if(!pk) 9758ed2b524SDag-Erling Smørgrav return NULL; 9768ed2b524SDag-Erling Smørgrav pk->u.ec.size = (len/2)*8; 9778ed2b524SDag-Erling Smørgrav if(SECITEM_CopyItem(pk->arena, &pk->u.ec.publicValue, &pub)) { 9788ed2b524SDag-Erling Smørgrav SECKEY_DestroyPublicKey(pk); 9798ed2b524SDag-Erling Smørgrav return NULL; 9808ed2b524SDag-Erling Smørgrav } 9818ed2b524SDag-Erling Smørgrav if(SECITEM_CopyItem(pk->arena, &pk->u.ec.DEREncodedParams, ¶ms)) { 9828ed2b524SDag-Erling Smørgrav SECKEY_DestroyPublicKey(pk); 9838ed2b524SDag-Erling Smørgrav return NULL; 9848ed2b524SDag-Erling Smørgrav } 9858ed2b524SDag-Erling Smørgrav 9868ed2b524SDag-Erling Smørgrav return pk; 9878ed2b524SDag-Erling Smørgrav } 9888ed2b524SDag-Erling Smørgrav 9898ed2b524SDag-Erling Smørgrav static SECKEYPublicKey* nss_buf2dsa(unsigned char* key, size_t len) 9908ed2b524SDag-Erling Smørgrav { 9918ed2b524SDag-Erling Smørgrav SECKEYPublicKey* pk; 9928ed2b524SDag-Erling Smørgrav uint8_t T; 9938ed2b524SDag-Erling Smørgrav uint16_t length; 9948ed2b524SDag-Erling Smørgrav uint16_t offset; 9958ed2b524SDag-Erling Smørgrav SECItem Q = {siBuffer, NULL, 0}; 9968ed2b524SDag-Erling Smørgrav SECItem P = {siBuffer, NULL, 0}; 9978ed2b524SDag-Erling Smørgrav SECItem G = {siBuffer, NULL, 0}; 9988ed2b524SDag-Erling Smørgrav SECItem Y = {siBuffer, NULL, 0}; 9998ed2b524SDag-Erling Smørgrav 10008ed2b524SDag-Erling Smørgrav if(len == 0) 10018ed2b524SDag-Erling Smørgrav return NULL; 10028ed2b524SDag-Erling Smørgrav T = (uint8_t)key[0]; 10038ed2b524SDag-Erling Smørgrav length = (64 + T * 8); 10048ed2b524SDag-Erling Smørgrav offset = 1; 10058ed2b524SDag-Erling Smørgrav 10068ed2b524SDag-Erling Smørgrav if (T > 8) { 10078ed2b524SDag-Erling Smørgrav return NULL; 10088ed2b524SDag-Erling Smørgrav } 10098ed2b524SDag-Erling Smørgrav if(len < (size_t)1 + SHA1_LENGTH + 3*length) 10108ed2b524SDag-Erling Smørgrav return NULL; 10118ed2b524SDag-Erling Smørgrav 10128ed2b524SDag-Erling Smørgrav Q.data = key+offset; 10138ed2b524SDag-Erling Smørgrav Q.len = SHA1_LENGTH; 10148ed2b524SDag-Erling Smørgrav offset += SHA1_LENGTH; 10158ed2b524SDag-Erling Smørgrav 10168ed2b524SDag-Erling Smørgrav P.data = key+offset; 10178ed2b524SDag-Erling Smørgrav P.len = length; 10188ed2b524SDag-Erling Smørgrav offset += length; 10198ed2b524SDag-Erling Smørgrav 10208ed2b524SDag-Erling Smørgrav G.data = key+offset; 10218ed2b524SDag-Erling Smørgrav G.len = length; 10228ed2b524SDag-Erling Smørgrav offset += length; 10238ed2b524SDag-Erling Smørgrav 10248ed2b524SDag-Erling Smørgrav Y.data = key+offset; 10258ed2b524SDag-Erling Smørgrav Y.len = length; 10268ed2b524SDag-Erling Smørgrav offset += length; 10278ed2b524SDag-Erling Smørgrav 10288ed2b524SDag-Erling Smørgrav pk = nss_key_create(dsaKey); 10298ed2b524SDag-Erling Smørgrav if(!pk) 10308ed2b524SDag-Erling Smørgrav return NULL; 10318ed2b524SDag-Erling Smørgrav if(SECITEM_CopyItem(pk->arena, &pk->u.dsa.params.prime, &P)) { 10328ed2b524SDag-Erling Smørgrav SECKEY_DestroyPublicKey(pk); 10338ed2b524SDag-Erling Smørgrav return NULL; 10348ed2b524SDag-Erling Smørgrav } 10358ed2b524SDag-Erling Smørgrav if(SECITEM_CopyItem(pk->arena, &pk->u.dsa.params.subPrime, &Q)) { 10368ed2b524SDag-Erling Smørgrav SECKEY_DestroyPublicKey(pk); 10378ed2b524SDag-Erling Smørgrav return NULL; 10388ed2b524SDag-Erling Smørgrav } 10398ed2b524SDag-Erling Smørgrav if(SECITEM_CopyItem(pk->arena, &pk->u.dsa.params.base, &G)) { 10408ed2b524SDag-Erling Smørgrav SECKEY_DestroyPublicKey(pk); 10418ed2b524SDag-Erling Smørgrav return NULL; 10428ed2b524SDag-Erling Smørgrav } 10438ed2b524SDag-Erling Smørgrav if(SECITEM_CopyItem(pk->arena, &pk->u.dsa.publicValue, &Y)) { 10448ed2b524SDag-Erling Smørgrav SECKEY_DestroyPublicKey(pk); 10458ed2b524SDag-Erling Smørgrav return NULL; 10468ed2b524SDag-Erling Smørgrav } 10478ed2b524SDag-Erling Smørgrav return pk; 10488ed2b524SDag-Erling Smørgrav } 10498ed2b524SDag-Erling Smørgrav 10508ed2b524SDag-Erling Smørgrav static SECKEYPublicKey* nss_buf2rsa(unsigned char* key, size_t len) 10518ed2b524SDag-Erling Smørgrav { 10528ed2b524SDag-Erling Smørgrav SECKEYPublicKey* pk; 10538ed2b524SDag-Erling Smørgrav uint16_t exp; 10548ed2b524SDag-Erling Smørgrav uint16_t offset; 10558ed2b524SDag-Erling Smørgrav uint16_t int16; 10568ed2b524SDag-Erling Smørgrav SECItem modulus = {siBuffer, NULL, 0}; 10578ed2b524SDag-Erling Smørgrav SECItem exponent = {siBuffer, NULL, 0}; 10588ed2b524SDag-Erling Smørgrav if(len == 0) 10598ed2b524SDag-Erling Smørgrav return NULL; 10608ed2b524SDag-Erling Smørgrav if(key[0] == 0) { 10618ed2b524SDag-Erling Smørgrav if(len < 3) 10628ed2b524SDag-Erling Smørgrav return NULL; 10638ed2b524SDag-Erling Smørgrav /* the exponent is too large so it's places further */ 10648ed2b524SDag-Erling Smørgrav memmove(&int16, key+1, 2); 10658ed2b524SDag-Erling Smørgrav exp = ntohs(int16); 10668ed2b524SDag-Erling Smørgrav offset = 3; 10678ed2b524SDag-Erling Smørgrav } else { 10688ed2b524SDag-Erling Smørgrav exp = key[0]; 10698ed2b524SDag-Erling Smørgrav offset = 1; 10708ed2b524SDag-Erling Smørgrav } 10718ed2b524SDag-Erling Smørgrav 10728ed2b524SDag-Erling Smørgrav /* key length at least one */ 10738ed2b524SDag-Erling Smørgrav if(len < (size_t)offset + exp + 1) 10748ed2b524SDag-Erling Smørgrav return NULL; 10758ed2b524SDag-Erling Smørgrav 10768ed2b524SDag-Erling Smørgrav exponent.data = key+offset; 10778ed2b524SDag-Erling Smørgrav exponent.len = exp; 10788ed2b524SDag-Erling Smørgrav offset += exp; 10798ed2b524SDag-Erling Smørgrav modulus.data = key+offset; 10808ed2b524SDag-Erling Smørgrav modulus.len = (len - offset); 10818ed2b524SDag-Erling Smørgrav 10828ed2b524SDag-Erling Smørgrav pk = nss_key_create(rsaKey); 10838ed2b524SDag-Erling Smørgrav if(!pk) 10848ed2b524SDag-Erling Smørgrav return NULL; 10858ed2b524SDag-Erling Smørgrav if(SECITEM_CopyItem(pk->arena, &pk->u.rsa.modulus, &modulus)) { 10868ed2b524SDag-Erling Smørgrav SECKEY_DestroyPublicKey(pk); 10878ed2b524SDag-Erling Smørgrav return NULL; 10888ed2b524SDag-Erling Smørgrav } 10898ed2b524SDag-Erling Smørgrav if(SECITEM_CopyItem(pk->arena, &pk->u.rsa.publicExponent, &exponent)) { 10908ed2b524SDag-Erling Smørgrav SECKEY_DestroyPublicKey(pk); 10918ed2b524SDag-Erling Smørgrav return NULL; 10928ed2b524SDag-Erling Smørgrav } 10938ed2b524SDag-Erling Smørgrav return pk; 10948ed2b524SDag-Erling Smørgrav } 10958ed2b524SDag-Erling Smørgrav 10968ed2b524SDag-Erling Smørgrav /** 10978ed2b524SDag-Erling Smørgrav * Setup key and digest for verification. Adjust sig if necessary. 10988ed2b524SDag-Erling Smørgrav * 10998ed2b524SDag-Erling Smørgrav * @param algo: key algorithm 11008ed2b524SDag-Erling Smørgrav * @param evp_key: EVP PKEY public key to create. 11018ed2b524SDag-Erling Smørgrav * @param digest_type: digest type to use 11028ed2b524SDag-Erling Smørgrav * @param key: key to setup for. 11038ed2b524SDag-Erling Smørgrav * @param keylen: length of key. 11048ed2b524SDag-Erling Smørgrav * @param prefix: if returned, the ASN prefix for the hashblob. 11058ed2b524SDag-Erling Smørgrav * @param prefixlen: length of the prefix. 11068ed2b524SDag-Erling Smørgrav * @return false on failure. 11078ed2b524SDag-Erling Smørgrav */ 11088ed2b524SDag-Erling Smørgrav static int 11098ed2b524SDag-Erling Smørgrav nss_setup_key_digest(int algo, SECKEYPublicKey** pubkey, HASH_HashType* htype, 11108ed2b524SDag-Erling Smørgrav unsigned char* key, size_t keylen, unsigned char** prefix, 11118ed2b524SDag-Erling Smørgrav size_t* prefixlen) 11128ed2b524SDag-Erling Smørgrav { 11138ed2b524SDag-Erling Smørgrav /* uses libNSS */ 11148ed2b524SDag-Erling Smørgrav 11158ed2b524SDag-Erling Smørgrav /* hash prefix for md5, RFC2537 */ 111617d15b25SDag-Erling Smørgrav static unsigned char p_md5[] = {0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 11178ed2b524SDag-Erling Smørgrav 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10}; 11188ed2b524SDag-Erling Smørgrav /* hash prefix to prepend to hash output, from RFC3110 */ 111917d15b25SDag-Erling Smørgrav static unsigned char p_sha1[] = {0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 11208ed2b524SDag-Erling Smørgrav 0x0E, 0x03, 0x02, 0x1A, 0x05, 0x00, 0x04, 0x14}; 11218ed2b524SDag-Erling Smørgrav /* from RFC5702 */ 112217d15b25SDag-Erling Smørgrav static unsigned char p_sha256[] = {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 11238ed2b524SDag-Erling Smørgrav 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20}; 112417d15b25SDag-Erling Smørgrav static unsigned char p_sha512[] = {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 11258ed2b524SDag-Erling Smørgrav 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40}; 11268ed2b524SDag-Erling Smørgrav /* from RFC6234 */ 11278ed2b524SDag-Erling Smørgrav /* for future RSASHA384 .. 112817d15b25SDag-Erling Smørgrav static unsigned char p_sha384[] = {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 11298ed2b524SDag-Erling Smørgrav 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30}; 11308ed2b524SDag-Erling Smørgrav */ 11318ed2b524SDag-Erling Smørgrav 11328ed2b524SDag-Erling Smørgrav switch(algo) { 113365b390aaSDag-Erling Smørgrav 113465b390aaSDag-Erling Smørgrav #if defined(USE_SHA1) || defined(USE_SHA2) 113565b390aaSDag-Erling Smørgrav #if defined(USE_DSA) && defined(USE_SHA1) 11368ed2b524SDag-Erling Smørgrav case LDNS_DSA: 11378ed2b524SDag-Erling Smørgrav case LDNS_DSA_NSEC3: 11388ed2b524SDag-Erling Smørgrav *pubkey = nss_buf2dsa(key, keylen); 11398ed2b524SDag-Erling Smørgrav if(!*pubkey) { 11408ed2b524SDag-Erling Smørgrav log_err("verify: malloc failure in crypto"); 11418ed2b524SDag-Erling Smørgrav return 0; 11428ed2b524SDag-Erling Smørgrav } 11438ed2b524SDag-Erling Smørgrav *htype = HASH_AlgSHA1; 11448ed2b524SDag-Erling Smørgrav /* no prefix for DSA verification */ 11458ed2b524SDag-Erling Smørgrav break; 1146e2d15004SDag-Erling Smørgrav #endif 114765b390aaSDag-Erling Smørgrav #ifdef USE_SHA1 11488ed2b524SDag-Erling Smørgrav case LDNS_RSASHA1: 11498ed2b524SDag-Erling Smørgrav case LDNS_RSASHA1_NSEC3: 115065b390aaSDag-Erling Smørgrav #endif 11518ed2b524SDag-Erling Smørgrav #ifdef USE_SHA2 11528ed2b524SDag-Erling Smørgrav case LDNS_RSASHA256: 11538ed2b524SDag-Erling Smørgrav #endif 11548ed2b524SDag-Erling Smørgrav #ifdef USE_SHA2 11558ed2b524SDag-Erling Smørgrav case LDNS_RSASHA512: 11568ed2b524SDag-Erling Smørgrav #endif 11578ed2b524SDag-Erling Smørgrav *pubkey = nss_buf2rsa(key, keylen); 11588ed2b524SDag-Erling Smørgrav if(!*pubkey) { 11598ed2b524SDag-Erling Smørgrav log_err("verify: malloc failure in crypto"); 11608ed2b524SDag-Erling Smørgrav return 0; 11618ed2b524SDag-Erling Smørgrav } 11628ed2b524SDag-Erling Smørgrav /* select SHA version */ 11638ed2b524SDag-Erling Smørgrav #ifdef USE_SHA2 11648ed2b524SDag-Erling Smørgrav if(algo == LDNS_RSASHA256) { 11658ed2b524SDag-Erling Smørgrav *htype = HASH_AlgSHA256; 11668ed2b524SDag-Erling Smørgrav *prefix = p_sha256; 11678ed2b524SDag-Erling Smørgrav *prefixlen = sizeof(p_sha256); 11688ed2b524SDag-Erling Smørgrav } else 11698ed2b524SDag-Erling Smørgrav #endif 11708ed2b524SDag-Erling Smørgrav #ifdef USE_SHA2 11718ed2b524SDag-Erling Smørgrav if(algo == LDNS_RSASHA512) { 11728ed2b524SDag-Erling Smørgrav *htype = HASH_AlgSHA512; 11738ed2b524SDag-Erling Smørgrav *prefix = p_sha512; 11748ed2b524SDag-Erling Smørgrav *prefixlen = sizeof(p_sha512); 11758ed2b524SDag-Erling Smørgrav } else 11768ed2b524SDag-Erling Smørgrav #endif 117765b390aaSDag-Erling Smørgrav #ifdef USE_SHA1 11788ed2b524SDag-Erling Smørgrav { 11798ed2b524SDag-Erling Smørgrav *htype = HASH_AlgSHA1; 11808ed2b524SDag-Erling Smørgrav *prefix = p_sha1; 11818ed2b524SDag-Erling Smørgrav *prefixlen = sizeof(p_sha1); 11828ed2b524SDag-Erling Smørgrav } 118365b390aaSDag-Erling Smørgrav #else 118465b390aaSDag-Erling Smørgrav { 118565b390aaSDag-Erling Smørgrav verbose(VERB_QUERY, "verify: no digest algo"); 118665b390aaSDag-Erling Smørgrav return 0; 118765b390aaSDag-Erling Smørgrav } 118865b390aaSDag-Erling Smørgrav #endif 11898ed2b524SDag-Erling Smørgrav 11908ed2b524SDag-Erling Smørgrav break; 119165b390aaSDag-Erling Smørgrav #endif /* SHA1 or SHA2 */ 119265b390aaSDag-Erling Smørgrav 11938ed2b524SDag-Erling Smørgrav case LDNS_RSAMD5: 11948ed2b524SDag-Erling Smørgrav *pubkey = nss_buf2rsa(key, keylen); 11958ed2b524SDag-Erling Smørgrav if(!*pubkey) { 11968ed2b524SDag-Erling Smørgrav log_err("verify: malloc failure in crypto"); 11978ed2b524SDag-Erling Smørgrav return 0; 11988ed2b524SDag-Erling Smørgrav } 11998ed2b524SDag-Erling Smørgrav *htype = HASH_AlgMD5; 12008ed2b524SDag-Erling Smørgrav *prefix = p_md5; 12018ed2b524SDag-Erling Smørgrav *prefixlen = sizeof(p_md5); 12028ed2b524SDag-Erling Smørgrav 12038ed2b524SDag-Erling Smørgrav break; 12048ed2b524SDag-Erling Smørgrav #ifdef USE_ECDSA 12058ed2b524SDag-Erling Smørgrav case LDNS_ECDSAP256SHA256: 12068ed2b524SDag-Erling Smørgrav *pubkey = nss_buf2ecdsa(key, keylen, 12078ed2b524SDag-Erling Smørgrav LDNS_ECDSAP256SHA256); 12088ed2b524SDag-Erling Smørgrav if(!*pubkey) { 12098ed2b524SDag-Erling Smørgrav log_err("verify: malloc failure in crypto"); 12108ed2b524SDag-Erling Smørgrav return 0; 12118ed2b524SDag-Erling Smørgrav } 12128ed2b524SDag-Erling Smørgrav *htype = HASH_AlgSHA256; 12138ed2b524SDag-Erling Smørgrav /* no prefix for DSA verification */ 12148ed2b524SDag-Erling Smørgrav break; 12158ed2b524SDag-Erling Smørgrav case LDNS_ECDSAP384SHA384: 12168ed2b524SDag-Erling Smørgrav *pubkey = nss_buf2ecdsa(key, keylen, 12178ed2b524SDag-Erling Smørgrav LDNS_ECDSAP384SHA384); 12188ed2b524SDag-Erling Smørgrav if(!*pubkey) { 12198ed2b524SDag-Erling Smørgrav log_err("verify: malloc failure in crypto"); 12208ed2b524SDag-Erling Smørgrav return 0; 12218ed2b524SDag-Erling Smørgrav } 12228ed2b524SDag-Erling Smørgrav *htype = HASH_AlgSHA384; 12238ed2b524SDag-Erling Smørgrav /* no prefix for DSA verification */ 12248ed2b524SDag-Erling Smørgrav break; 12258ed2b524SDag-Erling Smørgrav #endif /* USE_ECDSA */ 12268ed2b524SDag-Erling Smørgrav case LDNS_ECC_GOST: 12278ed2b524SDag-Erling Smørgrav default: 12288ed2b524SDag-Erling Smørgrav verbose(VERB_QUERY, "verify: unknown algorithm %d", 12298ed2b524SDag-Erling Smørgrav algo); 12308ed2b524SDag-Erling Smørgrav return 0; 12318ed2b524SDag-Erling Smørgrav } 12328ed2b524SDag-Erling Smørgrav return 1; 12338ed2b524SDag-Erling Smørgrav } 12348ed2b524SDag-Erling Smørgrav 12358ed2b524SDag-Erling Smørgrav /** 12368ed2b524SDag-Erling Smørgrav * Check a canonical sig+rrset and signature against a dnskey 12378ed2b524SDag-Erling Smørgrav * @param buf: buffer with data to verify, the first rrsig part and the 12388ed2b524SDag-Erling Smørgrav * canonicalized rrset. 12398ed2b524SDag-Erling Smørgrav * @param algo: DNSKEY algorithm. 12408ed2b524SDag-Erling Smørgrav * @param sigblock: signature rdata field from RRSIG 12418ed2b524SDag-Erling Smørgrav * @param sigblock_len: length of sigblock data. 12428ed2b524SDag-Erling Smørgrav * @param key: public key data from DNSKEY RR. 12438ed2b524SDag-Erling Smørgrav * @param keylen: length of keydata. 12448ed2b524SDag-Erling Smørgrav * @param reason: bogus reason in more detail. 12458ed2b524SDag-Erling Smørgrav * @return secure if verification succeeded, bogus on crypto failure, 12468ed2b524SDag-Erling Smørgrav * unchecked on format errors and alloc failures. 12478ed2b524SDag-Erling Smørgrav */ 12488ed2b524SDag-Erling Smørgrav enum sec_status 124917d15b25SDag-Erling Smørgrav verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock, 12508ed2b524SDag-Erling Smørgrav unsigned int sigblock_len, unsigned char* key, unsigned int keylen, 12518ed2b524SDag-Erling Smørgrav char** reason) 12528ed2b524SDag-Erling Smørgrav { 12538ed2b524SDag-Erling Smørgrav /* uses libNSS */ 12548ed2b524SDag-Erling Smørgrav /* large enough for the different hashes */ 12558ed2b524SDag-Erling Smørgrav unsigned char hash[HASH_LENGTH_MAX]; 12568ed2b524SDag-Erling Smørgrav unsigned char hash2[HASH_LENGTH_MAX*2]; 12578ed2b524SDag-Erling Smørgrav HASH_HashType htype = 0; 12588ed2b524SDag-Erling Smørgrav SECKEYPublicKey* pubkey = NULL; 12598ed2b524SDag-Erling Smørgrav SECItem secsig = {siBuffer, sigblock, sigblock_len}; 12608ed2b524SDag-Erling Smørgrav SECItem sechash = {siBuffer, hash, 0}; 12618ed2b524SDag-Erling Smørgrav SECStatus res; 12628ed2b524SDag-Erling Smørgrav unsigned char* prefix = NULL; /* prefix for hash, RFC3110, RFC5702 */ 12638ed2b524SDag-Erling Smørgrav size_t prefixlen = 0; 12648ed2b524SDag-Erling Smørgrav int err; 12658ed2b524SDag-Erling Smørgrav 12668ed2b524SDag-Erling Smørgrav if(!nss_setup_key_digest(algo, &pubkey, &htype, key, keylen, 12678ed2b524SDag-Erling Smørgrav &prefix, &prefixlen)) { 12688ed2b524SDag-Erling Smørgrav verbose(VERB_QUERY, "verify: failed to setup key"); 12698ed2b524SDag-Erling Smørgrav *reason = "use of key for crypto failed"; 12708ed2b524SDag-Erling Smørgrav SECKEY_DestroyPublicKey(pubkey); 12718ed2b524SDag-Erling Smørgrav return sec_status_bogus; 12728ed2b524SDag-Erling Smørgrav } 12738ed2b524SDag-Erling Smørgrav 127465b390aaSDag-Erling Smørgrav #if defined(USE_DSA) && defined(USE_SHA1) 12758ed2b524SDag-Erling Smørgrav /* need to convert DSA, ECDSA signatures? */ 12768ed2b524SDag-Erling Smørgrav if((algo == LDNS_DSA || algo == LDNS_DSA_NSEC3)) { 12778ed2b524SDag-Erling Smørgrav if(sigblock_len == 1+2*SHA1_LENGTH) { 12788ed2b524SDag-Erling Smørgrav secsig.data ++; 12798ed2b524SDag-Erling Smørgrav secsig.len --; 12808ed2b524SDag-Erling Smørgrav } else { 12818ed2b524SDag-Erling Smørgrav SECItem* p = DSAU_DecodeDerSig(&secsig); 12828ed2b524SDag-Erling Smørgrav if(!p) { 12838ed2b524SDag-Erling Smørgrav verbose(VERB_QUERY, "verify: failed DER decode"); 12848ed2b524SDag-Erling Smørgrav *reason = "signature DER decode failed"; 12858ed2b524SDag-Erling Smørgrav SECKEY_DestroyPublicKey(pubkey); 12868ed2b524SDag-Erling Smørgrav return sec_status_bogus; 12878ed2b524SDag-Erling Smørgrav } 12888ed2b524SDag-Erling Smørgrav if(SECITEM_CopyItem(pubkey->arena, &secsig, p)) { 12898ed2b524SDag-Erling Smørgrav log_err("alloc failure in DER decode"); 12908ed2b524SDag-Erling Smørgrav SECKEY_DestroyPublicKey(pubkey); 12918ed2b524SDag-Erling Smørgrav SECITEM_FreeItem(p, PR_TRUE); 12928ed2b524SDag-Erling Smørgrav return sec_status_unchecked; 12938ed2b524SDag-Erling Smørgrav } 12948ed2b524SDag-Erling Smørgrav SECITEM_FreeItem(p, PR_TRUE); 12958ed2b524SDag-Erling Smørgrav } 12968ed2b524SDag-Erling Smørgrav } 1297e2d15004SDag-Erling Smørgrav #endif /* USE_DSA */ 12988ed2b524SDag-Erling Smørgrav 12998ed2b524SDag-Erling Smørgrav /* do the signature cryptography work */ 13008ed2b524SDag-Erling Smørgrav /* hash the data */ 13018ed2b524SDag-Erling Smørgrav sechash.len = HASH_ResultLen(htype); 13028ed2b524SDag-Erling Smørgrav if(sechash.len > sizeof(hash)) { 13038ed2b524SDag-Erling Smørgrav verbose(VERB_QUERY, "verify: hash too large for buffer"); 13048ed2b524SDag-Erling Smørgrav SECKEY_DestroyPublicKey(pubkey); 13058ed2b524SDag-Erling Smørgrav return sec_status_unchecked; 13068ed2b524SDag-Erling Smørgrav } 130717d15b25SDag-Erling Smørgrav if(HASH_HashBuf(htype, hash, (unsigned char*)sldns_buffer_begin(buf), 130817d15b25SDag-Erling Smørgrav (unsigned int)sldns_buffer_limit(buf)) != SECSuccess) { 13098ed2b524SDag-Erling Smørgrav verbose(VERB_QUERY, "verify: HASH_HashBuf failed"); 13108ed2b524SDag-Erling Smørgrav SECKEY_DestroyPublicKey(pubkey); 13118ed2b524SDag-Erling Smørgrav return sec_status_unchecked; 13128ed2b524SDag-Erling Smørgrav } 13138ed2b524SDag-Erling Smørgrav if(prefix) { 13148ed2b524SDag-Erling Smørgrav int hashlen = sechash.len; 13158ed2b524SDag-Erling Smørgrav if(prefixlen+hashlen > sizeof(hash2)) { 13168ed2b524SDag-Erling Smørgrav verbose(VERB_QUERY, "verify: hashprefix too large"); 13178ed2b524SDag-Erling Smørgrav SECKEY_DestroyPublicKey(pubkey); 13188ed2b524SDag-Erling Smørgrav return sec_status_unchecked; 13198ed2b524SDag-Erling Smørgrav } 13208ed2b524SDag-Erling Smørgrav sechash.data = hash2; 13218ed2b524SDag-Erling Smørgrav sechash.len = prefixlen+hashlen; 13228ed2b524SDag-Erling Smørgrav memcpy(sechash.data, prefix, prefixlen); 13238ed2b524SDag-Erling Smørgrav memmove(sechash.data+prefixlen, hash, hashlen); 13248ed2b524SDag-Erling Smørgrav } 13258ed2b524SDag-Erling Smørgrav 13268ed2b524SDag-Erling Smørgrav /* verify the signature */ 13278ed2b524SDag-Erling Smørgrav res = PK11_Verify(pubkey, &secsig, &sechash, NULL /*wincx*/); 13288ed2b524SDag-Erling Smørgrav SECKEY_DestroyPublicKey(pubkey); 13298ed2b524SDag-Erling Smørgrav 13308ed2b524SDag-Erling Smørgrav if(res == SECSuccess) { 13318ed2b524SDag-Erling Smørgrav return sec_status_secure; 13328ed2b524SDag-Erling Smørgrav } 13338ed2b524SDag-Erling Smørgrav err = PORT_GetError(); 13348ed2b524SDag-Erling Smørgrav if(err != SEC_ERROR_BAD_SIGNATURE) { 13358ed2b524SDag-Erling Smørgrav /* failed to verify */ 13368ed2b524SDag-Erling Smørgrav verbose(VERB_QUERY, "verify: PK11_Verify failed: %s", 13378ed2b524SDag-Erling Smørgrav PORT_ErrorToString(err)); 13388ed2b524SDag-Erling Smørgrav /* if it is not supported, like ECC is removed, we get, 13398ed2b524SDag-Erling Smørgrav * SEC_ERROR_NO_MODULE */ 13408ed2b524SDag-Erling Smørgrav if(err == SEC_ERROR_NO_MODULE) 13418ed2b524SDag-Erling Smørgrav return sec_status_unchecked; 13428ed2b524SDag-Erling Smørgrav /* but other errors are commonly returned 13438ed2b524SDag-Erling Smørgrav * for a bad signature from NSS. Thus we return bogus, 13448ed2b524SDag-Erling Smørgrav * not unchecked */ 13458ed2b524SDag-Erling Smørgrav *reason = "signature crypto failed"; 13468ed2b524SDag-Erling Smørgrav return sec_status_bogus; 13478ed2b524SDag-Erling Smørgrav } 13488ed2b524SDag-Erling Smørgrav verbose(VERB_QUERY, "verify: signature mismatch: %s", 13498ed2b524SDag-Erling Smørgrav PORT_ErrorToString(err)); 13508ed2b524SDag-Erling Smørgrav *reason = "signature crypto failed"; 13518ed2b524SDag-Erling Smørgrav return sec_status_bogus; 13528ed2b524SDag-Erling Smørgrav } 13538ed2b524SDag-Erling Smørgrav 135405ab2901SDag-Erling Smørgrav #elif defined(HAVE_NETTLE) 13558ed2b524SDag-Erling Smørgrav 135605ab2901SDag-Erling Smørgrav #include "sha.h" 135705ab2901SDag-Erling Smørgrav #include "bignum.h" 135805ab2901SDag-Erling Smørgrav #include "macros.h" 135905ab2901SDag-Erling Smørgrav #include "rsa.h" 136005ab2901SDag-Erling Smørgrav #include "dsa.h" 1361b5663de9SDag-Erling Smørgrav #ifdef HAVE_NETTLE_DSA_COMPAT_H 1362b5663de9SDag-Erling Smørgrav #include "dsa-compat.h" 1363b5663de9SDag-Erling Smørgrav #endif 136405ab2901SDag-Erling Smørgrav #include "asn1.h" 136505ab2901SDag-Erling Smørgrav #ifdef USE_ECDSA 136605ab2901SDag-Erling Smørgrav #include "ecdsa.h" 136705ab2901SDag-Erling Smørgrav #include "ecc-curve.h" 136805ab2901SDag-Erling Smørgrav #endif 1369971980c3SDag-Erling Smørgrav #ifdef HAVE_NETTLE_EDDSA_H 1370971980c3SDag-Erling Smørgrav #include "eddsa.h" 1371971980c3SDag-Erling Smørgrav #endif 137205ab2901SDag-Erling Smørgrav 137305ab2901SDag-Erling Smørgrav static int 137405ab2901SDag-Erling Smørgrav _digest_nettle(int algo, uint8_t* buf, size_t len, 137505ab2901SDag-Erling Smørgrav unsigned char* res) 137605ab2901SDag-Erling Smørgrav { 137705ab2901SDag-Erling Smørgrav switch(algo) { 137805ab2901SDag-Erling Smørgrav case SHA1_DIGEST_SIZE: 137905ab2901SDag-Erling Smørgrav { 138005ab2901SDag-Erling Smørgrav struct sha1_ctx ctx; 138105ab2901SDag-Erling Smørgrav sha1_init(&ctx); 138205ab2901SDag-Erling Smørgrav sha1_update(&ctx, len, buf); 138305ab2901SDag-Erling Smørgrav sha1_digest(&ctx, SHA1_DIGEST_SIZE, res); 138405ab2901SDag-Erling Smørgrav return 1; 138505ab2901SDag-Erling Smørgrav } 138605ab2901SDag-Erling Smørgrav case SHA256_DIGEST_SIZE: 138705ab2901SDag-Erling Smørgrav { 138805ab2901SDag-Erling Smørgrav struct sha256_ctx ctx; 138905ab2901SDag-Erling Smørgrav sha256_init(&ctx); 139005ab2901SDag-Erling Smørgrav sha256_update(&ctx, len, buf); 139105ab2901SDag-Erling Smørgrav sha256_digest(&ctx, SHA256_DIGEST_SIZE, res); 139205ab2901SDag-Erling Smørgrav return 1; 139305ab2901SDag-Erling Smørgrav } 139405ab2901SDag-Erling Smørgrav case SHA384_DIGEST_SIZE: 139505ab2901SDag-Erling Smørgrav { 139605ab2901SDag-Erling Smørgrav struct sha384_ctx ctx; 139705ab2901SDag-Erling Smørgrav sha384_init(&ctx); 139805ab2901SDag-Erling Smørgrav sha384_update(&ctx, len, buf); 139905ab2901SDag-Erling Smørgrav sha384_digest(&ctx, SHA384_DIGEST_SIZE, res); 140005ab2901SDag-Erling Smørgrav return 1; 140105ab2901SDag-Erling Smørgrav } 140205ab2901SDag-Erling Smørgrav case SHA512_DIGEST_SIZE: 140305ab2901SDag-Erling Smørgrav { 140405ab2901SDag-Erling Smørgrav struct sha512_ctx ctx; 140505ab2901SDag-Erling Smørgrav sha512_init(&ctx); 140605ab2901SDag-Erling Smørgrav sha512_update(&ctx, len, buf); 140705ab2901SDag-Erling Smørgrav sha512_digest(&ctx, SHA512_DIGEST_SIZE, res); 140805ab2901SDag-Erling Smørgrav return 1; 140905ab2901SDag-Erling Smørgrav } 141005ab2901SDag-Erling Smørgrav default: 141105ab2901SDag-Erling Smørgrav break; 141205ab2901SDag-Erling Smørgrav } 141305ab2901SDag-Erling Smørgrav return 0; 141405ab2901SDag-Erling Smørgrav } 141505ab2901SDag-Erling Smørgrav 141605ab2901SDag-Erling Smørgrav /* return size of digest if supported, or 0 otherwise */ 141705ab2901SDag-Erling Smørgrav size_t 141805ab2901SDag-Erling Smørgrav nsec3_hash_algo_size_supported(int id) 141905ab2901SDag-Erling Smørgrav { 142005ab2901SDag-Erling Smørgrav switch(id) { 142105ab2901SDag-Erling Smørgrav case NSEC3_HASH_SHA1: 142205ab2901SDag-Erling Smørgrav return SHA1_DIGEST_SIZE; 142305ab2901SDag-Erling Smørgrav default: 142405ab2901SDag-Erling Smørgrav return 0; 142505ab2901SDag-Erling Smørgrav } 142605ab2901SDag-Erling Smørgrav } 142705ab2901SDag-Erling Smørgrav 142805ab2901SDag-Erling Smørgrav /* perform nsec3 hash. return false on failure */ 142905ab2901SDag-Erling Smørgrav int 143005ab2901SDag-Erling Smørgrav secalgo_nsec3_hash(int algo, unsigned char* buf, size_t len, 143105ab2901SDag-Erling Smørgrav unsigned char* res) 143205ab2901SDag-Erling Smørgrav { 143305ab2901SDag-Erling Smørgrav switch(algo) { 143405ab2901SDag-Erling Smørgrav case NSEC3_HASH_SHA1: 143505ab2901SDag-Erling Smørgrav return _digest_nettle(SHA1_DIGEST_SIZE, (uint8_t*)buf, len, 143605ab2901SDag-Erling Smørgrav res); 143705ab2901SDag-Erling Smørgrav default: 143805ab2901SDag-Erling Smørgrav return 0; 143905ab2901SDag-Erling Smørgrav } 144005ab2901SDag-Erling Smørgrav } 144105ab2901SDag-Erling Smørgrav 1442e2d15004SDag-Erling Smørgrav void 1443e2d15004SDag-Erling Smørgrav secalgo_hash_sha256(unsigned char* buf, size_t len, unsigned char* res) 1444e2d15004SDag-Erling Smørgrav { 1445e2d15004SDag-Erling Smørgrav _digest_nettle(SHA256_DIGEST_SIZE, (uint8_t*)buf, len, res); 1446e2d15004SDag-Erling Smørgrav } 1447e2d15004SDag-Erling Smørgrav 144805ab2901SDag-Erling Smørgrav /** 144905ab2901SDag-Erling Smørgrav * Return size of DS digest according to its hash algorithm. 145005ab2901SDag-Erling Smørgrav * @param algo: DS digest algo. 145105ab2901SDag-Erling Smørgrav * @return size in bytes of digest, or 0 if not supported. 145205ab2901SDag-Erling Smørgrav */ 145305ab2901SDag-Erling Smørgrav size_t 145405ab2901SDag-Erling Smørgrav ds_digest_size_supported(int algo) 145505ab2901SDag-Erling Smørgrav { 145605ab2901SDag-Erling Smørgrav switch(algo) { 145705ab2901SDag-Erling Smørgrav case LDNS_SHA1: 145865b390aaSDag-Erling Smørgrav #ifdef USE_SHA1 145905ab2901SDag-Erling Smørgrav return SHA1_DIGEST_SIZE; 146065b390aaSDag-Erling Smørgrav #else 146165b390aaSDag-Erling Smørgrav if(fake_sha1) return 20; 146265b390aaSDag-Erling Smørgrav return 0; 146365b390aaSDag-Erling Smørgrav #endif 146405ab2901SDag-Erling Smørgrav #ifdef USE_SHA2 146505ab2901SDag-Erling Smørgrav case LDNS_SHA256: 146605ab2901SDag-Erling Smørgrav return SHA256_DIGEST_SIZE; 146705ab2901SDag-Erling Smørgrav #endif 146805ab2901SDag-Erling Smørgrav #ifdef USE_ECDSA 146905ab2901SDag-Erling Smørgrav case LDNS_SHA384: 147005ab2901SDag-Erling Smørgrav return SHA384_DIGEST_SIZE; 147105ab2901SDag-Erling Smørgrav #endif 147205ab2901SDag-Erling Smørgrav /* GOST not supported */ 147305ab2901SDag-Erling Smørgrav case LDNS_HASH_GOST: 147405ab2901SDag-Erling Smørgrav default: 147505ab2901SDag-Erling Smørgrav break; 147605ab2901SDag-Erling Smørgrav } 147705ab2901SDag-Erling Smørgrav return 0; 147805ab2901SDag-Erling Smørgrav } 147905ab2901SDag-Erling Smørgrav 148005ab2901SDag-Erling Smørgrav int 148105ab2901SDag-Erling Smørgrav secalgo_ds_digest(int algo, unsigned char* buf, size_t len, 148205ab2901SDag-Erling Smørgrav unsigned char* res) 148305ab2901SDag-Erling Smørgrav { 148405ab2901SDag-Erling Smørgrav switch(algo) { 148565b390aaSDag-Erling Smørgrav #ifdef USE_SHA1 148605ab2901SDag-Erling Smørgrav case LDNS_SHA1: 148705ab2901SDag-Erling Smørgrav return _digest_nettle(SHA1_DIGEST_SIZE, buf, len, res); 148865b390aaSDag-Erling Smørgrav #endif 148905ab2901SDag-Erling Smørgrav #if defined(USE_SHA2) 149005ab2901SDag-Erling Smørgrav case LDNS_SHA256: 149105ab2901SDag-Erling Smørgrav return _digest_nettle(SHA256_DIGEST_SIZE, buf, len, res); 149205ab2901SDag-Erling Smørgrav #endif 149305ab2901SDag-Erling Smørgrav #ifdef USE_ECDSA 149405ab2901SDag-Erling Smørgrav case LDNS_SHA384: 149505ab2901SDag-Erling Smørgrav return _digest_nettle(SHA384_DIGEST_SIZE, buf, len, res); 149605ab2901SDag-Erling Smørgrav 149705ab2901SDag-Erling Smørgrav #endif 149805ab2901SDag-Erling Smørgrav case LDNS_HASH_GOST: 149905ab2901SDag-Erling Smørgrav default: 150005ab2901SDag-Erling Smørgrav verbose(VERB_QUERY, "unknown DS digest algorithm %d", 150105ab2901SDag-Erling Smørgrav algo); 150205ab2901SDag-Erling Smørgrav break; 150305ab2901SDag-Erling Smørgrav } 150405ab2901SDag-Erling Smørgrav return 0; 150505ab2901SDag-Erling Smørgrav } 150605ab2901SDag-Erling Smørgrav 150705ab2901SDag-Erling Smørgrav int 150805ab2901SDag-Erling Smørgrav dnskey_algo_id_is_supported(int id) 150905ab2901SDag-Erling Smørgrav { 151005ab2901SDag-Erling Smørgrav /* uses libnettle */ 151105ab2901SDag-Erling Smørgrav switch(id) { 151265b390aaSDag-Erling Smørgrav #if defined(USE_DSA) && defined(USE_SHA1) 151305ab2901SDag-Erling Smørgrav case LDNS_DSA: 151405ab2901SDag-Erling Smørgrav case LDNS_DSA_NSEC3: 1515e2d15004SDag-Erling Smørgrav #endif 151665b390aaSDag-Erling Smørgrav #ifdef USE_SHA1 151705ab2901SDag-Erling Smørgrav case LDNS_RSASHA1: 151805ab2901SDag-Erling Smørgrav case LDNS_RSASHA1_NSEC3: 151965b390aaSDag-Erling Smørgrav #endif 152005ab2901SDag-Erling Smørgrav #ifdef USE_SHA2 152105ab2901SDag-Erling Smørgrav case LDNS_RSASHA256: 152205ab2901SDag-Erling Smørgrav case LDNS_RSASHA512: 152305ab2901SDag-Erling Smørgrav #endif 152405ab2901SDag-Erling Smørgrav #ifdef USE_ECDSA 152505ab2901SDag-Erling Smørgrav case LDNS_ECDSAP256SHA256: 152605ab2901SDag-Erling Smørgrav case LDNS_ECDSAP384SHA384: 152705ab2901SDag-Erling Smørgrav #endif 152805ab2901SDag-Erling Smørgrav return 1; 1529971980c3SDag-Erling Smørgrav #ifdef USE_ED25519 1530971980c3SDag-Erling Smørgrav case LDNS_ED25519: 1531971980c3SDag-Erling Smørgrav return 1; 1532971980c3SDag-Erling Smørgrav #endif 153305ab2901SDag-Erling Smørgrav case LDNS_RSAMD5: /* RFC 6725 deprecates RSAMD5 */ 153405ab2901SDag-Erling Smørgrav case LDNS_ECC_GOST: 153505ab2901SDag-Erling Smørgrav default: 153605ab2901SDag-Erling Smørgrav return 0; 153705ab2901SDag-Erling Smørgrav } 153805ab2901SDag-Erling Smørgrav } 153905ab2901SDag-Erling Smørgrav 154065b390aaSDag-Erling Smørgrav #if defined(USE_DSA) && defined(USE_SHA1) 154105ab2901SDag-Erling Smørgrav static char * 154205ab2901SDag-Erling Smørgrav _verify_nettle_dsa(sldns_buffer* buf, unsigned char* sigblock, 154305ab2901SDag-Erling Smørgrav unsigned int sigblock_len, unsigned char* key, unsigned int keylen) 154405ab2901SDag-Erling Smørgrav { 154505ab2901SDag-Erling Smørgrav uint8_t digest[SHA1_DIGEST_SIZE]; 15463005e0a3SDag-Erling Smørgrav uint8_t key_t_value; 154705ab2901SDag-Erling Smørgrav int res = 0; 154805ab2901SDag-Erling Smørgrav size_t offset; 154905ab2901SDag-Erling Smørgrav struct dsa_public_key pubkey; 155005ab2901SDag-Erling Smørgrav struct dsa_signature signature; 155105ab2901SDag-Erling Smørgrav unsigned int expected_len; 155205ab2901SDag-Erling Smørgrav 155305ab2901SDag-Erling Smørgrav /* Extract DSA signature from the record */ 155405ab2901SDag-Erling Smørgrav nettle_dsa_signature_init(&signature); 155505ab2901SDag-Erling Smørgrav /* Signature length: 41 bytes - RFC 2536 sec. 3 */ 155605ab2901SDag-Erling Smørgrav if(sigblock_len == 41) { 155705ab2901SDag-Erling Smørgrav if(key[0] != sigblock[0]) 155805ab2901SDag-Erling Smørgrav return "invalid T value in DSA signature or pubkey"; 155905ab2901SDag-Erling Smørgrav nettle_mpz_set_str_256_u(signature.r, 20, sigblock+1); 156005ab2901SDag-Erling Smørgrav nettle_mpz_set_str_256_u(signature.s, 20, sigblock+1+20); 156105ab2901SDag-Erling Smørgrav } else { 156205ab2901SDag-Erling Smørgrav /* DER encoded, decode the ASN1 notated R and S bignums */ 156305ab2901SDag-Erling Smørgrav /* SEQUENCE { r INTEGER, s INTEGER } */ 156405ab2901SDag-Erling Smørgrav struct asn1_der_iterator i, seq; 156505ab2901SDag-Erling Smørgrav if(asn1_der_iterator_first(&i, sigblock_len, 156605ab2901SDag-Erling Smørgrav (uint8_t*)sigblock) != ASN1_ITERATOR_CONSTRUCTED 156705ab2901SDag-Erling Smørgrav || i.type != ASN1_SEQUENCE) 156805ab2901SDag-Erling Smørgrav return "malformed DER encoded DSA signature"; 156905ab2901SDag-Erling Smørgrav /* decode this element of i using the seq iterator */ 157005ab2901SDag-Erling Smørgrav if(asn1_der_decode_constructed(&i, &seq) != 157105ab2901SDag-Erling Smørgrav ASN1_ITERATOR_PRIMITIVE || seq.type != ASN1_INTEGER) 157205ab2901SDag-Erling Smørgrav return "malformed DER encoded DSA signature"; 157305ab2901SDag-Erling Smørgrav if(!asn1_der_get_bignum(&seq, signature.r, 20*8)) 157405ab2901SDag-Erling Smørgrav return "malformed DER encoded DSA signature"; 157505ab2901SDag-Erling Smørgrav if(asn1_der_iterator_next(&seq) != ASN1_ITERATOR_PRIMITIVE 157605ab2901SDag-Erling Smørgrav || seq.type != ASN1_INTEGER) 157705ab2901SDag-Erling Smørgrav return "malformed DER encoded DSA signature"; 157805ab2901SDag-Erling Smørgrav if(!asn1_der_get_bignum(&seq, signature.s, 20*8)) 157905ab2901SDag-Erling Smørgrav return "malformed DER encoded DSA signature"; 158005ab2901SDag-Erling Smørgrav if(asn1_der_iterator_next(&i) != ASN1_ITERATOR_END) 158105ab2901SDag-Erling Smørgrav return "malformed DER encoded DSA signature"; 158205ab2901SDag-Erling Smørgrav } 158305ab2901SDag-Erling Smørgrav 158405ab2901SDag-Erling Smørgrav /* Validate T values constraints - RFC 2536 sec. 2 & sec. 3 */ 15853005e0a3SDag-Erling Smørgrav key_t_value = key[0]; 15863005e0a3SDag-Erling Smørgrav if (key_t_value > 8) { 158705ab2901SDag-Erling Smørgrav return "invalid T value in DSA pubkey"; 158805ab2901SDag-Erling Smørgrav } 158905ab2901SDag-Erling Smørgrav 159005ab2901SDag-Erling Smørgrav /* Pubkey minimum length: 21 bytes - RFC 2536 sec. 2 */ 159105ab2901SDag-Erling Smørgrav if (keylen < 21) { 159205ab2901SDag-Erling Smørgrav return "DSA pubkey too short"; 159305ab2901SDag-Erling Smørgrav } 159405ab2901SDag-Erling Smørgrav 159505ab2901SDag-Erling Smørgrav expected_len = 1 + /* T */ 159605ab2901SDag-Erling Smørgrav 20 + /* Q */ 15973005e0a3SDag-Erling Smørgrav (64 + key_t_value*8) + /* P */ 15983005e0a3SDag-Erling Smørgrav (64 + key_t_value*8) + /* G */ 15993005e0a3SDag-Erling Smørgrav (64 + key_t_value*8); /* Y */ 160005ab2901SDag-Erling Smørgrav if (keylen != expected_len ) { 160105ab2901SDag-Erling Smørgrav return "invalid DSA pubkey length"; 160205ab2901SDag-Erling Smørgrav } 160305ab2901SDag-Erling Smørgrav 160405ab2901SDag-Erling Smørgrav /* Extract DSA pubkey from the record */ 160505ab2901SDag-Erling Smørgrav nettle_dsa_public_key_init(&pubkey); 160605ab2901SDag-Erling Smørgrav offset = 1; 160705ab2901SDag-Erling Smørgrav nettle_mpz_set_str_256_u(pubkey.q, 20, key+offset); 160805ab2901SDag-Erling Smørgrav offset += 20; 16093005e0a3SDag-Erling Smørgrav nettle_mpz_set_str_256_u(pubkey.p, (64 + key_t_value*8), key+offset); 16103005e0a3SDag-Erling Smørgrav offset += (64 + key_t_value*8); 16113005e0a3SDag-Erling Smørgrav nettle_mpz_set_str_256_u(pubkey.g, (64 + key_t_value*8), key+offset); 16123005e0a3SDag-Erling Smørgrav offset += (64 + key_t_value*8); 16133005e0a3SDag-Erling Smørgrav nettle_mpz_set_str_256_u(pubkey.y, (64 + key_t_value*8), key+offset); 161405ab2901SDag-Erling Smørgrav 161505ab2901SDag-Erling Smørgrav /* Digest content of "buf" and verify its DSA signature in "sigblock"*/ 161605ab2901SDag-Erling Smørgrav res = _digest_nettle(SHA1_DIGEST_SIZE, (unsigned char*)sldns_buffer_begin(buf), 161705ab2901SDag-Erling Smørgrav (unsigned int)sldns_buffer_limit(buf), (unsigned char*)digest); 161805ab2901SDag-Erling Smørgrav res &= dsa_sha1_verify_digest(&pubkey, digest, &signature); 161905ab2901SDag-Erling Smørgrav 162005ab2901SDag-Erling Smørgrav /* Clear and return */ 162105ab2901SDag-Erling Smørgrav nettle_dsa_signature_clear(&signature); 162205ab2901SDag-Erling Smørgrav nettle_dsa_public_key_clear(&pubkey); 162305ab2901SDag-Erling Smørgrav if (!res) 162405ab2901SDag-Erling Smørgrav return "DSA signature verification failed"; 162505ab2901SDag-Erling Smørgrav else 162605ab2901SDag-Erling Smørgrav return NULL; 162705ab2901SDag-Erling Smørgrav } 1628b5663de9SDag-Erling Smørgrav #endif /* USE_DSA */ 162905ab2901SDag-Erling Smørgrav 163005ab2901SDag-Erling Smørgrav static char * 163105ab2901SDag-Erling Smørgrav _verify_nettle_rsa(sldns_buffer* buf, unsigned int digest_size, char* sigblock, 163205ab2901SDag-Erling Smørgrav unsigned int sigblock_len, uint8_t* key, unsigned int keylen) 163305ab2901SDag-Erling Smørgrav { 163405ab2901SDag-Erling Smørgrav uint16_t exp_len = 0; 163505ab2901SDag-Erling Smørgrav size_t exp_offset = 0, mod_offset = 0; 163605ab2901SDag-Erling Smørgrav struct rsa_public_key pubkey; 163705ab2901SDag-Erling Smørgrav mpz_t signature; 163805ab2901SDag-Erling Smørgrav int res = 0; 163905ab2901SDag-Erling Smørgrav 164005ab2901SDag-Erling Smørgrav /* RSA pubkey parsing as per RFC 3110 sec. 2 */ 164105ab2901SDag-Erling Smørgrav if( keylen <= 1) { 164205ab2901SDag-Erling Smørgrav return "null RSA key"; 164305ab2901SDag-Erling Smørgrav } 164405ab2901SDag-Erling Smørgrav if (key[0] != 0) { 164505ab2901SDag-Erling Smørgrav /* 1-byte length */ 164605ab2901SDag-Erling Smørgrav exp_len = key[0]; 164705ab2901SDag-Erling Smørgrav exp_offset = 1; 164805ab2901SDag-Erling Smørgrav } else { 164905ab2901SDag-Erling Smørgrav /* 1-byte NUL + 2-bytes exponent length */ 165005ab2901SDag-Erling Smørgrav if (keylen < 3) { 165105ab2901SDag-Erling Smørgrav return "incorrect RSA key length"; 165205ab2901SDag-Erling Smørgrav } 165305ab2901SDag-Erling Smørgrav exp_len = READ_UINT16(key+1); 165405ab2901SDag-Erling Smørgrav if (exp_len == 0) 165505ab2901SDag-Erling Smørgrav return "null RSA exponent length"; 165605ab2901SDag-Erling Smørgrav exp_offset = 3; 165705ab2901SDag-Erling Smørgrav } 165805ab2901SDag-Erling Smørgrav /* Check that we are not over-running input length */ 165905ab2901SDag-Erling Smørgrav if (keylen < exp_offset + exp_len + 1) { 166005ab2901SDag-Erling Smørgrav return "RSA key content shorter than expected"; 166105ab2901SDag-Erling Smørgrav } 166205ab2901SDag-Erling Smørgrav mod_offset = exp_offset + exp_len; 166305ab2901SDag-Erling Smørgrav nettle_rsa_public_key_init(&pubkey); 166405ab2901SDag-Erling Smørgrav pubkey.size = keylen - mod_offset; 166505ab2901SDag-Erling Smørgrav nettle_mpz_set_str_256_u(pubkey.e, exp_len, &key[exp_offset]); 166605ab2901SDag-Erling Smørgrav nettle_mpz_set_str_256_u(pubkey.n, pubkey.size, &key[mod_offset]); 166705ab2901SDag-Erling Smørgrav 166805ab2901SDag-Erling Smørgrav /* Digest content of "buf" and verify its RSA signature in "sigblock"*/ 166905ab2901SDag-Erling Smørgrav nettle_mpz_init_set_str_256_u(signature, sigblock_len, (uint8_t*)sigblock); 167005ab2901SDag-Erling Smørgrav switch (digest_size) { 167105ab2901SDag-Erling Smørgrav case SHA1_DIGEST_SIZE: 167205ab2901SDag-Erling Smørgrav { 167305ab2901SDag-Erling Smørgrav uint8_t digest[SHA1_DIGEST_SIZE]; 167405ab2901SDag-Erling Smørgrav res = _digest_nettle(SHA1_DIGEST_SIZE, (unsigned char*)sldns_buffer_begin(buf), 167505ab2901SDag-Erling Smørgrav (unsigned int)sldns_buffer_limit(buf), (unsigned char*)digest); 167605ab2901SDag-Erling Smørgrav res &= rsa_sha1_verify_digest(&pubkey, digest, signature); 167705ab2901SDag-Erling Smørgrav break; 167805ab2901SDag-Erling Smørgrav } 167905ab2901SDag-Erling Smørgrav case SHA256_DIGEST_SIZE: 168005ab2901SDag-Erling Smørgrav { 168105ab2901SDag-Erling Smørgrav uint8_t digest[SHA256_DIGEST_SIZE]; 168205ab2901SDag-Erling Smørgrav res = _digest_nettle(SHA256_DIGEST_SIZE, (unsigned char*)sldns_buffer_begin(buf), 168305ab2901SDag-Erling Smørgrav (unsigned int)sldns_buffer_limit(buf), (unsigned char*)digest); 168405ab2901SDag-Erling Smørgrav res &= rsa_sha256_verify_digest(&pubkey, digest, signature); 168505ab2901SDag-Erling Smørgrav break; 168605ab2901SDag-Erling Smørgrav } 168705ab2901SDag-Erling Smørgrav case SHA512_DIGEST_SIZE: 168805ab2901SDag-Erling Smørgrav { 168905ab2901SDag-Erling Smørgrav uint8_t digest[SHA512_DIGEST_SIZE]; 169005ab2901SDag-Erling Smørgrav res = _digest_nettle(SHA512_DIGEST_SIZE, (unsigned char*)sldns_buffer_begin(buf), 169105ab2901SDag-Erling Smørgrav (unsigned int)sldns_buffer_limit(buf), (unsigned char*)digest); 169205ab2901SDag-Erling Smørgrav res &= rsa_sha512_verify_digest(&pubkey, digest, signature); 169305ab2901SDag-Erling Smørgrav break; 169405ab2901SDag-Erling Smørgrav } 169505ab2901SDag-Erling Smørgrav default: 169605ab2901SDag-Erling Smørgrav break; 169705ab2901SDag-Erling Smørgrav } 169805ab2901SDag-Erling Smørgrav 169905ab2901SDag-Erling Smørgrav /* Clear and return */ 170005ab2901SDag-Erling Smørgrav nettle_rsa_public_key_clear(&pubkey); 170105ab2901SDag-Erling Smørgrav mpz_clear(signature); 170205ab2901SDag-Erling Smørgrav if (!res) { 170305ab2901SDag-Erling Smørgrav return "RSA signature verification failed"; 170405ab2901SDag-Erling Smørgrav } else { 170505ab2901SDag-Erling Smørgrav return NULL; 170605ab2901SDag-Erling Smørgrav } 170705ab2901SDag-Erling Smørgrav } 170805ab2901SDag-Erling Smørgrav 170905ab2901SDag-Erling Smørgrav #ifdef USE_ECDSA 171005ab2901SDag-Erling Smørgrav static char * 171105ab2901SDag-Erling Smørgrav _verify_nettle_ecdsa(sldns_buffer* buf, unsigned int digest_size, unsigned char* sigblock, 171205ab2901SDag-Erling Smørgrav unsigned int sigblock_len, unsigned char* key, unsigned int keylen) 171305ab2901SDag-Erling Smørgrav { 171405ab2901SDag-Erling Smørgrav int res = 0; 171505ab2901SDag-Erling Smørgrav struct ecc_point pubkey; 171605ab2901SDag-Erling Smørgrav struct dsa_signature signature; 171705ab2901SDag-Erling Smørgrav 171805ab2901SDag-Erling Smørgrav /* Always matched strength, as per RFC 6605 sec. 1 */ 171905ab2901SDag-Erling Smørgrav if (sigblock_len != 2*digest_size || keylen != 2*digest_size) { 172005ab2901SDag-Erling Smørgrav return "wrong ECDSA signature length"; 172105ab2901SDag-Erling Smørgrav } 172205ab2901SDag-Erling Smørgrav 172305ab2901SDag-Erling Smørgrav /* Parse ECDSA signature as per RFC 6605 sec. 4 */ 172405ab2901SDag-Erling Smørgrav nettle_dsa_signature_init(&signature); 172505ab2901SDag-Erling Smørgrav switch (digest_size) { 172605ab2901SDag-Erling Smørgrav case SHA256_DIGEST_SIZE: 172705ab2901SDag-Erling Smørgrav { 172805ab2901SDag-Erling Smørgrav uint8_t digest[SHA256_DIGEST_SIZE]; 172905ab2901SDag-Erling Smørgrav mpz_t x, y; 1730*0eefd307SCy Schubert nettle_ecc_point_init(&pubkey, nettle_get_secp_256r1()); 173105ab2901SDag-Erling Smørgrav nettle_mpz_init_set_str_256_u(x, SHA256_DIGEST_SIZE, key); 173205ab2901SDag-Erling Smørgrav nettle_mpz_init_set_str_256_u(y, SHA256_DIGEST_SIZE, key+SHA256_DIGEST_SIZE); 173305ab2901SDag-Erling Smørgrav nettle_mpz_set_str_256_u(signature.r, SHA256_DIGEST_SIZE, sigblock); 173405ab2901SDag-Erling Smørgrav nettle_mpz_set_str_256_u(signature.s, SHA256_DIGEST_SIZE, sigblock+SHA256_DIGEST_SIZE); 173505ab2901SDag-Erling Smørgrav res = _digest_nettle(SHA256_DIGEST_SIZE, (unsigned char*)sldns_buffer_begin(buf), 173605ab2901SDag-Erling Smørgrav (unsigned int)sldns_buffer_limit(buf), (unsigned char*)digest); 173705ab2901SDag-Erling Smørgrav res &= nettle_ecc_point_set(&pubkey, x, y); 173805ab2901SDag-Erling Smørgrav res &= nettle_ecdsa_verify (&pubkey, SHA256_DIGEST_SIZE, digest, &signature); 173905ab2901SDag-Erling Smørgrav mpz_clear(x); 174005ab2901SDag-Erling Smørgrav mpz_clear(y); 174105ab2901SDag-Erling Smørgrav break; 174205ab2901SDag-Erling Smørgrav } 174305ab2901SDag-Erling Smørgrav case SHA384_DIGEST_SIZE: 174405ab2901SDag-Erling Smørgrav { 174505ab2901SDag-Erling Smørgrav uint8_t digest[SHA384_DIGEST_SIZE]; 174605ab2901SDag-Erling Smørgrav mpz_t x, y; 1747*0eefd307SCy Schubert nettle_ecc_point_init(&pubkey, nettle_get_secp_384r1()); 174805ab2901SDag-Erling Smørgrav nettle_mpz_init_set_str_256_u(x, SHA384_DIGEST_SIZE, key); 174905ab2901SDag-Erling Smørgrav nettle_mpz_init_set_str_256_u(y, SHA384_DIGEST_SIZE, key+SHA384_DIGEST_SIZE); 175005ab2901SDag-Erling Smørgrav nettle_mpz_set_str_256_u(signature.r, SHA384_DIGEST_SIZE, sigblock); 175105ab2901SDag-Erling Smørgrav nettle_mpz_set_str_256_u(signature.s, SHA384_DIGEST_SIZE, sigblock+SHA384_DIGEST_SIZE); 175205ab2901SDag-Erling Smørgrav res = _digest_nettle(SHA384_DIGEST_SIZE, (unsigned char*)sldns_buffer_begin(buf), 175305ab2901SDag-Erling Smørgrav (unsigned int)sldns_buffer_limit(buf), (unsigned char*)digest); 175405ab2901SDag-Erling Smørgrav res &= nettle_ecc_point_set(&pubkey, x, y); 175505ab2901SDag-Erling Smørgrav res &= nettle_ecdsa_verify (&pubkey, SHA384_DIGEST_SIZE, digest, &signature); 175605ab2901SDag-Erling Smørgrav mpz_clear(x); 175705ab2901SDag-Erling Smørgrav mpz_clear(y); 175805ab2901SDag-Erling Smørgrav nettle_ecc_point_clear(&pubkey); 175905ab2901SDag-Erling Smørgrav break; 176005ab2901SDag-Erling Smørgrav } 176105ab2901SDag-Erling Smørgrav default: 176205ab2901SDag-Erling Smørgrav return "unknown ECDSA algorithm"; 176305ab2901SDag-Erling Smørgrav } 176405ab2901SDag-Erling Smørgrav 176505ab2901SDag-Erling Smørgrav /* Clear and return */ 176605ab2901SDag-Erling Smørgrav nettle_dsa_signature_clear(&signature); 176705ab2901SDag-Erling Smørgrav if (!res) 176805ab2901SDag-Erling Smørgrav return "ECDSA signature verification failed"; 176905ab2901SDag-Erling Smørgrav else 177005ab2901SDag-Erling Smørgrav return NULL; 177105ab2901SDag-Erling Smørgrav } 177205ab2901SDag-Erling Smørgrav #endif 177305ab2901SDag-Erling Smørgrav 1774971980c3SDag-Erling Smørgrav #ifdef USE_ED25519 1775971980c3SDag-Erling Smørgrav static char * 1776971980c3SDag-Erling Smørgrav _verify_nettle_ed25519(sldns_buffer* buf, unsigned char* sigblock, 1777971980c3SDag-Erling Smørgrav unsigned int sigblock_len, unsigned char* key, unsigned int keylen) 1778971980c3SDag-Erling Smørgrav { 1779971980c3SDag-Erling Smørgrav int res = 0; 1780971980c3SDag-Erling Smørgrav 1781971980c3SDag-Erling Smørgrav if(sigblock_len != ED25519_SIGNATURE_SIZE) { 1782971980c3SDag-Erling Smørgrav return "wrong ED25519 signature length"; 1783971980c3SDag-Erling Smørgrav } 1784971980c3SDag-Erling Smørgrav if(keylen != ED25519_KEY_SIZE) { 1785971980c3SDag-Erling Smørgrav return "wrong ED25519 key length"; 1786971980c3SDag-Erling Smørgrav } 1787971980c3SDag-Erling Smørgrav 1788971980c3SDag-Erling Smørgrav res = ed25519_sha512_verify((uint8_t*)key, sldns_buffer_limit(buf), 1789971980c3SDag-Erling Smørgrav sldns_buffer_begin(buf), (uint8_t*)sigblock); 1790971980c3SDag-Erling Smørgrav 1791971980c3SDag-Erling Smørgrav if (!res) 1792971980c3SDag-Erling Smørgrav return "ED25519 signature verification failed"; 1793971980c3SDag-Erling Smørgrav else 1794971980c3SDag-Erling Smørgrav return NULL; 1795971980c3SDag-Erling Smørgrav } 1796971980c3SDag-Erling Smørgrav #endif 1797971980c3SDag-Erling Smørgrav 179805ab2901SDag-Erling Smørgrav /** 179905ab2901SDag-Erling Smørgrav * Check a canonical sig+rrset and signature against a dnskey 180005ab2901SDag-Erling Smørgrav * @param buf: buffer with data to verify, the first rrsig part and the 180105ab2901SDag-Erling Smørgrav * canonicalized rrset. 180205ab2901SDag-Erling Smørgrav * @param algo: DNSKEY algorithm. 180305ab2901SDag-Erling Smørgrav * @param sigblock: signature rdata field from RRSIG 180405ab2901SDag-Erling Smørgrav * @param sigblock_len: length of sigblock data. 180505ab2901SDag-Erling Smørgrav * @param key: public key data from DNSKEY RR. 180605ab2901SDag-Erling Smørgrav * @param keylen: length of keydata. 180705ab2901SDag-Erling Smørgrav * @param reason: bogus reason in more detail. 180805ab2901SDag-Erling Smørgrav * @return secure if verification succeeded, bogus on crypto failure, 180905ab2901SDag-Erling Smørgrav * unchecked on format errors and alloc failures. 181005ab2901SDag-Erling Smørgrav */ 181105ab2901SDag-Erling Smørgrav enum sec_status 181205ab2901SDag-Erling Smørgrav verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock, 181305ab2901SDag-Erling Smørgrav unsigned int sigblock_len, unsigned char* key, unsigned int keylen, 181405ab2901SDag-Erling Smørgrav char** reason) 181505ab2901SDag-Erling Smørgrav { 181605ab2901SDag-Erling Smørgrav unsigned int digest_size = 0; 181705ab2901SDag-Erling Smørgrav 181805ab2901SDag-Erling Smørgrav if (sigblock_len == 0 || keylen == 0) { 181905ab2901SDag-Erling Smørgrav *reason = "null signature"; 182005ab2901SDag-Erling Smørgrav return sec_status_bogus; 182105ab2901SDag-Erling Smørgrav } 182205ab2901SDag-Erling Smørgrav 182305ab2901SDag-Erling Smørgrav switch(algo) { 182465b390aaSDag-Erling Smørgrav #if defined(USE_DSA) && defined(USE_SHA1) 182505ab2901SDag-Erling Smørgrav case LDNS_DSA: 182605ab2901SDag-Erling Smørgrav case LDNS_DSA_NSEC3: 182705ab2901SDag-Erling Smørgrav *reason = _verify_nettle_dsa(buf, sigblock, sigblock_len, key, keylen); 182805ab2901SDag-Erling Smørgrav if (*reason != NULL) 182905ab2901SDag-Erling Smørgrav return sec_status_bogus; 183005ab2901SDag-Erling Smørgrav else 183105ab2901SDag-Erling Smørgrav return sec_status_secure; 1832e2d15004SDag-Erling Smørgrav #endif /* USE_DSA */ 183305ab2901SDag-Erling Smørgrav 183465b390aaSDag-Erling Smørgrav #ifdef USE_SHA1 183505ab2901SDag-Erling Smørgrav case LDNS_RSASHA1: 183605ab2901SDag-Erling Smørgrav case LDNS_RSASHA1_NSEC3: 183705ab2901SDag-Erling Smørgrav digest_size = (digest_size ? digest_size : SHA1_DIGEST_SIZE); 183865b390aaSDag-Erling Smørgrav #endif 1839971980c3SDag-Erling Smørgrav /* double fallthrough annotation to please gcc parser */ 1840971980c3SDag-Erling Smørgrav /* fallthrough */ 184105ab2901SDag-Erling Smørgrav #ifdef USE_SHA2 1842971980c3SDag-Erling Smørgrav /* fallthrough */ 184305ab2901SDag-Erling Smørgrav case LDNS_RSASHA256: 184405ab2901SDag-Erling Smørgrav digest_size = (digest_size ? digest_size : SHA256_DIGEST_SIZE); 1845971980c3SDag-Erling Smørgrav /* fallthrough */ 184605ab2901SDag-Erling Smørgrav case LDNS_RSASHA512: 184705ab2901SDag-Erling Smørgrav digest_size = (digest_size ? digest_size : SHA512_DIGEST_SIZE); 184805ab2901SDag-Erling Smørgrav 184905ab2901SDag-Erling Smørgrav #endif 185005ab2901SDag-Erling Smørgrav *reason = _verify_nettle_rsa(buf, digest_size, (char*)sigblock, 185105ab2901SDag-Erling Smørgrav sigblock_len, key, keylen); 185205ab2901SDag-Erling Smørgrav if (*reason != NULL) 185305ab2901SDag-Erling Smørgrav return sec_status_bogus; 185405ab2901SDag-Erling Smørgrav else 185505ab2901SDag-Erling Smørgrav return sec_status_secure; 185605ab2901SDag-Erling Smørgrav 185705ab2901SDag-Erling Smørgrav #ifdef USE_ECDSA 185805ab2901SDag-Erling Smørgrav case LDNS_ECDSAP256SHA256: 185905ab2901SDag-Erling Smørgrav digest_size = (digest_size ? digest_size : SHA256_DIGEST_SIZE); 1860971980c3SDag-Erling Smørgrav /* fallthrough */ 186105ab2901SDag-Erling Smørgrav case LDNS_ECDSAP384SHA384: 186205ab2901SDag-Erling Smørgrav digest_size = (digest_size ? digest_size : SHA384_DIGEST_SIZE); 186305ab2901SDag-Erling Smørgrav *reason = _verify_nettle_ecdsa(buf, digest_size, sigblock, 186405ab2901SDag-Erling Smørgrav sigblock_len, key, keylen); 186505ab2901SDag-Erling Smørgrav if (*reason != NULL) 186605ab2901SDag-Erling Smørgrav return sec_status_bogus; 186705ab2901SDag-Erling Smørgrav else 186805ab2901SDag-Erling Smørgrav return sec_status_secure; 186905ab2901SDag-Erling Smørgrav #endif 1870971980c3SDag-Erling Smørgrav #ifdef USE_ED25519 1871971980c3SDag-Erling Smørgrav case LDNS_ED25519: 1872971980c3SDag-Erling Smørgrav *reason = _verify_nettle_ed25519(buf, sigblock, sigblock_len, 1873971980c3SDag-Erling Smørgrav key, keylen); 1874971980c3SDag-Erling Smørgrav if (*reason != NULL) 1875971980c3SDag-Erling Smørgrav return sec_status_bogus; 1876971980c3SDag-Erling Smørgrav else 1877971980c3SDag-Erling Smørgrav return sec_status_secure; 1878971980c3SDag-Erling Smørgrav #endif 187905ab2901SDag-Erling Smørgrav case LDNS_RSAMD5: 188005ab2901SDag-Erling Smørgrav case LDNS_ECC_GOST: 188105ab2901SDag-Erling Smørgrav default: 188205ab2901SDag-Erling Smørgrav *reason = "unable to verify signature, unknown algorithm"; 188305ab2901SDag-Erling Smørgrav return sec_status_bogus; 188405ab2901SDag-Erling Smørgrav } 188505ab2901SDag-Erling Smørgrav } 188605ab2901SDag-Erling Smørgrav 188705ab2901SDag-Erling Smørgrav #endif /* HAVE_SSL or HAVE_NSS or HAVE_NETTLE */ 1888