Backport PSS signature support from HEAD.
authorDr. Stephen Henson <steve@openssl.org>
Sun, 9 Oct 2011 23:13:50 +0000 (23:13 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Sun, 9 Oct 2011 23:13:50 +0000 (23:13 +0000)
28 files changed:
CHANGES
apps/apps.h
apps/ca.c
apps/req.c
apps/x509.c
crypto/asn1/a_sign.c
crypto/asn1/a_verify.c
crypto/asn1/asn1.h
crypto/asn1/asn1_err.c
crypto/asn1/asn1_locl.h
crypto/asn1/t_crl.c
crypto/asn1/t_x509.c
crypto/cmac/cm_ameth.c
crypto/dh/dh_ameth.c
crypto/dsa/dsa.h
crypto/dsa/dsa_ameth.c
crypto/dsa/dsa_err.c
crypto/ec/ec_ameth.c
crypto/hmac/hm_ameth.c
crypto/objects/obj_xref.h
crypto/objects/obj_xref.txt
crypto/ossl_typ.h
crypto/rsa/rsa.h
crypto/rsa/rsa_ameth.c
crypto/rsa/rsa_asn1.c
crypto/rsa/rsa_err.c
crypto/x509/x509.h
crypto/x509/x_all.c

diff --git a/CHANGES b/CHANGES
index f1d22a7090efff4bd35c33c098984f42144e37d9..488abc5f783de4edaf43effc73aa0baed4a98926 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,40 @@
 
  Changes between 1.0.0e and 1.0.1  [xx XXX xxxx]
 
+  *) New -sigopt option to the ca, req and x509 utilities. Additional
+     signature parameters can be passed using this option and in
+     particular PSS. 
+     [Steve Henson]
+
+  *) Add RSA PSS signing function. This will generate and set the
+     appropriate AlgorithmIdentifiers for PSS based on those in the
+     corresponding EVP_MD_CTX structure. No application support yet.
+     [Steve Henson]
+
+  *) Support for companion algorithm specific ASN1 signing routines.
+     New function ASN1_item_sign_ctx() signs a pre-initialised
+     EVP_MD_CTX structure and sets AlgorithmIdentifiers based on
+     the appropriate parameters.
+     [Steve Henson]
+
+  *) Add new algorithm specific ASN1 verification initialisation function
+     to EVP_PKEY_ASN1_METHOD: this is not in EVP_PKEY_METHOD since the ASN1
+     handling will be the same no matter what EVP_PKEY_METHOD is used.
+     Add a PSS handler to support verification of PSS signatures: checked
+     against a number of sample certificates.
+     [Steve Henson]
+
+  *) Add signature printing for PSS. Add PSS OIDs.
+     [Steve Henson, Martin Kaiser <lists@kaiser.cx>]
+
+  *) Add algorithm specific signature printing. An individual ASN1 method
+     can now print out signatures instead of the standard hex dump. 
+
+     More complex signatures (e.g. PSS) can print out more meaningful
+     information. Include DSA version that prints out the signature
+     parameters r, s.
+     [Steve Henson]
+
   *) Password based recipient info support for CMS library: implementing
      RFC3211.
      [Steve Henson]
index f92744b42cb4930e41ad2abc58373073a3b6d83b..42a388648edc51d68d5a85e6fb81266093990b1f 100644 (file)
@@ -317,6 +317,12 @@ int bio_to_mem(unsigned char **out, int maxlen, BIO *in);
 int pkey_ctrl_string(EVP_PKEY_CTX *ctx, char *value);
 int init_gen_str(BIO *err, EVP_PKEY_CTX **pctx,
                        const char *algname, ENGINE *e, int do_param);
+int do_X509_sign(BIO *err, X509 *x, EVP_PKEY *pkey, const EVP_MD *md,
+                       STACK_OF(OPENSSL_STRING) *sigopts);
+int do_X509_REQ_sign(BIO *err, X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md,
+                       STACK_OF(OPENSSL_STRING) *sigopts);
+int do_X509_CRL_sign(BIO *err, X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md,
+                       STACK_OF(OPENSSL_STRING) *sigopts);
 #ifndef OPENSSL_NO_PSK
 extern char *psk_key;
 #endif
index 6b8b0ef8fd1b87ce23c353a97a3e727543d006b6..33e23910286e94a0b1c05cad0aa4848e09059303 100644 (file)
--- a/apps/ca.c
+++ b/apps/ca.c
@@ -197,26 +197,30 @@ extern int EF_ALIGNMENT;
 
 static void lookup_fail(const char *name, const char *tag);
 static int certify(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
-                  const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,CA_DB *db,
+                  const EVP_MD *dgst,STACK_OF(OPENSSL_STRING) *sigopts,
+                  STACK_OF(CONF_VALUE) *policy,CA_DB *db,
                   BIGNUM *serial, char *subj,unsigned long chtype, int multirdn, int email_dn, char *startdate,
                   char *enddate, long days, int batch, char *ext_sect, CONF *conf,
                   int verbose, unsigned long certopt, unsigned long nameopt,
                   int default_op, int ext_copy, int selfsign);
 static int certify_cert(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
-                       const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,
+                       const EVP_MD *dgst,STACK_OF(OPENSSL_STRING) *sigopts,
+                       STACK_OF(CONF_VALUE) *policy,
                        CA_DB *db, BIGNUM *serial, char *subj,unsigned long chtype, int multirdn, int email_dn,
                        char *startdate, char *enddate, long days, int batch,
                        char *ext_sect, CONF *conf,int verbose, unsigned long certopt,
                        unsigned long nameopt, int default_op, int ext_copy,
                        ENGINE *e);
 static int certify_spkac(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
-                        const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,
+                        const EVP_MD *dgst,STACK_OF(OPENSSL_STRING) *sigopts,
+                        STACK_OF(CONF_VALUE) *policy,
                         CA_DB *db, BIGNUM *serial,char *subj,unsigned long chtype, int multirdn, int email_dn,
                         char *startdate, char *enddate, long days, char *ext_sect,
                         CONF *conf, int verbose, unsigned long certopt, 
                         unsigned long nameopt, int default_op, int ext_copy);
 static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext);
 static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
+       STACK_OF(OPENSSL_STRING) *sigopts,
        STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial,char *subj,unsigned long chtype, int multirdn,
        int email_dn, char *startdate, char *enddate, long days, int batch,
                int verbose, X509_REQ *req, char *ext_sect, CONF *conf,
@@ -311,6 +315,7 @@ int MAIN(int argc, char **argv)
        const EVP_MD *dgst=NULL;
        STACK_OF(CONF_VALUE) *attribs=NULL;
        STACK_OF(X509) *cert_sk=NULL;
+       STACK_OF(OPENSSL_STRING) *sigopts = NULL;
 #undef BSIZE
 #define BSIZE 256
        MS_STATIC char buf[3][BSIZE];
@@ -435,6 +440,15 @@ EF_ALIGNMENT=0;
                        if (--argc < 1) goto bad;
                        outdir= *(++argv);
                        }
+               else if (strcmp(*argv,"-sigopt") == 0)
+                       {
+                       if (--argc < 1)
+                               goto bad;
+                       if (!sigopts)
+                               sigopts = sk_OPENSSL_STRING_new_null();
+                       if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, *(++argv)))
+                               goto bad;
+                       }
                else if (strcmp(*argv,"-notext") == 0)
                        notext=1;
                else if (strcmp(*argv,"-batch") == 0)
