/** * Setup key and digest for verification. Adjust sig if necessary. * * @param algo: key algorithm * @param evp_key: EVP PKEY public key to create. * @param digest_type: digest type to use * @param key: key to setup for. * @param keylen: length of key. * @return false on failure. */ static int setup_key_digest(int algo, EVP_PKEY** evp_key, const EVP_MD** digest_type, unsigned char* key, size_t keylen) { #if defined(USE_DSA) && defined(USE_SHA1) DSA* dsa; #endif RSA* rsa; switch(algo) { #if defined(USE_DSA) && defined(USE_SHA1) case LDNS_DSA: case LDNS_DSA_NSEC3: *evp_key = EVP_PKEY_new(); if(!*evp_key) { log_err("verify: malloc failure in crypto"); return 0; } dsa = sldns_key_buf2dsa_raw(key, keylen); if(!dsa) { verbose(VERB_QUERY, "verify: " "sldns_key_buf2dsa_raw failed"); return 0; } if(EVP_PKEY_assign_DSA(*evp_key, dsa) == 0) { verbose(VERB_QUERY, "verify: " "EVP_PKEY_assign_DSA failed"); return 0; } #ifdef HAVE_EVP_DSS1 *digest_type = EVP_dss1(); #else *digest_type = EVP_sha1(); #endif break; #endif /* USE_DSA && USE_SHA1 */ #if defined(USE_SHA1) || (defined(HAVE_EVP_SHA256) && defined(USE_SHA2)) || (defined(HAVE_EVP_SHA512) && defined(USE_SHA2)) #ifdef USE_SHA1 case LDNS_RSASHA1: case LDNS_RSASHA1_NSEC3: #endif #if defined(HAVE_EVP_SHA256) && defined(USE_SHA2) case LDNS_RSASHA256: #endif #if defined(HAVE_EVP_SHA512) && defined(USE_SHA2) case LDNS_RSASHA512: #endif *evp_key = EVP_PKEY_new(); if(!*evp_key) { log_err("verify: malloc failure in crypto"); return 0; } rsa = sldns_key_buf2rsa_raw(key, keylen); if(!rsa) { verbose(VERB_QUERY, "verify: " "sldns_key_buf2rsa_raw SHA failed"); return 0; } if(EVP_PKEY_assign_RSA(*evp_key, rsa) == 0) { verbose(VERB_QUERY, "verify: " "EVP_PKEY_assign_RSA SHA failed"); return 0; } /* select SHA version */ #if defined(HAVE_EVP_SHA256) && defined(USE_SHA2) if(algo == LDNS_RSASHA256) *digest_type = EVP_sha256(); else #endif #if defined(HAVE_EVP_SHA512) && defined(USE_SHA2) if(algo == LDNS_RSASHA512) *digest_type = EVP_sha512(); else #endif #ifdef USE_SHA1 *digest_type = EVP_sha1(); #else { verbose(VERB_QUERY, "no digest available"); return 0; } #endif break; #endif /* defined(USE_SHA1) || (defined(HAVE_EVP_SHA256) && defined(USE_SHA2)) || (defined(HAVE_EVP_SHA512) && defined(USE_SHA2)) */ case LDNS_RSAMD5: *evp_key = EVP_PKEY_new(); if(!*evp_key) { log_err("verify: malloc failure in crypto"); return 0; } rsa = sldns_key_buf2rsa_raw(key, keylen); if(!rsa) { verbose(VERB_QUERY, "verify: " "sldns_key_buf2rsa_raw MD5 failed"); return 0; } if(EVP_PKEY_assign_RSA(*evp_key, rsa) == 0) { verbose(VERB_QUERY, "verify: " "EVP_PKEY_assign_RSA MD5 failed"); return 0; } *digest_type = EVP_md5(); break; #ifdef USE_GOST case LDNS_ECC_GOST: *evp_key = sldns_gost2pkey_raw(key, keylen); if(!*evp_key) { verbose(VERB_QUERY, "verify: " "sldns_gost2pkey_raw failed"); return 0; } *digest_type = EVP_get_digestbyname("md_gost94"); if(!*digest_type) { verbose(VERB_QUERY, "verify: " "EVP_getdigest md_gost94 failed"); return 0; } break; #endif #ifdef USE_ECDSA case LDNS_ECDSAP256SHA256: *evp_key = sldns_ecdsa2pkey_raw(key, keylen, LDNS_ECDSAP256SHA256); if(!*evp_key) { verbose(VERB_QUERY, "verify: " "sldns_ecdsa2pkey_raw failed"); return 0; } #ifdef USE_ECDSA_EVP_WORKAROUND *digest_type = &ecdsa_evp_256_md; #else *digest_type = EVP_sha256(); #endif break; case LDNS_ECDSAP384SHA384: *evp_key = sldns_ecdsa2pkey_raw(key, keylen, LDNS_ECDSAP384SHA384); if(!*evp_key) { verbose(VERB_QUERY, "verify: " "sldns_ecdsa2pkey_raw failed"); return 0; } #ifdef USE_ECDSA_EVP_WORKAROUND *digest_type = &ecdsa_evp_384_md; #else *digest_type = EVP_sha384(); #endif break; #endif /* USE_ECDSA */ #ifdef USE_ED25519 case LDNS_ED25519: *evp_key = sldns_ed255192pkey_raw(key, keylen); if(!*evp_key) { verbose(VERB_QUERY, "verify: " "sldns_ed255192pkey_raw failed"); return 0; } *digest_type = NULL; break; #endif /* USE_ED25519 */ default: verbose(VERB_QUERY, "verify: unknown algorithm %d", algo); return 0; } return 1; }
/** * Setup key and digest for verification. Adjust sig if necessary. * * @param algo: key algorithm * @param evp_key: EVP PKEY public key to create. * @param digest_type: digest type to use * @param key: key to setup for. * @param keylen: length of key. * @return false on failure. */ static int setup_key_digest(int algo, EVP_PKEY** evp_key, const EVP_MD** digest_type, unsigned char* key, size_t keylen) { DSA* dsa; RSA* rsa; switch(algo) { case LDNS_DSA: case LDNS_DSA_NSEC3: *evp_key = EVP_PKEY_new(); if(!*evp_key) { log_err("verify: malloc failure in crypto"); return 0; } dsa = sldns_key_buf2dsa_raw(key, keylen); if(!dsa) { verbose(VERB_QUERY, "verify: " "sldns_key_buf2dsa_raw failed"); return 0; } if(EVP_PKEY_assign_DSA(*evp_key, dsa) == 0) { verbose(VERB_QUERY, "verify: " "EVP_PKEY_assign_DSA failed"); return 0; } #ifdef HAVE_EVP_DSS1 *digest_type = EVP_dss1(); #else *digest_type = EVP_sha1(); #endif break; case LDNS_RSASHA1: case LDNS_RSASHA1_NSEC3: #if defined(HAVE_EVP_SHA256) && defined(USE_SHA2) case LDNS_RSASHA256: #endif #if defined(HAVE_EVP_SHA512) && defined(USE_SHA2) case LDNS_RSASHA512: #endif *evp_key = EVP_PKEY_new(); if(!*evp_key) { log_err("verify: malloc failure in crypto"); return 0; } rsa = sldns_key_buf2rsa_raw(key, keylen); if(!rsa) { verbose(VERB_QUERY, "verify: " "sldns_key_buf2rsa_raw SHA failed"); return 0; } if(EVP_PKEY_assign_RSA(*evp_key, rsa) == 0) { verbose(VERB_QUERY, "verify: " "EVP_PKEY_assign_RSA SHA failed"); return 0; } /* select SHA version */ #if defined(HAVE_EVP_SHA256) && defined(USE_SHA2) if(algo == LDNS_RSASHA256) *digest_type = EVP_sha256(); else #endif #if defined(HAVE_EVP_SHA512) && defined(USE_SHA2) if(algo == LDNS_RSASHA512) *digest_type = EVP_sha512(); else #endif *digest_type = EVP_sha1(); break; case LDNS_RSAMD5: *evp_key = EVP_PKEY_new(); if(!*evp_key) { log_err("verify: malloc failure in crypto"); return 0; } rsa = sldns_key_buf2rsa_raw(key, keylen); if(!rsa) { verbose(VERB_QUERY, "verify: " "sldns_key_buf2rsa_raw MD5 failed"); return 0; } if(EVP_PKEY_assign_RSA(*evp_key, rsa) == 0) { verbose(VERB_QUERY, "verify: " "EVP_PKEY_assign_RSA MD5 failed"); return 0; } *digest_type = EVP_md5(); break; #ifdef USE_GOST case LDNS_ECC_GOST: *evp_key = sldns_gost2pkey_raw(key, keylen); if(!*evp_key) { verbose(VERB_QUERY, "verify: " "sldns_gost2pkey_raw failed"); return 0; } *digest_type = EVP_get_digestbyname("md_gost94"); if(!*digest_type) { verbose(VERB_QUERY, "verify: " "EVP_getdigest md_gost94 failed"); return 0; } break; #endif #ifdef USE_ECDSA case LDNS_ECDSAP256SHA256: *evp_key = sldns_ecdsa2pkey_raw(key, keylen, LDNS_ECDSAP256SHA256); if(!*evp_key) { verbose(VERB_QUERY, "verify: " "sldns_ecdsa2pkey_raw failed"); return 0; } #ifdef USE_ECDSA_EVP_WORKAROUND /* openssl before 1.0.0 fixes RSA with the SHA256 * hash in EVP. We create one for ecdsa_sha256 */ { static int md_ecdsa_256_done = 0; static EVP_MD md; if(!md_ecdsa_256_done) { EVP_MD m = *EVP_sha256(); md_ecdsa_256_done = 1; m.required_pkey_type[0] = (*evp_key)->type; m.verify = (void*)ECDSA_verify; md = m; } *digest_type = &md; } #else *digest_type = EVP_sha256(); #endif break; case LDNS_ECDSAP384SHA384: *evp_key = sldns_ecdsa2pkey_raw(key, keylen, LDNS_ECDSAP384SHA384); if(!*evp_key) { verbose(VERB_QUERY, "verify: " "sldns_ecdsa2pkey_raw failed"); return 0; } #ifdef USE_ECDSA_EVP_WORKAROUND /* openssl before 1.0.0 fixes RSA with the SHA384 * hash in EVP. We create one for ecdsa_sha384 */ { static int md_ecdsa_384_done = 0; static EVP_MD md; if(!md_ecdsa_384_done) { EVP_MD m = *EVP_sha384(); md_ecdsa_384_done = 1; m.required_pkey_type[0] = (*evp_key)->type; m.verify = (void*)ECDSA_verify; md = m; } *digest_type = &md; } #else *digest_type = EVP_sha384(); #endif break; #endif /* USE_ECDSA */ default: verbose(VERB_QUERY, "verify: unknown algorithm %d", algo); return 0; } return 1; }