Add support for default public key digest type ctrl.
[openssl.git] / crypto / dsa / dsa_ameth.c
index 7ef6aaa..e221fad 100644 (file)
@@ -108,7 +108,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,7 +123,7 @@ 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;
@@ -139,13 +139,11 @@ 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 +167,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 +271,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 +383,16 @@ 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 (dsa_cmp_parameters(a, b) == 0)
+               return 0;
+       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 +400,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)))
@@ -472,6 +473,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 +510,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_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 +589,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 +604,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
                }
        };