X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=crypto%2Fdsa%2Fdsa_ameth.c;h=376156ec5ef3a6ad23539296601180f7b4fa1472;hb=245a7eee177ccd7fd7986f86b67a4d59f5c4d6ad;hp=b9f7a4d687189638f8038e53dd769e6de2536d04;hpb=99516f81b17154ead5b9591f725251f81fa414a1;p=oweals%2Fopenssl.git diff --git a/crypto/dsa/dsa_ameth.c b/crypto/dsa/dsa_ameth.c index b9f7a4d687..376156ec5e 100644 --- a/crypto/dsa/dsa_ameth.c +++ b/crypto/dsa/dsa_ameth.c @@ -1,4 +1,4 @@ -/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project 2006. */ /* ==================================================================== @@ -60,6 +60,10 @@ #include #include #include +#include +#ifndef OPENSSL_NO_CMS +#include +#endif #include "asn1_locl.h" static int dsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) @@ -78,19 +82,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 +116,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); @@ -112,7 +127,7 @@ static int dsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) return 1; err: - if (pubkey) + if (public_key) ASN1_INTEGER_free(public_key); if (dsa) DSA_free(dsa); @@ -129,7 +144,7 @@ static int dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) 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(); @@ -144,6 +159,7 @@ static int dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) } else ptype = V_ASN1_UNDEF; + dsa->write_params=0; penclen = i2d_DSAPublicKey(dsa, &penc); @@ -167,14 +183,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. */ @@ -201,9 +209,7 @@ static int dsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) if (*p == (V_ASN1_SEQUENCE|V_ASN1_CONSTRUCTED)) { ASN1_TYPE *t1, *t2; - if(!(ndsa = ASN1_seq_unpack_ASN1_TYPE(p, pklen, - d2i_ASN1_TYPE, - ASN1_TYPE_free))) + if(!(ndsa = d2i_ASN1_SEQUENCE_ANY(NULL, &p, pklen))) goto decerr; if (sk_ASN1_TYPE_num(ndsa) != 2) goto decerr; @@ -231,8 +237,16 @@ static int dsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) } else { + const unsigned char *q = p; if (!(privkey=d2i_ASN1_INTEGER(NULL, &p, pklen))) goto decerr; + if (privkey->type == V_ASN1_NEG_INTEGER) + { + p8->broken = PKCS8_NEG_PRIVKEY; + ASN1_INTEGER_free(privkey); + if (!(privkey=d2i_ASN1_UINTEGER(NULL, &q, pklen))) + goto decerr; + } if (ptype != V_ASN1_SEQUENCE) goto decerr; } @@ -279,9 +293,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; } @@ -390,6 +405,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); @@ -397,14 +420,14 @@ 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))) *pbuflen = i; } -int do_dsa_print(BIO *bp, const DSA *x, int off, int ptype) +static int do_dsa_print(BIO *bp, const DSA *x, int off, int ptype) { unsigned char *m=NULL; int ret=0; @@ -430,12 +453,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); @@ -445,7 +462,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; } @@ -513,7 +530,7 @@ static int old_dsa_priv_decode(EVP_PKEY *pkey, DSA *dsa; if (!(dsa = d2i_DSAPrivateKey (NULL, pder, derlen))) { - DSAerr(DSA_F_DSA_PRIV_DECODE, ERR_R_DSA_LIB); + DSAerr(DSA_F_OLD_DSA_PRIV_DECODE, ERR_R_DSA_LIB); return 0; } EVP_PKEY_assign_DSA(pkey, dsa); @@ -525,6 +542,102 @@ static int old_dsa_priv_encode(const EVP_PKEY *pkey, unsigned char **pder) return i2d_DSAPrivateKey(pkey->pkey.dsa, pder); } +static int dsa_sig_print(BIO *bp, const X509_ALGOR *sigalg, + const ASN1_STRING *sig, + int indent, ASN1_PCTX *pctx) + { + DSA_SIG *dsa_sig; + const unsigned char *p; + if (!sig) + { + if (BIO_puts(bp, "\n") <= 0) + return 0; + else + return 1; + } + p = sig->data; + dsa_sig = d2i_DSA_SIG(NULL, &p, sig->length); + if (dsa_sig) + { + int rv = 0; + size_t buf_len = 0; + unsigned char *m=NULL; + update_buflen(dsa_sig->r, &buf_len); + update_buflen(dsa_sig->s, &buf_len); + m = OPENSSL_malloc(buf_len+10); + if (m == NULL) + { + DSAerr(DSA_F_DSA_SIG_PRINT,ERR_R_MALLOC_FAILURE); + goto err; + } + + if (BIO_write(bp, "\n", 1) != 1) + goto err; + + if (!ASN1_bn_print(bp,"r: ",dsa_sig->r,m,indent)) + goto err; + if (!ASN1_bn_print(bp,"s: ",dsa_sig->s,m,indent)) + goto err; + rv = 1; + err: + if (m) + OPENSSL_free(m); + DSA_SIG_free(dsa_sig); + return rv; + } + return X509_signature_dump(bp, sig, indent); + } + +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) + { + int snid, hnid; + X509_ALGOR *alg1, *alg2; + PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2); + if (alg1 == NULL || alg1->algorithm == NULL) + return -1; + hnid = OBJ_obj2nid(alg1->algorithm); + if (hnid == NID_undef) + return -1; + if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey))) + return -1; + X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0); + } + return 1; +#ifndef OPENSSL_NO_CMS + case ASN1_PKEY_CTRL_CMS_SIGN: + if (arg1 == 0) + { + int snid, hnid; + X509_ALGOR *alg1, *alg2; + CMS_SignerInfo_get0_algs(arg2, NULL, NULL, &alg1, &alg2); + if (alg1 == NULL || alg1->algorithm == NULL) + return -1; + hnid = OBJ_obj2nid(alg1->algorithm); + if (hnid == NID_undef) + return -1; + if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey))) + return -1; + X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0); + } + return 1; +#endif + + 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[] = @@ -580,9 +693,10 @@ const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[] = dsa_copy_parameters, dsa_cmp_parameters, dsa_param_print, + dsa_sig_print, int_dsa_free, - 0, + dsa_pkey_ctrl, old_dsa_priv_decode, old_dsa_priv_encode }