diff options
author | Dr. Stephen Henson <steve@openssl.org> | 2010-03-11 14:06:46 +0000 |
---|---|---|
committer | Dr. Stephen Henson <steve@openssl.org> | 2010-03-11 14:06:46 +0000 |
commit | 17c63d1cca64c6b099904a3547ecf3a47234b11f (patch) | |
tree | 2e14ac1dd4c6b6311b4229c405862ecca93c074d /crypto | |
parent | 877669d69c747b5aa3573fdcad6bc81f8d6f09ae (diff) |
RSA PSS ASN1 signing method
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/rsa/rsa_ameth.c | 95 | ||||
-rw-r--r-- | crypto/x509/x509.h | 3 |
2 files changed, 94 insertions, 4 deletions
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); |