@@ -1170,8 +1184,9 @@ bad:
                if (spkac_file != NULL)
                        {
                        total++;
-                       j=certify_spkac(&x,spkac_file,pkey,x509,dgst,attribs,db,
-                               serial,subj,chtype,multirdn,email_dn,startdate,enddate,days,extensions,
+                       j=certify_spkac(&x,spkac_file,pkey,x509,dgst,sigopts,
+                               attribs,db, serial,subj,chtype,multirdn,
+                               email_dn,startdate,enddate,days,extensions,
                                conf,verbose,certopt,nameopt,default_op,ext_copy);
                        if (j < 0) goto err;
                        if (j > 0)
@@ -1194,7 +1209,8 @@ bad:
                if (ss_cert_file != NULL)
                        {
                        total++;
-                       j=certify_cert(&x,ss_cert_file,pkey,x509,dgst,attribs,
+                       j=certify_cert(&x,ss_cert_file,pkey,x509,dgst,sigopts,
+                               attribs,
                                db,serial,subj,chtype,multirdn,email_dn,startdate,enddate,days,batch,
                                extensions,conf,verbose, certopt, nameopt,
                                default_op, ext_copy, e);
@@ -1214,7 +1230,7 @@ bad:
                if (infile != NULL)
                        {
                        total++;
-                       j=certify(&x,infile,pkey,x509p,dgst,attribs,db,
+                       j=certify(&x,infile,pkey,x509p,dgst,sigopts, attribs,db,
                                serial,subj,chtype,multirdn,email_dn,startdate,enddate,days,batch,
                                extensions,conf,verbose, certopt, nameopt,
                                default_op, ext_copy, selfsign);
@@ -1234,7 +1250,7 @@ bad:
                for (i=0; i<argc; i++)
                        {
                        total++;
-                       j=certify(&x,argv[i],pkey,x509p,dgst,attribs,db,
+                       j=certify(&x,argv[i],pkey,x509p,dgst,sigopts,attribs,db,
                                serial,subj,chtype,multirdn,email_dn,startdate,enddate,days,batch,
                                extensions,conf,verbose, certopt, nameopt,
                                default_op, ext_copy, selfsign);
@@ -1483,7 +1499,7 @@ bad:
                        crlnumber = NULL;
                        }
 
-               if (!X509_CRL_sign(crl,pkey,dgst)) goto err;
+               if (!do_X509_CRL_sign(bio_err,crl,pkey,dgst,sigopts)) goto err;
 
                PEM_write_bio_X509_CRL(Sout,crl);
 
@@ -1537,6 +1553,8 @@ err:
        BN_free(serial);
        BN_free(crlnumber);
        free_index(db);
+       if (sigopts)
+               sk_OPENSSL_STRING_free(sigopts);
        EVP_PKEY_free(pkey);
        if (x509) X509_free(x509);
        X509_CRL_free(crl);
@@ -1553,8 +1571,10 @@ static void lookup_fail(const char *name, const char *tag)
        }
 
 static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
-            const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, CA_DB *db,
-            BIGNUM *serial, char *subj,unsigned long chtype, int multirdn, int email_dn, char *startdate, char *enddate,
+            const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
+            STACK_OF(CONF_VALUE) *policy, CA_DB *db,
+            BIGNUM *serial, char *subj,unsigned long chtype, int multirdn,
+            int email_dn, char *startdate, char *enddate,
             long days, int batch, char *ext_sect, CONF *lconf, int verbose,
             unsigned long certopt, unsigned long nameopt, int default_op,
             int ext_copy, int selfsign)
@@ -1610,7 +1630,8 @@ static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
        else
                BIO_printf(bio_err,"Signature ok\n");
 
-       ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,chtype,multirdn, email_dn,
+       ok=do_body(xret,pkey,x509,dgst,sigopts, policy,db,serial,subj,chtype,
+               multirdn, email_dn,
                startdate,enddate,days,batch,verbose,req,ext_sect,lconf,
                certopt, nameopt, default_op, ext_copy, selfsign);
 
@@ -1621,7 +1642,8 @@ err:
        }
 
 static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
-            const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, CA_DB *db,
+            const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
+            STACK_OF(CONF_VALUE) *policy, CA_DB *db,
             BIGNUM *serial, char *subj, unsigned long chtype, int multirdn, int email_dn, char *startdate, char *enddate,
             long days, int batch, char *ext_sect, CONF *lconf, int verbose,
             unsigned long certopt, unsigned long nameopt, int default_op,
@@ -1664,7 +1686,7 @@ static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
        if ((rreq=X509_to_X509_REQ(req,NULL,EVP_md5())) == NULL)
                goto err;
 
-       ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,chtype,multirdn,email_dn,startdate,enddate,
+       ok=do_body(xret,pkey,x509,dgst,sigopts,policy,db,serial,subj,chtype,multirdn,email_dn,startdate,enddate,
                days,batch,verbose,rreq,ext_sect,lconf, certopt, nameopt, default_op,
                ext_copy, 0);
 
@@ -1675,7 +1697,8 @@ err:
        }
 
 static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
-            STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial, char *subj,
+            STACK_OF(OPENSSL_STRING) *sigopts, STACK_OF(CONF_VALUE) *policy,
+             CA_DB *db, BIGNUM *serial, char *subj,
             unsigned long chtype, int multirdn,
             int email_dn, char *startdate, char *enddate, long days, int batch,
             int verbose, X509_REQ *req, char *ext_sect, CONF *lconf,
@@ -2146,7 +2169,7 @@ again2:
                EVP_PKEY_copy_parameters(pktmp,pkey);
        EVP_PKEY_free(pktmp);
 
-       if (!X509_sign(ret,pkey,dgst))
+       if (!do_X509_sign(bio_err, ret,pkey,dgst, sigopts))
                goto err;
 
        /* We now just add it to the database */
@@ -2240,7 +2263,8 @@ static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext)
        }
 
 static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
-            const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, CA_DB *db,
+            const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
+            STACK_OF(CONF_VALUE) *policy, CA_DB *db,
             BIGNUM *serial, char *subj,unsigned long chtype, int multirdn, int email_dn, char *startdate, char *enddate,
             long days, char *ext_sect, CONF *lconf, int verbose, unsigned long certopt,
             unsigned long nameopt, int default_op, int ext_copy)
@@ -2366,9 +2390,9 @@ static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
 
        X509_REQ_set_pubkey(req,pktmp);
        EVP_PKEY_free(pktmp);
-       ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,chtype,multirdn,email_dn,startdate,enddate,
-                  days,1,verbose,req,ext_sect,lconf, certopt, nameopt, default_op,
-                       ext_copy, 0);
+       ok=do_body(xret,pkey,x509,dgst,sigopts,policy,db,serial,subj,chtype,
+                  multirdn,email_dn,startdate,enddate, days,1,verbose,req,
+                  ext_sect,lconf, certopt, nameopt, default_op, ext_copy, 0);
 err:
        if (req != NULL) X509_REQ_free(req);
        if (parms != NULL) CONF_free(parms);
index 820cd18fc70d02e3149560abaddb28fc9097ed2d..85526581cefed10a9ec539cac8b9a04568a754f9 100644 (file)
@@ -165,7 +165,7 @@ int MAIN(int argc, char **argv)
        EVP_PKEY_CTX *genctx = NULL;
        const char *keyalg = NULL;
        char *keyalgstr = NULL;
-       STACK_OF(OPENSSL_STRING) *pkeyopts = NULL;
+       STACK_OF(OPENSSL_STRING) *pkeyopts = NULL, *sigopts = NULL;
        EVP_PKEY *pkey=NULL;
        int i=0,badops=0,newreq=0,verbose=0,pkey_type=-1;
        long newkey = -1;
@@ -310,6 +310,15 @@ int MAIN(int argc, char **argv)
                        if (!pkeyopts || !sk_OPENSSL_STRING_push(pkeyopts, *(++argv)))
                                goto bad;
                        }
+               else if (strcmp(*argv,"-sigopt") == 0)
+                       {
+                       if (--argc < 1)
+                               goto bad;
+                       if (!sigopts)
+                               sigopts = sk_OPENSSL_STRING_new_null();
+                       if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, *(++argv)))
+                               goto bad;
+                       }
                else if (strcmp(*argv,"-batch") == 0)
                        batch=1;
                else if (strcmp(*argv,"-newhdr") == 0)
@@ -858,8 +867,9 @@ loop:
                                        extensions);
                                goto end;
                                }
-                       
-                       if (!(i=X509_sign(x509ss,pkey,digest)))
+
+                       i=do_X509_sign(bio_err, x509ss, pkey, digest, sigopts);
+                       if (!i)
                                {
                                ERR_print_errors(bio_err);
                                goto end;
@@ -883,7 +893,8 @@ loop:
                                        req_exts);
                                goto end;
                                }
-                       if (!(i=X509_REQ_sign(req,pkey,digest)))
+                       i=do_X509_REQ_sign(bio_err, req, pkey, digest, sigopts);
+                       if (!i)
                                {
                                ERR_print_errors(bio_err);
                                goto end;
@@ -1084,6 +1095,8 @@ end:
                EVP_PKEY_CTX_free(genctx);
        if (pkeyopts)
                sk_OPENSSL_STRING_free(pkeyopts);
+       if (sigopts)
+               sk_OPENSSL_STRING_free(sigopts);
 #ifndef OPENSSL_NO_ENGINE
        if (gen_eng)
                ENGINE_free(gen_eng);
@@ -1756,3 +1769,68 @@ static int genpkey_cb(EVP_PKEY_CTX *ctx)
 #endif
        return 1;
        }
