*/
#include "internal/deprecated.h"
+#include "internal/packet.h"
#include "crypto/rsa.h" /* rsa_get0_all_params() */
#include "prov/bio.h" /* ossl_prov_bio_printf() */
+#include "prov/der_rsa.h" /* DER_w_RSASSA_PSS_params() */
#include "prov/implementations.h" /* rsa_keymgmt_functions */
#include "serializer_local.h"
STACK_OF(BIGNUM_const) *factors = sk_BIGNUM_const_new_null();
STACK_OF(BIGNUM_const) *exps = sk_BIGNUM_const_new_null();
STACK_OF(BIGNUM_const) *coeffs = sk_BIGNUM_const_new_null();
+ RSA_PSS_PARAMS_30 *pss_params = rsa_get0_pss_params_30(rsa);
int ret = 0;
if (rsa == NULL || factors == NULL || exps == NULL || coeffs == NULL)
goto err;
}
}
+
+ switch (RSA_test_flags(rsa, RSA_FLAG_TYPE_MASK)) {
+ case RSA_FLAG_TYPE_RSA:
+ if (!rsa_pss_params_30_is_unrestricted(pss_params)) {
+ if (ossl_prov_bio_printf(out, "(INVALID PSS PARAMETERS)\n") <= 0)
+ goto err;
+ }
+ break;
+ case RSA_FLAG_TYPE_RSASSAPSS:
+ if (rsa_pss_params_30_is_unrestricted(pss_params)) {
+ if (ossl_prov_bio_printf(out,
+ "No PSS parameter restrictions\n") <= 0)
+ goto err;
+ } else {
+ int hashalg_nid = rsa_pss_params_30_hashalg(pss_params);
+ int maskgenalg_nid = rsa_pss_params_30_maskgenalg(pss_params);
+ int maskgenhashalg_nid =
+ rsa_pss_params_30_maskgenhashalg(pss_params);
+ int saltlen = rsa_pss_params_30_saltlen(pss_params);
+ int trailerfield = rsa_pss_params_30_trailerfield(pss_params);
+
+ if (ossl_prov_bio_printf(out, "PSS parameter restrictions:\n") <= 0)
+ goto err;
+ if (ossl_prov_bio_printf(out, " Hash Algorithm: %s%s\n",
+ rsa_oaeppss_nid2name(hashalg_nid),
+ (hashalg_nid == NID_sha1
+ ? " (default)" : "")) <= 0)
+ goto err;
+ if (ossl_prov_bio_printf(out, " Mask Algorithm: %s with %s%s\n",
+ rsa_mgf_nid2name(maskgenalg_nid),
+ rsa_oaeppss_nid2name(maskgenhashalg_nid),
+ (maskgenalg_nid == NID_mgf1
+ && maskgenhashalg_nid == NID_sha1
+ ? " (default)" : "")) <= 0)
+ goto err;
+ if (ossl_prov_bio_printf(out, " Minimum Salt Length: %d%s\n",
+ saltlen,
+ (saltlen == 20 ? " (default)" : "")) <= 0)
+ goto err;
+ /*
+ * TODO(3.0) Should we show the ASN.1 trailerField value, or
+ * the actual trailerfield byte (i.e. 0xBC for 1)?
+ * crypto/rsa/rsa_ameth.c isn't very clear on that, as it
+ * does display 0xBC when the default applies, but the ASN.1
+ * trailerField value otherwise...
+ */
+ if (ossl_prov_bio_printf(out, " Trailer Field: 0x%x%s\n",
+ trailerfield,
+ (trailerfield == 1 ? " (default)" : ""))
+ <= 0)
+ goto err;
+ }
+ break;
+ }
+
ret = 1;
err:
sk_BIGNUM_const_free(factors);
sk_BIGNUM_const_free(coeffs);
return ret;
}
+
+/*
+ * Helper functions to prepare RSA-PSS params for serialization. We would
+ * have simply written the whole AlgorithmIdentifier, but existing libcrypto
+ * functionality doesn't allow that.
+ */
+
+int ossl_prov_prepare_rsa_params(const void *rsa, int nid,
+ void **pstr, int *pstrtype)
+{
+ const RSA_PSS_PARAMS_30 *pss = rsa_get0_pss_params_30((RSA *)rsa);
+
+ *pstr = NULL;
+
+ switch (RSA_test_flags(rsa, RSA_FLAG_TYPE_MASK)) {
+ case RSA_FLAG_TYPE_RSA:
+ /* If plain RSA, the parameters shall be NULL */
+ *pstrtype = V_ASN1_NULL;
+ return 1;
+ case RSA_FLAG_TYPE_RSASSAPSS:
+ if (rsa_pss_params_30_is_unrestricted(pss)) {
+ *pstrtype = V_ASN1_UNDEF;
+ } else {
+ ASN1_STRING *astr = NULL;
+ WPACKET pkt;
+ unsigned char *str = NULL;
+ size_t str_sz = 0;
+ int i;
+
+ for (i = 0; i < 2; i++) {
+ switch (i) {
+ case 0:
+ if (!WPACKET_init_null_der(&pkt))
+ goto err;
+ break;
+ case 1:
+ if ((str = OPENSSL_malloc(str_sz)) == NULL
+ || !WPACKET_init_der(&pkt, str, str_sz)) {
+ goto err;
+ }
+ break;
+ }
+ if (!DER_w_RSASSA_PSS_params(&pkt, -1, pss)
+ || !WPACKET_finish(&pkt))
+ goto err;
+ WPACKET_get_total_written(&pkt, &str_sz);
+ WPACKET_cleanup(&pkt);
+
+ /*
+ * If no PSS parameters are going to be written, there's no
+ * point going for another iteration.
+ * This saves us from getting |str| allocated just to have it
+ * immediately de-allocated.
+ */
+ if (str_sz == 0)
+ break;
+ }
+
+ if ((astr = ASN1_STRING_new()) == NULL)
+ goto err;
+ *pstrtype = V_ASN1_SEQUENCE;
+ ASN1_STRING_set0(astr, str, (int)str_sz);
+ *pstr = astr;
+
+ return 1;
+ err:
+ OPENSSL_free(str);
+ return 0;
+ }
+ }
+
+ /* Currently unsupported RSA key type */
+ return 0;
+}
+
+int ossl_prov_rsa_type_to_evp(const RSA *rsa)
+{
+ switch (RSA_test_flags(rsa, RSA_FLAG_TYPE_MASK)) {
+ case RSA_FLAG_TYPE_RSA:
+ return EVP_PKEY_RSA;
+ case RSA_FLAG_TYPE_RSASSAPSS:
+ return EVP_PKEY_RSA_PSS;
+ }
+
+ /* Currently unsupported RSA key type */
+ return EVP_PKEY_NONE;
+}