Add support for default public key digest type ctrl.
authorDr. Stephen Henson <steve@openssl.org>
Sun, 7 May 2006 17:09:39 +0000 (17:09 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Sun, 7 May 2006 17:09:39 +0000 (17:09 +0000)
13 files changed:
CHANGES
apps/ca.c
apps/openssl.cnf
apps/req.c
apps/x509.c
crypto/asn1/a_sign.c
crypto/asn1/asn1.h
crypto/asn1/asn1_err.c
crypto/dsa/dsa_ameth.c
crypto/ec/ec_ameth.c
crypto/evp/evp.h
crypto/evp/p_lib.c
crypto/rsa/rsa_ameth.c

diff --git a/CHANGES b/CHANGES
index 1d536cd..991e4b0 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,16 @@
 
  Changes between 0.9.8a and 0.9.9  [xx XXX xxxx]
 
+  *) Add a ctrl to asn1 method to allow a public key algorithm to express
+     a default digest type to use. In most cases this will be SHA1 but some
+     algorithms (such as GOST) need to specify an alternative digest. The
+     return value indicates how strong the prefernce is 1 means optional and
+     2 is mandatory (that is it is the only supported type). Modify
+     ASN1_item_sign() to accept a NULL digest argument to indicate it should
+     use the default md. Update openssl utilities to use the default digest
+     type for signing if it is not explicitly indicated.
+     [Steve Henson]
+
   *) Use OID cross reference table in ASN1_sign() and ASN1_verify(). New 
      EVP_MD flag EVP_MD_FLAG_PKEY_METHOD_SIGNATURE. This uses the relevant
      signing method from the key type. This effectively removes the link
index f7532d2..9fde400 100644 (file)
--- a/apps/ca.c
+++ b/apps/ca.c
@@ -1016,6 +1016,17 @@ bad:
                goto err;
                }
 
+       if (!strcmp(md, "default"))
+               {
+               int def_nid;
+               if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) <= 0)
+                       {
+                       BIO_puts(bio_err,"no default digest\n");
+                       goto err;
+                       }
+               md = (char *)OBJ_nid2sn(def_nid);
+               }
+
        if ((dgst=EVP_get_digestbyname(md)) == NULL)
                {
                BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
@@ -1412,17 +1423,6 @@ bad:
 
                /* we now have a CRL */
                if (verbose) BIO_printf(bio_err,"signing CRL\n");
-#if 0
-#ifndef OPENSSL_NO_DSA
-               if (pkey->type == EVP_PKEY_DSA) 
-                       dgst=EVP_dss1();
-               else
-#endif
-#ifndef OPENSSL_NO_ECDSA
-               if (pkey->type == EVP_PKEY_EC)
-                       dgst=EVP_ecdsa();
-#endif
-#endif
 
                /* Add any extensions asked for */
 
@@ -2101,25 +2101,11 @@ again2:
                        }
                }
 
-
-#ifndef OPENSSL_NO_DSA
-       if (pkey->type == EVP_PKEY_DSA) dgst=EVP_dss1();
        pktmp=X509_get_pubkey(ret);
        if (EVP_PKEY_missing_parameters(pktmp) &&
                !EVP_PKEY_missing_parameters(pkey))
                EVP_PKEY_copy_parameters(pktmp,pkey);
        EVP_PKEY_free(pktmp);
-#endif
-#ifndef OPENSSL_NO_ECDSA
-       if (pkey->type == EVP_PKEY_EC)
-               dgst = EVP_ecdsa();
-       pktmp = X509_get_pubkey(ret);
-       if (EVP_PKEY_missing_parameters(pktmp) &&
-               !EVP_PKEY_missing_parameters(pkey))
-               EVP_PKEY_copy_parameters(pktmp, pkey);
-       EVP_PKEY_free(pktmp);
-#endif
-
 
        if (!X509_sign(ret,pkey,dgst))
                goto err;
index a620b98..2995800 100644 (file)
@@ -72,7 +72,7 @@ cert_opt      = ca_default            # Certificate field options
 
 default_days   = 365                   # how long to certify for
 default_crl_days= 30                   # how long before next CRL
-default_md     = sha1                  # which md to use.
+default_md     = default               # use public key default MD
 preserve       = no                    # keep passed DN ordering
 
 # A few difference way of specifying how similar the request should look