+
+static int do_sign_init(BIO *err, EVP_MD_CTX *ctx, EVP_PKEY *pkey,
+                       const EVP_MD *md, STACK_OF(OPENSSL_STRING) *sigopts)
+       {
+       EVP_PKEY_CTX *pkctx = NULL;
+       int i;
+       EVP_MD_CTX_init(ctx);
+       if (!EVP_DigestSignInit(ctx, &pkctx, md, NULL, pkey))
+               return 0;
+       for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++)
+               {
+               char *sigopt = sk_OPENSSL_STRING_value(sigopts, i);
+               if (pkey_ctrl_string(pkctx, sigopt) <= 0)
+                       {
+                       BIO_printf(err, "parameter error \"%s\"\n", sigopt);
+                       ERR_print_errors(bio_err);
+                       return 0;
+                       }
+               }
+       return 1;
+       }
+
+int do_X509_sign(BIO *err, X509 *x, EVP_PKEY *pkey, const EVP_MD *md,
+                       STACK_OF(OPENSSL_STRING) *sigopts)
+       {
+       int rv;
+       EVP_MD_CTX mctx;
+       EVP_MD_CTX_init(&mctx);
+       rv = do_sign_init(err, &mctx, pkey, md, sigopts);
+       if (rv > 0)
+               rv = X509_sign_ctx(x, &mctx);
+       EVP_MD_CTX_cleanup(&mctx);
+       return rv > 0 ? 1 : 0;
+       }
+
+
+int do_X509_REQ_sign(BIO *err, X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md,
+                       STACK_OF(OPENSSL_STRING) *sigopts)
+       {
+       int rv;
+       EVP_MD_CTX mctx;
+       EVP_MD_CTX_init(&mctx);
+       rv = do_sign_init(err, &mctx, pkey, md, sigopts);
+       if (rv > 0)
+               rv = X509_REQ_sign_ctx(x, &mctx);
+       EVP_MD_CTX_cleanup(&mctx);
+       return rv > 0 ? 1 : 0;
+       }
+               
+       
+
+int do_X509_CRL_sign(BIO *err, X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md,
+                       STACK_OF(OPENSSL_STRING) *sigopts)
+       {
+       int rv;
+       EVP_MD_CTX mctx;
+       EVP_MD_CTX_init(&mctx);
+       rv = do_sign_init(err, &mctx, pkey, md, sigopts);
+       if (rv > 0)
+               rv = X509_CRL_sign_ctx(x, &mctx);
+       EVP_MD_CTX_cleanup(&mctx);
+       return rv > 0 ? 1 : 0;
+       }
+               
+       
index 9f5eaeb6bebbd68fc5591ad8ca6ffc14641e6bed..e6e5e0d4e524d4f62b994c6b926c94c642b4a936 100644 (file)
@@ -157,9 +157,10 @@ static int MS_CALLBACK callb(int ok, X509_STORE_CTX *ctx);
 static int sign (X509 *x, EVP_PKEY *pkey,int days,int clrext, const EVP_MD *digest,
                                                CONF *conf, char *section);
 static int x509_certify (X509_STORE *ctx,char *CAfile,const EVP_MD *digest,
-                        X509 *x,X509 *xca,EVP_PKEY *pkey,char *serial,
-                        int create,int days, int clrext, CONF *conf, char *section,
-                                               ASN1_INTEGER *sno);
+                        X509 *x,X509 *xca,EVP_PKEY *pkey,
+                        STACK_OF(OPENSSL_STRING) *sigopts,
+                        char *serial, int create ,int days, int clrext,
+                        CONF *conf, char *section, ASN1_INTEGER *sno);
 static int purpose_print(BIO *bio, X509 *cert, X509_PURPOSE *pt);
 static int reqfile=0;
 
@@ -172,6 +173,7 @@ int MAIN(int argc, char **argv)
        X509_REQ *req=NULL;
        X509 *x=NULL,*xca=NULL;
        ASN1_OBJECT *objtmp;
+       STACK_OF(OPENSSL_STRING) *sigopts = NULL;
        EVP_PKEY *Upkey=NULL,*CApkey=NULL;
        ASN1_INTEGER *sno = NULL;
        int i,num,badops=0;
@@ -271,6 +273,15 @@ int MAIN(int argc, char **argv)
                        if (--argc < 1) goto bad;
                        CAkeyformat=str2fmt(*(++argv));
                        }
+               else if (strcmp(*argv,"-sigopt") == 0)
+                       {
+                       if (--argc < 1)
+                               goto bad;
+                       if (!sigopts)
+                               sigopts = sk_OPENSSL_STRING_new_null();
+                       if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, *(++argv)))
+                               goto bad;
+                       }
                else if (strcmp(*argv,"-days") == 0)
                        {
                        if (--argc < 1) goto bad;
@@ -970,7 +981,8 @@ bad:
                                
                                assert(need_rand);
                                if (!x509_certify(ctx,CAfile,digest,x,xca,
-                                       CApkey, CAserial,CA_createserial,days, clrext,
+                                       CApkey, sigopts,
+                                       CAserial,CA_createserial,days, clrext,
                                        extconf, extsect, sno))
                                        goto end;
                                }
@@ -1081,6 +1093,8 @@ end:
        X509_free(xca);
        EVP_PKEY_free(Upkey);
        EVP_PKEY_free(CApkey);
+       if (sigopts)
+               sk_OPENSSL_STRING_free(sigopts);
        X509_REQ_free(rq);
        ASN1_INTEGER_free(sno);
        sk_ASN1_OBJECT_pop_free(trust, ASN1_OBJECT_free);
@@ -1131,8 +1145,11 @@ static ASN1_INTEGER *x509_load_serial(char *CAfile, char *serialfile, int create
        }
 
 static int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest,
-            X509 *x, X509 *xca, EVP_PKEY *pkey, char *serialfile, int create,
-            int days, int clrext, CONF *conf, char *section, ASN1_INTEGER *sno)
+                       X509 *x, X509 *xca, EVP_PKEY *pkey,
+                       STACK_OF(OPENSSL_STRING) *sigopts,
+                       char *serialfile, int create,
+                       int days, int clrext, CONF *conf, char *section,
+                       ASN1_INTEGER *sno)
        {
        int ret=0;
        ASN1_INTEGER *bs=NULL;
@@ -1191,7 +1208,8 @@ static int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest,
                 if (!X509V3_EXT_add_nconf(conf, &ctx2, section, x)) goto end;
                }
 
-       if (!X509_sign(x,pkey,digest)) goto end;
+       if (!do_X509_sign(bio_err, x, pkey, digest, sigopts))
+               goto end;
        ret=1;
 end:
        X509_STORE_CTX_cleanup(&xsc);
index d96a622d8314c87e04e0ab14244be7a334b2c93c..7b4a193d6b15c54d955982ddd6c45f4766d88343 100644 (file)
@@ -218,65 +218,100 @@ int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2,
             const EVP_MD *type)
        {
        EVP_MD_CTX ctx;
+       EVP_MD_CTX_init(&ctx);
+       if (!EVP_DigestSignInit(&ctx, NULL, type, NULL, pkey))
+               {
+               EVP_MD_CTX_cleanup(&ctx);
+               return 0;
+               }
+       return ASN1_item_sign_ctx(it, algor1, algor2, signature, asn, &ctx);
+       }
+               
+
+int ASN1_item_sign_ctx(const ASN1_ITEM *it,
+               X509_ALGOR *algor1, X509_ALGOR *algor2,
+               ASN1_BIT_STRING *signature, void *asn, EVP_MD_CTX *ctx)
+       {
+       const EVP_MD *type;
+       EVP_PKEY *pkey;
        unsigned char *buf_in=NULL,*buf_out=NULL;
-       int inl=0,outl=0,outll=0;
+       size_t inl=0,outl=0,outll=0;
        int signid, paramtype;
+       int rv;
 
-       if (type == NULL)
+       type = EVP_MD_CTX_md(ctx);
+       pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx);
+
+       if (!type || !pkey)
                {
-               int def_nid;
-               if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) > 0)
-                       type = EVP_get_digestbynid(def_nid);
+               ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ASN1_R_CONTEXT_NOT_INITIALISED);
+               return 0;
                }
 
-       if (type == NULL)
+       if (pkey->ameth->item_sign)
                {
-               ASN1err(ASN1_F_ASN1_ITEM_SIGN, ASN1_R_NO_DEFAULT_DIGEST);
-               return 0;
+               rv = pkey->ameth->item_sign(ctx, it, asn, algor1, algor2,
+                                               signature);
+               if (rv == 1)
+                       outl = signature->length;
+               /* Return value meanings:
+                * <=0: error.
+                *   1: method does everything.
+                *   2: carry on as normal.
+                *   3: ASN1 method sets algorithm identifiers: just sign.
+                */
+               if (rv <= 0)
+                       ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_EVP_LIB);
+               if (rv <= 1)
+                       goto err;
                }
+       else
+               rv = 2;
 
-       if (type->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE)
+       if (rv == 2)
                {
-               if (!pkey->ameth ||
-                       !OBJ_find_sigid_by_algs(&signid, EVP_MD_nid(type),
-                                               pkey->ameth->pkey_id))
+               if (type->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE)
                        {
-                       ASN1err(ASN1_F_ASN1_ITEM_SIGN,
-                               ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED);
-                       return 0;
+                       if (!pkey->ameth ||
+                               !OBJ_find_sigid_by_algs(&signid,
+                                                       EVP_MD_nid(type),
+                                                       pkey->ameth->pkey_id))
+                               {
+                               ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX,
+                                       ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED);
+                               return 0;
+                               }
                        }
-               }
-       else
-               signid = type->pkey_type;
+               else
+                       signid = type->pkey_type;
 
-       if (pkey->ameth->pkey_flags & ASN1_PKEY_SIGPARAM_NULL)
-               paramtype = V_ASN1_NULL;
-       else
-               paramtype = V_ASN1_UNDEF;
+               if (pkey->ameth->pkey_flags & ASN1_PKEY_SIGPARAM_NULL)
+                       paramtype = V_ASN1_NULL;
+               else
+                       paramtype = V_ASN1_UNDEF;
 
-       if (algor1)
-               X509_ALGOR_set0(algor1, OBJ_nid2obj(signid), paramtype, NULL);
-       if (algor2)
-               X509_ALGOR_set0(algor2, OBJ_nid2obj(signid), paramtype, NULL);
+               if (algor1)
+                       X509_ALGOR_set0(algor1, OBJ_nid2obj(signid), paramtype, NULL);
+               if (algor2)
+                       X509_ALGOR_set0(algor2, OBJ_nid2obj(signid), paramtype, NULL);
+
+               }
 
-       EVP_MD_CTX_init(&ctx);
        inl=ASN1_item_i2d(asn,&buf_in, it);
        outll=outl=EVP_PKEY_size(pkey);
