return ret;
}
+static const struct {
+ const char *name;
+ int md_nid;
+ int md_a_must; /* md is a 'MUST' */
+ int noattr_md_nid; /* in case of 'without signed attributes' */
+ int noattr_md_a_must; /* noattr_md is a 'MUST' not a 'SHOULD' */
+} key2data[] = {
+ { "ML-DSA-44", NID_shake256, 0, NID_sha512, 0, },
+ { "ML-DSA-65", NID_shake256, 0, NID_sha512, 0, },
+ { "ML-DSA-87", NID_shake256, 0, NID_sha512, 0, },
+ { "ED25519", NID_sha512, 0, NID_sha512, 1, }, /* RFC 8419 */
+ /* RFC 8419 3.1 ED448: id-shake256-len MUST be used => NID_undef for now */
+ { "ED448", NID_undef, 1, NID_shake256, 1, },
+ { "SLH-DSA-SHA2-128f", NID_sha256, 0, NID_sha256, 0, }, /* RFC 9814 */
+ { "SLH-DSA-SHA2-128s", NID_sha256, 0, NID_sha256, 0, },
+ { "SLH-DSA-SHA2-192f", NID_sha512, 0, NID_sha512, 0, },
+ { "SLH-DSA-SHA2-192s", NID_sha512, 0, NID_sha512, 0, },
+ { "SLH-DSA-SHA2-256f", NID_sha512, 0, NID_sha512, 0, },
+ { "SLH-DSA-SHA2-256s", NID_sha512, 0, NID_sha512, 0, },
+ { "SLH-DSA-SHAKE-128f", NID_shake128, 0, NID_shake128, 0, },
+ { "SLH-DSA-SHAKE-128s", NID_shake128, 0, NID_shake128, 0, },
+ { "SLH-DSA-SHAKE-192f", NID_shake256, 0, NID_shake256, 0, },
+ { "SLH-DSA-SHAKE-192s", NID_shake256, 0, NID_shake256, 0, },
+ { "SLH-DSA-SHAKE-256f", NID_shake256, 0, NID_shake256, 0, },
+ { "SLH-DSA-SHAKE-256s", NID_shake256, 0, NID_shake256, 0, },
+ { NULL, NID_undef, NID_undef, 0, } /* last */
+};
+
+static const EVP_MD *ossl_cms_get_default_md(EVP_PKEY *pk, int *md_a_must)
+{
+ const EVP_MD *md;
+ unsigned int i;
+ int def_nid = NID_undef;
+
+ *md_a_must = 0;
+
+ for (i = 0; key2data[i].name; i++) {
+ if (EVP_PKEY_is_a(pk, key2data[i].name)) {
+ def_nid = key2data[i].md_nid;
+ *md_a_must = key2data[i].md_a_must;
+ break;
+ }
+ }
+
+ if (def_nid == NID_undef &&
+ EVP_PKEY_get_default_digest_nid(pk, &def_nid) <= 0) {
+ ERR_raise_data(ERR_LIB_CMS, CMS_R_NO_DEFAULT_DIGEST,
+ "pkey nid=%d", EVP_PKEY_get_id(pk));
+ return NULL;
+ }
+ md = EVP_get_digestbynid(def_nid);
+ if (md == NULL)
+ ERR_raise_data(ERR_LIB_CMS, CMS_R_NO_DEFAULT_DIGEST,
+ "default md nid=%d", def_nid);
+ return md;
+}
+
+static const EVP_MD *ossl_cms_get_noattr_md(EVP_PKEY *pk, int *noattr_md_a_must)
+{
+ unsigned int i;
+
+ for (i = 0; key2data[i].name; i++) {
+ if (EVP_PKEY_is_a(pk, key2data[i].name)) {
+ *noattr_md_a_must = key2data[i].noattr_md_a_must;
+ return EVP_get_digestbynid(key2data[i].noattr_md_nid);
+ }
+ }
+ return NULL;
+}
+
+static int ossl_cms_adjust_md(EVP_PKEY *pk, const EVP_MD **md, unsigned int flags)
+{
+ const EVP_MD *tmp_md;
+ int md_a_must = 0;
+
+ while ((flags & CMS_NOATTR) != 0) {
+ /*
+ * Some key types require that a certain type of hash is being used in the
+ * case of signed attributes being absent, others have a suggested hash.
+ * In the latter case only use the suggested one if no hash is given.
+ */
+ int noattr_md_a_must = 0;
+
+ tmp_md = ossl_cms_get_noattr_md(pk, &noattr_md_a_must);
+ if (!tmp_md)
+ break; /* key type not listed - use the default */
+
+ if (noattr_md_a_must)
+ *md = tmp_md;
+ else if (*md == NULL)
+ *md = tmp_md;
+ return 1;
+ }
+
+ tmp_md = ossl_cms_get_default_md(pk, &md_a_must);
+ if (md_a_must)
+ *md = tmp_md;
+ else if (*md == NULL)
+ *md = tmp_md;
+
+ if (*md == NULL) /* ED448 case */
+ return 0;
+
+ return 1;
+}
+
CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
X509 *signer, EVP_PKEY *pk, const EVP_MD *md,
unsigned int flags)
if (!ossl_cms_set1_SignerIdentifier(si->sid, signer, type, ctx))
goto err;
- if (md == NULL) {
- int def_nid;
-
- if (EVP_PKEY_get_default_digest_nid(pk, &def_nid) <= 0) {
- ERR_raise_data(ERR_LIB_CMS, CMS_R_NO_DEFAULT_DIGEST,
- "pkey nid=%d", EVP_PKEY_get_id(pk));
- goto err;
- }
- md = EVP_get_digestbynid(def_nid);
- if (md == NULL) {
- ERR_raise_data(ERR_LIB_CMS, CMS_R_NO_DEFAULT_DIGEST,
- "default md nid=%d", def_nid);
- goto err;
- }
- }
+ if (ossl_cms_adjust_md(pk, &md, flags) != 1)
+ goto err;
X509_ALGOR_set_md(si->digestAlgorithm, md);
if (EVP_MD_is_a(md, name))
break;
}
-
if (i == sk_X509_ALGOR_num(sd->digestAlgorithms)) {
if ((alg = X509_ALGOR_new()) == NULL) {
ERR_raise(ERR_LIB_CMS, ERR_R_ASN1_LIB);
goto err;
}
}
-
if (!(flags & CMS_KEY_PARAM) && !cms_sd_asn1_ctrl(si, 0)) {
ERR_raise_data(ERR_LIB_CMS, CMS_R_UNSUPPORTED_SIGNATURE_ALGORITHM,
"pkey nid=%d", EVP_PKEY_get_id(pk));
goto err;
}
}
-
if (!(flags & CMS_NOSMIMECAP)) {
STACK_OF(X509_ALGOR) *smcap = NULL;
goto err;
}
}
-
if (flags & CMS_KEY_PARAM) {
if (flags & CMS_NOATTR) {
si->pctx = EVP_PKEY_CTX_new_from_pkey(ossl_cms_ctx_get0_libctx(ctx),
EVP_MD_CTX_set_flags(si->mctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX);
}
}
-
if (sd->signerInfos == NULL)
sd->signerInfos = sk_CMS_SignerInfo_new_null();
if (sd->signerInfos == NULL || !sk_CMS_SignerInfo_push(sd->signerInfos, si)) {
ERR_raise(ERR_LIB_CMS, ERR_R_CRYPTO_LIB);
goto err;
}
-
return si;
err:
M_ASN1_free_of(si, CMS_SignerInfo);
return NULL;
-
}
void ossl_cms_SignerInfos_set_cmsctx(CMS_ContentInfo *cms)