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 57091e9e46SCy Schubert /** fake DSA support for unit tests */ 58091e9e46SCy Schubert int fake_dsa = 0; 59091e9e46SCy Schubert /** fake SHA1 support for unit tests */ 60091e9e46SCy Schubert int fake_sha1 = 0; 61091e9e46SCy Schubert 628ed2b524SDag-Erling Smørgrav /* OpenSSL implementation */ 638ed2b524SDag-Erling Smørgrav #ifdef HAVE_SSL 648ed2b524SDag-Erling Smørgrav #ifdef HAVE_OPENSSL_ERR_H 658ed2b524SDag-Erling Smørgrav #include <openssl/err.h> 668ed2b524SDag-Erling Smørgrav #endif 678ed2b524SDag-Erling Smørgrav 688ed2b524SDag-Erling Smørgrav #ifdef HAVE_OPENSSL_RAND_H 698ed2b524SDag-Erling Smørgrav #include <openssl/rand.h> 708ed2b524SDag-Erling Smørgrav #endif 718ed2b524SDag-Erling Smørgrav 728ed2b524SDag-Erling Smørgrav #ifdef HAVE_OPENSSL_CONF_H 738ed2b524SDag-Erling Smørgrav #include <openssl/conf.h> 748ed2b524SDag-Erling Smørgrav #endif 758ed2b524SDag-Erling Smørgrav 768ed2b524SDag-Erling Smørgrav #ifdef HAVE_OPENSSL_ENGINE_H 778ed2b524SDag-Erling Smørgrav #include <openssl/engine.h> 788ed2b524SDag-Erling Smørgrav #endif 798ed2b524SDag-Erling Smørgrav 80*25039b37SCy Schubert #if defined(HAVE_OPENSSL_DSA_H) && defined(USE_DSA) 81*25039b37SCy Schubert #include <openssl/dsa.h> 82*25039b37SCy Schubert #endif 83*25039b37SCy Schubert 84a755b6f6SDag-Erling Smørgrav /** 85a755b6f6SDag-Erling Smørgrav * Output a libcrypto openssl error to the logfile. 86a755b6f6SDag-Erling Smørgrav * @param str: string to add to it. 87a755b6f6SDag-Erling Smørgrav * @param e: the error to output, error number from ERR_get_error(). 88a755b6f6SDag-Erling Smørgrav */ 89a755b6f6SDag-Erling Smørgrav static void 90a755b6f6SDag-Erling Smørgrav log_crypto_error(const char* str, unsigned long e) 91a755b6f6SDag-Erling Smørgrav { 92a755b6f6SDag-Erling Smørgrav char buf[128]; 93a755b6f6SDag-Erling Smørgrav /* or use ERR_error_string if ERR_error_string_n is not avail TODO */ 94a755b6f6SDag-Erling Smørgrav ERR_error_string_n(e, buf, sizeof(buf)); 95a755b6f6SDag-Erling Smørgrav /* buf now contains */ 96a755b6f6SDag-Erling Smørgrav /* error:[error code]:[library name]:[function name]:[reason string] */ 97a755b6f6SDag-Erling Smørgrav log_err("%s crypto %s", str, buf); 98a755b6f6SDag-Erling Smørgrav } 99a755b6f6SDag-Erling Smørgrav 10005ab2901SDag-Erling Smørgrav /* return size of digest if supported, or 0 otherwise */ 10105ab2901SDag-Erling Smørgrav size_t 10205ab2901SDag-Erling Smørgrav nsec3_hash_algo_size_supported(int id) 10305ab2901SDag-Erling Smørgrav { 10405ab2901SDag-Erling Smørgrav switch(id) { 10505ab2901SDag-Erling Smørgrav case NSEC3_HASH_SHA1: 10605ab2901SDag-Erling Smørgrav return SHA_DIGEST_LENGTH; 10705ab2901SDag-Erling Smørgrav default: 10805ab2901SDag-Erling Smørgrav return 0; 10905ab2901SDag-Erling Smørgrav } 11005ab2901SDag-Erling Smørgrav } 11105ab2901SDag-Erling Smørgrav 11205ab2901SDag-Erling Smørgrav /* perform nsec3 hash. return false on failure */ 11305ab2901SDag-Erling Smørgrav int 11405ab2901SDag-Erling Smørgrav secalgo_nsec3_hash(int algo, unsigned char* buf, size_t len, 11505ab2901SDag-Erling Smørgrav unsigned char* res) 11605ab2901SDag-Erling Smørgrav { 11705ab2901SDag-Erling Smørgrav switch(algo) { 11805ab2901SDag-Erling Smørgrav case NSEC3_HASH_SHA1: 119a755b6f6SDag-Erling Smørgrav #ifdef OPENSSL_FIPS 120a755b6f6SDag-Erling Smørgrav if(!sldns_digest_evp(buf, len, res, EVP_sha1())) 121a755b6f6SDag-Erling Smørgrav log_crypto_error("could not digest with EVP_sha1", 122a755b6f6SDag-Erling Smørgrav ERR_get_error()); 123a755b6f6SDag-Erling Smørgrav #else 12405ab2901SDag-Erling Smørgrav (void)SHA1(buf, len, res); 125a755b6f6SDag-Erling Smørgrav #endif 12605ab2901SDag-Erling Smørgrav return 1; 12705ab2901SDag-Erling Smørgrav default: 12805ab2901SDag-Erling Smørgrav return 0; 12905ab2901SDag-Erling Smørgrav } 13005ab2901SDag-Erling Smørgrav } 13105ab2901SDag-Erling Smørgrav 132e2d15004SDag-Erling Smørgrav void 133e2d15004SDag-Erling Smørgrav secalgo_hash_sha256(unsigned char* buf, size_t len, unsigned char* res) 134e2d15004SDag-Erling Smørgrav { 135a755b6f6SDag-Erling Smørgrav #ifdef OPENSSL_FIPS 136a755b6f6SDag-Erling Smørgrav if(!sldns_digest_evp(buf, len, res, EVP_sha256())) 137a755b6f6SDag-Erling Smørgrav log_crypto_error("could not digest with EVP_sha256", 138a755b6f6SDag-Erling Smørgrav ERR_get_error()); 139a755b6f6SDag-Erling Smørgrav #else 140e2d15004SDag-Erling Smørgrav (void)SHA256(buf, len, res); 141a755b6f6SDag-Erling Smørgrav #endif 142e2d15004SDag-Erling Smørgrav } 143e2d15004SDag-Erling Smørgrav 1448ed2b524SDag-Erling Smørgrav /** 1458ed2b524SDag-Erling Smørgrav * Return size of DS digest according to its hash algorithm. 1468ed2b524SDag-Erling Smørgrav * @param algo: DS digest algo. 1478ed2b524SDag-Erling Smørgrav * @return size in bytes of digest, or 0 if not supported. 1488ed2b524SDag-Erling Smørgrav */ 1498ed2b524SDag-Erling Smørgrav size_t 1508ed2b524SDag-Erling Smørgrav ds_digest_size_supported(int algo) 1518ed2b524SDag-Erling Smørgrav { 1528ed2b524SDag-Erling Smørgrav switch(algo) { 1538ed2b524SDag-Erling Smørgrav case LDNS_SHA1: 15465b390aaSDag-Erling Smørgrav #if defined(HAVE_EVP_SHA1) && defined(USE_SHA1) 1558ed2b524SDag-Erling Smørgrav return SHA_DIGEST_LENGTH; 15665b390aaSDag-Erling Smørgrav #else 15765b390aaSDag-Erling Smørgrav if(fake_sha1) return 20; 15865b390aaSDag-Erling Smørgrav return 0; 1598ed2b524SDag-Erling Smørgrav #endif 1608ed2b524SDag-Erling Smørgrav #ifdef HAVE_EVP_SHA256 1618ed2b524SDag-Erling Smørgrav case LDNS_SHA256: 1628ed2b524SDag-Erling Smørgrav return SHA256_DIGEST_LENGTH; 1638ed2b524SDag-Erling Smørgrav #endif 1648ed2b524SDag-Erling Smørgrav #ifdef USE_GOST 1658ed2b524SDag-Erling Smørgrav case LDNS_HASH_GOST: 166f61ef7f6SDag-Erling Smørgrav /* we support GOST if it can be loaded */ 167f61ef7f6SDag-Erling Smørgrav (void)sldns_key_EVP_load_gost_id(); 1688ed2b524SDag-Erling Smørgrav if(EVP_get_digestbyname("md_gost94")) 1698ed2b524SDag-Erling Smørgrav return 32; 1708ed2b524SDag-Erling Smørgrav else return 0; 1718ed2b524SDag-Erling Smørgrav #endif 1728ed2b524SDag-Erling Smørgrav #ifdef USE_ECDSA 1738ed2b524SDag-Erling Smørgrav case LDNS_SHA384: 1748ed2b524SDag-Erling Smørgrav return SHA384_DIGEST_LENGTH; 1758ed2b524SDag-Erling Smørgrav #endif 1768ed2b524SDag-Erling Smørgrav default: break; 1778ed2b524SDag-Erling Smørgrav } 1788ed2b524SDag-Erling Smørgrav return 0; 1798ed2b524SDag-Erling Smørgrav } 1808ed2b524SDag-Erling Smørgrav 1818ed2b524SDag-Erling Smørgrav #ifdef USE_GOST 1828ed2b524SDag-Erling Smørgrav /** Perform GOST hash */ 1838ed2b524SDag-Erling Smørgrav static int 1848ed2b524SDag-Erling Smørgrav do_gost94(unsigned char* data, size_t len, unsigned char* dest) 1858ed2b524SDag-Erling Smørgrav { 1868ed2b524SDag-Erling Smørgrav const EVP_MD* md = EVP_get_digestbyname("md_gost94"); 1878ed2b524SDag-Erling Smørgrav if(!md) 1888ed2b524SDag-Erling Smørgrav return 0; 18917d15b25SDag-Erling Smørgrav return sldns_digest_evp(data, (unsigned int)len, dest, md); 1908ed2b524SDag-Erling Smørgrav } 1918ed2b524SDag-Erling Smørgrav #endif 1928ed2b524SDag-Erling Smørgrav 1938ed2b524SDag-Erling Smørgrav int 1948ed2b524SDag-Erling Smørgrav secalgo_ds_digest(int algo, unsigned char* buf, size_t len, 1958ed2b524SDag-Erling Smørgrav unsigned char* res) 1968ed2b524SDag-Erling Smørgrav { 1978ed2b524SDag-Erling Smørgrav switch(algo) { 19865b390aaSDag-Erling Smørgrav #if defined(HAVE_EVP_SHA1) && defined(USE_SHA1) 1998ed2b524SDag-Erling Smørgrav case LDNS_SHA1: 200a755b6f6SDag-Erling Smørgrav #ifdef OPENSSL_FIPS 201a755b6f6SDag-Erling Smørgrav if(!sldns_digest_evp(buf, len, res, EVP_sha1())) 202a755b6f6SDag-Erling Smørgrav log_crypto_error("could not digest with EVP_sha1", 203a755b6f6SDag-Erling Smørgrav ERR_get_error()); 204a755b6f6SDag-Erling Smørgrav #else 2058ed2b524SDag-Erling Smørgrav (void)SHA1(buf, len, res); 206a755b6f6SDag-Erling Smørgrav #endif 2078ed2b524SDag-Erling Smørgrav return 1; 2088ed2b524SDag-Erling Smørgrav #endif 2098ed2b524SDag-Erling Smørgrav #ifdef HAVE_EVP_SHA256 2108ed2b524SDag-Erling Smørgrav case LDNS_SHA256: 211a755b6f6SDag-Erling Smørgrav #ifdef OPENSSL_FIPS 212a755b6f6SDag-Erling Smørgrav if(!sldns_digest_evp(buf, len, res, EVP_sha256())) 213a755b6f6SDag-Erling Smørgrav log_crypto_error("could not digest with EVP_sha256", 214a755b6f6SDag-Erling Smørgrav ERR_get_error()); 215a755b6f6SDag-Erling Smørgrav #else 2168ed2b524SDag-Erling Smørgrav (void)SHA256(buf, len, res); 217a755b6f6SDag-Erling Smørgrav #endif 2188ed2b524SDag-Erling Smørgrav return 1; 2198ed2b524SDag-Erling Smørgrav #endif 2208ed2b524SDag-Erling Smørgrav #ifdef USE_GOST 2218ed2b524SDag-Erling Smørgrav case LDNS_HASH_GOST: 2228ed2b524SDag-Erling Smørgrav if(do_gost94(buf, len, res)) 2238ed2b524SDag-Erling Smørgrav return 1; 2248ed2b524SDag-Erling Smørgrav break; 2258ed2b524SDag-Erling Smørgrav #endif 2268ed2b524SDag-Erling Smørgrav #ifdef USE_ECDSA 2278ed2b524SDag-Erling Smørgrav case LDNS_SHA384: 228a755b6f6SDag-Erling Smørgrav #ifdef OPENSSL_FIPS 229a755b6f6SDag-Erling Smørgrav if(!sldns_digest_evp(buf, len, res, EVP_sha384())) 230a755b6f6SDag-Erling Smørgrav log_crypto_error("could not digest with EVP_sha384", 231a755b6f6SDag-Erling Smørgrav ERR_get_error()); 232a755b6f6SDag-Erling Smørgrav #else 2338ed2b524SDag-Erling Smørgrav (void)SHA384(buf, len, res); 234a755b6f6SDag-Erling Smørgrav #endif 2358ed2b524SDag-Erling Smørgrav return 1; 2368ed2b524SDag-Erling Smørgrav #endif 2378ed2b524SDag-Erling Smørgrav default: 2388ed2b524SDag-Erling Smørgrav verbose(VERB_QUERY, "unknown DS digest algorithm %d", 2398ed2b524SDag-Erling Smørgrav algo); 2408ed2b524SDag-Erling Smørgrav break; 2418ed2b524SDag-Erling Smørgrav } 2428ed2b524SDag-Erling Smørgrav return 0; 2438ed2b524SDag-Erling Smørgrav } 2448ed2b524SDag-Erling Smørgrav 2458ed2b524SDag-Erling Smørgrav /** return true if DNSKEY algorithm id is supported */ 2468ed2b524SDag-Erling Smørgrav int 2478ed2b524SDag-Erling Smørgrav dnskey_algo_id_is_supported(int id) 2488ed2b524SDag-Erling Smørgrav { 2498ed2b524SDag-Erling Smørgrav switch(id) { 2508ed2b524SDag-Erling Smørgrav case LDNS_RSAMD5: 2518ed2b524SDag-Erling Smørgrav /* RFC 6725 deprecates RSAMD5 */ 2528ed2b524SDag-Erling Smørgrav return 0; 2538ed2b524SDag-Erling Smørgrav case LDNS_DSA: 2548ed2b524SDag-Erling Smørgrav case LDNS_DSA_NSEC3: 25565b390aaSDag-Erling Smørgrav #if defined(USE_DSA) && defined(USE_SHA1) 256bc892140SDag-Erling Smørgrav return 1; 257bc892140SDag-Erling Smørgrav #else 25865b390aaSDag-Erling Smørgrav if(fake_dsa || fake_sha1) return 1; 259bc892140SDag-Erling Smørgrav return 0; 260e2d15004SDag-Erling Smørgrav #endif 26165b390aaSDag-Erling Smørgrav 2628ed2b524SDag-Erling Smørgrav case LDNS_RSASHA1: 2638ed2b524SDag-Erling Smørgrav case LDNS_RSASHA1_NSEC3: 26465b390aaSDag-Erling Smørgrav #ifdef USE_SHA1 26565b390aaSDag-Erling Smørgrav return 1; 26665b390aaSDag-Erling Smørgrav #else 26765b390aaSDag-Erling Smørgrav if(fake_sha1) return 1; 26865b390aaSDag-Erling Smørgrav return 0; 26965b390aaSDag-Erling Smørgrav #endif 27065b390aaSDag-Erling Smørgrav 2718ed2b524SDag-Erling Smørgrav #if defined(HAVE_EVP_SHA256) && defined(USE_SHA2) 2728ed2b524SDag-Erling Smørgrav case LDNS_RSASHA256: 2738ed2b524SDag-Erling Smørgrav #endif 2748ed2b524SDag-Erling Smørgrav #if defined(HAVE_EVP_SHA512) && defined(USE_SHA2) 2758ed2b524SDag-Erling Smørgrav case LDNS_RSASHA512: 2768ed2b524SDag-Erling Smørgrav #endif 2778ed2b524SDag-Erling Smørgrav #ifdef USE_ECDSA 2788ed2b524SDag-Erling Smørgrav case LDNS_ECDSAP256SHA256: 2798ed2b524SDag-Erling Smørgrav case LDNS_ECDSAP384SHA384: 2808ed2b524SDag-Erling Smørgrav #endif 281c7f4d7adSDag-Erling Smørgrav #ifdef USE_ED25519 282c7f4d7adSDag-Erling Smørgrav case LDNS_ED25519: 283c7f4d7adSDag-Erling Smørgrav #endif 2840fb34990SDag-Erling Smørgrav #ifdef USE_ED448 2850fb34990SDag-Erling Smørgrav case LDNS_ED448: 2860fb34990SDag-Erling Smørgrav #endif 2870fb34990SDag-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) 2888ed2b524SDag-Erling Smørgrav return 1; 28965b390aaSDag-Erling Smørgrav #endif 29065b390aaSDag-Erling Smørgrav 2918ed2b524SDag-Erling Smørgrav #ifdef USE_GOST 2928ed2b524SDag-Erling Smørgrav case LDNS_ECC_GOST: 2938ed2b524SDag-Erling Smørgrav /* we support GOST if it can be loaded */ 29417d15b25SDag-Erling Smørgrav return sldns_key_EVP_load_gost_id(); 2958ed2b524SDag-Erling Smørgrav #endif 2968ed2b524SDag-Erling Smørgrav default: 2978ed2b524SDag-Erling Smørgrav return 0; 2988ed2b524SDag-Erling Smørgrav } 2998ed2b524SDag-Erling Smørgrav } 3008ed2b524SDag-Erling Smørgrav 301e2d15004SDag-Erling Smørgrav #ifdef USE_DSA 3028ed2b524SDag-Erling Smørgrav /** 3038ed2b524SDag-Erling Smørgrav * Setup DSA key digest in DER encoding ... 3048ed2b524SDag-Erling Smørgrav * @param sig: input is signature output alloced ptr (unless failure). 3058ed2b524SDag-Erling Smørgrav * caller must free alloced ptr if this routine returns true. 3068ed2b524SDag-Erling Smørgrav * @param len: input is initial siglen, output is output len. 3078ed2b524SDag-Erling Smørgrav * @return false on failure. 3088ed2b524SDag-Erling Smørgrav */ 3098ed2b524SDag-Erling Smørgrav static int 3108ed2b524SDag-Erling Smørgrav setup_dsa_sig(unsigned char** sig, unsigned int* len) 3118ed2b524SDag-Erling Smørgrav { 3128ed2b524SDag-Erling Smørgrav unsigned char* orig = *sig; 3138ed2b524SDag-Erling Smørgrav unsigned int origlen = *len; 3148ed2b524SDag-Erling Smørgrav int newlen; 3158ed2b524SDag-Erling Smørgrav BIGNUM *R, *S; 3168ed2b524SDag-Erling Smørgrav DSA_SIG *dsasig; 3178ed2b524SDag-Erling Smørgrav 3188ed2b524SDag-Erling Smørgrav /* extract the R and S field from the sig buffer */ 3198ed2b524SDag-Erling Smørgrav if(origlen < 1 + 2*SHA_DIGEST_LENGTH) 3208ed2b524SDag-Erling Smørgrav return 0; 3218ed2b524SDag-Erling Smørgrav R = BN_new(); 3228ed2b524SDag-Erling Smørgrav if(!R) return 0; 3238ed2b524SDag-Erling Smørgrav (void) BN_bin2bn(orig + 1, SHA_DIGEST_LENGTH, R); 3248ed2b524SDag-Erling Smørgrav S = BN_new(); 3258ed2b524SDag-Erling Smørgrav if(!S) return 0; 3268ed2b524SDag-Erling Smørgrav (void) BN_bin2bn(orig + 21, SHA_DIGEST_LENGTH, S); 3278ed2b524SDag-Erling Smørgrav dsasig = DSA_SIG_new(); 3288ed2b524SDag-Erling Smørgrav if(!dsasig) return 0; 3298ed2b524SDag-Erling Smørgrav 330bc892140SDag-Erling Smørgrav #ifdef HAVE_DSA_SIG_SET0 331bc892140SDag-Erling Smørgrav if(!DSA_SIG_set0(dsasig, R, S)) return 0; 332bc892140SDag-Erling Smørgrav #else 3330eefd307SCy Schubert # ifndef S_SPLINT_S 3348ed2b524SDag-Erling Smørgrav dsasig->r = R; 3358ed2b524SDag-Erling Smørgrav dsasig->s = S; 3360eefd307SCy Schubert # endif /* S_SPLINT_S */ 337bc892140SDag-Erling Smørgrav #endif 3388ed2b524SDag-Erling Smørgrav *sig = NULL; 3398ed2b524SDag-Erling Smørgrav newlen = i2d_DSA_SIG(dsasig, sig); 3408ed2b524SDag-Erling Smørgrav if(newlen < 0) { 3418ed2b524SDag-Erling Smørgrav DSA_SIG_free(dsasig); 3428ed2b524SDag-Erling Smørgrav free(*sig); 3438ed2b524SDag-Erling Smørgrav return 0; 3448ed2b524SDag-Erling Smørgrav } 3458ed2b524SDag-Erling Smørgrav *len = (unsigned int)newlen; 3468ed2b524SDag-Erling Smørgrav DSA_SIG_free(dsasig); 3478ed2b524SDag-Erling Smørgrav return 1; 3488ed2b524SDag-Erling Smørgrav } 349e2d15004SDag-Erling Smørgrav #endif /* USE_DSA */ 3508ed2b524SDag-Erling Smørgrav 3518ed2b524SDag-Erling Smørgrav #ifdef USE_ECDSA 3528ed2b524SDag-Erling Smørgrav /** 3538ed2b524SDag-Erling Smørgrav * Setup the ECDSA signature in its encoding that the library wants. 3548ed2b524SDag-Erling Smørgrav * Converts from plain numbers to ASN formatted. 3558ed2b524SDag-Erling Smørgrav * @param sig: input is signature, output alloced ptr (unless failure). 3568ed2b524SDag-Erling Smørgrav * caller must free alloced ptr if this routine returns true. 3578ed2b524SDag-Erling Smørgrav * @param len: input is initial siglen, output is output len. 3588ed2b524SDag-Erling Smørgrav * @return false on failure. 3598ed2b524SDag-Erling Smørgrav */ 3608ed2b524SDag-Erling Smørgrav static int 3618ed2b524SDag-Erling Smørgrav setup_ecdsa_sig(unsigned char** sig, unsigned int* len) 3628ed2b524SDag-Erling Smørgrav { 363e2d15004SDag-Erling Smørgrav /* convert from two BIGNUMs in the rdata buffer, to ASN notation. 3648a384985SDag-Erling Smørgrav * ASN preamble: 30440220 <R 32bytefor256> 0220 <S 32bytefor256> 365e2d15004SDag-Erling Smørgrav * the '20' is the length of that field (=bnsize). 366e2d15004SDag-Erling Smørgrav i * the '44' is the total remaining length. 367e2d15004SDag-Erling Smørgrav * if negative, start with leading zero. 368e2d15004SDag-Erling Smørgrav * if starts with 00s, remove them from the number. 369e2d15004SDag-Erling Smørgrav */ 370e2d15004SDag-Erling Smørgrav uint8_t pre[] = {0x30, 0x44, 0x02, 0x20}; 371e2d15004SDag-Erling Smørgrav int pre_len = 4; 372e2d15004SDag-Erling Smørgrav uint8_t mid[] = {0x02, 0x20}; 373e2d15004SDag-Erling Smørgrav int mid_len = 2; 374e2d15004SDag-Erling Smørgrav int raw_sig_len, r_high, s_high, r_rem=0, s_rem=0; 3758ed2b524SDag-Erling Smørgrav int bnsize = (int)((*len)/2); 376e2d15004SDag-Erling Smørgrav unsigned char* d = *sig; 377e2d15004SDag-Erling Smørgrav uint8_t* p; 3788ed2b524SDag-Erling Smørgrav /* if too short or not even length, fails */ 3798ed2b524SDag-Erling Smørgrav if(*len < 16 || bnsize*2 != (int)*len) 3808ed2b524SDag-Erling Smørgrav return 0; 3818ed2b524SDag-Erling Smørgrav 382e2d15004SDag-Erling Smørgrav /* strip leading zeroes from r (but not last one) */ 383e2d15004SDag-Erling Smørgrav while(r_rem < bnsize-1 && d[r_rem] == 0) 384e2d15004SDag-Erling Smørgrav r_rem++; 385e2d15004SDag-Erling Smørgrav /* strip leading zeroes from s (but not last one) */ 386e2d15004SDag-Erling Smørgrav while(s_rem < bnsize-1 && d[bnsize+s_rem] == 0) 387e2d15004SDag-Erling Smørgrav s_rem++; 388e2d15004SDag-Erling Smørgrav 389e2d15004SDag-Erling Smørgrav r_high = ((d[0+r_rem]&0x80)?1:0); 390e2d15004SDag-Erling Smørgrav s_high = ((d[bnsize+s_rem]&0x80)?1:0); 391e2d15004SDag-Erling Smørgrav raw_sig_len = pre_len + r_high + bnsize - r_rem + mid_len + 392e2d15004SDag-Erling Smørgrav s_high + bnsize - s_rem; 393e2d15004SDag-Erling Smørgrav *sig = (unsigned char*)malloc((size_t)raw_sig_len); 394e2d15004SDag-Erling Smørgrav if(!*sig) 3958ed2b524SDag-Erling Smørgrav return 0; 396e2d15004SDag-Erling Smørgrav p = (uint8_t*)*sig; 397e2d15004SDag-Erling Smørgrav p[0] = pre[0]; 398e2d15004SDag-Erling Smørgrav p[1] = (uint8_t)(raw_sig_len-2); 399e2d15004SDag-Erling Smørgrav p[2] = pre[2]; 400e2d15004SDag-Erling Smørgrav p[3] = (uint8_t)(bnsize + r_high - r_rem); 401e2d15004SDag-Erling Smørgrav p += 4; 402e2d15004SDag-Erling Smørgrav if(r_high) { 403e2d15004SDag-Erling Smørgrav *p = 0; 404e2d15004SDag-Erling Smørgrav p += 1; 4058ed2b524SDag-Erling Smørgrav } 406e2d15004SDag-Erling Smørgrav memmove(p, d+r_rem, (size_t)bnsize-r_rem); 407e2d15004SDag-Erling Smørgrav p += bnsize-r_rem; 408e2d15004SDag-Erling Smørgrav memmove(p, mid, (size_t)mid_len-1); 409e2d15004SDag-Erling Smørgrav p += mid_len-1; 410e2d15004SDag-Erling Smørgrav *p = (uint8_t)(bnsize + s_high - s_rem); 411e2d15004SDag-Erling Smørgrav p += 1; 412e2d15004SDag-Erling Smørgrav if(s_high) { 413e2d15004SDag-Erling Smørgrav *p = 0; 414e2d15004SDag-Erling Smørgrav p += 1; 415e2d15004SDag-Erling Smørgrav } 416e2d15004SDag-Erling Smørgrav memmove(p, d+bnsize+s_rem, (size_t)bnsize-s_rem); 417e2d15004SDag-Erling Smørgrav *len = (unsigned int)raw_sig_len; 4188ed2b524SDag-Erling Smørgrav return 1; 4198ed2b524SDag-Erling Smørgrav } 4208ed2b524SDag-Erling Smørgrav #endif /* USE_ECDSA */ 4218ed2b524SDag-Erling Smørgrav 422b5663de9SDag-Erling Smørgrav #ifdef USE_ECDSA_EVP_WORKAROUND 423b5663de9SDag-Erling Smørgrav static EVP_MD ecdsa_evp_256_md; 424b5663de9SDag-Erling Smørgrav static EVP_MD ecdsa_evp_384_md; 425b5663de9SDag-Erling Smørgrav void ecdsa_evp_workaround_init(void) 426b5663de9SDag-Erling Smørgrav { 427b5663de9SDag-Erling Smørgrav /* openssl before 1.0.0 fixes RSA with the SHA256 428b5663de9SDag-Erling Smørgrav * hash in EVP. We create one for ecdsa_sha256 */ 429b5663de9SDag-Erling Smørgrav ecdsa_evp_256_md = *EVP_sha256(); 430b5663de9SDag-Erling Smørgrav ecdsa_evp_256_md.required_pkey_type[0] = EVP_PKEY_EC; 431b5663de9SDag-Erling Smørgrav ecdsa_evp_256_md.verify = (void*)ECDSA_verify; 432b5663de9SDag-Erling Smørgrav 433b5663de9SDag-Erling Smørgrav ecdsa_evp_384_md = *EVP_sha384(); 434b5663de9SDag-Erling Smørgrav ecdsa_evp_384_md.required_pkey_type[0] = EVP_PKEY_EC; 435b5663de9SDag-Erling Smørgrav ecdsa_evp_384_md.verify = (void*)ECDSA_verify; 436b5663de9SDag-Erling Smørgrav } 437b5663de9SDag-Erling Smørgrav #endif /* USE_ECDSA_EVP_WORKAROUND */ 438b5663de9SDag-Erling Smørgrav 4398ed2b524SDag-Erling Smørgrav /** 4408ed2b524SDag-Erling Smørgrav * Setup key and digest for verification. Adjust sig if necessary. 4418ed2b524SDag-Erling Smørgrav * 4428ed2b524SDag-Erling Smørgrav * @param algo: key algorithm 4438ed2b524SDag-Erling Smørgrav * @param evp_key: EVP PKEY public key to create. 4448ed2b524SDag-Erling Smørgrav * @param digest_type: digest type to use 4458ed2b524SDag-Erling Smørgrav * @param key: key to setup for. 4468ed2b524SDag-Erling Smørgrav * @param keylen: length of key. 4478ed2b524SDag-Erling Smørgrav * @return false on failure. 4488ed2b524SDag-Erling Smørgrav */ 4498ed2b524SDag-Erling Smørgrav static int 4508ed2b524SDag-Erling Smørgrav setup_key_digest(int algo, EVP_PKEY** evp_key, const EVP_MD** digest_type, 4518ed2b524SDag-Erling Smørgrav unsigned char* key, size_t keylen) 4528ed2b524SDag-Erling Smørgrav { 45365b390aaSDag-Erling Smørgrav #if defined(USE_DSA) && defined(USE_SHA1) 4548ed2b524SDag-Erling Smørgrav DSA* dsa; 455e2d15004SDag-Erling Smørgrav #endif 4568ed2b524SDag-Erling Smørgrav RSA* rsa; 4578ed2b524SDag-Erling Smørgrav 4588ed2b524SDag-Erling Smørgrav switch(algo) { 45965b390aaSDag-Erling Smørgrav #if defined(USE_DSA) && defined(USE_SHA1) 4608ed2b524SDag-Erling Smørgrav case LDNS_DSA: 4618ed2b524SDag-Erling Smørgrav case LDNS_DSA_NSEC3: 4628ed2b524SDag-Erling Smørgrav *evp_key = EVP_PKEY_new(); 4638ed2b524SDag-Erling Smørgrav if(!*evp_key) { 4648ed2b524SDag-Erling Smørgrav log_err("verify: malloc failure in crypto"); 4658ed2b524SDag-Erling Smørgrav return 0; 4668ed2b524SDag-Erling Smørgrav } 46717d15b25SDag-Erling Smørgrav dsa = sldns_key_buf2dsa_raw(key, keylen); 4688ed2b524SDag-Erling Smørgrav if(!dsa) { 4698ed2b524SDag-Erling Smørgrav verbose(VERB_QUERY, "verify: " 47017d15b25SDag-Erling Smørgrav "sldns_key_buf2dsa_raw failed"); 4718ed2b524SDag-Erling Smørgrav return 0; 4728ed2b524SDag-Erling Smørgrav } 4738ed2b524SDag-Erling Smørgrav if(EVP_PKEY_assign_DSA(*evp_key, dsa) == 0) { 4748ed2b524SDag-Erling Smørgrav verbose(VERB_QUERY, "verify: " 4758ed2b524SDag-Erling Smørgrav "EVP_PKEY_assign_DSA failed"); 4768ed2b524SDag-Erling Smørgrav return 0; 4778ed2b524SDag-Erling Smørgrav } 478bc892140SDag-Erling Smørgrav #ifdef HAVE_EVP_DSS1 4798ed2b524SDag-Erling Smørgrav *digest_type = EVP_dss1(); 480bc892140SDag-Erling Smørgrav #else 481bc892140SDag-Erling Smørgrav *digest_type = EVP_sha1(); 482bc892140SDag-Erling Smørgrav #endif 4838ed2b524SDag-Erling Smørgrav 4848ed2b524SDag-Erling Smørgrav break; 48565b390aaSDag-Erling Smørgrav #endif /* USE_DSA && USE_SHA1 */ 48665b390aaSDag-Erling Smørgrav 48765b390aaSDag-Erling Smørgrav #if defined(USE_SHA1) || (defined(HAVE_EVP_SHA256) && defined(USE_SHA2)) || (defined(HAVE_EVP_SHA512) && defined(USE_SHA2)) 48865b390aaSDag-Erling Smørgrav #ifdef USE_SHA1 4898ed2b524SDag-Erling Smørgrav case LDNS_RSASHA1: 4908ed2b524SDag-Erling Smørgrav case LDNS_RSASHA1_NSEC3: 49165b390aaSDag-Erling Smørgrav #endif 4928ed2b524SDag-Erling Smørgrav #if defined(HAVE_EVP_SHA256) && defined(USE_SHA2) 4938ed2b524SDag-Erling Smørgrav case LDNS_RSASHA256: 4948ed2b524SDag-Erling Smørgrav #endif 4958ed2b524SDag-Erling Smørgrav #if defined(HAVE_EVP_SHA512) && defined(USE_SHA2) 4968ed2b524SDag-Erling Smørgrav case LDNS_RSASHA512: 4978ed2b524SDag-Erling Smørgrav #endif 4988ed2b524SDag-Erling Smørgrav *evp_key = EVP_PKEY_new(); 4998ed2b524SDag-Erling Smørgrav if(!*evp_key) { 5008ed2b524SDag-Erling Smørgrav log_err("verify: malloc failure in crypto"); 5018ed2b524SDag-Erling Smørgrav return 0; 5028ed2b524SDag-Erling Smørgrav } 50317d15b25SDag-Erling Smørgrav rsa = sldns_key_buf2rsa_raw(key, keylen); 5048ed2b524SDag-Erling Smørgrav if(!rsa) { 5058ed2b524SDag-Erling Smørgrav verbose(VERB_QUERY, "verify: " 50617d15b25SDag-Erling Smørgrav "sldns_key_buf2rsa_raw SHA failed"); 5078ed2b524SDag-Erling Smørgrav return 0; 5088ed2b524SDag-Erling Smørgrav } 5098ed2b524SDag-Erling Smørgrav if(EVP_PKEY_assign_RSA(*evp_key, rsa) == 0) { 5108ed2b524SDag-Erling Smørgrav verbose(VERB_QUERY, "verify: " 5118ed2b524SDag-Erling Smørgrav "EVP_PKEY_assign_RSA SHA failed"); 5128ed2b524SDag-Erling Smørgrav return 0; 5138ed2b524SDag-Erling Smørgrav } 5148ed2b524SDag-Erling Smørgrav 5158ed2b524SDag-Erling Smørgrav /* select SHA version */ 5168ed2b524SDag-Erling Smørgrav #if defined(HAVE_EVP_SHA256) && defined(USE_SHA2) 5178ed2b524SDag-Erling Smørgrav if(algo == LDNS_RSASHA256) 5188ed2b524SDag-Erling Smørgrav *digest_type = EVP_sha256(); 5198ed2b524SDag-Erling Smørgrav else 5208ed2b524SDag-Erling Smørgrav #endif 5218ed2b524SDag-Erling Smørgrav #if defined(HAVE_EVP_SHA512) && defined(USE_SHA2) 5228ed2b524SDag-Erling Smørgrav if(algo == LDNS_RSASHA512) 5238ed2b524SDag-Erling Smørgrav *digest_type = EVP_sha512(); 5248ed2b524SDag-Erling Smørgrav else 5258ed2b524SDag-Erling Smørgrav #endif 52665b390aaSDag-Erling Smørgrav #ifdef USE_SHA1 5278ed2b524SDag-Erling Smørgrav *digest_type = EVP_sha1(); 52865b390aaSDag-Erling Smørgrav #else 52965b390aaSDag-Erling Smørgrav { verbose(VERB_QUERY, "no digest available"); return 0; } 53065b390aaSDag-Erling Smørgrav #endif 5318ed2b524SDag-Erling Smørgrav break; 53265b390aaSDag-Erling Smørgrav #endif /* defined(USE_SHA1) || (defined(HAVE_EVP_SHA256) && defined(USE_SHA2)) || (defined(HAVE_EVP_SHA512) && defined(USE_SHA2)) */ 53365b390aaSDag-Erling Smørgrav 5348ed2b524SDag-Erling Smørgrav case LDNS_RSAMD5: 5358ed2b524SDag-Erling Smørgrav *evp_key = EVP_PKEY_new(); 5368ed2b524SDag-Erling Smørgrav if(!*evp_key) { 5378ed2b524SDag-Erling Smørgrav log_err("verify: malloc failure in crypto"); 5388ed2b524SDag-Erling Smørgrav return 0; 5398ed2b524SDag-Erling Smørgrav } 54017d15b25SDag-Erling Smørgrav rsa = sldns_key_buf2rsa_raw(key, keylen); 5418ed2b524SDag-Erling Smørgrav if(!rsa) { 5428ed2b524SDag-Erling Smørgrav verbose(VERB_QUERY, "verify: " 54317d15b25SDag-Erling Smørgrav "sldns_key_buf2rsa_raw MD5 failed"); 5448ed2b524SDag-Erling Smørgrav return 0; 5458ed2b524SDag-Erling Smørgrav } 5468ed2b524SDag-Erling Smørgrav if(EVP_PKEY_assign_RSA(*evp_key, rsa) == 0) { 5478ed2b524SDag-Erling Smørgrav verbose(VERB_QUERY, "verify: " 5488ed2b524SDag-Erling Smørgrav "EVP_PKEY_assign_RSA MD5 failed"); 5498ed2b524SDag-Erling Smørgrav return 0; 5508ed2b524SDag-Erling Smørgrav } 5518ed2b524SDag-Erling Smørgrav *digest_type = EVP_md5(); 5528ed2b524SDag-Erling Smørgrav 5538ed2b524SDag-Erling Smørgrav break; 5548ed2b524SDag-Erling Smørgrav #ifdef USE_GOST 5558ed2b524SDag-Erling Smørgrav case LDNS_ECC_GOST: 55617d15b25SDag-Erling Smørgrav *evp_key = sldns_gost2pkey_raw(key, keylen); 5578ed2b524SDag-Erling Smørgrav if(!*evp_key) { 5588ed2b524SDag-Erling Smørgrav verbose(VERB_QUERY, "verify: " 55917d15b25SDag-Erling Smørgrav "sldns_gost2pkey_raw failed"); 5608ed2b524SDag-Erling Smørgrav return 0; 5618ed2b524SDag-Erling Smørgrav } 5628ed2b524SDag-Erling Smørgrav *digest_type = EVP_get_digestbyname("md_gost94"); 5638ed2b524SDag-Erling Smørgrav if(!*digest_type) { 5648ed2b524SDag-Erling Smørgrav verbose(VERB_QUERY, "verify: " 5658ed2b524SDag-Erling Smørgrav "EVP_getdigest md_gost94 failed"); 5668ed2b524SDag-Erling Smørgrav return 0; 5678ed2b524SDag-Erling Smørgrav } 5688ed2b524SDag-Erling Smørgrav break; 5698ed2b524SDag-Erling Smørgrav #endif 5708ed2b524SDag-Erling Smørgrav #ifdef USE_ECDSA 5718ed2b524SDag-Erling Smørgrav case LDNS_ECDSAP256SHA256: 57217d15b25SDag-Erling Smørgrav *evp_key = sldns_ecdsa2pkey_raw(key, keylen, 5738ed2b524SDag-Erling Smørgrav LDNS_ECDSAP256SHA256); 5748ed2b524SDag-Erling Smørgrav if(!*evp_key) { 5758ed2b524SDag-Erling Smørgrav verbose(VERB_QUERY, "verify: " 57617d15b25SDag-Erling Smørgrav "sldns_ecdsa2pkey_raw failed"); 5778ed2b524SDag-Erling Smørgrav return 0; 5788ed2b524SDag-Erling Smørgrav } 5798ed2b524SDag-Erling Smørgrav #ifdef USE_ECDSA_EVP_WORKAROUND 580b5663de9SDag-Erling Smørgrav *digest_type = &ecdsa_evp_256_md; 5818ed2b524SDag-Erling Smørgrav #else 5828ed2b524SDag-Erling Smørgrav *digest_type = EVP_sha256(); 5838ed2b524SDag-Erling Smørgrav #endif 5848ed2b524SDag-Erling Smørgrav break; 5858ed2b524SDag-Erling Smørgrav case LDNS_ECDSAP384SHA384: 58617d15b25SDag-Erling Smørgrav *evp_key = sldns_ecdsa2pkey_raw(key, keylen, 5878ed2b524SDag-Erling Smørgrav LDNS_ECDSAP384SHA384); 5888ed2b524SDag-Erling Smørgrav if(!*evp_key) { 5898ed2b524SDag-Erling Smørgrav verbose(VERB_QUERY, "verify: " 59017d15b25SDag-Erling Smørgrav "sldns_ecdsa2pkey_raw failed"); 5918ed2b524SDag-Erling Smørgrav return 0; 5928ed2b524SDag-Erling Smørgrav } 5938ed2b524SDag-Erling Smørgrav #ifdef USE_ECDSA_EVP_WORKAROUND 594b5663de9SDag-Erling Smørgrav *digest_type = &ecdsa_evp_384_md; 5958ed2b524SDag-Erling Smørgrav #else 5968ed2b524SDag-Erling Smørgrav *digest_type = EVP_sha384(); 5978ed2b524SDag-Erling Smørgrav #endif 5988ed2b524SDag-Erling Smørgrav break; 5998ed2b524SDag-Erling Smørgrav #endif /* USE_ECDSA */ 600c7f4d7adSDag-Erling Smørgrav #ifdef USE_ED25519 601c7f4d7adSDag-Erling Smørgrav case LDNS_ED25519: 602c7f4d7adSDag-Erling Smørgrav *evp_key = sldns_ed255192pkey_raw(key, keylen); 603c7f4d7adSDag-Erling Smørgrav if(!*evp_key) { 604c7f4d7adSDag-Erling Smørgrav verbose(VERB_QUERY, "verify: " 605c7f4d7adSDag-Erling Smørgrav "sldns_ed255192pkey_raw failed"); 606c7f4d7adSDag-Erling Smørgrav return 0; 607c7f4d7adSDag-Erling Smørgrav } 608c7f4d7adSDag-Erling Smørgrav *digest_type = NULL; 609c7f4d7adSDag-Erling Smørgrav break; 610c7f4d7adSDag-Erling Smørgrav #endif /* USE_ED25519 */ 6110fb34990SDag-Erling Smørgrav #ifdef USE_ED448 6120fb34990SDag-Erling Smørgrav case LDNS_ED448: 6130fb34990SDag-Erling Smørgrav *evp_key = sldns_ed4482pkey_raw(key, keylen); 6140fb34990SDag-Erling Smørgrav if(!*evp_key) { 6150fb34990SDag-Erling Smørgrav verbose(VERB_QUERY, "verify: " 6160fb34990SDag-Erling Smørgrav "sldns_ed4482pkey_raw failed"); 6170fb34990SDag-Erling Smørgrav return 0; 6180fb34990SDag-Erling Smørgrav } 6190fb34990SDag-Erling Smørgrav *digest_type = NULL; 6200fb34990SDag-Erling Smørgrav break; 6210fb34990SDag-Erling Smørgrav #endif /* USE_ED448 */ 6228ed2b524SDag-Erling Smørgrav default: 6238ed2b524SDag-Erling Smørgrav verbose(VERB_QUERY, "verify: unknown algorithm %d", 6248ed2b524SDag-Erling Smørgrav algo); 6258ed2b524SDag-Erling Smørgrav return 0; 6268ed2b524SDag-Erling Smørgrav } 6278ed2b524SDag-Erling Smørgrav return 1; 6288ed2b524SDag-Erling Smørgrav } 6298ed2b524SDag-Erling Smørgrav 6308ed2b524SDag-Erling Smørgrav /** 6318ed2b524SDag-Erling Smørgrav * Check a canonical sig+rrset and signature against a dnskey 6328ed2b524SDag-Erling Smørgrav * @param buf: buffer with data to verify, the first rrsig part and the 6338ed2b524SDag-Erling Smørgrav * canonicalized rrset. 6348ed2b524SDag-Erling Smørgrav * @param algo: DNSKEY algorithm. 6358ed2b524SDag-Erling Smørgrav * @param sigblock: signature rdata field from RRSIG 6368ed2b524SDag-Erling Smørgrav * @param sigblock_len: length of sigblock data. 6378ed2b524SDag-Erling Smørgrav * @param key: public key data from DNSKEY RR. 6388ed2b524SDag-Erling Smørgrav * @param keylen: length of keydata. 6398ed2b524SDag-Erling Smørgrav * @param reason: bogus reason in more detail. 6408ed2b524SDag-Erling Smørgrav * @return secure if verification succeeded, bogus on crypto failure, 6418ed2b524SDag-Erling Smørgrav * unchecked on format errors and alloc failures. 6428ed2b524SDag-Erling Smørgrav */ 6438ed2b524SDag-Erling Smørgrav enum sec_status 64417d15b25SDag-Erling Smørgrav verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock, 6458ed2b524SDag-Erling Smørgrav unsigned int sigblock_len, unsigned char* key, unsigned int keylen, 6468ed2b524SDag-Erling Smørgrav char** reason) 6478ed2b524SDag-Erling Smørgrav { 6488ed2b524SDag-Erling Smørgrav const EVP_MD *digest_type; 649e2d15004SDag-Erling Smørgrav EVP_MD_CTX* ctx; 650e2d15004SDag-Erling Smørgrav int res, dofree = 0, docrypto_free = 0; 6518ed2b524SDag-Erling Smørgrav EVP_PKEY *evp_key = NULL; 6528ed2b524SDag-Erling Smørgrav 653bc892140SDag-Erling Smørgrav #ifndef USE_DSA 65465b390aaSDag-Erling Smørgrav if((algo == LDNS_DSA || algo == LDNS_DSA_NSEC3) &&(fake_dsa||fake_sha1)) 65565b390aaSDag-Erling Smørgrav return sec_status_secure; 65665b390aaSDag-Erling Smørgrav #endif 65765b390aaSDag-Erling Smørgrav #ifndef USE_SHA1 65865b390aaSDag-Erling Smørgrav if(fake_sha1 && (algo == LDNS_DSA || algo == LDNS_DSA_NSEC3 || algo == LDNS_RSASHA1 || algo == LDNS_RSASHA1_NSEC3)) 659bc892140SDag-Erling Smørgrav return sec_status_secure; 660bc892140SDag-Erling Smørgrav #endif 661bc892140SDag-Erling Smørgrav 6628ed2b524SDag-Erling Smørgrav if(!setup_key_digest(algo, &evp_key, &digest_type, key, keylen)) { 6638ed2b524SDag-Erling Smørgrav verbose(VERB_QUERY, "verify: failed to setup key"); 6648ed2b524SDag-Erling Smørgrav *reason = "use of key for crypto failed"; 6658ed2b524SDag-Erling Smørgrav EVP_PKEY_free(evp_key); 6668ed2b524SDag-Erling Smørgrav return sec_status_bogus; 6678ed2b524SDag-Erling Smørgrav } 668e2d15004SDag-Erling Smørgrav #ifdef USE_DSA 6698ed2b524SDag-Erling Smørgrav /* if it is a DSA signature in bind format, convert to DER format */ 6708ed2b524SDag-Erling Smørgrav if((algo == LDNS_DSA || algo == LDNS_DSA_NSEC3) && 6718ed2b524SDag-Erling Smørgrav sigblock_len == 1+2*SHA_DIGEST_LENGTH) { 6728ed2b524SDag-Erling Smørgrav if(!setup_dsa_sig(&sigblock, &sigblock_len)) { 6738ed2b524SDag-Erling Smørgrav verbose(VERB_QUERY, "verify: failed to setup DSA sig"); 6748ed2b524SDag-Erling Smørgrav *reason = "use of key for DSA crypto failed"; 6758ed2b524SDag-Erling Smørgrav EVP_PKEY_free(evp_key); 6768ed2b524SDag-Erling Smørgrav return sec_status_bogus; 6778ed2b524SDag-Erling Smørgrav } 678e2d15004SDag-Erling Smørgrav docrypto_free = 1; 6798ed2b524SDag-Erling Smørgrav } 680e2d15004SDag-Erling Smørgrav #endif 681e2d15004SDag-Erling Smørgrav #if defined(USE_ECDSA) && defined(USE_DSA) 682e2d15004SDag-Erling Smørgrav else 683e2d15004SDag-Erling Smørgrav #endif 6848ed2b524SDag-Erling Smørgrav #ifdef USE_ECDSA 685e2d15004SDag-Erling Smørgrav if(algo == LDNS_ECDSAP256SHA256 || algo == LDNS_ECDSAP384SHA384) { 6868ed2b524SDag-Erling Smørgrav /* EVP uses ASN prefix on sig, which is not in the wire data */ 6878ed2b524SDag-Erling Smørgrav if(!setup_ecdsa_sig(&sigblock, &sigblock_len)) { 6888ed2b524SDag-Erling Smørgrav verbose(VERB_QUERY, "verify: failed to setup ECDSA sig"); 6898ed2b524SDag-Erling Smørgrav *reason = "use of signature for ECDSA crypto failed"; 6908ed2b524SDag-Erling Smørgrav EVP_PKEY_free(evp_key); 6918ed2b524SDag-Erling Smørgrav return sec_status_bogus; 6928ed2b524SDag-Erling Smørgrav } 6938ed2b524SDag-Erling Smørgrav dofree = 1; 6948ed2b524SDag-Erling Smørgrav } 6958ed2b524SDag-Erling Smørgrav #endif /* USE_ECDSA */ 6968ed2b524SDag-Erling Smørgrav 6978ed2b524SDag-Erling Smørgrav /* do the signature cryptography work */ 698e2d15004SDag-Erling Smørgrav #ifdef HAVE_EVP_MD_CTX_NEW 699e2d15004SDag-Erling Smørgrav ctx = EVP_MD_CTX_new(); 700e2d15004SDag-Erling Smørgrav #else 701e2d15004SDag-Erling Smørgrav ctx = (EVP_MD_CTX*)malloc(sizeof(*ctx)); 702e2d15004SDag-Erling Smørgrav if(ctx) EVP_MD_CTX_init(ctx); 703e2d15004SDag-Erling Smørgrav #endif 704e2d15004SDag-Erling Smørgrav if(!ctx) { 705e2d15004SDag-Erling Smørgrav log_err("EVP_MD_CTX_new: malloc failure"); 7068ed2b524SDag-Erling Smørgrav EVP_PKEY_free(evp_key); 7078ed2b524SDag-Erling Smørgrav if(dofree) free(sigblock); 708b5663de9SDag-Erling Smørgrav else if(docrypto_free) OPENSSL_free(sigblock); 7098ed2b524SDag-Erling Smørgrav return sec_status_unchecked; 7108ed2b524SDag-Erling Smørgrav } 711c7f4d7adSDag-Erling Smørgrav #ifndef HAVE_EVP_DIGESTVERIFY 712c7f4d7adSDag-Erling Smørgrav if(EVP_DigestInit(ctx, digest_type) == 0) { 713c7f4d7adSDag-Erling Smørgrav verbose(VERB_QUERY, "verify: EVP_DigestInit failed"); 714c7f4d7adSDag-Erling Smørgrav #ifdef HAVE_EVP_MD_CTX_NEW 715e2d15004SDag-Erling Smørgrav EVP_MD_CTX_destroy(ctx); 716c7f4d7adSDag-Erling Smørgrav #else 717c7f4d7adSDag-Erling Smørgrav EVP_MD_CTX_cleanup(ctx); 718c7f4d7adSDag-Erling Smørgrav free(ctx); 719c7f4d7adSDag-Erling Smørgrav #endif 720e2d15004SDag-Erling Smørgrav EVP_PKEY_free(evp_key); 721e2d15004SDag-Erling Smørgrav if(dofree) free(sigblock); 722b5663de9SDag-Erling Smørgrav else if(docrypto_free) OPENSSL_free(sigblock); 723e2d15004SDag-Erling Smørgrav return sec_status_unchecked; 724e2d15004SDag-Erling Smørgrav } 725c7f4d7adSDag-Erling Smørgrav if(EVP_DigestUpdate(ctx, (unsigned char*)sldns_buffer_begin(buf), 72617d15b25SDag-Erling Smørgrav (unsigned int)sldns_buffer_limit(buf)) == 0) { 727c7f4d7adSDag-Erling Smørgrav verbose(VERB_QUERY, "verify: EVP_DigestUpdate failed"); 728c7f4d7adSDag-Erling Smørgrav #ifdef HAVE_EVP_MD_CTX_NEW 729e2d15004SDag-Erling Smørgrav EVP_MD_CTX_destroy(ctx); 730c7f4d7adSDag-Erling Smørgrav #else 731c7f4d7adSDag-Erling Smørgrav EVP_MD_CTX_cleanup(ctx); 732c7f4d7adSDag-Erling Smørgrav free(ctx); 733c7f4d7adSDag-Erling Smørgrav #endif 7348ed2b524SDag-Erling Smørgrav EVP_PKEY_free(evp_key); 7358ed2b524SDag-Erling Smørgrav if(dofree) free(sigblock); 736b5663de9SDag-Erling Smørgrav else if(docrypto_free) OPENSSL_free(sigblock); 7378ed2b524SDag-Erling Smørgrav return sec_status_unchecked; 7388ed2b524SDag-Erling Smørgrav } 7398ed2b524SDag-Erling Smørgrav 740e2d15004SDag-Erling Smørgrav res = EVP_VerifyFinal(ctx, sigblock, sigblock_len, evp_key); 741c7f4d7adSDag-Erling Smørgrav #else /* HAVE_EVP_DIGESTVERIFY */ 742c7f4d7adSDag-Erling Smørgrav if(EVP_DigestVerifyInit(ctx, NULL, digest_type, NULL, evp_key) == 0) { 743c7f4d7adSDag-Erling Smørgrav verbose(VERB_QUERY, "verify: EVP_DigestVerifyInit failed"); 744c7f4d7adSDag-Erling Smørgrav #ifdef HAVE_EVP_MD_CTX_NEW 745c7f4d7adSDag-Erling Smørgrav EVP_MD_CTX_destroy(ctx); 746c7f4d7adSDag-Erling Smørgrav #else 747c7f4d7adSDag-Erling Smørgrav EVP_MD_CTX_cleanup(ctx); 748c7f4d7adSDag-Erling Smørgrav free(ctx); 749c7f4d7adSDag-Erling Smørgrav #endif 750c7f4d7adSDag-Erling Smørgrav EVP_PKEY_free(evp_key); 751c7f4d7adSDag-Erling Smørgrav if(dofree) free(sigblock); 752c7f4d7adSDag-Erling Smørgrav else if(docrypto_free) OPENSSL_free(sigblock); 753c7f4d7adSDag-Erling Smørgrav return sec_status_unchecked; 754c7f4d7adSDag-Erling Smørgrav } 755c7f4d7adSDag-Erling Smørgrav res = EVP_DigestVerify(ctx, sigblock, sigblock_len, 756c7f4d7adSDag-Erling Smørgrav (unsigned char*)sldns_buffer_begin(buf), 757c7f4d7adSDag-Erling Smørgrav sldns_buffer_limit(buf)); 758c7f4d7adSDag-Erling Smørgrav #endif 759e2d15004SDag-Erling Smørgrav #ifdef HAVE_EVP_MD_CTX_NEW 760e2d15004SDag-Erling Smørgrav EVP_MD_CTX_destroy(ctx); 761e2d15004SDag-Erling Smørgrav #else 762e2d15004SDag-Erling Smørgrav EVP_MD_CTX_cleanup(ctx); 763e2d15004SDag-Erling Smørgrav free(ctx); 764e2d15004SDag-Erling Smørgrav #endif 7658ed2b524SDag-Erling Smørgrav EVP_PKEY_free(evp_key); 7668ed2b524SDag-Erling Smørgrav 767e2d15004SDag-Erling Smørgrav if(dofree) free(sigblock); 768b5663de9SDag-Erling Smørgrav else if(docrypto_free) OPENSSL_free(sigblock); 7698ed2b524SDag-Erling Smørgrav 7708ed2b524SDag-Erling Smørgrav if(res == 1) { 7718ed2b524SDag-Erling Smørgrav return sec_status_secure; 7728ed2b524SDag-Erling Smørgrav } else if(res == 0) { 7738ed2b524SDag-Erling Smørgrav verbose(VERB_QUERY, "verify: signature mismatch"); 7748ed2b524SDag-Erling Smørgrav *reason = "signature crypto failed"; 7758ed2b524SDag-Erling Smørgrav return sec_status_bogus; 7768ed2b524SDag-Erling Smørgrav } 7778ed2b524SDag-Erling Smørgrav 7788ed2b524SDag-Erling Smørgrav log_crypto_error("verify:", ERR_get_error()); 7798ed2b524SDag-Erling Smørgrav return sec_status_unchecked; 7808ed2b524SDag-Erling Smørgrav } 7818ed2b524SDag-Erling Smørgrav 7828ed2b524SDag-Erling Smørgrav /**************************************************/ 7838ed2b524SDag-Erling Smørgrav #elif defined(HAVE_NSS) 7848ed2b524SDag-Erling Smørgrav /* libnss implementation */ 7858ed2b524SDag-Erling Smørgrav /* nss3 */ 7868ed2b524SDag-Erling Smørgrav #include "sechash.h" 7878ed2b524SDag-Erling Smørgrav #include "pk11pub.h" 7888ed2b524SDag-Erling Smørgrav #include "keyhi.h" 7898ed2b524SDag-Erling Smørgrav #include "secerr.h" 7908ed2b524SDag-Erling Smørgrav #include "cryptohi.h" 7918ed2b524SDag-Erling Smørgrav /* nspr4 */ 7928ed2b524SDag-Erling Smørgrav #include "prerror.h" 7938ed2b524SDag-Erling Smørgrav 79405ab2901SDag-Erling Smørgrav /* return size of digest if supported, or 0 otherwise */ 79505ab2901SDag-Erling Smørgrav size_t 79605ab2901SDag-Erling Smørgrav nsec3_hash_algo_size_supported(int id) 79705ab2901SDag-Erling Smørgrav { 79805ab2901SDag-Erling Smørgrav switch(id) { 79905ab2901SDag-Erling Smørgrav case NSEC3_HASH_SHA1: 80005ab2901SDag-Erling Smørgrav return SHA1_LENGTH; 80105ab2901SDag-Erling Smørgrav default: 80205ab2901SDag-Erling Smørgrav return 0; 80305ab2901SDag-Erling Smørgrav } 80405ab2901SDag-Erling Smørgrav } 80505ab2901SDag-Erling Smørgrav 80605ab2901SDag-Erling Smørgrav /* perform nsec3 hash. return false on failure */ 80705ab2901SDag-Erling Smørgrav int 80805ab2901SDag-Erling Smørgrav secalgo_nsec3_hash(int algo, unsigned char* buf, size_t len, 80905ab2901SDag-Erling Smørgrav unsigned char* res) 81005ab2901SDag-Erling Smørgrav { 81105ab2901SDag-Erling Smørgrav switch(algo) { 81205ab2901SDag-Erling Smørgrav case NSEC3_HASH_SHA1: 81305ab2901SDag-Erling Smørgrav (void)HASH_HashBuf(HASH_AlgSHA1, res, buf, (unsigned long)len); 81405ab2901SDag-Erling Smørgrav return 1; 81505ab2901SDag-Erling Smørgrav default: 81605ab2901SDag-Erling Smørgrav return 0; 81705ab2901SDag-Erling Smørgrav } 81805ab2901SDag-Erling Smørgrav } 81905ab2901SDag-Erling Smørgrav 820e2d15004SDag-Erling Smørgrav void 821e2d15004SDag-Erling Smørgrav secalgo_hash_sha256(unsigned char* buf, size_t len, unsigned char* res) 822e2d15004SDag-Erling Smørgrav { 823e2d15004SDag-Erling Smørgrav (void)HASH_HashBuf(HASH_AlgSHA256, res, buf, (unsigned long)len); 824e2d15004SDag-Erling Smørgrav } 825e2d15004SDag-Erling Smørgrav 8268ed2b524SDag-Erling Smørgrav size_t 8278ed2b524SDag-Erling Smørgrav ds_digest_size_supported(int algo) 8288ed2b524SDag-Erling Smørgrav { 8298ed2b524SDag-Erling Smørgrav /* uses libNSS */ 8308ed2b524SDag-Erling Smørgrav switch(algo) { 83165b390aaSDag-Erling Smørgrav #ifdef USE_SHA1 8328ed2b524SDag-Erling Smørgrav case LDNS_SHA1: 8338ed2b524SDag-Erling Smørgrav return SHA1_LENGTH; 83465b390aaSDag-Erling Smørgrav #endif 8358ed2b524SDag-Erling Smørgrav #ifdef USE_SHA2 8368ed2b524SDag-Erling Smørgrav case LDNS_SHA256: 8378ed2b524SDag-Erling Smørgrav return SHA256_LENGTH; 8388ed2b524SDag-Erling Smørgrav #endif 8398ed2b524SDag-Erling Smørgrav #ifdef USE_ECDSA 8408ed2b524SDag-Erling Smørgrav case LDNS_SHA384: 8418ed2b524SDag-Erling Smørgrav return SHA384_LENGTH; 8428ed2b524SDag-Erling Smørgrav #endif 8438ed2b524SDag-Erling Smørgrav /* GOST not supported in NSS */ 8448ed2b524SDag-Erling Smørgrav case LDNS_HASH_GOST: 8458ed2b524SDag-Erling Smørgrav default: break; 8468ed2b524SDag-Erling Smørgrav } 8478ed2b524SDag-Erling Smørgrav return 0; 8488ed2b524SDag-Erling Smørgrav } 8498ed2b524SDag-Erling Smørgrav 8508ed2b524SDag-Erling Smørgrav int 8518ed2b524SDag-Erling Smørgrav secalgo_ds_digest(int algo, unsigned char* buf, size_t len, 8528ed2b524SDag-Erling Smørgrav unsigned char* res) 8538ed2b524SDag-Erling Smørgrav { 8548ed2b524SDag-Erling Smørgrav /* uses libNSS */ 8558ed2b524SDag-Erling Smørgrav switch(algo) { 85665b390aaSDag-Erling Smørgrav #ifdef USE_SHA1 8578ed2b524SDag-Erling Smørgrav case LDNS_SHA1: 8588ed2b524SDag-Erling Smørgrav return HASH_HashBuf(HASH_AlgSHA1, res, buf, len) 8598ed2b524SDag-Erling Smørgrav == SECSuccess; 86065b390aaSDag-Erling Smørgrav #endif 8618ed2b524SDag-Erling Smørgrav #if defined(USE_SHA2) 8628ed2b524SDag-Erling Smørgrav case LDNS_SHA256: 8638ed2b524SDag-Erling Smørgrav return HASH_HashBuf(HASH_AlgSHA256, res, buf, len) 8648ed2b524SDag-Erling Smørgrav == SECSuccess; 8658ed2b524SDag-Erling Smørgrav #endif 8668ed2b524SDag-Erling Smørgrav #ifdef USE_ECDSA 8678ed2b524SDag-Erling Smørgrav case LDNS_SHA384: 8688ed2b524SDag-Erling Smørgrav return HASH_HashBuf(HASH_AlgSHA384, res, buf, len) 8698ed2b524SDag-Erling Smørgrav == SECSuccess; 8708ed2b524SDag-Erling Smørgrav #endif 8718ed2b524SDag-Erling Smørgrav case LDNS_HASH_GOST: 8728ed2b524SDag-Erling Smørgrav default: 8738ed2b524SDag-Erling Smørgrav verbose(VERB_QUERY, "unknown DS digest algorithm %d", 8748ed2b524SDag-Erling Smørgrav algo); 8758ed2b524SDag-Erling Smørgrav break; 8768ed2b524SDag-Erling Smørgrav } 8778ed2b524SDag-Erling Smørgrav return 0; 8788ed2b524SDag-Erling Smørgrav } 8798ed2b524SDag-Erling Smørgrav 8808ed2b524SDag-Erling Smørgrav int 8818ed2b524SDag-Erling Smørgrav dnskey_algo_id_is_supported(int id) 8828ed2b524SDag-Erling Smørgrav { 8838ed2b524SDag-Erling Smørgrav /* uses libNSS */ 8848ed2b524SDag-Erling Smørgrav switch(id) { 8858ed2b524SDag-Erling Smørgrav case LDNS_RSAMD5: 8868ed2b524SDag-Erling Smørgrav /* RFC 6725 deprecates RSAMD5 */ 8878ed2b524SDag-Erling Smørgrav return 0; 88865b390aaSDag-Erling Smørgrav #if defined(USE_SHA1) || defined(USE_SHA2) 88965b390aaSDag-Erling Smørgrav #if defined(USE_DSA) && defined(USE_SHA1) 8908ed2b524SDag-Erling Smørgrav case LDNS_DSA: 8918ed2b524SDag-Erling Smørgrav case LDNS_DSA_NSEC3: 892e2d15004SDag-Erling Smørgrav #endif 89365b390aaSDag-Erling Smørgrav #ifdef USE_SHA1 8948ed2b524SDag-Erling Smørgrav case LDNS_RSASHA1: 8958ed2b524SDag-Erling Smørgrav case LDNS_RSASHA1_NSEC3: 89665b390aaSDag-Erling Smørgrav #endif 8978ed2b524SDag-Erling Smørgrav #ifdef USE_SHA2 8988ed2b524SDag-Erling Smørgrav case LDNS_RSASHA256: 8998ed2b524SDag-Erling Smørgrav #endif 9008ed2b524SDag-Erling Smørgrav #ifdef USE_SHA2 9018ed2b524SDag-Erling Smørgrav case LDNS_RSASHA512: 9028ed2b524SDag-Erling Smørgrav #endif 9038ed2b524SDag-Erling Smørgrav return 1; 90465b390aaSDag-Erling Smørgrav #endif /* SHA1 or SHA2 */ 90565b390aaSDag-Erling Smørgrav 9068ed2b524SDag-Erling Smørgrav #ifdef USE_ECDSA 9078ed2b524SDag-Erling Smørgrav case LDNS_ECDSAP256SHA256: 9088ed2b524SDag-Erling Smørgrav case LDNS_ECDSAP384SHA384: 9098ed2b524SDag-Erling Smørgrav return PK11_TokenExists(CKM_ECDSA); 9108ed2b524SDag-Erling Smørgrav #endif 9118ed2b524SDag-Erling Smørgrav case LDNS_ECC_GOST: 9128ed2b524SDag-Erling Smørgrav default: 9138ed2b524SDag-Erling Smørgrav return 0; 9148ed2b524SDag-Erling Smørgrav } 9158ed2b524SDag-Erling Smørgrav } 9168ed2b524SDag-Erling Smørgrav 9178ed2b524SDag-Erling Smørgrav /* return a new public key for NSS */ 9188ed2b524SDag-Erling Smørgrav static SECKEYPublicKey* nss_key_create(KeyType ktype) 9198ed2b524SDag-Erling Smørgrav { 9208ed2b524SDag-Erling Smørgrav SECKEYPublicKey* key; 9218ed2b524SDag-Erling Smørgrav PLArenaPool* arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); 9228ed2b524SDag-Erling Smørgrav if(!arena) { 9238ed2b524SDag-Erling Smørgrav log_err("out of memory, PORT_NewArena failed"); 9248ed2b524SDag-Erling Smørgrav return NULL; 9258ed2b524SDag-Erling Smørgrav } 9268ed2b524SDag-Erling Smørgrav key = PORT_ArenaZNew(arena, SECKEYPublicKey); 9278ed2b524SDag-Erling Smørgrav if(!key) { 9288ed2b524SDag-Erling Smørgrav log_err("out of memory, PORT_ArenaZNew failed"); 9298ed2b524SDag-Erling Smørgrav PORT_FreeArena(arena, PR_FALSE); 9308ed2b524SDag-Erling Smørgrav return NULL; 9318ed2b524SDag-Erling Smørgrav } 9328ed2b524SDag-Erling Smørgrav key->arena = arena; 9338ed2b524SDag-Erling Smørgrav key->keyType = ktype; 9348ed2b524SDag-Erling Smørgrav key->pkcs11Slot = NULL; 9358ed2b524SDag-Erling Smørgrav key->pkcs11ID = CK_INVALID_HANDLE; 9368ed2b524SDag-Erling Smørgrav return key; 9378ed2b524SDag-Erling Smørgrav } 9388ed2b524SDag-Erling Smørgrav 9398ed2b524SDag-Erling Smørgrav static SECKEYPublicKey* nss_buf2ecdsa(unsigned char* key, size_t len, int algo) 9408ed2b524SDag-Erling Smørgrav { 9418ed2b524SDag-Erling Smørgrav SECKEYPublicKey* pk; 9428ed2b524SDag-Erling Smørgrav SECItem pub = {siBuffer, NULL, 0}; 9438ed2b524SDag-Erling Smørgrav SECItem params = {siBuffer, NULL, 0}; 94417d15b25SDag-Erling Smørgrav static unsigned char param256[] = { 9458ed2b524SDag-Erling Smørgrav /* OBJECTIDENTIFIER 1.2.840.10045.3.1.7 (P-256) 9468ed2b524SDag-Erling Smørgrav * {iso(1) member-body(2) us(840) ansi-x962(10045) curves(3) prime(1) prime256v1(7)} */ 9478ed2b524SDag-Erling Smørgrav 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07 9488ed2b524SDag-Erling Smørgrav }; 94917d15b25SDag-Erling Smørgrav static unsigned char param384[] = { 9508ed2b524SDag-Erling Smørgrav /* OBJECTIDENTIFIER 1.3.132.0.34 (P-384) 9518ed2b524SDag-Erling Smørgrav * {iso(1) identified-organization(3) certicom(132) curve(0) ansip384r1(34)} */ 9528ed2b524SDag-Erling Smørgrav 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x22 9538ed2b524SDag-Erling Smørgrav }; 9548ed2b524SDag-Erling Smørgrav unsigned char buf[256+2]; /* sufficient for 2*384/8+1 */ 9558ed2b524SDag-Erling Smørgrav 9568ed2b524SDag-Erling Smørgrav /* check length, which uncompressed must be 2 bignums */ 9578ed2b524SDag-Erling Smørgrav if(algo == LDNS_ECDSAP256SHA256) { 9588ed2b524SDag-Erling Smørgrav if(len != 2*256/8) return NULL; 9598ed2b524SDag-Erling Smørgrav /* ECCurve_X9_62_PRIME_256V1 */ 9608ed2b524SDag-Erling Smørgrav } else if(algo == LDNS_ECDSAP384SHA384) { 9618ed2b524SDag-Erling Smørgrav if(len != 2*384/8) return NULL; 9628ed2b524SDag-Erling Smørgrav /* ECCurve_X9_62_PRIME_384R1 */ 9638ed2b524SDag-Erling Smørgrav } else return NULL; 9648ed2b524SDag-Erling Smørgrav 9658ed2b524SDag-Erling Smørgrav buf[0] = 0x04; /* POINT_FORM_UNCOMPRESSED */ 9668ed2b524SDag-Erling Smørgrav memmove(buf+1, key, len); 9678ed2b524SDag-Erling Smørgrav pub.data = buf; 9688ed2b524SDag-Erling Smørgrav pub.len = len+1; 9698ed2b524SDag-Erling Smørgrav if(algo == LDNS_ECDSAP256SHA256) { 9708ed2b524SDag-Erling Smørgrav params.data = param256; 9718ed2b524SDag-Erling Smørgrav params.len = sizeof(param256); 9728ed2b524SDag-Erling Smørgrav } else { 9738ed2b524SDag-Erling Smørgrav params.data = param384; 9748ed2b524SDag-Erling Smørgrav params.len = sizeof(param384); 9758ed2b524SDag-Erling Smørgrav } 9768ed2b524SDag-Erling Smørgrav 9778ed2b524SDag-Erling Smørgrav pk = nss_key_create(ecKey); 9788ed2b524SDag-Erling Smørgrav if(!pk) 9798ed2b524SDag-Erling Smørgrav return NULL; 9808ed2b524SDag-Erling Smørgrav pk->u.ec.size = (len/2)*8; 9818ed2b524SDag-Erling Smørgrav if(SECITEM_CopyItem(pk->arena, &pk->u.ec.publicValue, &pub)) { 9828ed2b524SDag-Erling Smørgrav SECKEY_DestroyPublicKey(pk); 9838ed2b524SDag-Erling Smørgrav return NULL; 9848ed2b524SDag-Erling Smørgrav } 9858ed2b524SDag-Erling Smørgrav if(SECITEM_CopyItem(pk->arena, &pk->u.ec.DEREncodedParams, ¶ms)) { 9868ed2b524SDag-Erling Smørgrav SECKEY_DestroyPublicKey(pk); 9878ed2b524SDag-Erling Smørgrav return NULL; 9888ed2b524SDag-Erling Smørgrav } 9898ed2b524SDag-Erling Smørgrav 9908ed2b524SDag-Erling Smørgrav return pk; 9918ed2b524SDag-Erling Smørgrav } 9928ed2b524SDag-Erling Smørgrav 9938ed2b524SDag-Erling Smørgrav static SECKEYPublicKey* nss_buf2dsa(unsigned char* key, size_t len) 9948ed2b524SDag-Erling Smørgrav { 9958ed2b524SDag-Erling Smørgrav SECKEYPublicKey* pk; 9968ed2b524SDag-Erling Smørgrav uint8_t T; 9978ed2b524SDag-Erling Smørgrav uint16_t length; 9988ed2b524SDag-Erling Smørgrav uint16_t offset; 9998ed2b524SDag-Erling Smørgrav SECItem Q = {siBuffer, NULL, 0}; 10008ed2b524SDag-Erling Smørgrav SECItem P = {siBuffer, NULL, 0}; 10018ed2b524SDag-Erling Smørgrav SECItem G = {siBuffer, NULL, 0}; 10028ed2b524SDag-Erling Smørgrav SECItem Y = {siBuffer, NULL, 0}; 10038ed2b524SDag-Erling Smørgrav 10048ed2b524SDag-Erling Smørgrav if(len == 0) 10058ed2b524SDag-Erling Smørgrav return NULL; 10068ed2b524SDag-Erling Smørgrav T = (uint8_t)key[0]; 10078ed2b524SDag-Erling Smørgrav length = (64 + T * 8); 10088ed2b524SDag-Erling Smørgrav offset = 1; 10098ed2b524SDag-Erling Smørgrav 10108ed2b524SDag-Erling Smørgrav if (T > 8) { 10118ed2b524SDag-Erling Smørgrav return NULL; 10128ed2b524SDag-Erling Smørgrav } 10138ed2b524SDag-Erling Smørgrav if(len < (size_t)1 + SHA1_LENGTH + 3*length) 10148ed2b524SDag-Erling Smørgrav return NULL; 10158ed2b524SDag-Erling Smørgrav 10168ed2b524SDag-Erling Smørgrav Q.data = key+offset; 10178ed2b524SDag-Erling Smørgrav Q.len = SHA1_LENGTH; 10188ed2b524SDag-Erling Smørgrav offset += SHA1_LENGTH; 10198ed2b524SDag-Erling Smørgrav 10208ed2b524SDag-Erling Smørgrav P.data = key+offset; 10218ed2b524SDag-Erling Smørgrav P.len = length; 10228ed2b524SDag-Erling Smørgrav offset += length; 10238ed2b524SDag-Erling Smørgrav 10248ed2b524SDag-Erling Smørgrav G.data = key+offset; 10258ed2b524SDag-Erling Smørgrav G.len = length; 10268ed2b524SDag-Erling Smørgrav offset += length; 10278ed2b524SDag-Erling Smørgrav 10288ed2b524SDag-Erling Smørgrav Y.data = key+offset; 10298ed2b524SDag-Erling Smørgrav Y.len = length; 10308ed2b524SDag-Erling Smørgrav offset += length; 10318ed2b524SDag-Erling Smørgrav 10328ed2b524SDag-Erling Smørgrav pk = nss_key_create(dsaKey); 10338ed2b524SDag-Erling Smørgrav if(!pk) 10348ed2b524SDag-Erling Smørgrav return NULL; 10358ed2b524SDag-Erling Smørgrav if(SECITEM_CopyItem(pk->arena, &pk->u.dsa.params.prime, &P)) { 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.subPrime, &Q)) { 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.params.base, &G)) { 10448ed2b524SDag-Erling Smørgrav SECKEY_DestroyPublicKey(pk); 10458ed2b524SDag-Erling Smørgrav return NULL; 10468ed2b524SDag-Erling Smørgrav } 10478ed2b524SDag-Erling Smørgrav if(SECITEM_CopyItem(pk->arena, &pk->u.dsa.publicValue, &Y)) { 10488ed2b524SDag-Erling Smørgrav SECKEY_DestroyPublicKey(pk); 10498ed2b524SDag-Erling Smørgrav return NULL; 10508ed2b524SDag-Erling Smørgrav } 10518ed2b524SDag-Erling Smørgrav return pk; 10528ed2b524SDag-Erling Smørgrav } 10538ed2b524SDag-Erling Smørgrav 10548ed2b524SDag-Erling Smørgrav static SECKEYPublicKey* nss_buf2rsa(unsigned char* key, size_t len) 10558ed2b524SDag-Erling Smørgrav { 10568ed2b524SDag-Erling Smørgrav SECKEYPublicKey* pk; 10578ed2b524SDag-Erling Smørgrav uint16_t exp; 10588ed2b524SDag-Erling Smørgrav uint16_t offset; 10598ed2b524SDag-Erling Smørgrav uint16_t int16; 10608ed2b524SDag-Erling Smørgrav SECItem modulus = {siBuffer, NULL, 0}; 10618ed2b524SDag-Erling Smørgrav SECItem exponent = {siBuffer, NULL, 0}; 10628ed2b524SDag-Erling Smørgrav if(len == 0) 10638ed2b524SDag-Erling Smørgrav return NULL; 10648ed2b524SDag-Erling Smørgrav if(key[0] == 0) { 10658ed2b524SDag-Erling Smørgrav if(len < 3) 10668ed2b524SDag-Erling Smørgrav return NULL; 10678ed2b524SDag-Erling Smørgrav /* the exponent is too large so it's places further */ 10688ed2b524SDag-Erling Smørgrav memmove(&int16, key+1, 2); 10698ed2b524SDag-Erling Smørgrav exp = ntohs(int16); 10708ed2b524SDag-Erling Smørgrav offset = 3; 10718ed2b524SDag-Erling Smørgrav } else { 10728ed2b524SDag-Erling Smørgrav exp = key[0]; 10738ed2b524SDag-Erling Smørgrav offset = 1; 10748ed2b524SDag-Erling Smørgrav } 10758ed2b524SDag-Erling Smørgrav 10768ed2b524SDag-Erling Smørgrav /* key length at least one */ 10778ed2b524SDag-Erling Smørgrav if(len < (size_t)offset + exp + 1) 10788ed2b524SDag-Erling Smørgrav return NULL; 10798ed2b524SDag-Erling Smørgrav 10808ed2b524SDag-Erling Smørgrav exponent.data = key+offset; 10818ed2b524SDag-Erling Smørgrav exponent.len = exp; 10828ed2b524SDag-Erling Smørgrav offset += exp; 10838ed2b524SDag-Erling Smørgrav modulus.data = key+offset; 10848ed2b524SDag-Erling Smørgrav modulus.len = (len - offset); 10858ed2b524SDag-Erling Smørgrav 10868ed2b524SDag-Erling Smørgrav pk = nss_key_create(rsaKey); 10878ed2b524SDag-Erling Smørgrav if(!pk) 10888ed2b524SDag-Erling Smørgrav return NULL; 10898ed2b524SDag-Erling Smørgrav if(SECITEM_CopyItem(pk->arena, &pk->u.rsa.modulus, &modulus)) { 10908ed2b524SDag-Erling Smørgrav SECKEY_DestroyPublicKey(pk); 10918ed2b524SDag-Erling Smørgrav return NULL; 10928ed2b524SDag-Erling Smørgrav } 10938ed2b524SDag-Erling Smørgrav if(SECITEM_CopyItem(pk->arena, &pk->u.rsa.publicExponent, &exponent)) { 10948ed2b524SDag-Erling Smørgrav SECKEY_DestroyPublicKey(pk); 10958ed2b524SDag-Erling Smørgrav return NULL; 10968ed2b524SDag-Erling Smørgrav } 10978ed2b524SDag-Erling Smørgrav return pk; 10988ed2b524SDag-Erling Smørgrav } 10998ed2b524SDag-Erling Smørgrav 11008ed2b524SDag-Erling Smørgrav /** 11018ed2b524SDag-Erling Smørgrav * Setup key and digest for verification. Adjust sig if necessary. 11028ed2b524SDag-Erling Smørgrav * 11038ed2b524SDag-Erling Smørgrav * @param algo: key algorithm 11048ed2b524SDag-Erling Smørgrav * @param evp_key: EVP PKEY public key to create. 11058ed2b524SDag-Erling Smørgrav * @param digest_type: digest type to use 11068ed2b524SDag-Erling Smørgrav * @param key: key to setup for. 11078ed2b524SDag-Erling Smørgrav * @param keylen: length of key. 11088ed2b524SDag-Erling Smørgrav * @param prefix: if returned, the ASN prefix for the hashblob. 11098ed2b524SDag-Erling Smørgrav * @param prefixlen: length of the prefix. 11108ed2b524SDag-Erling Smørgrav * @return false on failure. 11118ed2b524SDag-Erling Smørgrav */ 11128ed2b524SDag-Erling Smørgrav static int 11138ed2b524SDag-Erling Smørgrav nss_setup_key_digest(int algo, SECKEYPublicKey** pubkey, HASH_HashType* htype, 11148ed2b524SDag-Erling Smørgrav unsigned char* key, size_t keylen, unsigned char** prefix, 11158ed2b524SDag-Erling Smørgrav size_t* prefixlen) 11168ed2b524SDag-Erling Smørgrav { 11178ed2b524SDag-Erling Smørgrav /* uses libNSS */ 11188ed2b524SDag-Erling Smørgrav 11198ed2b524SDag-Erling Smørgrav /* hash prefix for md5, RFC2537 */ 112017d15b25SDag-Erling Smørgrav static unsigned char p_md5[] = {0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 11218ed2b524SDag-Erling Smørgrav 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10}; 11228ed2b524SDag-Erling Smørgrav /* hash prefix to prepend to hash output, from RFC3110 */ 112317d15b25SDag-Erling Smørgrav static unsigned char p_sha1[] = {0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 11248ed2b524SDag-Erling Smørgrav 0x0E, 0x03, 0x02, 0x1A, 0x05, 0x00, 0x04, 0x14}; 11258ed2b524SDag-Erling Smørgrav /* from RFC5702 */ 112617d15b25SDag-Erling Smørgrav static unsigned char p_sha256[] = {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 11278ed2b524SDag-Erling Smørgrav 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20}; 112817d15b25SDag-Erling Smørgrav static unsigned char p_sha512[] = {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 11298ed2b524SDag-Erling Smørgrav 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40}; 11308ed2b524SDag-Erling Smørgrav /* from RFC6234 */ 11318ed2b524SDag-Erling Smørgrav /* for future RSASHA384 .. 113217d15b25SDag-Erling Smørgrav static unsigned char p_sha384[] = {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 11338ed2b524SDag-Erling Smørgrav 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30}; 11348ed2b524SDag-Erling Smørgrav */ 11358ed2b524SDag-Erling Smørgrav 11368ed2b524SDag-Erling Smørgrav switch(algo) { 113765b390aaSDag-Erling Smørgrav 113865b390aaSDag-Erling Smørgrav #if defined(USE_SHA1) || defined(USE_SHA2) 113965b390aaSDag-Erling Smørgrav #if defined(USE_DSA) && defined(USE_SHA1) 11408ed2b524SDag-Erling Smørgrav case LDNS_DSA: 11418ed2b524SDag-Erling Smørgrav case LDNS_DSA_NSEC3: 11428ed2b524SDag-Erling Smørgrav *pubkey = nss_buf2dsa(key, keylen); 11438ed2b524SDag-Erling Smørgrav if(!*pubkey) { 11448ed2b524SDag-Erling Smørgrav log_err("verify: malloc failure in crypto"); 11458ed2b524SDag-Erling Smørgrav return 0; 11468ed2b524SDag-Erling Smørgrav } 11478ed2b524SDag-Erling Smørgrav *htype = HASH_AlgSHA1; 11488ed2b524SDag-Erling Smørgrav /* no prefix for DSA verification */ 11498ed2b524SDag-Erling Smørgrav break; 1150e2d15004SDag-Erling Smørgrav #endif 115165b390aaSDag-Erling Smørgrav #ifdef USE_SHA1 11528ed2b524SDag-Erling Smørgrav case LDNS_RSASHA1: 11538ed2b524SDag-Erling Smørgrav case LDNS_RSASHA1_NSEC3: 115465b390aaSDag-Erling Smørgrav #endif 11558ed2b524SDag-Erling Smørgrav #ifdef USE_SHA2 11568ed2b524SDag-Erling Smørgrav case LDNS_RSASHA256: 11578ed2b524SDag-Erling Smørgrav #endif 11588ed2b524SDag-Erling Smørgrav #ifdef USE_SHA2 11598ed2b524SDag-Erling Smørgrav case LDNS_RSASHA512: 11608ed2b524SDag-Erling Smørgrav #endif 11618ed2b524SDag-Erling Smørgrav *pubkey = nss_buf2rsa(key, keylen); 11628ed2b524SDag-Erling Smørgrav if(!*pubkey) { 11638ed2b524SDag-Erling Smørgrav log_err("verify: malloc failure in crypto"); 11648ed2b524SDag-Erling Smørgrav return 0; 11658ed2b524SDag-Erling Smørgrav } 11668ed2b524SDag-Erling Smørgrav /* select SHA version */ 11678ed2b524SDag-Erling Smørgrav #ifdef USE_SHA2 11688ed2b524SDag-Erling Smørgrav if(algo == LDNS_RSASHA256) { 11698ed2b524SDag-Erling Smørgrav *htype = HASH_AlgSHA256; 11708ed2b524SDag-Erling Smørgrav *prefix = p_sha256; 11718ed2b524SDag-Erling Smørgrav *prefixlen = sizeof(p_sha256); 11728ed2b524SDag-Erling Smørgrav } else 11738ed2b524SDag-Erling Smørgrav #endif 11748ed2b524SDag-Erling Smørgrav #ifdef USE_SHA2 11758ed2b524SDag-Erling Smørgrav if(algo == LDNS_RSASHA512) { 11768ed2b524SDag-Erling Smørgrav *htype = HASH_AlgSHA512; 11778ed2b524SDag-Erling Smørgrav *prefix = p_sha512; 11788ed2b524SDag-Erling Smørgrav *prefixlen = sizeof(p_sha512); 11798ed2b524SDag-Erling Smørgrav } else 11808ed2b524SDag-Erling Smørgrav #endif 118165b390aaSDag-Erling Smørgrav #ifdef USE_SHA1 11828ed2b524SDag-Erling Smørgrav { 11838ed2b524SDag-Erling Smørgrav *htype = HASH_AlgSHA1; 11848ed2b524SDag-Erling Smørgrav *prefix = p_sha1; 11858ed2b524SDag-Erling Smørgrav *prefixlen = sizeof(p_sha1); 11868ed2b524SDag-Erling Smørgrav } 118765b390aaSDag-Erling Smørgrav #else 118865b390aaSDag-Erling Smørgrav { 118965b390aaSDag-Erling Smørgrav verbose(VERB_QUERY, "verify: no digest algo"); 119065b390aaSDag-Erling Smørgrav return 0; 119165b390aaSDag-Erling Smørgrav } 119265b390aaSDag-Erling Smørgrav #endif 11938ed2b524SDag-Erling Smørgrav 11948ed2b524SDag-Erling Smørgrav break; 119565b390aaSDag-Erling Smørgrav #endif /* SHA1 or SHA2 */ 119665b390aaSDag-Erling Smørgrav 11978ed2b524SDag-Erling Smørgrav case LDNS_RSAMD5: 11988ed2b524SDag-Erling Smørgrav *pubkey = nss_buf2rsa(key, keylen); 11998ed2b524SDag-Erling Smørgrav if(!*pubkey) { 12008ed2b524SDag-Erling Smørgrav log_err("verify: malloc failure in crypto"); 12018ed2b524SDag-Erling Smørgrav return 0; 12028ed2b524SDag-Erling Smørgrav } 12038ed2b524SDag-Erling Smørgrav *htype = HASH_AlgMD5; 12048ed2b524SDag-Erling Smørgrav *prefix = p_md5; 12058ed2b524SDag-Erling Smørgrav *prefixlen = sizeof(p_md5); 12068ed2b524SDag-Erling Smørgrav 12078ed2b524SDag-Erling Smørgrav break; 12088ed2b524SDag-Erling Smørgrav #ifdef USE_ECDSA 12098ed2b524SDag-Erling Smørgrav case LDNS_ECDSAP256SHA256: 12108ed2b524SDag-Erling Smørgrav *pubkey = nss_buf2ecdsa(key, keylen, 12118ed2b524SDag-Erling Smørgrav LDNS_ECDSAP256SHA256); 12128ed2b524SDag-Erling Smørgrav if(!*pubkey) { 12138ed2b524SDag-Erling Smørgrav log_err("verify: malloc failure in crypto"); 12148ed2b524SDag-Erling Smørgrav return 0; 12158ed2b524SDag-Erling Smørgrav } 12168ed2b524SDag-Erling Smørgrav *htype = HASH_AlgSHA256; 12178ed2b524SDag-Erling Smørgrav /* no prefix for DSA verification */ 12188ed2b524SDag-Erling Smørgrav break; 12198ed2b524SDag-Erling Smørgrav case LDNS_ECDSAP384SHA384: 12208ed2b524SDag-Erling Smørgrav *pubkey = nss_buf2ecdsa(key, keylen, 12218ed2b524SDag-Erling Smørgrav LDNS_ECDSAP384SHA384); 12228ed2b524SDag-Erling Smørgrav if(!*pubkey) { 12238ed2b524SDag-Erling Smørgrav log_err("verify: malloc failure in crypto"); 12248ed2b524SDag-Erling Smørgrav return 0; 12258ed2b524SDag-Erling Smørgrav } 12268ed2b524SDag-Erling Smørgrav *htype = HASH_AlgSHA384; 12278ed2b524SDag-Erling Smørgrav /* no prefix for DSA verification */ 12288ed2b524SDag-Erling Smørgrav break; 12298ed2b524SDag-Erling Smørgrav #endif /* USE_ECDSA */ 12308ed2b524SDag-Erling Smørgrav case LDNS_ECC_GOST: 12318ed2b524SDag-Erling Smørgrav default: 12328ed2b524SDag-Erling Smørgrav verbose(VERB_QUERY, "verify: unknown algorithm %d", 12338ed2b524SDag-Erling Smørgrav algo); 12348ed2b524SDag-Erling Smørgrav return 0; 12358ed2b524SDag-Erling Smørgrav } 12368ed2b524SDag-Erling Smørgrav return 1; 12378ed2b524SDag-Erling Smørgrav } 12388ed2b524SDag-Erling Smørgrav 12398ed2b524SDag-Erling Smørgrav /** 12408ed2b524SDag-Erling Smørgrav * Check a canonical sig+rrset and signature against a dnskey 12418ed2b524SDag-Erling Smørgrav * @param buf: buffer with data to verify, the first rrsig part and the 12428ed2b524SDag-Erling Smørgrav * canonicalized rrset. 12438ed2b524SDag-Erling Smørgrav * @param algo: DNSKEY algorithm. 12448ed2b524SDag-Erling Smørgrav * @param sigblock: signature rdata field from RRSIG 12458ed2b524SDag-Erling Smørgrav * @param sigblock_len: length of sigblock data. 12468ed2b524SDag-Erling Smørgrav * @param key: public key data from DNSKEY RR. 12478ed2b524SDag-Erling Smørgrav * @param keylen: length of keydata. 12488ed2b524SDag-Erling Smørgrav * @param reason: bogus reason in more detail. 12498ed2b524SDag-Erling Smørgrav * @return secure if verification succeeded, bogus on crypto failure, 12508ed2b524SDag-Erling Smørgrav * unchecked on format errors and alloc failures. 12518ed2b524SDag-Erling Smørgrav */ 12528ed2b524SDag-Erling Smørgrav enum sec_status 125317d15b25SDag-Erling Smørgrav verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock, 12548ed2b524SDag-Erling Smørgrav unsigned int sigblock_len, unsigned char* key, unsigned int keylen, 12558ed2b524SDag-Erling Smørgrav char** reason) 12568ed2b524SDag-Erling Smørgrav { 12578ed2b524SDag-Erling Smørgrav /* uses libNSS */ 12588ed2b524SDag-Erling Smørgrav /* large enough for the different hashes */ 12598ed2b524SDag-Erling Smørgrav unsigned char hash[HASH_LENGTH_MAX]; 12608ed2b524SDag-Erling Smørgrav unsigned char hash2[HASH_LENGTH_MAX*2]; 12618ed2b524SDag-Erling Smørgrav HASH_HashType htype = 0; 12628ed2b524SDag-Erling Smørgrav SECKEYPublicKey* pubkey = NULL; 12638ed2b524SDag-Erling Smørgrav SECItem secsig = {siBuffer, sigblock, sigblock_len}; 12648ed2b524SDag-Erling Smørgrav SECItem sechash = {siBuffer, hash, 0}; 12658ed2b524SDag-Erling Smørgrav SECStatus res; 12668ed2b524SDag-Erling Smørgrav unsigned char* prefix = NULL; /* prefix for hash, RFC3110, RFC5702 */ 12678ed2b524SDag-Erling Smørgrav size_t prefixlen = 0; 12688ed2b524SDag-Erling Smørgrav int err; 12698ed2b524SDag-Erling Smørgrav 12708ed2b524SDag-Erling Smørgrav if(!nss_setup_key_digest(algo, &pubkey, &htype, key, keylen, 12718ed2b524SDag-Erling Smørgrav &prefix, &prefixlen)) { 12728ed2b524SDag-Erling Smørgrav verbose(VERB_QUERY, "verify: failed to setup key"); 12738ed2b524SDag-Erling Smørgrav *reason = "use of key for crypto failed"; 12748ed2b524SDag-Erling Smørgrav SECKEY_DestroyPublicKey(pubkey); 12758ed2b524SDag-Erling Smørgrav return sec_status_bogus; 12768ed2b524SDag-Erling Smørgrav } 12778ed2b524SDag-Erling Smørgrav 127865b390aaSDag-Erling Smørgrav #if defined(USE_DSA) && defined(USE_SHA1) 12798ed2b524SDag-Erling Smørgrav /* need to convert DSA, ECDSA signatures? */ 12808ed2b524SDag-Erling Smørgrav if((algo == LDNS_DSA || algo == LDNS_DSA_NSEC3)) { 12818ed2b524SDag-Erling Smørgrav if(sigblock_len == 1+2*SHA1_LENGTH) { 12828ed2b524SDag-Erling Smørgrav secsig.data ++; 12838ed2b524SDag-Erling Smørgrav secsig.len --; 12848ed2b524SDag-Erling Smørgrav } else { 12858ed2b524SDag-Erling Smørgrav SECItem* p = DSAU_DecodeDerSig(&secsig); 12868ed2b524SDag-Erling Smørgrav if(!p) { 12878ed2b524SDag-Erling Smørgrav verbose(VERB_QUERY, "verify: failed DER decode"); 12888ed2b524SDag-Erling Smørgrav *reason = "signature DER decode failed"; 12898ed2b524SDag-Erling Smørgrav SECKEY_DestroyPublicKey(pubkey); 12908ed2b524SDag-Erling Smørgrav return sec_status_bogus; 12918ed2b524SDag-Erling Smørgrav } 12928ed2b524SDag-Erling Smørgrav if(SECITEM_CopyItem(pubkey->arena, &secsig, p)) { 12938ed2b524SDag-Erling Smørgrav log_err("alloc failure in DER decode"); 12948ed2b524SDag-Erling Smørgrav SECKEY_DestroyPublicKey(pubkey); 12958ed2b524SDag-Erling Smørgrav SECITEM_FreeItem(p, PR_TRUE); 12968ed2b524SDag-Erling Smørgrav return sec_status_unchecked; 12978ed2b524SDag-Erling Smørgrav } 12988ed2b524SDag-Erling Smørgrav SECITEM_FreeItem(p, PR_TRUE); 12998ed2b524SDag-Erling Smørgrav } 13008ed2b524SDag-Erling Smørgrav } 1301e2d15004SDag-Erling Smørgrav #endif /* USE_DSA */ 13028ed2b524SDag-Erling Smørgrav 13038ed2b524SDag-Erling Smørgrav /* do the signature cryptography work */ 13048ed2b524SDag-Erling Smørgrav /* hash the data */ 13058ed2b524SDag-Erling Smørgrav sechash.len = HASH_ResultLen(htype); 13068ed2b524SDag-Erling Smørgrav if(sechash.len > sizeof(hash)) { 13078ed2b524SDag-Erling Smørgrav verbose(VERB_QUERY, "verify: hash too large for buffer"); 13088ed2b524SDag-Erling Smørgrav SECKEY_DestroyPublicKey(pubkey); 13098ed2b524SDag-Erling Smørgrav return sec_status_unchecked; 13108ed2b524SDag-Erling Smørgrav } 131117d15b25SDag-Erling Smørgrav if(HASH_HashBuf(htype, hash, (unsigned char*)sldns_buffer_begin(buf), 131217d15b25SDag-Erling Smørgrav (unsigned int)sldns_buffer_limit(buf)) != SECSuccess) { 13138ed2b524SDag-Erling Smørgrav verbose(VERB_QUERY, "verify: HASH_HashBuf failed"); 13148ed2b524SDag-Erling Smørgrav SECKEY_DestroyPublicKey(pubkey); 13158ed2b524SDag-Erling Smørgrav return sec_status_unchecked; 13168ed2b524SDag-Erling Smørgrav } 13178ed2b524SDag-Erling Smørgrav if(prefix) { 13188ed2b524SDag-Erling Smørgrav int hashlen = sechash.len; 13198ed2b524SDag-Erling Smørgrav if(prefixlen+hashlen > sizeof(hash2)) { 13208ed2b524SDag-Erling Smørgrav verbose(VERB_QUERY, "verify: hashprefix too large"); 13218ed2b524SDag-Erling Smørgrav SECKEY_DestroyPublicKey(pubkey); 13228ed2b524SDag-Erling Smørgrav return sec_status_unchecked; 13238ed2b524SDag-Erling Smørgrav } 13248ed2b524SDag-Erling Smørgrav sechash.data = hash2; 13258ed2b524SDag-Erling Smørgrav sechash.len = prefixlen+hashlen; 13268ed2b524SDag-Erling Smørgrav memcpy(sechash.data, prefix, prefixlen); 13278ed2b524SDag-Erling Smørgrav memmove(sechash.data+prefixlen, hash, hashlen); 13288ed2b524SDag-Erling Smørgrav } 13298ed2b524SDag-Erling Smørgrav 13308ed2b524SDag-Erling Smørgrav /* verify the signature */ 13318ed2b524SDag-Erling Smørgrav res = PK11_Verify(pubkey, &secsig, &sechash, NULL /*wincx*/); 13328ed2b524SDag-Erling Smørgrav SECKEY_DestroyPublicKey(pubkey); 13338ed2b524SDag-Erling Smørgrav 13348ed2b524SDag-Erling Smørgrav if(res == SECSuccess) { 13358ed2b524SDag-Erling Smørgrav return sec_status_secure; 13368ed2b524SDag-Erling Smørgrav } 13378ed2b524SDag-Erling Smørgrav err = PORT_GetError(); 13388ed2b524SDag-Erling Smørgrav if(err != SEC_ERROR_BAD_SIGNATURE) { 13398ed2b524SDag-Erling Smørgrav /* failed to verify */ 13408ed2b524SDag-Erling Smørgrav verbose(VERB_QUERY, "verify: PK11_Verify failed: %s", 13418ed2b524SDag-Erling Smørgrav PORT_ErrorToString(err)); 13428ed2b524SDag-Erling Smørgrav /* if it is not supported, like ECC is removed, we get, 13438ed2b524SDag-Erling Smørgrav * SEC_ERROR_NO_MODULE */ 13448ed2b524SDag-Erling Smørgrav if(err == SEC_ERROR_NO_MODULE) 13458ed2b524SDag-Erling Smørgrav return sec_status_unchecked; 13468ed2b524SDag-Erling Smørgrav /* but other errors are commonly returned 13478ed2b524SDag-Erling Smørgrav * for a bad signature from NSS. Thus we return bogus, 13488ed2b524SDag-Erling Smørgrav * not unchecked */ 13498ed2b524SDag-Erling Smørgrav *reason = "signature crypto failed"; 13508ed2b524SDag-Erling Smørgrav return sec_status_bogus; 13518ed2b524SDag-Erling Smørgrav } 13528ed2b524SDag-Erling Smørgrav verbose(VERB_QUERY, "verify: signature mismatch: %s", 13538ed2b524SDag-Erling Smørgrav PORT_ErrorToString(err)); 13548ed2b524SDag-Erling Smørgrav *reason = "signature crypto failed"; 13558ed2b524SDag-Erling Smørgrav return sec_status_bogus; 13568ed2b524SDag-Erling Smørgrav } 13578ed2b524SDag-Erling Smørgrav 135805ab2901SDag-Erling Smørgrav #elif defined(HAVE_NETTLE) 13598ed2b524SDag-Erling Smørgrav 136005ab2901SDag-Erling Smørgrav #include "sha.h" 136105ab2901SDag-Erling Smørgrav #include "bignum.h" 136205ab2901SDag-Erling Smørgrav #include "macros.h" 136305ab2901SDag-Erling Smørgrav #include "rsa.h" 136405ab2901SDag-Erling Smørgrav #include "dsa.h" 1365b5663de9SDag-Erling Smørgrav #ifdef HAVE_NETTLE_DSA_COMPAT_H 1366b5663de9SDag-Erling Smørgrav #include "dsa-compat.h" 1367b5663de9SDag-Erling Smørgrav #endif 136805ab2901SDag-Erling Smørgrav #include "asn1.h" 136905ab2901SDag-Erling Smørgrav #ifdef USE_ECDSA 137005ab2901SDag-Erling Smørgrav #include "ecdsa.h" 137105ab2901SDag-Erling Smørgrav #include "ecc-curve.h" 137205ab2901SDag-Erling Smørgrav #endif 1373971980c3SDag-Erling Smørgrav #ifdef HAVE_NETTLE_EDDSA_H 1374971980c3SDag-Erling Smørgrav #include "eddsa.h" 1375971980c3SDag-Erling Smørgrav #endif 137605ab2901SDag-Erling Smørgrav 137705ab2901SDag-Erling Smørgrav static int 137805ab2901SDag-Erling Smørgrav _digest_nettle(int algo, uint8_t* buf, size_t len, 137905ab2901SDag-Erling Smørgrav unsigned char* res) 138005ab2901SDag-Erling Smørgrav { 138105ab2901SDag-Erling Smørgrav switch(algo) { 138205ab2901SDag-Erling Smørgrav case SHA1_DIGEST_SIZE: 138305ab2901SDag-Erling Smørgrav { 138405ab2901SDag-Erling Smørgrav struct sha1_ctx ctx; 138505ab2901SDag-Erling Smørgrav sha1_init(&ctx); 138605ab2901SDag-Erling Smørgrav sha1_update(&ctx, len, buf); 138705ab2901SDag-Erling Smørgrav sha1_digest(&ctx, SHA1_DIGEST_SIZE, res); 138805ab2901SDag-Erling Smørgrav return 1; 138905ab2901SDag-Erling Smørgrav } 139005ab2901SDag-Erling Smørgrav case SHA256_DIGEST_SIZE: 139105ab2901SDag-Erling Smørgrav { 139205ab2901SDag-Erling Smørgrav struct sha256_ctx ctx; 139305ab2901SDag-Erling Smørgrav sha256_init(&ctx); 139405ab2901SDag-Erling Smørgrav sha256_update(&ctx, len, buf); 139505ab2901SDag-Erling Smørgrav sha256_digest(&ctx, SHA256_DIGEST_SIZE, res); 139605ab2901SDag-Erling Smørgrav return 1; 139705ab2901SDag-Erling Smørgrav } 139805ab2901SDag-Erling Smørgrav case SHA384_DIGEST_SIZE: 139905ab2901SDag-Erling Smørgrav { 140005ab2901SDag-Erling Smørgrav struct sha384_ctx ctx; 140105ab2901SDag-Erling Smørgrav sha384_init(&ctx); 140205ab2901SDag-Erling Smørgrav sha384_update(&ctx, len, buf); 140305ab2901SDag-Erling Smørgrav sha384_digest(&ctx, SHA384_DIGEST_SIZE, res); 140405ab2901SDag-Erling Smørgrav return 1; 140505ab2901SDag-Erling Smørgrav } 140605ab2901SDag-Erling Smørgrav case SHA512_DIGEST_SIZE: 140705ab2901SDag-Erling Smørgrav { 140805ab2901SDag-Erling Smørgrav struct sha512_ctx ctx; 140905ab2901SDag-Erling Smørgrav sha512_init(&ctx); 141005ab2901SDag-Erling Smørgrav sha512_update(&ctx, len, buf); 141105ab2901SDag-Erling Smørgrav sha512_digest(&ctx, SHA512_DIGEST_SIZE, res); 141205ab2901SDag-Erling Smørgrav return 1; 141305ab2901SDag-Erling Smørgrav } 141405ab2901SDag-Erling Smørgrav default: 141505ab2901SDag-Erling Smørgrav break; 141605ab2901SDag-Erling Smørgrav } 141705ab2901SDag-Erling Smørgrav return 0; 141805ab2901SDag-Erling Smørgrav } 141905ab2901SDag-Erling Smørgrav 142005ab2901SDag-Erling Smørgrav /* return size of digest if supported, or 0 otherwise */ 142105ab2901SDag-Erling Smørgrav size_t 142205ab2901SDag-Erling Smørgrav nsec3_hash_algo_size_supported(int id) 142305ab2901SDag-Erling Smørgrav { 142405ab2901SDag-Erling Smørgrav switch(id) { 142505ab2901SDag-Erling Smørgrav case NSEC3_HASH_SHA1: 142605ab2901SDag-Erling Smørgrav return SHA1_DIGEST_SIZE; 142705ab2901SDag-Erling Smørgrav default: 142805ab2901SDag-Erling Smørgrav return 0; 142905ab2901SDag-Erling Smørgrav } 143005ab2901SDag-Erling Smørgrav } 143105ab2901SDag-Erling Smørgrav 143205ab2901SDag-Erling Smørgrav /* perform nsec3 hash. return false on failure */ 143305ab2901SDag-Erling Smørgrav int 143405ab2901SDag-Erling Smørgrav secalgo_nsec3_hash(int algo, unsigned char* buf, size_t len, 143505ab2901SDag-Erling Smørgrav unsigned char* res) 143605ab2901SDag-Erling Smørgrav { 143705ab2901SDag-Erling Smørgrav switch(algo) { 143805ab2901SDag-Erling Smørgrav case NSEC3_HASH_SHA1: 143905ab2901SDag-Erling Smørgrav return _digest_nettle(SHA1_DIGEST_SIZE, (uint8_t*)buf, len, 144005ab2901SDag-Erling Smørgrav res); 144105ab2901SDag-Erling Smørgrav default: 144205ab2901SDag-Erling Smørgrav return 0; 144305ab2901SDag-Erling Smørgrav } 144405ab2901SDag-Erling Smørgrav } 144505ab2901SDag-Erling Smørgrav 1446e2d15004SDag-Erling Smørgrav void 1447e2d15004SDag-Erling Smørgrav secalgo_hash_sha256(unsigned char* buf, size_t len, unsigned char* res) 1448e2d15004SDag-Erling Smørgrav { 1449e2d15004SDag-Erling Smørgrav _digest_nettle(SHA256_DIGEST_SIZE, (uint8_t*)buf, len, res); 1450e2d15004SDag-Erling Smørgrav } 1451e2d15004SDag-Erling Smørgrav 145205ab2901SDag-Erling Smørgrav /** 145305ab2901SDag-Erling Smørgrav * Return size of DS digest according to its hash algorithm. 145405ab2901SDag-Erling Smørgrav * @param algo: DS digest algo. 145505ab2901SDag-Erling Smørgrav * @return size in bytes of digest, or 0 if not supported. 145605ab2901SDag-Erling Smørgrav */ 145705ab2901SDag-Erling Smørgrav size_t 145805ab2901SDag-Erling Smørgrav ds_digest_size_supported(int algo) 145905ab2901SDag-Erling Smørgrav { 146005ab2901SDag-Erling Smørgrav switch(algo) { 146105ab2901SDag-Erling Smørgrav case LDNS_SHA1: 146265b390aaSDag-Erling Smørgrav #ifdef USE_SHA1 146305ab2901SDag-Erling Smørgrav return SHA1_DIGEST_SIZE; 146465b390aaSDag-Erling Smørgrav #else 146565b390aaSDag-Erling Smørgrav if(fake_sha1) return 20; 146665b390aaSDag-Erling Smørgrav return 0; 146765b390aaSDag-Erling Smørgrav #endif 146805ab2901SDag-Erling Smørgrav #ifdef USE_SHA2 146905ab2901SDag-Erling Smørgrav case LDNS_SHA256: 147005ab2901SDag-Erling Smørgrav return SHA256_DIGEST_SIZE; 147105ab2901SDag-Erling Smørgrav #endif 147205ab2901SDag-Erling Smørgrav #ifdef USE_ECDSA 147305ab2901SDag-Erling Smørgrav case LDNS_SHA384: 147405ab2901SDag-Erling Smørgrav return SHA384_DIGEST_SIZE; 147505ab2901SDag-Erling Smørgrav #endif 147605ab2901SDag-Erling Smørgrav /* GOST not supported */ 147705ab2901SDag-Erling Smørgrav case LDNS_HASH_GOST: 147805ab2901SDag-Erling Smørgrav default: 147905ab2901SDag-Erling Smørgrav break; 148005ab2901SDag-Erling Smørgrav } 148105ab2901SDag-Erling Smørgrav return 0; 148205ab2901SDag-Erling Smørgrav } 148305ab2901SDag-Erling Smørgrav 148405ab2901SDag-Erling Smørgrav int 148505ab2901SDag-Erling Smørgrav secalgo_ds_digest(int algo, unsigned char* buf, size_t len, 148605ab2901SDag-Erling Smørgrav unsigned char* res) 148705ab2901SDag-Erling Smørgrav { 148805ab2901SDag-Erling Smørgrav switch(algo) { 148965b390aaSDag-Erling Smørgrav #ifdef USE_SHA1 149005ab2901SDag-Erling Smørgrav case LDNS_SHA1: 149105ab2901SDag-Erling Smørgrav return _digest_nettle(SHA1_DIGEST_SIZE, buf, len, res); 149265b390aaSDag-Erling Smørgrav #endif 149305ab2901SDag-Erling Smørgrav #if defined(USE_SHA2) 149405ab2901SDag-Erling Smørgrav case LDNS_SHA256: 149505ab2901SDag-Erling Smørgrav return _digest_nettle(SHA256_DIGEST_SIZE, buf, len, res); 149605ab2901SDag-Erling Smørgrav #endif 149705ab2901SDag-Erling Smørgrav #ifdef USE_ECDSA 149805ab2901SDag-Erling Smørgrav case LDNS_SHA384: 149905ab2901SDag-Erling Smørgrav return _digest_nettle(SHA384_DIGEST_SIZE, buf, len, res); 150005ab2901SDag-Erling Smørgrav 150105ab2901SDag-Erling Smørgrav #endif 150205ab2901SDag-Erling Smørgrav case LDNS_HASH_GOST: 150305ab2901SDag-Erling Smørgrav default: 150405ab2901SDag-Erling Smørgrav verbose(VERB_QUERY, "unknown DS digest algorithm %d", 150505ab2901SDag-Erling Smørgrav algo); 150605ab2901SDag-Erling Smørgrav break; 150705ab2901SDag-Erling Smørgrav } 150805ab2901SDag-Erling Smørgrav return 0; 150905ab2901SDag-Erling Smørgrav } 151005ab2901SDag-Erling Smørgrav 151105ab2901SDag-Erling Smørgrav int 151205ab2901SDag-Erling Smørgrav dnskey_algo_id_is_supported(int id) 151305ab2901SDag-Erling Smørgrav { 151405ab2901SDag-Erling Smørgrav /* uses libnettle */ 151505ab2901SDag-Erling Smørgrav switch(id) { 151605ab2901SDag-Erling Smørgrav case LDNS_DSA: 151705ab2901SDag-Erling Smørgrav case LDNS_DSA_NSEC3: 1518091e9e46SCy Schubert #if defined(USE_DSA) && defined(USE_SHA1) 1519091e9e46SCy Schubert return 1; 1520091e9e46SCy Schubert #else 1521091e9e46SCy Schubert if(fake_dsa || fake_sha1) return 1; 1522091e9e46SCy Schubert return 0; 1523e2d15004SDag-Erling Smørgrav #endif 152405ab2901SDag-Erling Smørgrav case LDNS_RSASHA1: 152505ab2901SDag-Erling Smørgrav case LDNS_RSASHA1_NSEC3: 1526091e9e46SCy Schubert #ifdef USE_SHA1 1527091e9e46SCy Schubert return 1; 1528091e9e46SCy Schubert #else 1529091e9e46SCy Schubert if(fake_sha1) return 1; 1530091e9e46SCy Schubert return 0; 153165b390aaSDag-Erling Smørgrav #endif 153205ab2901SDag-Erling Smørgrav #ifdef USE_SHA2 153305ab2901SDag-Erling Smørgrav case LDNS_RSASHA256: 153405ab2901SDag-Erling Smørgrav case LDNS_RSASHA512: 153505ab2901SDag-Erling Smørgrav #endif 153605ab2901SDag-Erling Smørgrav #ifdef USE_ECDSA 153705ab2901SDag-Erling Smørgrav case LDNS_ECDSAP256SHA256: 153805ab2901SDag-Erling Smørgrav case LDNS_ECDSAP384SHA384: 153905ab2901SDag-Erling Smørgrav #endif 154005ab2901SDag-Erling Smørgrav return 1; 1541971980c3SDag-Erling Smørgrav #ifdef USE_ED25519 1542971980c3SDag-Erling Smørgrav case LDNS_ED25519: 1543971980c3SDag-Erling Smørgrav return 1; 1544971980c3SDag-Erling Smørgrav #endif 154505ab2901SDag-Erling Smørgrav case LDNS_RSAMD5: /* RFC 6725 deprecates RSAMD5 */ 154605ab2901SDag-Erling Smørgrav case LDNS_ECC_GOST: 154705ab2901SDag-Erling Smørgrav default: 154805ab2901SDag-Erling Smørgrav return 0; 154905ab2901SDag-Erling Smørgrav } 155005ab2901SDag-Erling Smørgrav } 155105ab2901SDag-Erling Smørgrav 155265b390aaSDag-Erling Smørgrav #if defined(USE_DSA) && defined(USE_SHA1) 155305ab2901SDag-Erling Smørgrav static char * 155405ab2901SDag-Erling Smørgrav _verify_nettle_dsa(sldns_buffer* buf, unsigned char* sigblock, 155505ab2901SDag-Erling Smørgrav unsigned int sigblock_len, unsigned char* key, unsigned int keylen) 155605ab2901SDag-Erling Smørgrav { 155705ab2901SDag-Erling Smørgrav uint8_t digest[SHA1_DIGEST_SIZE]; 15583005e0a3SDag-Erling Smørgrav uint8_t key_t_value; 155905ab2901SDag-Erling Smørgrav int res = 0; 156005ab2901SDag-Erling Smørgrav size_t offset; 156105ab2901SDag-Erling Smørgrav struct dsa_public_key pubkey; 156205ab2901SDag-Erling Smørgrav struct dsa_signature signature; 156305ab2901SDag-Erling Smørgrav unsigned int expected_len; 156405ab2901SDag-Erling Smørgrav 156505ab2901SDag-Erling Smørgrav /* Extract DSA signature from the record */ 156605ab2901SDag-Erling Smørgrav nettle_dsa_signature_init(&signature); 156705ab2901SDag-Erling Smørgrav /* Signature length: 41 bytes - RFC 2536 sec. 3 */ 156805ab2901SDag-Erling Smørgrav if(sigblock_len == 41) { 156905ab2901SDag-Erling Smørgrav if(key[0] != sigblock[0]) 157005ab2901SDag-Erling Smørgrav return "invalid T value in DSA signature or pubkey"; 157105ab2901SDag-Erling Smørgrav nettle_mpz_set_str_256_u(signature.r, 20, sigblock+1); 157205ab2901SDag-Erling Smørgrav nettle_mpz_set_str_256_u(signature.s, 20, sigblock+1+20); 157305ab2901SDag-Erling Smørgrav } else { 157405ab2901SDag-Erling Smørgrav /* DER encoded, decode the ASN1 notated R and S bignums */ 157505ab2901SDag-Erling Smørgrav /* SEQUENCE { r INTEGER, s INTEGER } */ 157605ab2901SDag-Erling Smørgrav struct asn1_der_iterator i, seq; 157705ab2901SDag-Erling Smørgrav if(asn1_der_iterator_first(&i, sigblock_len, 157805ab2901SDag-Erling Smørgrav (uint8_t*)sigblock) != ASN1_ITERATOR_CONSTRUCTED 157905ab2901SDag-Erling Smørgrav || i.type != ASN1_SEQUENCE) 158005ab2901SDag-Erling Smørgrav return "malformed DER encoded DSA signature"; 158105ab2901SDag-Erling Smørgrav /* decode this element of i using the seq iterator */ 158205ab2901SDag-Erling Smørgrav if(asn1_der_decode_constructed(&i, &seq) != 158305ab2901SDag-Erling Smørgrav ASN1_ITERATOR_PRIMITIVE || seq.type != ASN1_INTEGER) 158405ab2901SDag-Erling Smørgrav return "malformed DER encoded DSA signature"; 158505ab2901SDag-Erling Smørgrav if(!asn1_der_get_bignum(&seq, signature.r, 20*8)) 158605ab2901SDag-Erling Smørgrav return "malformed DER encoded DSA signature"; 158705ab2901SDag-Erling Smørgrav if(asn1_der_iterator_next(&seq) != ASN1_ITERATOR_PRIMITIVE 158805ab2901SDag-Erling Smørgrav || seq.type != ASN1_INTEGER) 158905ab2901SDag-Erling Smørgrav return "malformed DER encoded DSA signature"; 159005ab2901SDag-Erling Smørgrav if(!asn1_der_get_bignum(&seq, signature.s, 20*8)) 159105ab2901SDag-Erling Smørgrav return "malformed DER encoded DSA signature"; 159205ab2901SDag-Erling Smørgrav if(asn1_der_iterator_next(&i) != ASN1_ITERATOR_END) 159305ab2901SDag-Erling Smørgrav return "malformed DER encoded DSA signature"; 159405ab2901SDag-Erling Smørgrav } 159505ab2901SDag-Erling Smørgrav 159605ab2901SDag-Erling Smørgrav /* Validate T values constraints - RFC 2536 sec. 2 & sec. 3 */ 15973005e0a3SDag-Erling Smørgrav key_t_value = key[0]; 15983005e0a3SDag-Erling Smørgrav if (key_t_value > 8) { 159905ab2901SDag-Erling Smørgrav return "invalid T value in DSA pubkey"; 160005ab2901SDag-Erling Smørgrav } 160105ab2901SDag-Erling Smørgrav 160205ab2901SDag-Erling Smørgrav /* Pubkey minimum length: 21 bytes - RFC 2536 sec. 2 */ 160305ab2901SDag-Erling Smørgrav if (keylen < 21) { 160405ab2901SDag-Erling Smørgrav return "DSA pubkey too short"; 160505ab2901SDag-Erling Smørgrav } 160605ab2901SDag-Erling Smørgrav 160705ab2901SDag-Erling Smørgrav expected_len = 1 + /* T */ 160805ab2901SDag-Erling Smørgrav 20 + /* Q */ 16093005e0a3SDag-Erling Smørgrav (64 + key_t_value*8) + /* P */ 16103005e0a3SDag-Erling Smørgrav (64 + key_t_value*8) + /* G */ 16113005e0a3SDag-Erling Smørgrav (64 + key_t_value*8); /* Y */ 161205ab2901SDag-Erling Smørgrav if (keylen != expected_len ) { 161305ab2901SDag-Erling Smørgrav return "invalid DSA pubkey length"; 161405ab2901SDag-Erling Smørgrav } 161505ab2901SDag-Erling Smørgrav 161605ab2901SDag-Erling Smørgrav /* Extract DSA pubkey from the record */ 161705ab2901SDag-Erling Smørgrav nettle_dsa_public_key_init(&pubkey); 161805ab2901SDag-Erling Smørgrav offset = 1; 161905ab2901SDag-Erling Smørgrav nettle_mpz_set_str_256_u(pubkey.q, 20, key+offset); 162005ab2901SDag-Erling Smørgrav offset += 20; 16213005e0a3SDag-Erling Smørgrav nettle_mpz_set_str_256_u(pubkey.p, (64 + key_t_value*8), key+offset); 16223005e0a3SDag-Erling Smørgrav offset += (64 + key_t_value*8); 16233005e0a3SDag-Erling Smørgrav nettle_mpz_set_str_256_u(pubkey.g, (64 + key_t_value*8), key+offset); 16243005e0a3SDag-Erling Smørgrav offset += (64 + key_t_value*8); 16253005e0a3SDag-Erling Smørgrav nettle_mpz_set_str_256_u(pubkey.y, (64 + key_t_value*8), key+offset); 162605ab2901SDag-Erling Smørgrav 162705ab2901SDag-Erling Smørgrav /* Digest content of "buf" and verify its DSA signature in "sigblock"*/ 162805ab2901SDag-Erling Smørgrav res = _digest_nettle(SHA1_DIGEST_SIZE, (unsigned char*)sldns_buffer_begin(buf), 162905ab2901SDag-Erling Smørgrav (unsigned int)sldns_buffer_limit(buf), (unsigned char*)digest); 163005ab2901SDag-Erling Smørgrav res &= dsa_sha1_verify_digest(&pubkey, digest, &signature); 163105ab2901SDag-Erling Smørgrav 163205ab2901SDag-Erling Smørgrav /* Clear and return */ 163305ab2901SDag-Erling Smørgrav nettle_dsa_signature_clear(&signature); 163405ab2901SDag-Erling Smørgrav nettle_dsa_public_key_clear(&pubkey); 163505ab2901SDag-Erling Smørgrav if (!res) 163605ab2901SDag-Erling Smørgrav return "DSA signature verification failed"; 163705ab2901SDag-Erling Smørgrav else 163805ab2901SDag-Erling Smørgrav return NULL; 163905ab2901SDag-Erling Smørgrav } 1640b5663de9SDag-Erling Smørgrav #endif /* USE_DSA */ 164105ab2901SDag-Erling Smørgrav 164205ab2901SDag-Erling Smørgrav static char * 164305ab2901SDag-Erling Smørgrav _verify_nettle_rsa(sldns_buffer* buf, unsigned int digest_size, char* sigblock, 164405ab2901SDag-Erling Smørgrav unsigned int sigblock_len, uint8_t* key, unsigned int keylen) 164505ab2901SDag-Erling Smørgrav { 164605ab2901SDag-Erling Smørgrav uint16_t exp_len = 0; 164705ab2901SDag-Erling Smørgrav size_t exp_offset = 0, mod_offset = 0; 164805ab2901SDag-Erling Smørgrav struct rsa_public_key pubkey; 164905ab2901SDag-Erling Smørgrav mpz_t signature; 165005ab2901SDag-Erling Smørgrav int res = 0; 165105ab2901SDag-Erling Smørgrav 165205ab2901SDag-Erling Smørgrav /* RSA pubkey parsing as per RFC 3110 sec. 2 */ 165305ab2901SDag-Erling Smørgrav if( keylen <= 1) { 165405ab2901SDag-Erling Smørgrav return "null RSA key"; 165505ab2901SDag-Erling Smørgrav } 165605ab2901SDag-Erling Smørgrav if (key[0] != 0) { 165705ab2901SDag-Erling Smørgrav /* 1-byte length */ 165805ab2901SDag-Erling Smørgrav exp_len = key[0]; 165905ab2901SDag-Erling Smørgrav exp_offset = 1; 166005ab2901SDag-Erling Smørgrav } else { 166105ab2901SDag-Erling Smørgrav /* 1-byte NUL + 2-bytes exponent length */ 166205ab2901SDag-Erling Smørgrav if (keylen < 3) { 166305ab2901SDag-Erling Smørgrav return "incorrect RSA key length"; 166405ab2901SDag-Erling Smørgrav } 166505ab2901SDag-Erling Smørgrav exp_len = READ_UINT16(key+1); 166605ab2901SDag-Erling Smørgrav if (exp_len == 0) 166705ab2901SDag-Erling Smørgrav return "null RSA exponent length"; 166805ab2901SDag-Erling Smørgrav exp_offset = 3; 166905ab2901SDag-Erling Smørgrav } 167005ab2901SDag-Erling Smørgrav /* Check that we are not over-running input length */ 167105ab2901SDag-Erling Smørgrav if (keylen < exp_offset + exp_len + 1) { 167205ab2901SDag-Erling Smørgrav return "RSA key content shorter than expected"; 167305ab2901SDag-Erling Smørgrav } 167405ab2901SDag-Erling Smørgrav mod_offset = exp_offset + exp_len; 167505ab2901SDag-Erling Smørgrav nettle_rsa_public_key_init(&pubkey); 167605ab2901SDag-Erling Smørgrav pubkey.size = keylen - mod_offset; 167705ab2901SDag-Erling Smørgrav nettle_mpz_set_str_256_u(pubkey.e, exp_len, &key[exp_offset]); 167805ab2901SDag-Erling Smørgrav nettle_mpz_set_str_256_u(pubkey.n, pubkey.size, &key[mod_offset]); 167905ab2901SDag-Erling Smørgrav 168005ab2901SDag-Erling Smørgrav /* Digest content of "buf" and verify its RSA signature in "sigblock"*/ 168105ab2901SDag-Erling Smørgrav nettle_mpz_init_set_str_256_u(signature, sigblock_len, (uint8_t*)sigblock); 168205ab2901SDag-Erling Smørgrav switch (digest_size) { 168305ab2901SDag-Erling Smørgrav case SHA1_DIGEST_SIZE: 168405ab2901SDag-Erling Smørgrav { 168505ab2901SDag-Erling Smørgrav uint8_t digest[SHA1_DIGEST_SIZE]; 168605ab2901SDag-Erling Smørgrav res = _digest_nettle(SHA1_DIGEST_SIZE, (unsigned char*)sldns_buffer_begin(buf), 168705ab2901SDag-Erling Smørgrav (unsigned int)sldns_buffer_limit(buf), (unsigned char*)digest); 168805ab2901SDag-Erling Smørgrav res &= rsa_sha1_verify_digest(&pubkey, digest, signature); 168905ab2901SDag-Erling Smørgrav break; 169005ab2901SDag-Erling Smørgrav } 169105ab2901SDag-Erling Smørgrav case SHA256_DIGEST_SIZE: 169205ab2901SDag-Erling Smørgrav { 169305ab2901SDag-Erling Smørgrav uint8_t digest[SHA256_DIGEST_SIZE]; 169405ab2901SDag-Erling Smørgrav res = _digest_nettle(SHA256_DIGEST_SIZE, (unsigned char*)sldns_buffer_begin(buf), 169505ab2901SDag-Erling Smørgrav (unsigned int)sldns_buffer_limit(buf), (unsigned char*)digest); 169605ab2901SDag-Erling Smørgrav res &= rsa_sha256_verify_digest(&pubkey, digest, signature); 169705ab2901SDag-Erling Smørgrav break; 169805ab2901SDag-Erling Smørgrav } 169905ab2901SDag-Erling Smørgrav case SHA512_DIGEST_SIZE: 170005ab2901SDag-Erling Smørgrav { 170105ab2901SDag-Erling Smørgrav uint8_t digest[SHA512_DIGEST_SIZE]; 170205ab2901SDag-Erling Smørgrav res = _digest_nettle(SHA512_DIGEST_SIZE, (unsigned char*)sldns_buffer_begin(buf), 170305ab2901SDag-Erling Smørgrav (unsigned int)sldns_buffer_limit(buf), (unsigned char*)digest); 170405ab2901SDag-Erling Smørgrav res &= rsa_sha512_verify_digest(&pubkey, digest, signature); 170505ab2901SDag-Erling Smørgrav break; 170605ab2901SDag-Erling Smørgrav } 170705ab2901SDag-Erling Smørgrav default: 170805ab2901SDag-Erling Smørgrav break; 170905ab2901SDag-Erling Smørgrav } 171005ab2901SDag-Erling Smørgrav 171105ab2901SDag-Erling Smørgrav /* Clear and return */ 171205ab2901SDag-Erling Smørgrav nettle_rsa_public_key_clear(&pubkey); 171305ab2901SDag-Erling Smørgrav mpz_clear(signature); 171405ab2901SDag-Erling Smørgrav if (!res) { 171505ab2901SDag-Erling Smørgrav return "RSA signature verification failed"; 171605ab2901SDag-Erling Smørgrav } else { 171705ab2901SDag-Erling Smørgrav return NULL; 171805ab2901SDag-Erling Smørgrav } 171905ab2901SDag-Erling Smørgrav } 172005ab2901SDag-Erling Smørgrav 172105ab2901SDag-Erling Smørgrav #ifdef USE_ECDSA 172205ab2901SDag-Erling Smørgrav static char * 172305ab2901SDag-Erling Smørgrav _verify_nettle_ecdsa(sldns_buffer* buf, unsigned int digest_size, unsigned char* sigblock, 172405ab2901SDag-Erling Smørgrav unsigned int sigblock_len, unsigned char* key, unsigned int keylen) 172505ab2901SDag-Erling Smørgrav { 172605ab2901SDag-Erling Smørgrav int res = 0; 172705ab2901SDag-Erling Smørgrav struct ecc_point pubkey; 172805ab2901SDag-Erling Smørgrav struct dsa_signature signature; 172905ab2901SDag-Erling Smørgrav 173005ab2901SDag-Erling Smørgrav /* Always matched strength, as per RFC 6605 sec. 1 */ 173105ab2901SDag-Erling Smørgrav if (sigblock_len != 2*digest_size || keylen != 2*digest_size) { 173205ab2901SDag-Erling Smørgrav return "wrong ECDSA signature length"; 173305ab2901SDag-Erling Smørgrav } 173405ab2901SDag-Erling Smørgrav 173505ab2901SDag-Erling Smørgrav /* Parse ECDSA signature as per RFC 6605 sec. 4 */ 173605ab2901SDag-Erling Smørgrav nettle_dsa_signature_init(&signature); 173705ab2901SDag-Erling Smørgrav switch (digest_size) { 173805ab2901SDag-Erling Smørgrav case SHA256_DIGEST_SIZE: 173905ab2901SDag-Erling Smørgrav { 174005ab2901SDag-Erling Smørgrav uint8_t digest[SHA256_DIGEST_SIZE]; 174105ab2901SDag-Erling Smørgrav mpz_t x, y; 17420eefd307SCy Schubert nettle_ecc_point_init(&pubkey, nettle_get_secp_256r1()); 174305ab2901SDag-Erling Smørgrav nettle_mpz_init_set_str_256_u(x, SHA256_DIGEST_SIZE, key); 174405ab2901SDag-Erling Smørgrav nettle_mpz_init_set_str_256_u(y, SHA256_DIGEST_SIZE, key+SHA256_DIGEST_SIZE); 174505ab2901SDag-Erling Smørgrav nettle_mpz_set_str_256_u(signature.r, SHA256_DIGEST_SIZE, sigblock); 174605ab2901SDag-Erling Smørgrav nettle_mpz_set_str_256_u(signature.s, SHA256_DIGEST_SIZE, sigblock+SHA256_DIGEST_SIZE); 174705ab2901SDag-Erling Smørgrav res = _digest_nettle(SHA256_DIGEST_SIZE, (unsigned char*)sldns_buffer_begin(buf), 174805ab2901SDag-Erling Smørgrav (unsigned int)sldns_buffer_limit(buf), (unsigned char*)digest); 174905ab2901SDag-Erling Smørgrav res &= nettle_ecc_point_set(&pubkey, x, y); 175005ab2901SDag-Erling Smørgrav res &= nettle_ecdsa_verify (&pubkey, SHA256_DIGEST_SIZE, digest, &signature); 175105ab2901SDag-Erling Smørgrav mpz_clear(x); 175205ab2901SDag-Erling Smørgrav mpz_clear(y); 1753*25039b37SCy Schubert nettle_ecc_point_clear(&pubkey); 175405ab2901SDag-Erling Smørgrav break; 175505ab2901SDag-Erling Smørgrav } 175605ab2901SDag-Erling Smørgrav case SHA384_DIGEST_SIZE: 175705ab2901SDag-Erling Smørgrav { 175805ab2901SDag-Erling Smørgrav uint8_t digest[SHA384_DIGEST_SIZE]; 175905ab2901SDag-Erling Smørgrav mpz_t x, y; 17600eefd307SCy Schubert nettle_ecc_point_init(&pubkey, nettle_get_secp_384r1()); 176105ab2901SDag-Erling Smørgrav nettle_mpz_init_set_str_256_u(x, SHA384_DIGEST_SIZE, key); 176205ab2901SDag-Erling Smørgrav nettle_mpz_init_set_str_256_u(y, SHA384_DIGEST_SIZE, key+SHA384_DIGEST_SIZE); 176305ab2901SDag-Erling Smørgrav nettle_mpz_set_str_256_u(signature.r, SHA384_DIGEST_SIZE, sigblock); 176405ab2901SDag-Erling Smørgrav nettle_mpz_set_str_256_u(signature.s, SHA384_DIGEST_SIZE, sigblock+SHA384_DIGEST_SIZE); 176505ab2901SDag-Erling Smørgrav res = _digest_nettle(SHA384_DIGEST_SIZE, (unsigned char*)sldns_buffer_begin(buf), 176605ab2901SDag-Erling Smørgrav (unsigned int)sldns_buffer_limit(buf), (unsigned char*)digest); 176705ab2901SDag-Erling Smørgrav res &= nettle_ecc_point_set(&pubkey, x, y); 176805ab2901SDag-Erling Smørgrav res &= nettle_ecdsa_verify (&pubkey, SHA384_DIGEST_SIZE, digest, &signature); 176905ab2901SDag-Erling Smørgrav mpz_clear(x); 177005ab2901SDag-Erling Smørgrav mpz_clear(y); 177105ab2901SDag-Erling Smørgrav nettle_ecc_point_clear(&pubkey); 177205ab2901SDag-Erling Smørgrav break; 177305ab2901SDag-Erling Smørgrav } 177405ab2901SDag-Erling Smørgrav default: 177505ab2901SDag-Erling Smørgrav return "unknown ECDSA algorithm"; 177605ab2901SDag-Erling Smørgrav } 177705ab2901SDag-Erling Smørgrav 177805ab2901SDag-Erling Smørgrav /* Clear and return */ 177905ab2901SDag-Erling Smørgrav nettle_dsa_signature_clear(&signature); 178005ab2901SDag-Erling Smørgrav if (!res) 178105ab2901SDag-Erling Smørgrav return "ECDSA signature verification failed"; 178205ab2901SDag-Erling Smørgrav else 178305ab2901SDag-Erling Smørgrav return NULL; 178405ab2901SDag-Erling Smørgrav } 178505ab2901SDag-Erling Smørgrav #endif 178605ab2901SDag-Erling Smørgrav 1787971980c3SDag-Erling Smørgrav #ifdef USE_ED25519 1788971980c3SDag-Erling Smørgrav static char * 1789971980c3SDag-Erling Smørgrav _verify_nettle_ed25519(sldns_buffer* buf, unsigned char* sigblock, 1790971980c3SDag-Erling Smørgrav unsigned int sigblock_len, unsigned char* key, unsigned int keylen) 1791971980c3SDag-Erling Smørgrav { 1792971980c3SDag-Erling Smørgrav int res = 0; 1793971980c3SDag-Erling Smørgrav 1794971980c3SDag-Erling Smørgrav if(sigblock_len != ED25519_SIGNATURE_SIZE) { 1795971980c3SDag-Erling Smørgrav return "wrong ED25519 signature length"; 1796971980c3SDag-Erling Smørgrav } 1797971980c3SDag-Erling Smørgrav if(keylen != ED25519_KEY_SIZE) { 1798971980c3SDag-Erling Smørgrav return "wrong ED25519 key length"; 1799971980c3SDag-Erling Smørgrav } 1800971980c3SDag-Erling Smørgrav 1801971980c3SDag-Erling Smørgrav res = ed25519_sha512_verify((uint8_t*)key, sldns_buffer_limit(buf), 1802971980c3SDag-Erling Smørgrav sldns_buffer_begin(buf), (uint8_t*)sigblock); 1803971980c3SDag-Erling Smørgrav 1804971980c3SDag-Erling Smørgrav if (!res) 1805971980c3SDag-Erling Smørgrav return "ED25519 signature verification failed"; 1806971980c3SDag-Erling Smørgrav else 1807971980c3SDag-Erling Smørgrav return NULL; 1808971980c3SDag-Erling Smørgrav } 1809971980c3SDag-Erling Smørgrav #endif 1810971980c3SDag-Erling Smørgrav 181105ab2901SDag-Erling Smørgrav /** 181205ab2901SDag-Erling Smørgrav * Check a canonical sig+rrset and signature against a dnskey 181305ab2901SDag-Erling Smørgrav * @param buf: buffer with data to verify, the first rrsig part and the 181405ab2901SDag-Erling Smørgrav * canonicalized rrset. 181505ab2901SDag-Erling Smørgrav * @param algo: DNSKEY algorithm. 181605ab2901SDag-Erling Smørgrav * @param sigblock: signature rdata field from RRSIG 181705ab2901SDag-Erling Smørgrav * @param sigblock_len: length of sigblock data. 181805ab2901SDag-Erling Smørgrav * @param key: public key data from DNSKEY RR. 181905ab2901SDag-Erling Smørgrav * @param keylen: length of keydata. 182005ab2901SDag-Erling Smørgrav * @param reason: bogus reason in more detail. 182105ab2901SDag-Erling Smørgrav * @return secure if verification succeeded, bogus on crypto failure, 182205ab2901SDag-Erling Smørgrav * unchecked on format errors and alloc failures. 182305ab2901SDag-Erling Smørgrav */ 182405ab2901SDag-Erling Smørgrav enum sec_status 182505ab2901SDag-Erling Smørgrav verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock, 182605ab2901SDag-Erling Smørgrav unsigned int sigblock_len, unsigned char* key, unsigned int keylen, 182705ab2901SDag-Erling Smørgrav char** reason) 182805ab2901SDag-Erling Smørgrav { 182905ab2901SDag-Erling Smørgrav unsigned int digest_size = 0; 183005ab2901SDag-Erling Smørgrav 183105ab2901SDag-Erling Smørgrav if (sigblock_len == 0 || keylen == 0) { 183205ab2901SDag-Erling Smørgrav *reason = "null signature"; 183305ab2901SDag-Erling Smørgrav return sec_status_bogus; 183405ab2901SDag-Erling Smørgrav } 183505ab2901SDag-Erling Smørgrav 1836091e9e46SCy Schubert #ifndef USE_DSA 1837091e9e46SCy Schubert if((algo == LDNS_DSA || algo == LDNS_DSA_NSEC3) &&(fake_dsa||fake_sha1)) 1838091e9e46SCy Schubert return sec_status_secure; 1839091e9e46SCy Schubert #endif 1840091e9e46SCy Schubert #ifndef USE_SHA1 1841091e9e46SCy Schubert if(fake_sha1 && (algo == LDNS_DSA || algo == LDNS_DSA_NSEC3 || algo == LDNS_RSASHA1 || algo == LDNS_RSASHA1_NSEC3)) 1842091e9e46SCy Schubert return sec_status_secure; 1843091e9e46SCy Schubert #endif 1844091e9e46SCy Schubert 184505ab2901SDag-Erling Smørgrav switch(algo) { 184665b390aaSDag-Erling Smørgrav #if defined(USE_DSA) && defined(USE_SHA1) 184705ab2901SDag-Erling Smørgrav case LDNS_DSA: 184805ab2901SDag-Erling Smørgrav case LDNS_DSA_NSEC3: 184905ab2901SDag-Erling Smørgrav *reason = _verify_nettle_dsa(buf, sigblock, sigblock_len, key, keylen); 185005ab2901SDag-Erling Smørgrav if (*reason != NULL) 185105ab2901SDag-Erling Smørgrav return sec_status_bogus; 185205ab2901SDag-Erling Smørgrav else 185305ab2901SDag-Erling Smørgrav return sec_status_secure; 1854e2d15004SDag-Erling Smørgrav #endif /* USE_DSA */ 185505ab2901SDag-Erling Smørgrav 185665b390aaSDag-Erling Smørgrav #ifdef USE_SHA1 185705ab2901SDag-Erling Smørgrav case LDNS_RSASHA1: 185805ab2901SDag-Erling Smørgrav case LDNS_RSASHA1_NSEC3: 185905ab2901SDag-Erling Smørgrav digest_size = (digest_size ? digest_size : SHA1_DIGEST_SIZE); 186065b390aaSDag-Erling Smørgrav #endif 1861971980c3SDag-Erling Smørgrav /* double fallthrough annotation to please gcc parser */ 1862971980c3SDag-Erling Smørgrav /* fallthrough */ 186305ab2901SDag-Erling Smørgrav #ifdef USE_SHA2 1864971980c3SDag-Erling Smørgrav /* fallthrough */ 186505ab2901SDag-Erling Smørgrav case LDNS_RSASHA256: 186605ab2901SDag-Erling Smørgrav digest_size = (digest_size ? digest_size : SHA256_DIGEST_SIZE); 1867971980c3SDag-Erling Smørgrav /* fallthrough */ 186805ab2901SDag-Erling Smørgrav case LDNS_RSASHA512: 186905ab2901SDag-Erling Smørgrav digest_size = (digest_size ? digest_size : SHA512_DIGEST_SIZE); 187005ab2901SDag-Erling Smørgrav 187105ab2901SDag-Erling Smørgrav #endif 187205ab2901SDag-Erling Smørgrav *reason = _verify_nettle_rsa(buf, digest_size, (char*)sigblock, 187305ab2901SDag-Erling Smørgrav sigblock_len, key, keylen); 187405ab2901SDag-Erling Smørgrav if (*reason != NULL) 187505ab2901SDag-Erling Smørgrav return sec_status_bogus; 187605ab2901SDag-Erling Smørgrav else 187705ab2901SDag-Erling Smørgrav return sec_status_secure; 187805ab2901SDag-Erling Smørgrav 187905ab2901SDag-Erling Smørgrav #ifdef USE_ECDSA 188005ab2901SDag-Erling Smørgrav case LDNS_ECDSAP256SHA256: 188105ab2901SDag-Erling Smørgrav digest_size = (digest_size ? digest_size : SHA256_DIGEST_SIZE); 1882971980c3SDag-Erling Smørgrav /* fallthrough */ 188305ab2901SDag-Erling Smørgrav case LDNS_ECDSAP384SHA384: 188405ab2901SDag-Erling Smørgrav digest_size = (digest_size ? digest_size : SHA384_DIGEST_SIZE); 188505ab2901SDag-Erling Smørgrav *reason = _verify_nettle_ecdsa(buf, digest_size, sigblock, 188605ab2901SDag-Erling Smørgrav sigblock_len, key, keylen); 188705ab2901SDag-Erling Smørgrav if (*reason != NULL) 188805ab2901SDag-Erling Smørgrav return sec_status_bogus; 188905ab2901SDag-Erling Smørgrav else 189005ab2901SDag-Erling Smørgrav return sec_status_secure; 189105ab2901SDag-Erling Smørgrav #endif 1892971980c3SDag-Erling Smørgrav #ifdef USE_ED25519 1893971980c3SDag-Erling Smørgrav case LDNS_ED25519: 1894971980c3SDag-Erling Smørgrav *reason = _verify_nettle_ed25519(buf, sigblock, sigblock_len, 1895971980c3SDag-Erling Smørgrav key, keylen); 1896971980c3SDag-Erling Smørgrav if (*reason != NULL) 1897971980c3SDag-Erling Smørgrav return sec_status_bogus; 1898971980c3SDag-Erling Smørgrav else 1899971980c3SDag-Erling Smørgrav return sec_status_secure; 1900971980c3SDag-Erling Smørgrav #endif 190105ab2901SDag-Erling Smørgrav case LDNS_RSAMD5: 190205ab2901SDag-Erling Smørgrav case LDNS_ECC_GOST: 190305ab2901SDag-Erling Smørgrav default: 190405ab2901SDag-Erling Smørgrav *reason = "unable to verify signature, unknown algorithm"; 190505ab2901SDag-Erling Smørgrav return sec_status_bogus; 190605ab2901SDag-Erling Smørgrav } 190705ab2901SDag-Erling Smørgrav } 190805ab2901SDag-Erling Smørgrav 190905ab2901SDag-Erling Smørgrav #endif /* HAVE_SSL or HAVE_NSS or HAVE_NETTLE */ 1910