diff --git a/ssh-dss.c b/ssh-dss.c index a169b1baf271..3174ef146dc3 100644 --- a/ssh-dss.c +++ b/ssh-dss.c @@ -32,10 +32,6 @@ #include #include #include -#if (OPENSSL_VERSION_NUMBER >= 0x30000000L) -#include -#include -#endif #include #include @@ -265,15 +261,11 @@ ssh_dss_sign(struct sshkey *key, const u_char *data, size_t datalen, const char *alg, const char *sk_provider, const char *sk_pin, u_int compat) { - EVP_PKEY *pkey = NULL; DSA_SIG *sig = NULL; const BIGNUM *sig_r, *sig_s; - u_char sigblob[SIGBLOB_LEN]; - size_t rlen, slen; - int len; + u_char digest[SSH_DIGEST_MAX_LENGTH], sigblob[SIGBLOB_LEN]; + size_t rlen, slen, len, dlen = ssh_digest_bytes(SSH_DIGEST_SHA1); struct sshbuf *b = NULL; - u_char *sigb = NULL; - const u_char *psig = NULL; int ret = SSH_ERR_INVALID_ARGUMENT; if (lenp != NULL) @@ -284,23 +276,17 @@ ssh_dss_sign(struct sshkey *key, if (key == NULL || key->dsa == NULL || sshkey_type_plain(key->type) != KEY_DSA) return SSH_ERR_INVALID_ARGUMENT; + if (dlen == 0) + return SSH_ERR_INTERNAL_ERROR; - if ((ret = ssh_create_evp_dss(key, &pkey)) != 0) - return ret; - ret = sshkey_calculate_signature(pkey, SSH_DIGEST_SHA1, &sigb, &len, - data, datalen); - EVP_PKEY_free(pkey); - if (ret < 0) { + if ((ret = ssh_digest_memory(SSH_DIGEST_SHA1, data, datalen, + digest, sizeof(digest))) != 0) goto out; - } - psig = sigb; - if ((sig = d2i_DSA_SIG(NULL, &psig, len)) == NULL) { + if ((sig = DSA_do_sign(digest, dlen, key->dsa)) == NULL) { ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; } - free(sigb); - sigb = NULL; DSA_SIG_get0(sig, &sig_r, &sig_s); rlen = BN_num_bytes(sig_r); @@ -333,7 +319,7 @@ ssh_dss_sign(struct sshkey *key, *lenp = len; ret = 0; out: - free(sigb); + explicit_bzero(digest, sizeof(digest)); DSA_SIG_free(sig); sshbuf_free(b); return ret; @@ -345,20 +331,20 @@ ssh_dss_verify(const struct sshkey *key, const u_char *data, size_t dlen, const char *alg, u_int compat, struct sshkey_sig_details **detailsp) { - EVP_PKEY *pkey = NULL; DSA_SIG *dsig = NULL; BIGNUM *sig_r = NULL, *sig_s = NULL; - u_char *sigblob = NULL; - size_t len, slen; + u_char digest[SSH_DIGEST_MAX_LENGTH], *sigblob = NULL; + size_t len, hlen = ssh_digest_bytes(SSH_DIGEST_SHA1); int ret = SSH_ERR_INTERNAL_ERROR; struct sshbuf *b = NULL; char *ktype = NULL; - u_char *sigb = NULL, *psig = NULL; if (key == NULL || key->dsa == NULL || sshkey_type_plain(key->type) != KEY_DSA || sig == NULL || siglen == 0) return SSH_ERR_INVALID_ARGUMENT; + if (hlen == 0) + return SSH_ERR_INTERNAL_ERROR; /* fetch signature */ if ((b = sshbuf_from(sig, siglen)) == NULL) @@ -400,28 +386,25 @@ ssh_dss_verify(const struct sshkey *key, } sig_r = sig_s = NULL; /* transferred */ - if ((slen = i2d_DSA_SIG(dsig, NULL)) == 0) { - ret = SSH_ERR_LIBCRYPTO_ERROR; + /* sha1 the data */ + if ((ret = ssh_digest_memory(SSH_DIGEST_SHA1, data, dlen, + digest, sizeof(digest))) != 0) goto out; - } - if ((sigb = malloc(slen)) == NULL) { - ret = SSH_ERR_ALLOC_FAIL; + + switch (DSA_do_verify(digest, hlen, dsig, key->dsa)) { + case 1: + ret = 0; + break; + case 0: + ret = SSH_ERR_SIGNATURE_INVALID; goto out; - } - psig = sigb; - if ((slen = i2d_DSA_SIG(dsig, &psig)) == 0) { + default: ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; } - if ((ret = ssh_create_evp_dss(key, &pkey)) != 0) - goto out; - ret = sshkey_verify_signature(pkey, SSH_DIGEST_SHA1, data, dlen, - sigb, slen); - EVP_PKEY_free(pkey); - out: - free(sigb); + explicit_bzero(digest, sizeof(digest)); DSA_SIG_free(dsig); BN_clear_free(sig_r); BN_clear_free(sig_s); @@ -432,78 +415,6 @@ ssh_dss_verify(const struct sshkey *key, return ret; } -int -ssh_create_evp_dss(const struct sshkey *k, EVP_PKEY **pkey) -{ -#if (OPENSSL_VERSION_NUMBER >= 0x30000000L) - OSSL_PARAM_BLD *param_bld = NULL; - EVP_PKEY_CTX *ctx = NULL; - const BIGNUM *p = NULL, *q = NULL, *g = NULL, *pub = NULL, *priv = NULL; - int ret = 0; - - if (k == NULL) - return SSH_ERR_INVALID_ARGUMENT; - if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "DSA", NULL)) == NULL || - (param_bld = OSSL_PARAM_BLD_new()) == NULL) { - ret = SSH_ERR_ALLOC_FAIL; - goto out; - } - - DSA_get0_pqg(k->dsa, &p, &q, &g); - DSA_get0_key(k->dsa, &pub, &priv); - - if (p != NULL && - OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_P, p) != 1) { - ret = SSH_ERR_LIBCRYPTO_ERROR; - goto out; - } - if (q != NULL && - OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_Q, q) != 1) { - ret = SSH_ERR_LIBCRYPTO_ERROR; - goto out; - } - if (g != NULL && - OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_G, g) != 1) { - ret = SSH_ERR_LIBCRYPTO_ERROR; - goto out; - } - if (pub != NULL && - OSSL_PARAM_BLD_push_BN(param_bld, - OSSL_PKEY_PARAM_PUB_KEY, - pub) != 1) { - ret = SSH_ERR_LIBCRYPTO_ERROR; - goto out; - } - if (priv != NULL && - OSSL_PARAM_BLD_push_BN(param_bld, - OSSL_PKEY_PARAM_PRIV_KEY, - priv) != 1) { - ret = SSH_ERR_LIBCRYPTO_ERROR; - goto out; - } - if ((*pkey = sshkey_create_evp(param_bld, ctx)) == NULL) { - ret = SSH_ERR_LIBCRYPTO_ERROR; - goto out; - } - -out: - OSSL_PARAM_BLD_free(param_bld); - EVP_PKEY_CTX_free(ctx); - return ret; -#else - EVP_PKEY * res = EVP_PKEY_new(); - if (res == NULL) - return SSH_ERR_ALLOC_FAIL; - - if (EVP_PKEY_set1_DSA(res, k->dsa) == 0) { - EVP_PKEY_free(res); - return SSH_ERR_LIBCRYPTO_ERROR; - } - *pkey = res; - return 0; -#endif -} - static const struct sshkey_impl_funcs sshkey_dss_funcs = { /* .size = */ ssh_dss_size, /* .alloc = */ ssh_dss_alloc,