-       buf_out=(unsigned char *)OPENSSL_malloc((unsigned int)outl);
+       buf_out=OPENSSL_malloc((unsigned int)outl);
        if ((buf_in == NULL) || (buf_out == NULL))
                {
                outl=0;
-               ASN1err(ASN1_F_ASN1_ITEM_SIGN,ERR_R_MALLOC_FAILURE);
+               ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX,ERR_R_MALLOC_FAILURE);
                goto err;
                }
 
-       if (!EVP_SignInit_ex(&ctx,type, NULL)
-               || !EVP_SignUpdate(&ctx,(unsigned char *)buf_in,inl)
-               || !EVP_SignFinal(&ctx,(unsigned char *)buf_out,
-                       (unsigned int *)&outl,pkey))
+       if (!EVP_DigestSignUpdate(ctx, buf_in, inl)
+               || !EVP_DigestSignFinal(ctx, buf_out, &outl))
                {
                outl=0;
-               ASN1err(ASN1_F_ASN1_ITEM_SIGN,ERR_R_EVP_LIB);
+               ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX,ERR_R_EVP_LIB);
                goto err;
                }
        if (signature->data != NULL) OPENSSL_free(signature->data);
@@ -289,7 +324,7 @@ int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2,
        signature->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
        signature->flags|=ASN1_STRING_FLAG_BITS_LEFT;
 err:
-       EVP_MD_CTX_cleanup(&ctx);
+       EVP_MD_CTX_cleanup(ctx);
        if (buf_in != NULL)
                { OPENSSL_cleanse((char *)buf_in,(unsigned int)inl); OPENSSL_free(buf_in); }
        if (buf_out != NULL)
index d9332ee15db95e57c48bcc006cf33274cb57580c..432722e4099e6d9ecdc73646e8b931826705b69d 100644 (file)
@@ -131,11 +131,10 @@ err:
 #endif
 
 
-int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a, ASN1_BIT_STRING *signature,
-            void *asn, EVP_PKEY *pkey)
+int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a,
+               ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey)
        {
        EVP_MD_CTX ctx;
-       const EVP_MD *type = NULL;
        unsigned char *buf_in=NULL;
        int ret= -1,inl;
 
@@ -149,25 +148,47 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a, ASN1_BIT_STRING *signat
                ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM);
                goto err;
                }
-       type=EVP_get_digestbynid(mdnid);
-       if (type == NULL)
+       if (mdnid == NID_undef)
                {
-               ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM);
-               goto err;
+               if (!pkey->ameth || !pkey->ameth->item_verify)
+                       {
+                       ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM);
+                       goto err;
+                       }
+               ret = pkey->ameth->item_verify(&ctx, it, asn, a,
+                                                       signature, pkey);
+               /* Return value of 2 means carry on, anything else means we
+                * exit straight away: either a fatal error of the underlying
+                * verification routine handles all verification.
+                */
+               if (ret != 2)
+                       goto err;
+               ret = -1;
                }
-
-       /* Check public key OID matches public key type */
-       if (EVP_PKEY_type(pknid) != pkey->ameth->pkey_id)
+       else
                {
-               ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ASN1_R_WRONG_PUBLIC_KEY_TYPE);
-               goto err;
-               }
+               const EVP_MD *type;
+               type=EVP_get_digestbynid(mdnid);
+               if (type == NULL)
+                       {
+                       ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM);
+                       goto err;
+                       }
+
+               /* Check public key OID matches public key type */
+               if (EVP_PKEY_type(pknid) != pkey->ameth->pkey_id)
+                       {
+                       ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ASN1_R_WRONG_PUBLIC_KEY_TYPE);
+                       goto err;
+                       }
+
+               if (!EVP_DigestVerifyInit(&ctx, NULL, type, NULL, pkey))
+                       {
+                       ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ERR_R_EVP_LIB);
+                       ret=0;
+                       goto err;
+                       }
 
-       if (!EVP_VerifyInit_ex(&ctx,type, NULL))
-               {
-               ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ERR_R_EVP_LIB);
-               ret=0;
-               goto err;
                }
 
        inl = ASN1_item_i2d(asn, &buf_in, it);
@@ -178,7 +199,7 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a, ASN1_BIT_STRING *signat
                goto err;
                }
 
-       if (!EVP_VerifyUpdate(&ctx,(unsigned char *)buf_in,inl))
+       if (!EVP_DigestVerifyUpdate(&ctx,buf_in,inl))
                {
                ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ERR_R_EVP_LIB);
                ret=0;
@@ -188,8 +209,8 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a, ASN1_BIT_STRING *signat
        OPENSSL_cleanse(buf_in,(unsigned int)inl);
        OPENSSL_free(buf_in);
 
-       if (EVP_VerifyFinal(&ctx,(unsigned char *)signature->data,
-                       (unsigned int)signature->length,pkey) <= 0)
+       if (EVP_DigestVerifyFinal(&ctx,signature->data,
+                       (size_t)signature->length) <= 0)
                {
                ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ERR_R_EVP_LIB);
                ret=0;
index 439e76044a13b40c56efc63ca2eea5a27051c637..220a0c8c637e12e5aa96ffd403616b182280580a 100644 (file)
@@ -235,7 +235,7 @@ typedef struct asn1_object_st
  */
 #define ASN1_STRING_FLAG_MSTRING 0x040 
 /* This is the base type that holds just about everything :-) */
-typedef struct asn1_string_st
+struct asn1_string_st
        {
        int length;
        int type;
@@ -245,7 +245,7 @@ typedef struct asn1_string_st
         * input data has a non-zero 'unused bits' value, it will be
         * handled correctly */
        long flags;
-       } ASN1_STRING;
+       };
 
 /* ASN1_ENCODING structure: this is used to save the received
  * encoding of an ASN1 type. This is useful to get round
@@ -293,7 +293,6 @@ DECLARE_STACK_OF(ASN1_STRING_TABLE)
  * see asn1t.h
  */
 typedef struct ASN1_TEMPLATE_st ASN1_TEMPLATE;
-typedef struct ASN1_ITEM_st ASN1_ITEM;
 typedef struct ASN1_TLC_st ASN1_TLC;
 /* This is just an opaque pointer */
 typedef struct ASN1_VALUE_st ASN1_VALUE;
@@ -1194,6 +1193,7 @@ void ERR_load_ASN1_strings(void);
 #define ASN1_F_ASN1_ITEM_I2D_FP                                 193
 #define ASN1_F_ASN1_ITEM_PACK                           198
 #define ASN1_F_ASN1_ITEM_SIGN                           195
+#define ASN1_F_ASN1_ITEM_SIGN_CTX                       220
 #define ASN1_F_ASN1_ITEM_UNPACK                                 199
 #define ASN1_F_ASN1_ITEM_VERIFY                                 197
 #define ASN1_F_ASN1_MBSTRING_NCOPY                      122
@@ -1292,6 +1292,7 @@ void ERR_load_ASN1_strings(void);
 #define ASN1_R_BOOLEAN_IS_WRONG_LENGTH                  106
 #define ASN1_R_BUFFER_TOO_SMALL                                 107
 #define ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER          108
+#define ASN1_R_CONTEXT_NOT_INITIALISED                  217
 #define ASN1_R_DATA_IS_WRONG                            109
 #define ASN1_R_DECODE_ERROR                             110
 #define ASN1_R_DECODING_ERROR                           111
index 7e209956e64c073fbb6d1155d1d92fcb7279c0c0..1a30bf119bd2ae7327b4575dbc42ebb13311e54e 100644 (file)
@@ -107,6 +107,7 @@ static ERR_STRING_DATA ASN1_str_functs[]=
 {ERR_FUNC(ASN1_F_ASN1_ITEM_I2D_FP),    "ASN1_item_i2d_fp"},
 {ERR_FUNC(ASN1_F_ASN1_ITEM_PACK),      "ASN1_item_pack"},
 {ERR_FUNC(ASN1_F_ASN1_ITEM_SIGN),      "ASN1_item_sign"},
+{ERR_FUNC(ASN1_F_ASN1_ITEM_SIGN_CTX),  "ASN1_item_sign_ctx"},
 {ERR_FUNC(ASN1_F_ASN1_ITEM_UNPACK),    "ASN1_item_unpack"},
 {ERR_FUNC(ASN1_F_ASN1_ITEM_VERIFY),    "ASN1_item_verify"},
 {ERR_FUNC(ASN1_F_ASN1_MBSTRING_NCOPY), "ASN1_mbstring_ncopy"},
@@ -208,6 +209,7 @@ static ERR_STRING_DATA ASN1_str_reasons[]=
 {ERR_REASON(ASN1_R_BOOLEAN_IS_WRONG_LENGTH),"boolean is wrong length"},
 {ERR_REASON(ASN1_R_BUFFER_TOO_SMALL)     ,"buffer too small"},
 {ERR_REASON(ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER),"cipher has no object identifier"},
+{ERR_REASON(ASN1_R_CONTEXT_NOT_INITIALISED),"context not initialised"},
 {ERR_REASON(ASN1_R_DATA_IS_WRONG)        ,"data is wrong"},
 {ERR_REASON(ASN1_R_DECODE_ERROR)         ,"decode error"},
 {ERR_REASON(ASN1_R_DECODING_ERROR)       ,"decoding error"},
