From 17c63d1cca64c6b099904a3547ecf3a47234b11f Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Thu, 11 Mar 2010 14:06:46 +0000 Subject: [PATCH] RSA PSS ASN1 signing method --- CHANGES | 5 +++ crypto/rsa/rsa_ameth.c | 95 ++++++++++++++++++++++++++++++++++++++++-- crypto/x509/x509.h | 3 ++ 3 files changed, 99 insertions(+), 4 deletions(-) diff --git a/CHANGES b/CHANGES index fad16c1185..2c1fd55605 100644 --- a/CHANGES +++ b/CHANGES @@ -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 diff --git a/crypto/rsa/rsa_ameth.c b/crypto/rsa/rsa_ameth.c index f5c59b2339..dcf4a12585 100644 --- a/crypto/rsa/rsa_ameth.c +++ b/crypto/rsa/rsa_ameth.c @@ -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 }, { diff --git a/crypto/x509/x509.h b/crypto/x509/x509.h index 9090f2ee4b..abd526ec86 100644 --- a/crypto/x509/x509.h +++ b/crypto/x509/x509.h @@ -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); -- 2.25.1