Commit 9309ea66 authored by Dr. Stephen Henson's avatar Dr. Stephen Henson
Browse files

Backport PSS signature support from HEAD.

parent 05c9e3ae
Loading
Loading
Loading
Loading
+34 −0
Original line number Diff line number Diff line
@@ -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]
+6 −0
Original line number Diff line number Diff line
@@ -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
+44 −20
Original line number Diff line number Diff line
@@ -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);
+82 −4
Original line number Diff line number Diff line
@@ -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)
@@ -859,7 +868,8 @@ loop:
				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;
	}
		
	
+25 −7
Original line number Diff line number Diff line
@@ -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);
Loading