index 5aa65e28f5f5cc241d9ec6394b2f2a0fc0c0b447..9fcf0d9530ff9a82dc008d45b537fda2c9ead109 100644 (file)
@@ -102,6 +102,10 @@ struct evp_pkey_asn1_method_st
        int (*param_cmp)(const EVP_PKEY *a, const EVP_PKEY *b);
        int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent,
                                                        ASN1_PCTX *pctx);
+       int (*sig_print)(BIO *out,
+                        const X509_ALGOR *sigalg, const ASN1_STRING *sig,
+                                        int indent, ASN1_PCTX *pctx);
+
 
        void (*pkey_free)(EVP_PKEY *pkey);
        int (*pkey_ctrl)(EVP_PKEY *pkey, int op, long arg1, void *arg2);
@@ -111,6 +115,13 @@ struct evp_pkey_asn1_method_st
        int (*old_priv_decode)(EVP_PKEY *pkey,
                                const unsigned char **pder, int derlen);
        int (*old_priv_encode)(const EVP_PKEY *pkey, unsigned char **pder);
+       /* Custom ASN1 signature verification */
+       int (*item_verify)(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
+                               X509_ALGOR *a, ASN1_BIT_STRING *sig,
+                               EVP_PKEY *pkey);
+       int (*item_sign)(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
+                               X509_ALGOR *alg1, X509_ALGOR *alg2, 
+                               ASN1_BIT_STRING *sig);
 
        } /* EVP_PKEY_ASN1_METHOD */;
 
index ee5a687ce83a94b41fbba5c367b2c54bb6e8cf3a..c61169208a34ddae94ac0e384a8763fe14eaac4a 100644 (file)
@@ -94,8 +94,7 @@ int X509_CRL_print(BIO *out, X509_CRL *x)
        l = X509_CRL_get_version(x);
        BIO_printf(out, "%8sVersion %lu (0x%lx)\n", "", l+1, l);
        i = OBJ_obj2nid(x->sig_alg->algorithm);
-       BIO_printf(out, "%8sSignature Algorithm: %s\n", "",
-                                (i == NID_undef) ? "NONE" : OBJ_nid2ln(i));
+       X509_signature_print(out, x->sig_alg, NULL);
        p=X509_NAME_oneline(X509_CRL_get_issuer(x),NULL,0);
        BIO_printf(out,"%8sIssuer: %s\n","",p);
        OPENSSL_free(p);
index 01cf9e427a14233929aeb0c8a1488f873344a4ab..db88f3a3e15dddace268e53b6e7cef85ec72d1eb 100644 (file)
@@ -72,6 +72,7 @@
 #include <openssl/objects.h>
 #include <openssl/x509.h>
 #include <openssl/x509v3.h>
+#include "asn1_locl.h"
 
 #ifndef OPENSSL_NO_FP_API
 int X509_print_fp(FILE *fp, X509 *x)
@@ -167,12 +168,16 @@ int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, unsigned long cflag)
 
        if(!(cflag & X509_FLAG_NO_SIGNAME))
                {
+               if(X509_signature_print(bp, x->sig_alg, NULL) <= 0)
+                       goto err;
+#if 0
                if (BIO_printf(bp,"%8sSignature Algorithm: ","") <= 0) 
                        goto err;
                if (i2a_ASN1_OBJECT(bp, ci->signature->algorithm) <= 0)
                        goto err;
                if (BIO_puts(bp, "\n") <= 0)
                        goto err;
+#endif
                }
 
        if(!(cflag & X509_FLAG_NO_ISSUER))
@@ -286,23 +291,50 @@ err:
        return(0);
        }
 
-int X509_signature_print(BIO *bp, X509_ALGOR *sigalg, ASN1_STRING *sig)
+int X509_signature_dump(BIO *bp, const ASN1_STRING *sig, int indent)
 {
-       unsigned char *s;
+       const unsigned char *s;
        int i, n;
-       if (BIO_puts(bp,"    Signature Algorithm: ") <= 0) return 0;
-       if (i2a_ASN1_OBJECT(bp, sigalg->algorithm) <= 0) return 0;
 
        n=sig->length;
        s=sig->data;
        for (i=0; i<n; i++)
                {
                if ((i%18) == 0)
-                       if (BIO_write(bp,"\n        ",9) <= 0) return 0;
+                       {
+                       if (BIO_write(bp,"\n",1) <= 0) return 0;
+                       if (BIO_indent(bp, indent, indent) <= 0) return 0;
+                       }
                        if (BIO_printf(bp,"%02x%s",s[i],
                                ((i+1) == n)?"":":") <= 0) return 0;
                }
        if (BIO_write(bp,"\n",1) != 1) return 0;
+
+       return 1;
+}
+
+int X509_signature_print(BIO *bp, X509_ALGOR *sigalg, ASN1_STRING *sig)
+{
+       int sig_nid;
+       if (BIO_puts(bp,"    Signature Algorithm: ") <= 0) return 0;
+       if (i2a_ASN1_OBJECT(bp, sigalg->algorithm) <= 0) return 0;
+
+       sig_nid = OBJ_obj2nid(sigalg->algorithm);
+       if (sig_nid != NID_undef)
+               {
+               int pkey_nid, dig_nid;
+               const EVP_PKEY_ASN1_METHOD *ameth;
+               if (OBJ_find_sigid_algs(sig_nid, &dig_nid, &pkey_nid))
+                       {
+                       ameth = EVP_PKEY_asn1_find(NULL, pkey_nid);
+                       if (ameth && ameth->sig_print)
+                               return ameth->sig_print(bp, sigalg, sig, 9, 0);
+                       }
+               }
+       if (sig)
+               return X509_signature_dump(bp, sig, 9);
+       else if (BIO_puts(bp, "\n") <= 0)
+               return 0;
        return 1;
 }
 
index 6a43ba2b5b1e7f8f309cc27f54567f197cf94259..0b8e5670b0ec7b0ef09bb04929306293346ca570 100644 (file)
@@ -88,7 +88,7 @@ const EVP_PKEY_ASN1_METHOD cmac_asn1_meth =
 
        cmac_size,
        0,
-       0,0,0,0,0,0,
+       0,0,0,0,0,0,0,
 
        cmac_key_free,
        0,
index 377caf96c930df8ee497d8c660aa9a26d0db3b9d..02ec2d47b4bd39998fa2278f727c085403aa9e8e 100644 (file)
@@ -493,6 +493,7 @@ const EVP_PKEY_ASN1_METHOD dh_asn1_meth =
        dh_copy_parameters,
        dh_cmp_parameters,
        dh_param_print,
+       0,
 
        int_dh_free,
        0
index 295470e8683b36e39d7cfa6a3e32d684fe493bbe..a6f6d0b0b24307c5b28acb729802c2130560afb1 100644 (file)
@@ -299,6 +299,7 @@ void ERR_load_DSA_strings(void);
 #define DSA_F_DSA_SIGN                                  106
 #define DSA_F_DSA_SIGN_SETUP                            107
 #define DSA_F_DSA_SIG_NEW                               109
+#define DSA_F_DSA_SIG_PRINT                             125
 #define DSA_F_DSA_VERIFY                                108
 #define DSA_F_I2D_DSA_SIG                               111
 #define DSA_F_OLD_DSA_PRIV_DECODE                       122
index 6413aae46e26348331d4b7c724b46da32f87ef46..376156ec5ef3a6ad23539296601180f7b4fa1472 100644 (file)
@@ -542,6 +542,52 @@ 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)
@@ -647,6 +693,7 @@ const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[] =
                dsa_copy_parameters,
                dsa_cmp_parameters,
                dsa_param_print,
+               dsa_sig_print,
 
                int_dsa_free,
                dsa_pkey_ctrl,
index 6c495232891065ed8dca8126dc465b80998df3a4..00545b7b9fa9410a63df06e1f8a5bc71416150a4 100644 (file)
@@ -88,6 +88,7 @@ static ERR_STRING_DATA DSA_str_functs[]=
 {ERR_FUNC(DSA_F_DSA_SIGN),     "DSA_sign"},
 {ERR_FUNC(DSA_F_DSA_SIGN_SETUP),       "DSA_sign_setup"},
 {ERR_FUNC(DSA_F_DSA_SIG_NEW),  "DSA_SIG_new"},
+{ERR_FUNC(DSA_F_DSA_SIG_PRINT),        "DSA_SIG_PRINT"},
 {ERR_FUNC(DSA_F_DSA_VERIFY),   "DSA_verify"},
 {ERR_FUNC(DSA_F_I2D_DSA_SIG),  "i2d_DSA_SIG"},
 {ERR_FUNC(DSA_F_OLD_DSA_PRIV_DECODE),  "OLD_DSA_PRIV_DECODE"},
index c00f7d746c36e293a451a5aed64b144aef54c315..83909c185359a73046952b2ad9ac38991211b2e7 100644 (file)
@@ -651,6 +651,7 @@ const EVP_PKEY_ASN1_METHOD eckey_asn1_meth =
        ec_copy_parameters,
        ec_cmp_parameters,
        eckey_param_print,
+       0,
 
        int_ec_free,
        ec_pkey_ctrl,
index 6d8a89149ee3290cf6e9a00c7f76e5391d4c0446..e03f24aedab983b26fb4eb995fdf5ae511c69449 100644 (file)
@@ -153,7 +153,7 @@ const EVP_PKEY_ASN1_METHOD hmac_asn1_meth =
 
        hmac_size,
        0,
