X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fdsa%2Fdsa_ameth.c;h=371d5afc1765e2b97b0aaec4dea934f1cf1adb6d;hp=7ef6aaa8d40bf86b23ad1b91a696dc52d0032b1d;hb=5c95c2ac23dd30f3c458e2738598383d2ca58181;hpb=18e377b4ffa6d15572d7283f1eb1743ce5875804 diff --git a/crypto/dsa/dsa_ameth.c b/crypto/dsa/dsa_ameth.c index 7ef6aaa8d4..371d5afc17 100644 --- a/crypto/dsa/dsa_ameth.c +++ b/crypto/dsa/dsa_ameth.c @@ -78,19 +78,31 @@ static int dsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) return 0; X509_ALGOR_get0(NULL, &ptype, &pval, palg); - if (ptype != V_ASN1_SEQUENCE) + + if (ptype == V_ASN1_SEQUENCE) { - DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_PARAMETER_ENCODING_ERROR); - goto err; - } + pstr = pval; + pm = pstr->data; + pmlen = pstr->length; - pstr = pval; - pm = pstr->data; - pmlen = pstr->length; + if (!(dsa = d2i_DSAparams(NULL, &pm, pmlen))) + { + DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_DECODE_ERROR); + goto err; + } - if (!(dsa = d2i_DSAparams(NULL, &pm, pmlen))) + } + else if ((ptype == V_ASN1_NULL) || (ptype == V_ASN1_UNDEF)) { - DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_DECODE_ERROR); + if (!(dsa = DSA_new())) + { + DSAerr(DSA_F_DSA_PUB_DECODE, ERR_R_MALLOC_FAILURE); + goto err; + } + } + else + { + DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_PARAMETER_ENCODING_ERROR); goto err; } @@ -100,7 +112,6 @@ static int dsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) goto err; } - /* We have parameters now set public key */ if (!(dsa->pub_key = ASN1_INTEGER_to_BN(public_key, NULL))) { DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_BN_DECODE_ERROR); @@ -108,7 +119,7 @@ static int dsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) } ASN1_INTEGER_free(public_key); - + EVP_PKEY_assign_DSA(pkey, dsa); return 1; err: @@ -123,13 +134,13 @@ static int dsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) static int dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) { DSA *dsa; - void *pval; + void *pval = NULL; int ptype; unsigned char *penc = NULL; int penclen; dsa=pkey->pkey.dsa; - if (pkey->save_parameters) + if (pkey->save_parameters && dsa->p && dsa->q && dsa->g) { ASN1_STRING *str; str = ASN1_STRING_new(); @@ -139,13 +150,12 @@ static int dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE); goto err; } + pval = str; ptype = V_ASN1_SEQUENCE; } else - { ptype = V_ASN1_UNDEF; - pval = NULL; - } + dsa->write_params=0; penclen = i2d_DSAPublicKey(dsa, &penc); @@ -169,14 +179,6 @@ static int dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) return 0; } -static int dsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) - { - if (BN_cmp(b->pkey.dsa->pub_key,a->pkey.dsa->pub_key) != 0) - return 0; - else - return 1; - } - /* In PKCS#8 DSA: you just get a private key integer and parameters in the * AlgorithmIdentifier the pubkey must be recalculated. */ @@ -281,9 +283,10 @@ static int dsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) DSAerr(DSA_F_DSA_PRIV_DECODE, EVP_R_DECODE_ERROR); dsaerr: BN_CTX_free (ctx); + if (privkey) + ASN1_INTEGER_free(privkey); sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free); DSA_free(dsa); - EVP_PKEY_free(pkey); return 0; } @@ -392,6 +395,14 @@ static int dsa_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) return 1; } +static int dsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) + { + if (BN_cmp(b->pkey.dsa->pub_key,a->pkey.dsa->pub_key) != 0) + return 0; + else + return 1; + } + static void int_dsa_free(EVP_PKEY *pkey) { DSA_free(pkey->pkey.dsa); @@ -399,7 +410,7 @@ static void int_dsa_free(EVP_PKEY *pkey) static void update_buflen(const BIGNUM *b, size_t *pbuflen) { - int i; + size_t i; if (!b) return; if (*pbuflen < (i = (size_t)BN_num_bytes(b))) @@ -432,12 +443,6 @@ int do_dsa_print(BIO *bp, const DSA *x, int off, int ptype) else ktype = "DSA-Parameters"; - if (x->p == NULL) - { - DSAerr(DSA_F_DSA_PRINT,DSA_R_MISSING_PARAMETERS); - goto err; - } - update_buflen(x->p, &buf_len); update_buflen(x->q, &buf_len); update_buflen(x->g, &buf_len); @@ -447,7 +452,7 @@ int do_dsa_print(BIO *bp, const DSA *x, int off, int ptype) m=(unsigned char *)OPENSSL_malloc(buf_len+10); if (m == NULL) { - DSAerr(DSA_F_DSA_PRINT,ERR_R_MALLOC_FAILURE); + DSAerr(DSA_F_DO_DSA_PRINT,ERR_R_MALLOC_FAILURE); goto err; } @@ -472,6 +477,23 @@ err: return(ret); } +static int dsa_param_decode(EVP_PKEY *pkey, + const unsigned char **pder, int derlen) + { + DSA *dsa; + if (!(dsa = d2i_DSAparams(NULL, pder, derlen))) + { + DSAerr(DSA_F_DSA_PARAM_DECODE, ERR_R_DSA_LIB); + return 0; + } + EVP_PKEY_assign_DSA(pkey, dsa); + return 1; + } + +static int dsa_param_encode(const EVP_PKEY *pkey, unsigned char **pder) + { + return i2d_DSAparams(pkey->pkey.dsa, pder); + } static int dsa_param_print(BIO *bp, const EVP_PKEY *pkey, int indent, ASN1_PCTX *ctx) @@ -492,6 +514,51 @@ static int dsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, return do_dsa_print(bp, pkey->pkey.dsa, indent, 2); } +static int old_dsa_priv_decode(EVP_PKEY *pkey, + const unsigned char **pder, int derlen) + { + DSA *dsa; + if (!(dsa = d2i_DSAPrivateKey (NULL, pder, derlen))) + { + DSAerr(DSA_F_OLD_DSA_PRIV_DECODE, ERR_R_DSA_LIB); + return 0; + } + EVP_PKEY_assign_DSA(pkey, dsa); + return 1; + } + +static int old_dsa_priv_encode(const EVP_PKEY *pkey, unsigned char **pder) + { + return i2d_DSAPrivateKey(pkey->pkey.dsa, pder); + } + +static int dsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) + { + switch (op) + { + case ASN1_PKEY_CTRL_PKCS7_SIGN: + if (arg1 == 0) + { + X509_ALGOR *alg1, *alg2; + PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2); + X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_sha1), + V_ASN1_NULL, 0); + X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_dsaWithSHA1), + V_ASN1_UNDEF, 0); + } + return 1; + + case ASN1_PKEY_CTRL_DEFAULT_MD_NID: + *(int *)arg2 = NID_sha1; + return 2; + + default: + return -2; + + } + + } + /* NB these are sorted in pkey_id order, lowest first */ const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[] = @@ -526,6 +593,9 @@ const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[] = EVP_PKEY_DSA, 0, + "DSA", + "OpenSSL DSA method", + dsa_pub_decode, dsa_pub_encode, dsa_pub_cmp, @@ -538,14 +608,17 @@ const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[] = int_dsa_size, dsa_bits, - 0,0, + dsa_param_decode, + dsa_param_encode, dsa_missing_parameters, dsa_copy_parameters, dsa_cmp_parameters, dsa_param_print, int_dsa_free, - 0 + dsa_pkey_ctrl, + old_dsa_priv_decode, + old_dsa_priv_encode } };