/*
- * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2006-2017 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
return 1;
}
/* Encode PSS parameters */
- if (!ASN1_item_pack(rsa->pss, ASN1_ITEM_rptr(RSA_PSS_PARAMS), pstr)) {
- ASN1_STRING_free(*pstr);
- *pstr = NULL;
+ if (ASN1_item_pack(rsa->pss, ASN1_ITEM_rptr(RSA_PSS_PARAMS), pstr) == NULL)
return 0;
- }
*pstrtype = V_ASN1_SEQUENCE;
return 1;
if (rklen <= 0) {
RSAerr(RSA_F_RSA_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
+ ASN1_STRING_free(str);
return 0;
}
if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(pkey->ameth->pkey_id), 0,
strtype, str, rk, rklen)) {
RSAerr(RSA_F_RSA_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
+ ASN1_STRING_free(str);
return 0;
}
if (pss->hashAlgorithm) {
if (i2a_ASN1_OBJECT(bp, pss->hashAlgorithm->algorithm) <= 0)
goto err;
- } else if (BIO_puts(bp, "sha1 (default)") <= 0)
+ } else if (BIO_puts(bp, "sha1 (default)") <= 0) {
goto err;
+ }
if (BIO_puts(bp, "\n") <= 0)
goto err;
if (maskHash != NULL) {
if (i2a_ASN1_OBJECT(bp, maskHash->algorithm) <= 0)
goto err;
- } else if (BIO_puts(bp, "INVALID") <= 0)
+ } else if (BIO_puts(bp, "INVALID") <= 0) {
goto err;
- } else if (BIO_puts(bp, "mgf1 with sha1 (default)") <= 0)
+ }
+ } else if (BIO_puts(bp, "mgf1 with sha1 (default)") <= 0) {
goto err;
+ }
BIO_puts(bp, "\n");
if (!BIO_indent(bp, indent, 128))
if (pss->saltLength) {
if (i2a_ASN1_INTEGER(bp, pss->saltLength) <= 0)
goto err;
- } else if (BIO_puts(bp, "14 (default)") <= 0)
+ } else if (BIO_puts(bp, "14 (default)") <= 0) {
goto err;
+ }
BIO_puts(bp, "\n");
if (!BIO_indent(bp, indent, 128))
if (pss->trailerField) {
if (i2a_ASN1_INTEGER(bp, pss->trailerField) <= 0)
goto err;
- } else if (BIO_puts(bp, "BC (default)") <= 0)
+ } else if (BIO_puts(bp, "BC (default)") <= 0) {
goto err;
+ }
BIO_puts(bp, "\n");
rv = 1;
if (OBJ_obj2nid(sigalg->algorithm) == EVP_PKEY_RSA_PSS) {
int rv;
RSA_PSS_PARAMS *pss = rsa_pss_decode(sigalg);
+
rv = rsa_pss_param_print(bp, 0, pss, indent);
RSA_PSS_PARAMS_free(pss);
if (!rv)
/* need to embed algorithm ID inside another */
if (!rsa_md_to_algor(&algtmp, mgf1md))
goto err;
- if (!ASN1_item_pack(algtmp, ASN1_ITEM_rptr(X509_ALGOR), &stmp))
+ if (ASN1_item_pack(algtmp, ASN1_ITEM_rptr(X509_ALGOR), &stmp) == NULL)
goto err;
*palg = X509_ALGOR_new();
if (*palg == NULL)
return NULL;
if (!EVP_PKEY_CTX_get_rsa_pss_saltlen(pkctx, &saltlen))
return NULL;
- if (saltlen == -1)
+ if (saltlen == -1) {
saltlen = EVP_MD_size(sigmd);
- else if (saltlen == -2) {
+ } else if (saltlen == -2) {
saltlen = EVP_PKEY_size(pk) - EVP_MD_size(sigmd) - 2;
- if (((EVP_PKEY_bits(pk) - 1) & 0x7) == 0)
+ if ((EVP_PKEY_bits(pk) & 0x7) == 1)
saltlen--;
}
if (!rsa_md_to_algor(&pss->hashAlgorithm, sigmd))
goto err;
if (mgf1md == NULL)
- mgf1md = sigmd;
+ mgf1md = sigmd;
if (!rsa_md_to_mgf1(&pss->maskGenAlgorithm, mgf1md))
goto err;
+ if (!rsa_md_to_algor(&pss->maskHash, mgf1md))
+ goto err;
return pss;
err:
RSA_PSS_PARAMS_free(pss);
static ASN1_STRING *rsa_ctx_to_pss_string(EVP_PKEY_CTX *pkctx)
{
RSA_PSS_PARAMS *pss = rsa_ctx_to_pss(pkctx);
- ASN1_STRING *os = NULL;
+ ASN1_STRING *os;
if (pss == NULL)
return NULL;
- if (!ASN1_item_pack(pss, ASN1_ITEM_rptr(RSA_PSS_PARAMS), &os)) {
- ASN1_STRING_free(os);
- os = NULL;
- }
+ os = ASN1_item_pack(pss, ASN1_ITEM_rptr(RSA_PSS_PARAMS), NULL);
RSA_PSS_PARAMS_free(pss);
return os;
}
RSAerr(RSA_F_RSA_PSS_GET_PARAM, RSA_R_INVALID_SALT_LENGTH);
return 0;
}
- } else
+ } else {
*psaltlen = 20;
+ }
/*
* low-level routines support only trailer field 0xbc (value 1) and
*/
if (pss->trailerField && ASN1_INTEGER_get(pss->trailerField) != 1) {
RSAerr(RSA_F_RSA_PSS_GET_PARAM, RSA_R_INVALID_TRAILER);
- return 0;
+ return 0;
}
return 1;
return 2;
}
+static int rsa_sig_info_set(X509_SIG_INFO *siginf, const X509_ALGOR *sigalg,
+ const ASN1_STRING *sig)
+{
+ int rv = 0;
+ int mdnid, saltlen;
+ uint32_t flags;
+ const EVP_MD *mgf1md = NULL, *md = NULL;
+ RSA_PSS_PARAMS *pss;
+
+ /* Sanity check: make sure it is PSS */
+ if (OBJ_obj2nid(sigalg->algorithm) != EVP_PKEY_RSA_PSS)
+ return 0;
+ /* Decode PSS parameters */
+ pss = rsa_pss_decode(sigalg);
+ if (!rsa_pss_get_param(pss, &md, &mgf1md, &saltlen))
+ goto err;
+ mdnid = EVP_MD_type(md);
+ /*
+ * For TLS need SHA256, SHA384 or SHA512, digest and MGF1 digest must
+ * match and salt length must equal digest size
+ */
+ if ((mdnid == NID_sha256 || mdnid == NID_sha384 || mdnid == NID_sha512)
+ && mdnid == EVP_MD_type(mgf1md) && saltlen == EVP_MD_size(md))
+ flags = X509_SIG_INFO_TLS;
+ else
+ flags = 0;
+ /* Note: security bits half number of digest bits */
+ X509_SIG_INFO_set(siginf, mdnid, EVP_PKEY_RSA_PSS, EVP_MD_size(md) * 4,
+ flags);
+ rv = 1;
+ err:
+ RSA_PSS_PARAMS_free(pss);
+ return rv;
+}
+
#ifndef OPENSSL_NO_CMS
static RSA_OAEP_PARAMS *rsa_oaep_decode(const X509_ALGOR *alg)
{
}
#endif
+static int rsa_pkey_check(const EVP_PKEY *pkey)
+{
+ return RSA_check_key_ex(pkey->pkey.rsa, NULL);
+}
+
const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[2] = {
{
EVP_PKEY_RSA,
old_rsa_priv_decode,
old_rsa_priv_encode,
rsa_item_verify,
- rsa_item_sign},
+ rsa_item_sign,
+ rsa_sig_info_set,
+ rsa_pkey_check
+ },
{
EVP_PKEY_RSA2,
0, 0,
rsa_item_verify,
rsa_item_sign,
+ 0,
+ rsa_pkey_check
};