-       0,0,0,0,0,0,
+       0,0,0,0,0,0,0,
 
        hmac_key_free,
        hmac_pkey_ctrl,
index 7836f01d95ccacbc6a51b66abf65fdda8abef2fd..e23938c2960492751d4264dc9c88b804e010ceee 100644 (file)
@@ -1,4 +1,4 @@
-/* AUTOGENERATED BY crypto/objects/objxref.pl, DO NOT EDIT */
+/* AUTOGENERATED BY objxref.pl, DO NOT EDIT */
 
 typedef struct
        {
@@ -38,10 +38,12 @@ static const nid_triple sigoid_srt[] =
        {NID_id_GostR3411_94_with_GostR3410_94, NID_id_GostR3411_94, NID_id_GostR3410_94},
        {NID_id_GostR3411_94_with_GostR3410_94_cc, NID_id_GostR3411_94, NID_id_GostR3410_94_cc},
        {NID_id_GostR3411_94_with_GostR3410_2001_cc, NID_id_GostR3411_94, NID_id_GostR3410_2001_cc},
+       {NID_rsassaPss, NID_undef, NID_rsaEncryption},
        };
 
 static const nid_triple * const sigoid_srt_xref[] =
        {
+       &sigoid_srt[29],
        &sigoid_srt[17],
        &sigoid_srt[18],
        &sigoid_srt[0],
index e45b3d34b9bcd7b8be33a6e0d1ccfa2c9a02cc8f..cb917182ee2f9e74343591b65e929faf70ac8388 100644 (file)
@@ -13,6 +13,10 @@ sha512WithRSAEncryption      sha512  rsaEncryption
 sha224WithRSAEncryption        sha224  rsaEncryption
 mdc2WithRSA            mdc2    rsaEncryption
 ripemd160WithRSA       ripemd160 rsaEncryption
+# For PSS the digest algorithm can vary and depends on the included
+# AlgorithmIdentifier. The digest "undef" indicates the public key
+# method should handle this explicitly.
+rsassaPss              undef   rsaEncryption
 
 # Alternative deprecated OIDs. By using the older "rsa" OID this
 # type will be recognized by not normally used.
index 12bd7014de36b32e65bcff9f208d814f8ac50ea0..ea9227f6f95a88ff1672680a53bf38225d8b2b81 100644 (file)
@@ -91,10 +91,12 @@ typedef struct asn1_string_st ASN1_TIME;
 typedef struct asn1_string_st ASN1_GENERALIZEDTIME;
 typedef struct asn1_string_st ASN1_VISIBLESTRING;
 typedef struct asn1_string_st ASN1_UTF8STRING;
+typedef struct asn1_string_st ASN1_STRING;
 typedef int ASN1_BOOLEAN;
 typedef int ASN1_NULL;
 #endif
 
+typedef struct ASN1_ITEM_st ASN1_ITEM;
 typedef struct asn1_pctx_st ASN1_PCTX;
 
 #ifdef OPENSSL_SYS_WIN32
index 71da4b64222369c75eb368a91d285d3874759a05..4814a2fc15e879197f306accae3edf11b9a3ca84 100644 (file)
@@ -323,6 +323,16 @@ const RSA_METHOD *RSA_null_method(void);
 DECLARE_ASN1_ENCODE_FUNCTIONS_const(RSA, RSAPublicKey)
 DECLARE_ASN1_ENCODE_FUNCTIONS_const(RSA, RSAPrivateKey)
 
+typedef struct rsa_pss_params_st
+       {
+       X509_ALGOR *hashAlgorithm;
+       X509_ALGOR *maskGenAlgorithm;
+       ASN1_INTEGER *saltLength;
+       ASN1_INTEGER *trailerField;
+       } RSA_PSS_PARAMS;
+
+DECLARE_ASN1_FUNCTIONS(RSA_PSS_PARAMS)
+
 #ifndef OPENSSL_NO_FP_API
 int    RSA_print_fp(FILE *fp, const RSA *r,int offset);
 #endif
@@ -465,6 +475,7 @@ void ERR_load_RSA_strings(void);
 #define RSA_F_RSA_EAY_PUBLIC_ENCRYPT                    104
 #define RSA_F_RSA_GENERATE_KEY                          105
 #define RSA_F_RSA_GENERATE_KEY_EX                       155
+#define RSA_F_RSA_ITEM_VERIFY                           156
 #define RSA_F_RSA_MEMORY_LOCK                           130
 #define RSA_F_RSA_NEW_METHOD                            106
 #define RSA_F_RSA_NULL                                  124
@@ -528,22 +539,24 @@ void ERR_load_RSA_strings(void);
 #define RSA_R_INVALID_HEADER                            137
 #define RSA_R_INVALID_KEYBITS                           145
 #define RSA_R_INVALID_MESSAGE_LENGTH                    131
-#define RSA_R_INVALID_MGF1_MD                           149
+#define RSA_R_INVALID_MGF1_MD                           156
 #define RSA_R_INVALID_PADDING                           138
 #define RSA_R_INVALID_PADDING_MODE                      141
+#define RSA_R_INVALID_PSS_PARAMETERS                    149
 #define RSA_R_INVALID_PSS_SALTLEN                       146
+#define RSA_R_INVALID_SALT_LENGTH                       150
 #define RSA_R_INVALID_TRAILER                           139
 #define RSA_R_INVALID_X931_DIGEST                       142
 #define RSA_R_IQMP_NOT_INVERSE_OF_Q                     126
 #define RSA_R_KEY_SIZE_TOO_SMALL                        120
 #define RSA_R_LAST_OCTET_INVALID                        134
 #define RSA_R_MODULUS_TOO_LARGE                                 105
-#define RSA_R_NON_FIPS_RSA_METHOD                       150
+#define RSA_R_NON_FIPS_RSA_METHOD                       157
 #define RSA_R_NO_PUBLIC_EXPONENT                        140
 #define RSA_R_NULL_BEFORE_BLOCK_MISSING                         113
 #define RSA_R_N_DOES_NOT_EQUAL_P_Q                      127
 #define RSA_R_OAEP_DECODING_ERROR                       121
-#define RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE        151
+#define RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE        158
 #define RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE  148
 #define RSA_R_PADDING_CHECK_FAILED                      114
 #define RSA_R_P_NOT_PRIME                               128
@@ -554,7 +567,12 @@ void ERR_load_RSA_strings(void);
 #define RSA_R_SSLV3_ROLLBACK_ATTACK                     115
 #define RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD 116
 #define RSA_R_UNKNOWN_ALGORITHM_TYPE                    117
+#define RSA_R_UNKNOWN_MASK_DIGEST                       151
 #define RSA_R_UNKNOWN_PADDING_TYPE                      118
+#define RSA_R_UNKNOWN_PSS_DIGEST                        152
+#define RSA_R_UNSUPPORTED_MASK_ALGORITHM                153
+#define RSA_R_UNSUPPORTED_MASK_PARAMETER                154
+#define RSA_R_UNSUPPORTED_SIGNATURE_TYPE                155
 #define RSA_R_VALUE_MISSING                             147
 #define RSA_R_WRONG_SIGNATURE_LENGTH                    119
 
index 8c3209885eab2f1bf3f4c18d3c5e06cf00cacfa2..2460910ab2783e5dc198e6437462a18e32f7f9b8 100644 (file)
@@ -265,6 +265,147 @@ static int rsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
        return do_rsa_print(bp, pkey->pkey.rsa, indent, 1);
        }
 
