Commit 17c63d1c authored by Dr. Stephen Henson's avatar Dr. Stephen Henson
Browse files

RSA PSS ASN1 signing method

parent 877669d6
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -4,6 +4,11 @@

 Changes between 1.0.0 and 1.1.0  [xx XXX xxxx]

  *) Add RSA PSS signing function. This will generated 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
+91 −4
Original line number Diff line number Diff line
@@ -535,13 +535,13 @@ static int rsa_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
	if (!EVP_DigestVerifyInit(ctx, &pkctx, md, NULL, pkey))
		goto err;

	if (!EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_PSS_PADDING))
	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))
	if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkctx, saltlen) <= 0)
		goto err;

	if (!EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md))
	if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md) <= 0)
		goto err;
	/* Carry on */
	rv = 2;
@@ -553,6 +553,92 @@ static int rsa_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
	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;
		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;
		os2 = ASN1_STRING_dup(os1);
		if (!os2)
			goto err;
		X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_rsassaPss),
					V_ASN1_SEQUENCE, os1);
		X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_rsassaPss),
					V_ASN1_SEQUENCE, os2);
		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[] = 
	{
		{
@@ -582,7 +668,8 @@ const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[] =
		rsa_pkey_ctrl,
		old_rsa_priv_decode,
		old_rsa_priv_encode,
		rsa_item_verify
		rsa_item_verify,
		rsa_item_sign
		},

		{
+3 −0
Original line number Diff line number Diff line
@@ -897,6 +897,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(EVP_MD_CTX *ctx,
		const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2,
	     	ASN1_BIT_STRING *signature, void *asn);
#endif

int 		X509_set_version(X509 *x,long version);