static isc_result_t openssldsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { isc_sha1_t *sha1ctx = dctx->opaque; dst_key_t *key = dctx->key; DSA *dsa = key->opaque; DSA_SIG *dsasig; isc_region_t r; unsigned char digest[ISC_SHA1_DIGESTLENGTH]; isc_buffer_availableregion(sig, &r); if (r.length < ISC_SHA1_DIGESTLENGTH * 2 + 1) return (ISC_R_NOSPACE); isc_sha1_final(sha1ctx, digest); dsasig = DSA_do_sign(digest, ISC_SHA1_DIGESTLENGTH, dsa); if (dsasig == NULL) return (dst__openssl_toresult(DST_R_SIGNFAILURE)); *r.base++ = (key->key_size - 512)/64; BN_bn2bin_fixed(dsasig->r, r.base, ISC_SHA1_DIGESTLENGTH); r.base += ISC_SHA1_DIGESTLENGTH; BN_bn2bin_fixed(dsasig->s, r.base, ISC_SHA1_DIGESTLENGTH); r.base += ISC_SHA1_DIGESTLENGTH; DSA_SIG_free(dsasig); isc_buffer_add(sig, ISC_SHA1_DIGESTLENGTH * 2 + 1); return (ISC_R_SUCCESS); }
static isc_result_t opensslecdsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { isc_result_t ret; dst_key_t *key = dctx->key; isc_region_t r; ECDSA_SIG *ecdsasig; EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; EVP_PKEY *pkey = key->keydata.pkey; EC_KEY *eckey = EVP_PKEY_get1_EC_KEY(pkey); unsigned int dgstlen, siglen; unsigned char digest[EVP_MAX_MD_SIZE]; REQUIRE(key->key_alg == DST_ALG_ECDSA256 || key->key_alg == DST_ALG_ECDSA384); if (eckey == NULL) return (ISC_R_FAILURE); if (key->key_alg == DST_ALG_ECDSA256) siglen = DNS_SIG_ECDSA256SIZE; else siglen = DNS_SIG_ECDSA384SIZE; isc_buffer_availableregion(sig, &r); if (r.length < siglen) DST_RET(ISC_R_NOSPACE); if (!EVP_DigestFinal(evp_md_ctx, digest, &dgstlen)) DST_RET(dst__openssl_toresult3(dctx->category, "EVP_DigestFinal", ISC_R_FAILURE)); ecdsasig = ECDSA_do_sign(digest, dgstlen, eckey); if (ecdsasig == NULL) DST_RET(dst__openssl_toresult3(dctx->category, "ECDSA_do_sign", DST_R_SIGNFAILURE)); BN_bn2bin_fixed(ecdsasig->r, r.base, siglen / 2); r.base += siglen / 2; BN_bn2bin_fixed(ecdsasig->s, r.base, siglen / 2); r.base += siglen / 2; ECDSA_SIG_free(ecdsasig); isc_buffer_add(sig, siglen); ret = ISC_R_SUCCESS; err: if (eckey != NULL) EC_KEY_free(eckey); return (ret); }
static isc_result_t openssldsa_todns(const dst_key_t *key, isc_buffer_t *data) { DSA *dsa; isc_region_t r; int dnslen; unsigned int t, p_bytes; REQUIRE(key->keydata.dsa != NULL); dsa = key->keydata.dsa; isc_buffer_availableregion(data, &r); t = (BN_num_bytes(dsa->p) - 64) / 8; if (t > 8) return (DST_R_INVALIDPUBLICKEY); p_bytes = 64 + 8 * t; dnslen = 1 + (key->key_size * 3)/8 + ISC_SHA1_DIGESTLENGTH; if (r.length < (unsigned int) dnslen) return (ISC_R_NOSPACE); *r.base = t; isc_region_consume(&r, 1); BN_bn2bin_fixed(dsa->q, r.base, ISC_SHA1_DIGESTLENGTH); isc_region_consume(&r, ISC_SHA1_DIGESTLENGTH); BN_bn2bin_fixed(dsa->p, r.base, key->key_size/8); isc_region_consume(&r, p_bytes); BN_bn2bin_fixed(dsa->g, r.base, key->key_size/8); isc_region_consume(&r, p_bytes); BN_bn2bin_fixed(dsa->pub_key, r.base, key->key_size/8); isc_region_consume(&r, p_bytes); isc_buffer_add(data, dnslen); return (ISC_R_SUCCESS); }
static isc_result_t openssldsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { dst_key_t *key = dctx->key; DSA *dsa = key->keydata.dsa; isc_region_t r; DSA_SIG *dsasig; #if USE_EVP EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; EVP_PKEY *pkey; unsigned char *sigbuf; const unsigned char *sb; unsigned int siglen; #else isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx; unsigned char digest[ISC_SHA1_DIGESTLENGTH]; #endif isc_buffer_availableregion(sig, &r); if (r.length < ISC_SHA1_DIGESTLENGTH * 2 + 1) return (ISC_R_NOSPACE); #if USE_EVP pkey = EVP_PKEY_new(); if (pkey == NULL) return (ISC_R_NOMEMORY); if (!EVP_PKEY_set1_DSA(pkey, dsa)) { EVP_PKEY_free(pkey); return (ISC_R_FAILURE); } sigbuf = malloc(EVP_PKEY_size(pkey)); if (sigbuf == NULL) { EVP_PKEY_free(pkey); return (ISC_R_NOMEMORY); } if (!EVP_SignFinal(evp_md_ctx, sigbuf, &siglen, pkey)) { EVP_PKEY_free(pkey); free(sigbuf); return (ISC_R_FAILURE); } INSIST(EVP_PKEY_size(pkey) >= (int) siglen); EVP_PKEY_free(pkey); /* Convert from Dss-Sig-Value (RFC2459). */ dsasig = DSA_SIG_new(); if (dsasig == NULL) { free(sigbuf); return (ISC_R_NOMEMORY); } sb = sigbuf; if (d2i_DSA_SIG(&dsasig, &sb, (long) siglen) == NULL) { free(sigbuf); return (ISC_R_FAILURE); } free(sigbuf); #elif 0 /* Only use EVP for the Digest */ if (!EVP_DigestFinal_ex(evp_md_ctx, digest, &siglen)) { return (ISC_R_FAILURE); } dsasig = DSA_do_sign(digest, ISC_SHA1_DIGESTLENGTH, dsa); if (dsasig == NULL) return (dst__openssl_toresult(DST_R_SIGNFAILURE)); #else isc_sha1_final(sha1ctx, digest); dsasig = DSA_do_sign(digest, ISC_SHA1_DIGESTLENGTH, dsa); if (dsasig == NULL) return (dst__openssl_toresult(DST_R_SIGNFAILURE)); #endif *r.base++ = (key->key_size - 512)/64; BN_bn2bin_fixed(dsasig->r, r.base, ISC_SHA1_DIGESTLENGTH); r.base += ISC_SHA1_DIGESTLENGTH; BN_bn2bin_fixed(dsasig->s, r.base, ISC_SHA1_DIGESTLENGTH); r.base += ISC_SHA1_DIGESTLENGTH; DSA_SIG_free(dsasig); isc_buffer_add(sig, ISC_SHA1_DIGESTLENGTH * 2 + 1); return (ISC_R_SUCCESS); }