+static RSA_PSS_PARAMS *rsa_pss_decode(const X509_ALGOR *alg,
+                                       X509_ALGOR **pmaskHash)
+       {
+       const unsigned char *p;
+       int plen;
+       RSA_PSS_PARAMS *pss;
+
+       *pmaskHash = NULL;
+
+       if (!alg->parameter || alg->parameter->type != V_ASN1_SEQUENCE)
+               return NULL;
+       p = alg->parameter->value.sequence->data;
+       plen = alg->parameter->value.sequence->length;
+       pss = d2i_RSA_PSS_PARAMS(NULL, &p, plen);
+
+       if (!pss)
+               return NULL;
+       
+       if (pss->maskGenAlgorithm)
+               {
+               ASN1_TYPE *param = pss->maskGenAlgorithm->parameter;
+               if (OBJ_obj2nid(pss->maskGenAlgorithm->algorithm) == NID_mgf1
+                       && param->type == V_ASN1_SEQUENCE)
+                       {
+                       p = param->value.sequence->data;
+                       plen = param->value.sequence->length;
+                       *pmaskHash = d2i_X509_ALGOR(NULL, &p, plen);
+                       }
+               }
+
+       return pss;
+       }
+
+static int rsa_pss_param_print(BIO *bp, RSA_PSS_PARAMS *pss, 
+                               X509_ALGOR *maskHash, int indent)
+       {
+       int rv = 0;
+       if (!pss)
+               {
+               if (BIO_puts(bp, " (INVALID PSS PARAMETERS)\n") <= 0)
+                       return 0;
+               return 1;
+               }
+       if (BIO_puts(bp, "\n") <= 0)
+               goto err;
+       if (!BIO_indent(bp, indent, 128))
+               goto err;
+       if (BIO_puts(bp, "Hash Algorithm: ") <= 0)
+               goto err;
+
+       if (pss->hashAlgorithm)
+               {
+               if (i2a_ASN1_OBJECT(bp, pss->hashAlgorithm->algorithm) <= 0)
+                       goto err;
+               }
+       else if (BIO_puts(bp, "sha1 (default)") <= 0)
+               goto err;
+
+       if (BIO_puts(bp, "\n") <= 0)
+               goto err;
+
+       if (!BIO_indent(bp, indent, 128))
+               goto err;
+
+       if (BIO_puts(bp, "Mask Algorithm: ") <= 0)
+                       goto err;
+       if (pss->maskGenAlgorithm)
+               {
+               if (i2a_ASN1_OBJECT(bp, pss->maskGenAlgorithm->algorithm) <= 0)
+                       goto err;
+               if (BIO_puts(bp, " with ") <= 0)
+                       goto err;
+               if (maskHash)
+                       {
+                       if (i2a_ASN1_OBJECT(bp, maskHash->algorithm) <= 0)
+                       goto err;
+                       }
+               else if (BIO_puts(bp, "INVALID") <= 0)
+                       goto err;
+               }
+       else if (BIO_puts(bp, "mgf1 with sha1 (default)") <= 0)
+               goto err;
+       BIO_puts(bp, "\n");
+
+       if (!BIO_indent(bp, indent, 128))
+               goto err;
+       if (BIO_puts(bp, "Salt Length: ") <= 0)
+                       goto err;
+       if (pss->saltLength)
+               {
+               if (i2a_ASN1_INTEGER(bp, pss->saltLength) <= 0)
+                       goto err;
+               }
+       else if (BIO_puts(bp, "20 (default)") <= 0)
+               goto err;
+       BIO_puts(bp, "\n");
+
+       if (!BIO_indent(bp, indent, 128))
+               goto err;
+       if (BIO_puts(bp, "Trailer Field: ") <= 0)
+                       goto err;
+       if (pss->trailerField)
+               {
+               if (i2a_ASN1_INTEGER(bp, pss->trailerField) <= 0)
+                       goto err;
+               }
+       else if (BIO_puts(bp, "0xbc (default)") <= 0)
+               goto err;
+       BIO_puts(bp, "\n");
+       
+       rv = 1;
+
+       err:
+       return rv;
+
+       }
+
+static int rsa_sig_print(BIO *bp, const X509_ALGOR *sigalg,
+                                       const ASN1_STRING *sig,
+                                       int indent, ASN1_PCTX *pctx)
+       {
+       if (OBJ_obj2nid(sigalg->algorithm) == NID_rsassaPss)
+               {
+               int rv;
+               RSA_PSS_PARAMS *pss;
+               X509_ALGOR *maskHash;
+               pss = rsa_pss_decode(sigalg, &maskHash);
+               rv = rsa_pss_param_print(bp, pss, maskHash, indent);
+               if (pss)
+                       RSA_PSS_PARAMS_free(pss);
+               if (maskHash)
+                       X509_ALGOR_free(maskHash);
+               if (!rv)
+                       return 0;
+               }
+       else if (!sig && BIO_puts(bp, "\n") <= 0)
+               return 0;
+       if (sig)
+               return X509_signature_dump(bp, sig, indent);
+       return 1;
+       }
 
 static int rsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
        {
@@ -310,6 +451,211 @@ static int rsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
 
        }
 