index b9a3852..4c95bb9 100644 (file)
@@ -193,7 +193,7 @@ int MAIN(int argc, char **argv)
        char *p;
        char *subj = NULL;
        int multirdn = 0;
-       const EVP_MD *md_alg=NULL,*digest=EVP_sha1();
+       const EVP_MD *md_alg=NULL,*digest=NULL;
        unsigned long chtype = MBSTRING_ASC;
 #ifndef MONOLITH
        char *to_free;
@@ -894,16 +894,7 @@ loop:
                        BIO_printf(bio_err,"you need to specify a private key\n");
                        goto end;
                        }
-#if 0
-#ifndef OPENSSL_NO_DSA
-               if (pkey->type == EVP_PKEY_DSA)
-                       digest=EVP_dss1();
-#endif
-#ifndef OPENSSL_NO_ECDSA
-               if (pkey->type == EVP_PKEY_EC)
-                       digest=EVP_ecdsa();
-#endif
-#endif
+
                if (req == NULL)
                        {
                        req=X509_REQ_new();
index e3a9738..dfe41a6 100644 (file)
@@ -188,7 +188,7 @@ int MAIN(int argc, char **argv)
        X509_REQ *rq=NULL;
        int fingerprint=0;
        char buf[256];
-       const EVP_MD *md_alg,*digest=EVP_sha1();
+       const EVP_MD *md_alg,*digest=NULL;
        CONF *extconf = NULL;
        char *extsect = NULL, *extfile = NULL, *passin = NULL, *passargin = NULL;
        int need_rand = 0;
@@ -885,14 +885,18 @@ bad:
                                int j;
                                unsigned int n;
                                unsigned char md[EVP_MAX_MD_SIZE];
+                               const EVP_MD *fdig = digest;
 
-                               if (!X509_digest(x,digest,md,&n))
+                               if (!fdig)
+                                       fdig = EVP_sha1();
+
+                               if (!X509_digest(x,fdig,md,&n))
                                        {
                                        BIO_printf(bio_err,"out of memory\n");
                                        goto end;
                                        }
                                BIO_printf(STDout,"%s Fingerprint=",
-                                               OBJ_nid2sn(EVP_MD_type(digest)));
+                                               OBJ_nid2sn(EVP_MD_type(fdig)));
                                for (j=0; j<(int)n; j++)
                                        {
                                        BIO_printf(STDout,"%02X%c",md[j],
@@ -912,16 +916,6 @@ bad:
                                                passin, e, "Private key");
                                        if (Upkey == NULL) goto end;
                                        }
-#if 0
-#ifndef OPENSSL_NO_DSA
-                               if (Upkey->type == EVP_PKEY_DSA)
-                                       digest=EVP_dss1();
-#endif
-#ifndef OPENSSL_NO_ECDSA
-                               if (Upkey->type == EVP_PKEY_EC)
-                                       digest=EVP_ecdsa();
-#endif
-#endif
 
                                assert(need_rand);
                                if (!sign(x,Upkey,days,clrext,digest,
@@ -938,14 +932,6 @@ bad:
                                                "CA Private Key");
                                        if (CApkey == NULL) goto end;
                                        }