+/* Customised RSA item verification routine. This is called 
+ * when a signature is encountered requiring special handling. We 
+ * currently only handle PSS.
+ */
+
+
+static int rsa_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
+                       X509_ALGOR *sigalg, ASN1_BIT_STRING *sig,
+                       EVP_PKEY *pkey)
+       {
+       int rv = -1;
+       int saltlen;
+       const EVP_MD *mgf1md = NULL, *md = NULL;
+       RSA_PSS_PARAMS *pss;
+       X509_ALGOR *maskHash;
+       EVP_PKEY_CTX *pkctx;
+       /* Sanity check: make sure it is PSS */
+       if (OBJ_obj2nid(sigalg->algorithm) != NID_rsassaPss)
+               {
+               RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNSUPPORTED_SIGNATURE_TYPE);
+               return -1;
+               }
+       /* Decode PSS parameters */
+       pss = rsa_pss_decode(sigalg, &maskHash);
+
+       if (pss == NULL)
+               {
+               RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_INVALID_PSS_PARAMETERS);
+               goto err;
+               }
+       /* Check mask and lookup mask hash algorithm */
+       if (pss->maskGenAlgorithm)
+               {
+               if (OBJ_obj2nid(pss->maskGenAlgorithm->algorithm) != NID_mgf1)
+                       {
+                       RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNSUPPORTED_MASK_ALGORITHM);
+                       goto err;
+                       }
+               if (!maskHash)
+                       {
+                       RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNSUPPORTED_MASK_PARAMETER);
+                       goto err;
+                       }
+               mgf1md = EVP_get_digestbyobj(maskHash->algorithm);
+               if (mgf1md == NULL)
+                       {
+                       RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNKNOWN_MASK_DIGEST);
+                       goto err;
+                       }
+               }
+       else
+               mgf1md = EVP_sha1();
+
+       if (pss->hashAlgorithm)
+               {
+               md = EVP_get_digestbyobj(pss->hashAlgorithm->algorithm);
+               if (md == NULL)
+                       {
+                       RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNKNOWN_PSS_DIGEST);
+                       goto err;
+                       }
+               }
+       else
+               md = EVP_sha1();
+
+       if (pss->saltLength)
+               {
+               saltlen = ASN1_INTEGER_get(pss->saltLength);
+
+               /* Could perform more salt length sanity checks but the main
+                * RSA routines will trap other invalid values anyway.
+                */
+               if (saltlen < 0)
+                       {
+                       RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_INVALID_SALT_LENGTH);
+                       goto err;
+                       }
+               }
+       else
+               saltlen = 20;
+
+       /* low-level routines support only trailer field 0xbc (value 1)
+        * and PKCS#1 says we should reject any other value anyway.
+        */
+       if (pss->trailerField && ASN1_INTEGER_get(pss->trailerField) != 1)
+               {
+               RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_INVALID_TRAILER);
+               goto err;
+               }
+
+       /* We have all parameters now set up context */
+
+       if (!EVP_DigestVerifyInit(ctx, &pkctx, md, NULL, pkey))
+               goto err;
+
+       if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_PSS_PADDING) <= 0)
+               goto err;
+
+       if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkctx, saltlen) <= 0)
+               goto err;
+
+       if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md) <= 0)
+               goto err;
+       /* Carry on */
+       rv = 2;
+
+       err:
+       RSA_PSS_PARAMS_free(pss);
+       if (maskHash)
+               X509_ALGOR_free(maskHash);
+       return rv;
+       }
+
+static int rsa_item_sign(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
+                               X509_ALGOR *alg1, X509_ALGOR *alg2, 
+                               ASN1_BIT_STRING *sig)
+       {
+       int pad_mode;
+       EVP_PKEY_CTX *pkctx = ctx->pctx;
+       if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0)
+               return 0;
+       if (pad_mode == RSA_PKCS1_PADDING)
+               return 2;
+       if (pad_mode == RSA_PKCS1_PSS_PADDING)
+               {
+               const EVP_MD *sigmd, *mgf1md;
+               RSA_PSS_PARAMS *pss = NULL;
+               X509_ALGOR *mgf1alg = NULL;
+               ASN1_STRING *os1 = NULL, *os2 = NULL;
+               EVP_PKEY *pk = EVP_PKEY_CTX_get0_pkey(pkctx);
+               int saltlen, rv = 0;
+               sigmd = EVP_MD_CTX_md(ctx);
+               if (EVP_PKEY_CTX_get_rsa_mgf1_md(pkctx, &mgf1md) <= 0)
+                       goto err;
+               if (!EVP_PKEY_CTX_get_rsa_pss_saltlen(pkctx, &saltlen))
+                       goto err;
+               if (saltlen == -1)
+                       saltlen = EVP_MD_size(sigmd);
+               else if (saltlen == -2)
+                       {
+                       saltlen = EVP_PKEY_size(pk) - EVP_MD_size(sigmd) - 2;
+                       if (((EVP_PKEY_bits(pk) - 1) & 0x7) == 0)
+                               saltlen--;
+                       }
+               pss = RSA_PSS_PARAMS_new();
+               if (!pss)
+                       goto err;
+               if (saltlen != 20)
+                       {
+                       pss->saltLength = ASN1_INTEGER_new();
+                       if (!pss->saltLength)
+                               goto err;
+                       if (!ASN1_INTEGER_set(pss->saltLength, saltlen))
+                               goto err;
+                       }
+               if (EVP_MD_type(sigmd) != NID_sha1)
+                       {
+                       pss->hashAlgorithm = X509_ALGOR_new();
+                       if (!pss->hashAlgorithm)
+                               goto err;
+                       X509_ALGOR_set_md(pss->hashAlgorithm, sigmd);
+                       }
+               if (EVP_MD_type(mgf1md) != NID_sha1)
+                       {
+                       ASN1_STRING *stmp = NULL;
+                       /* need to embed algorithm ID inside another */
+                       mgf1alg = X509_ALGOR_new();
+                       X509_ALGOR_set_md(mgf1alg, mgf1md);
+                       if (!ASN1_item_pack(mgf1alg, ASN1_ITEM_rptr(X509_ALGOR),
+                                                                       &stmp))
+                                       goto err;
+                       pss->maskGenAlgorithm = X509_ALGOR_new();
+                       if (!pss->maskGenAlgorithm)
+                               goto err;
+                       X509_ALGOR_set0(pss->maskGenAlgorithm,
+                                       OBJ_nid2obj(NID_mgf1),
+                                       V_ASN1_SEQUENCE, stmp);
+                       }
+               /* Finally create string with pss parameter encoding. */
+               if (!ASN1_item_pack(pss, ASN1_ITEM_rptr(RSA_PSS_PARAMS), &os1))
+                       goto err;
+               if (alg2)
+                       {
+                       os2 = ASN1_STRING_dup(os1);
+                       if (!os2)
+                               goto err;
+                       X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_rsassaPss),
+                                               V_ASN1_SEQUENCE, os2);
+                       }
+               X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_rsassaPss),
+                                       V_ASN1_SEQUENCE, os1);
+               os1 = os2 = NULL;
+               rv = 3;
+               err:
+               if (mgf1alg)
+                       X509_ALGOR_free(mgf1alg);
+               if (pss)
+                       RSA_PSS_PARAMS_free(pss);
+               if (os1)
+                       ASN1_STRING_free(os1);
+               return rv;
+               
+               }
+       return 2;
+       }
 
 const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[] = 
        {
@@ -335,10 +681,13 @@ const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[] =
 
                0,0,0,0,0,0,
 
+               rsa_sig_print,
                int_rsa_free,
                rsa_pkey_ctrl,
                old_rsa_priv_decode,
-               old_rsa_priv_encode
+               old_rsa_priv_encode,
+               rsa_item_verify,
+               rsa_item_sign
                },
 
                {
index 4efca8cdc8090b050d4e360fad4aef0437ef2554..6ed5de3db4d4b71a32df73570b1169780628a508 100644 (file)
@@ -60,6 +60,7 @@
 #include "cryptlib.h"
 #include <openssl/bn.h>
 #include <openssl/rsa.h>
+#include <openssl/x509.h>
 #include <openssl/asn1t.h>
 
 /* Override the default free and new methods */
@@ -96,6 +97,15 @@ ASN1_SEQUENCE_cb(RSAPublicKey, rsa_cb) = {
        ASN1_SIMPLE(RSA, e, BIGNUM),
 } ASN1_SEQUENCE_END_cb(RSA, RSAPublicKey)
 
+ASN1_SEQUENCE(RSA_PSS_PARAMS) = {
+       ASN1_EXP_OPT(RSA_PSS_PARAMS, hashAlgorithm, X509_ALGOR,0),
+       ASN1_EXP_OPT(RSA_PSS_PARAMS, maskGenAlgorithm, X509_ALGOR,1),
+       ASN1_EXP_OPT(RSA_PSS_PARAMS, saltLength, ASN1_INTEGER,2),
+       ASN1_EXP_OPT(RSA_PSS_PARAMS, trailerField, ASN1_INTEGER,3)
+} ASN1_SEQUENCE_END(RSA_PSS_PARAMS)
+
+IMPLEMENT_ASN1_FUNCTIONS(RSA_PSS_PARAMS)
+
 IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(RSA, RSAPrivateKey, RSAPrivateKey)
 
 IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(RSA, RSAPublicKey, RSAPublicKey)
index d0c9659cb53681e00d12cb3cb57563c3b1772be5..46e0bf99806c63280ce3f3e29ea39d5d4ebb711a 100644 (file)
@@ -88,6 +88,7 @@ static ERR_STRING_DATA RSA_str_functs[]=
 {ERR_FUNC(RSA_F_RSA_EAY_PUBLIC_ENCRYPT),       "RSA_EAY_PUBLIC_ENCRYPT"},
 {ERR_FUNC(RSA_F_RSA_GENERATE_KEY),     "RSA_generate_key"},
 {ERR_FUNC(RSA_F_RSA_GENERATE_KEY_EX),  "RSA_generate_key_ex"},
+{ERR_FUNC(RSA_F_RSA_ITEM_VERIFY),      "RSA_ITEM_VERIFY"},
 {ERR_FUNC(RSA_F_RSA_MEMORY_LOCK),      "RSA_memory_lock"},
 {ERR_FUNC(RSA_F_RSA_NEW_METHOD),       "RSA_new_method"},
 {ERR_FUNC(RSA_F_RSA_NULL),     "RSA_NULL"},
@@ -157,7 +158,9 @@ static ERR_STRING_DATA RSA_str_reasons[]=
 {ERR_REASON(RSA_R_INVALID_MGF1_MD)       ,"invalid mgf1 md"},
 {ERR_REASON(RSA_R_INVALID_PADDING)       ,"invalid padding"},
 {ERR_REASON(RSA_R_INVALID_PADDING_MODE)  ,"invalid padding mode"},
+{ERR_REASON(RSA_R_INVALID_PSS_PARAMETERS),"invalid pss parameters"},
 {ERR_REASON(RSA_R_INVALID_PSS_SALTLEN)   ,"invalid pss saltlen"},
+{ERR_REASON(RSA_R_INVALID_SALT_LENGTH)   ,"invalid salt length"},
 {ERR_REASON(RSA_R_INVALID_TRAILER)       ,"invalid trailer"},
 {ERR_REASON(RSA_R_INVALID_X931_DIGEST)   ,"invalid x931 digest"},
 {ERR_REASON(RSA_R_IQMP_NOT_INVERSE_OF_Q) ,"iqmp not inverse of q"},
@@ -180,7 +183,12 @@ static ERR_STRING_DATA RSA_str_reasons[]=
 {ERR_REASON(RSA_R_SSLV3_ROLLBACK_ATTACK) ,"sslv3 rollback attack"},
 {ERR_REASON(RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD),"the asn1 object identifier is not known for this md"},
 {ERR_REASON(RSA_R_UNKNOWN_ALGORITHM_TYPE),"unknown algorithm type"},
+{ERR_REASON(RSA_R_UNKNOWN_MASK_DIGEST)   ,"unknown mask digest"},
 {ERR_REASON(RSA_R_UNKNOWN_PADDING_TYPE)  ,"unknown padding type"},
+{ERR_REASON(RSA_R_UNKNOWN_PSS_DIGEST)    ,"unknown pss digest"},
+{ERR_REASON(RSA_R_UNSUPPORTED_MASK_ALGORITHM),"unsupported mask algorithm"},
+{ERR_REASON(RSA_R_UNSUPPORTED_MASK_PARAMETER),"unsupported mask parameter"},
+{ERR_REASON(RSA_R_UNSUPPORTED_SIGNATURE_TYPE),"unsupported signature type"},
 {ERR_REASON(RSA_R_VALUE_MISSING)         ,"value missing"},
 {ERR_REASON(RSA_R_WRONG_SIGNATURE_LENGTH),"wrong signature length"},
 {0,NULL}
index 243748c4d3edf92d85359c1d3b0522ece621fe4c..092dd7450d3b0aefab4802daea0572ac85c48e52 100644 (file)
@@ -657,11 +657,15 @@ int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey);
 
 int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki);
 
+int X509_signature_dump(BIO *bp,const ASN1_STRING *sig, int indent);
 int X509_signature_print(BIO *bp,X509_ALGOR *alg, ASN1_STRING *sig);
 
 int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md);
+int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx);
 int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md);
+int X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx);
 int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md);
+int X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx);
 int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md);
 
 int X509_pubkey_digest(const X509 *data,const EVP_MD *type,
@@ -897,6 +901,9 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *algor1,
 int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2,
        ASN1_BIT_STRING *signature,
        void *data, EVP_PKEY *pkey, const EVP_MD *type);
+int ASN1_item_sign_ctx(const ASN1_ITEM *it,
+               X509_ALGOR *algor1, X509_ALGOR *algor2,
+               ASN1_BIT_STRING *signature, void *asn, EVP_MD_CTX *ctx);
 #endif
 
 int            X509_set_version(X509 *x,long version);
index 8ec88c215a4f6c5b79e5a96c27076bb1d333be33..b94aeeb873fddf4408129e2d269bf9111478a508 100644 (file)
@@ -95,12 +95,25 @@ int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md)
                x->sig_alg, x->signature, x->cert_info,pkey,md));
        }
 
+int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx)
+       {
+       return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_CINF),
+               x->cert_info->signature,
+               x->sig_alg, x->signature, x->cert_info, ctx);
+       }
+
 int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md)
        {
        return(ASN1_item_sign(ASN1_ITEM_rptr(X509_REQ_INFO),x->sig_alg, NULL,
                x->signature, x->req_info,pkey,md));
        }
 
+int X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx)
+       {
+       return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_REQ_INFO),
+               x->sig_alg, NULL, x->signature, x->req_info, ctx);
+       }
+
 int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md)
        {
        x->crl->enc.modified = 1;
@@ -108,6 +121,12 @@ int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md)
                x->sig_alg, x->signature, x->crl,pkey,md));
        }
 
+int X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx)
+       {
+       return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_CRL_INFO),
+               x->crl->sig_alg, x->sig_alg, x->signature, x->crl, ctx);
+       }
+
 int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md)
        {
        return(ASN1_item_sign(ASN1_ITEM_rptr(NETSCAPE_SPKAC), x->sig_algor,NULL,