-#ifndef OPENSSL_NO_DSA
-                               if (CApkey->type == EVP_PKEY_DSA)
-                                       digest=EVP_dss1();
-#endif
-#ifndef OPENSSL_NO_ECDSA
-                               if (CApkey->type == EVP_PKEY_EC)
-                                       digest = EVP_ecdsa();
-#endif
                                
                                assert(need_rand);
                                if (!x509_certify(ctx,CAfile,digest,x,xca,
@@ -973,15 +959,6 @@ bad:
 
                                BIO_printf(bio_err,"Generating certificate request\n");
 
-#ifndef OPENSSL_NO_DSA
-                               if (pk->type == EVP_PKEY_DSA)
-                                       digest=EVP_dss1();
-#endif
-#ifndef OPENSSL_NO_ECDSA
-                               if (pk->type == EVP_PKEY_EC)
-                                       digest=EVP_ecdsa();
-#endif
-
                                rq=X509_to_X509_REQ(x,pk,digest);
                                EVP_PKEY_free(pk);
                                if (rq == NULL)
index c98dc7c..ff63bfc 100644 (file)
@@ -222,6 +222,19 @@ int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2,
        int inl=0,outl=0,outll=0;
        int signid, paramtype;
 
+       if (type == NULL)
+               {
+               int def_nid;
+               if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) > 0)
+                       type = EVP_get_digestbynid(def_nid);
+               }
+
+       if (type == NULL)
+               {
+               ASN1err(ASN1_F_ASN1_ITEM_SIGN, ASN1_R_NO_DEFAULT_DIGEST);
+               return 0;
+               }
+
        if (type->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE)
                {
                if (!pkey->ameth ||
index ea57f77..912619e 100644 (file)
@@ -1228,6 +1228,7 @@ void ERR_load_ASN1_strings(void);
 #define ASN1_R_NON_HEX_CHARACTERS                       141
 #define ASN1_R_NOT_ASCII_FORMAT                                 190
 #define ASN1_R_NOT_ENOUGH_DATA                          142
+#define ASN1_R_NO_DEFAULT_DIGEST                        201
 #define ASN1_R_NO_MATCHING_CHOICE_TYPE                  143
 #define ASN1_R_NULL_IS_WRONG_LENGTH                     144
 #define ASN1_R_OBJECT_NOT_ASCII_FORMAT                  191
index 8b1a651..148455c 100644 (file)
@@ -248,6 +248,7 @@ static ERR_STRING_DATA ASN1_str_reasons[]=
 {ERR_REASON(ASN1_R_NON_HEX_CHARACTERS)   ,"non hex characters"},
 {ERR_REASON(ASN1_R_NOT_ASCII_FORMAT)     ,"not ascii format"},
 {ERR_REASON(ASN1_R_NOT_ENOUGH_DATA)      ,"not enough data"},
+{ERR_REASON(ASN1_R_NO_DEFAULT_DIGEST)    ,"no default digest"},
 {ERR_REASON(ASN1_R_NO_MATCHING_CHOICE_TYPE),"no matching choice type"},
 {ERR_REASON(ASN1_R_NULL_IS_WRONG_LENGTH) ,"null is wrong length"},
 {ERR_REASON(ASN1_R_OBJECT_NOT_ASCII_FORMAT),"object not ascii format"},
index 3178bac..e221fad 100644 (file)
@@ -544,6 +544,10 @@ static int dsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
                        }
                return 1;
 
+               case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
+               *(int *)arg2 = NID_sha1;
+               return 2;
+
                default:
                return -2;
 
index 12b85b6..ba61164 100644 (file)
@@ -586,6 +586,10 @@ static int ec_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
                        }
                return 1;
 
+               case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
+               *(int *)arg2 = NID_sha1;
+               return 2;
+
                default:
                return -2;
 
index 83bf805..ff95a34 100644 (file)
@@ -770,6 +770,8 @@ int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey,
 int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey,
                                int indent, ASN1_PCTX *pctx);
 
+int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid);
+
 int EVP_CIPHER_type(const EVP_CIPHER *ctx);
 
 /* calls methods */
@@ -805,6 +807,7 @@ void EVP_PBE_cleanup(void);
 
 #define ASN1_PKEY_CTRL_PKCS7_SIGN      0x1
 #define ASN1_PKEY_CTRL_PKCS7_ENCRYPT   0x2
+#define ASN1_PKEY_CTRL_DEFAULT_MD_NID  0x3
 
 int EVP_PKEY_asn1_get_count(void);
 const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx);
index 19644ab..730520f 100644 (file)
@@ -361,3 +361,12 @@ int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey,
                return pkey->ameth->param_print(out, pkey, indent, pctx);
        return unsup_alg(out, pkey, indent, "Parameters");
        }
+
+int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid)
+       {
+       if (!pkey->ameth || !pkey->ameth->pkey_ctrl)
+               return -2;
+       return pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_DEFAULT_MD_NID,
+                                               0, pnid);
+       }
+
index 917b376..0378549 100644 (file)
@@ -287,6 +287,10 @@ static int rsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
                        }
                return 1;
 
+               case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
+               *(int *)arg2 = NID_sha1;
+               return 1;
+
                default:
                return -2;