[openssl] master update
Matt Caswell
matt at openssl.org
Thu Oct 15 09:09:34 UTC 2020
The branch master has been updated
via 29000e43ea257bf54f6ccb2064b3744853b821b2 (commit)
via 0d30e15a57fdd9c27a9148c17289a1005345f0c7 (commit)
via 7022d9b9032794330cd2d753f077670db95d33d4 (commit)
via 9ab7fe483629704b09dc43c1998e0e489615390f (commit)
via 0b3a4ef27a6c2a427dc2d4a87c52677d57c90f4c (commit)
via 99b3b762c33fad9383cb2d1791be9c9f7d44710a (commit)
from 5b70206cb316024c6dc30ce54f585ce5cf001a56 (commit)
- Log -----------------------------------------------------------------
commit 29000e43ea257bf54f6ccb2064b3744853b821b2
Author: Matt Caswell <matt at openssl.org>
Date: Mon Oct 12 17:12:03 2020 +0100
Make evp_pkey_ctx_get0_libctx/propq public API
These were previously added as an internal API. But since the CMS code
needs them, other code might do too.
Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
(Merged from https://github.com/openssl/openssl/pull/13088)
commit 0d30e15a57fdd9c27a9148c17289a1005345f0c7
Author: Matt Caswell <matt at openssl.org>
Date: Tue Oct 6 17:02:45 2020 +0100
Remove some more CMS key downgrades
Fixes #12983
Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
(Merged from https://github.com/openssl/openssl/pull/13088)
commit 7022d9b9032794330cd2d753f077670db95d33d4
Author: Matt Caswell <matt at openssl.org>
Date: Wed Oct 7 15:59:28 2020 +0100
Remove CMS recipient info information out of the algorithm implementations
Low level algorithm implementations have no business knowing about details
of the higher level CMS concept. This knowledge is therefore moved into the
CMS layer.
Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
(Merged from https://github.com/openssl/openssl/pull/13088)
commit 9ab7fe483629704b09dc43c1998e0e489615390f
Author: Matt Caswell <matt at openssl.org>
Date: Wed Oct 7 14:45:22 2020 +0100
Move CMS signing code out of the algorithms and into CMS
There is a large amount of CMS sepcific code in the algorithms. This is in
the wrong place and breaks layering. This code should be in the CMS layer.
Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
(Merged from https://github.com/openssl/openssl/pull/13088)
commit 0b3a4ef27a6c2a427dc2d4a87c52677d57c90f4c
Author: Matt Caswell <matt at openssl.org>
Date: Tue Oct 6 16:02:43 2020 +0100
Move CMS enveloping code out of the algorithms and into CMS
There is quite a large amount of algorithm specific CMS code sitting in
the algorithm directories. However, this seems to break layering.
Algorithms really have no business knowing anything about CMS. Really it
should be the other way around. Where there is algorithm specific CMS code
it is the CMS layer that should know how to handle different algorithms.
Therefore we move this code into the CMS layer.
Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
(Merged from https://github.com/openssl/openssl/pull/13088)
commit 99b3b762c33fad9383cb2d1791be9c9f7d44710a
Author: Matt Caswell <matt at openssl.org>
Date: Fri Oct 2 11:25:25 2020 +0100
Remove a CMS key downgrade
We were downgrading a key in the CMS code. This is no longer necessary.
Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
(Merged from https://github.com/openssl/openssl/pull/13088)
-----------------------------------------------------------------------
Summary of changes:
apps/cms.c | 14 --
crypto/asn1/asn1_err.c | 1 +
crypto/asn1/x_algor.c | 63 +++++
crypto/cms/build.info | 9 +-
crypto/cms/cms_dh.c | 320 ++++++++++++++++++++++++++
crypto/cms/cms_ec.c | 419 ++++++++++++++++++++++++++++++++++
crypto/cms/cms_env.c | 29 +++
crypto/cms/cms_err.c | 12 +
crypto/cms/cms_kari.c | 46 ----
crypto/cms/cms_local.h | 6 +
crypto/cms/cms_rsa.c | 253 ++++++++++++++++++++
crypto/cms/cms_sd.c | 9 +
crypto/dh/dh_ameth.c | 334 +--------------------------
crypto/dsa/dsa_ameth.c | 22 --
crypto/ec/ec_ameth.c | 358 -----------------------------
crypto/err/openssl.txt | 9 +
crypto/evp/pmeth_lib.c | 10 +
crypto/rsa/rsa_ameth.c | 338 ++-------------------------
doc/man3/EVP_PKEY_CTX_get0_libctx.pod | 45 ++++
include/crypto/asn1.h | 5 +
include/crypto/rsa.h | 4 +
include/openssl/asn1err.h | 1 +
include/openssl/cmserr.h | 8 +
include/openssl/evp.h | 3 +
util/libcrypto.num | 2 +
25 files changed, 1228 insertions(+), 1092 deletions(-)
create mode 100644 crypto/cms/cms_dh.c
create mode 100644 crypto/cms/cms_ec.c
create mode 100644 crypto/cms/cms_rsa.c
create mode 100644 doc/man3/EVP_PKEY_CTX_get0_libctx.pod
diff --git a/apps/cms.c b/apps/cms.c
index 91d951980d..37b1e96a14 100644
--- a/apps/cms.c
+++ b/apps/cms.c
@@ -862,13 +862,6 @@ int cms_main(int argc, char **argv)
key = load_key(keyfile, keyform, 0, passin, e, "signing key");
if (key == NULL)
goto end;
-
- /*
- * TODO: Remove this when CMS has full support for provider-native
- * EVP_PKEYs
- */
- if (EVP_PKEY_get0(key) == NULL)
- goto end;
}
in = bio_open_default(infile, 'r', informat);
@@ -1067,13 +1060,6 @@ int cms_main(int argc, char **argv)
goto end;
}
- /*
- * TODO: Remove this when CMS has full support for provider-native
- * EVP_PKEYs
- */
- if (EVP_PKEY_get0(key) == NULL)
- goto end;
-
for (kparam = key_first; kparam; kparam = kparam->next) {
if (kparam->idx == i) {
tflags |= CMS_KEY_PARAM;
diff --git a/crypto/asn1/asn1_err.c b/crypto/asn1/asn1_err.c
index 6a599bc067..814cd91373 100644
--- a/crypto/asn1/asn1_err.c
+++ b/crypto/asn1/asn1_err.c
@@ -171,6 +171,7 @@ static const ERR_STRING_DATA ASN1_str_reasons[] = {
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_UNEXPECTED_EOC), "unexpected eoc"},
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH),
"universalstring is wrong length"},
+ {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_UNKNOWN_DIGEST), "unknown digest"},
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_UNKNOWN_FORMAT), "unknown format"},
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM),
"unknown message digest algorithm"},
diff --git a/crypto/asn1/x_algor.c b/crypto/asn1/x_algor.c
index f29d26d91c..7e198a558c 100644
--- a/crypto/asn1/x_algor.c
+++ b/crypto/asn1/x_algor.c
@@ -11,6 +11,8 @@
#include <openssl/x509.h>
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
+#include <openssl/err.h>
+#include "crypto/asn1.h"
#include "crypto/evp.h"
ASN1_SEQUENCE(X509_ALGOR) = {
@@ -125,3 +127,64 @@ int X509_ALGOR_copy(X509_ALGOR *dest, const X509_ALGOR *src)
return 1;
}
+
+/* allocate and set algorithm ID from EVP_MD, default SHA1 */
+int x509_algor_new_from_md(X509_ALGOR **palg, const EVP_MD *md)
+{
+ /* Default is SHA1 so no need to create it - still success */
+ if (md == NULL || EVP_MD_is_a(md, "SHA1"))
+ return 1;
+ *palg = X509_ALGOR_new();
+ if (*palg == NULL)
+ return 0;
+ X509_ALGOR_set_md(*palg, md);
+ return 1;
+}
+
+/* convert algorithm ID to EVP_MD, default SHA1 */
+const EVP_MD *x509_algor_get_md(X509_ALGOR *alg)
+{
+ const EVP_MD *md;
+
+ if (alg == NULL)
+ return EVP_sha1();
+ md = EVP_get_digestbyobj(alg->algorithm);
+ if (md == NULL)
+ ASN1err(0, ASN1_R_UNKNOWN_DIGEST);
+ return md;
+}
+
+X509_ALGOR *x509_algor_mgf1_decode(X509_ALGOR *alg)
+{
+ if (OBJ_obj2nid(alg->algorithm) != NID_mgf1)
+ return NULL;
+ return ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(X509_ALGOR),
+ alg->parameter);
+}
+
+/* Allocate and set MGF1 algorithm ID from EVP_MD */
+int x509_algor_md_to_mgf1(X509_ALGOR **palg, const EVP_MD *mgf1md)
+{
+ X509_ALGOR *algtmp = NULL;
+ ASN1_STRING *stmp = NULL;
+
+ *palg = NULL;
+ if (mgf1md == NULL || EVP_MD_is_a(mgf1md, "SHA1"))
+ return 1;
+ /* need to embed algorithm ID inside another */
+ if (!x509_algor_new_from_md(&algtmp, mgf1md))
+ goto err;
+ if (ASN1_item_pack(algtmp, ASN1_ITEM_rptr(X509_ALGOR), &stmp) == NULL)
+ goto err;
+ *palg = X509_ALGOR_new();
+ if (*palg == NULL)
+ goto err;
+ X509_ALGOR_set0(*palg, OBJ_nid2obj(NID_mgf1), V_ASN1_SEQUENCE, stmp);
+ stmp = NULL;
+ err:
+ ASN1_STRING_free(stmp);
+ X509_ALGOR_free(algtmp);
+ if (*palg != NULL)
+ return 1;
+ return 0;
+}
diff --git a/crypto/cms/build.info b/crypto/cms/build.info
index cb675436ef..c7579f78c1 100644
--- a/crypto/cms/build.info
+++ b/crypto/cms/build.info
@@ -2,4 +2,11 @@ LIBS=../../libcrypto
SOURCE[../../libcrypto]= \
cms_lib.c cms_asn1.c cms_att.c cms_io.c cms_smime.c cms_err.c \
cms_sd.c cms_dd.c cms_cd.c cms_env.c cms_enc.c cms_ess.c \
- cms_pwri.c cms_kari.c
+ cms_pwri.c cms_kari.c cms_rsa.c
+
+IF[{- !$disabled{dh} -}]
+ SOURCE[../../libcrypto]=cms_dh.c
+ENDIF
+IF[{- !$disabled{ec} || !$disabled{dsa}-}]
+ SOURCE[../../libcrypto]=cms_ec.c
+ENDIF
diff --git a/crypto/cms/cms_dh.c b/crypto/cms/cms_dh.c
new file mode 100644
index 0000000000..0d9eac50b3
--- /dev/null
+++ b/crypto/cms/cms_dh.c
@@ -0,0 +1,320 @@
+/*
+ * Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <assert.h>
+#include <openssl/cms.h>
+#include <openssl/dh.h>
+#include <openssl/err.h>
+#include <openssl/core_names.h>
+#include "cms_local.h"
+
+static int dh_cms_set_peerkey(EVP_PKEY_CTX *pctx,
+ X509_ALGOR *alg, ASN1_BIT_STRING *pubkey)
+{
+ const ASN1_OBJECT *aoid;
+ int atype;
+ const void *aval;
+ ASN1_INTEGER *public_key = NULL;
+ int rv = 0;
+ EVP_PKEY *pkpeer = NULL, *pk = NULL;
+ const unsigned char *p;
+ int plen;
+
+ X509_ALGOR_get0(&aoid, &atype, &aval, alg);
+ if (OBJ_obj2nid(aoid) != NID_dhpublicnumber)
+ goto err;
+ /* Only absent parameters allowed in RFC XXXX */
+ if (atype != V_ASN1_UNDEF && atype == V_ASN1_NULL)
+ goto err;
+
+ pk = EVP_PKEY_CTX_get0_pkey(pctx);
+ if (pk == NULL || !EVP_PKEY_is_a(pk, "DHX"))
+ goto err;
+
+ /* Get public key */
+ plen = ASN1_STRING_length(pubkey);
+ p = ASN1_STRING_get0_data(pubkey);
+ if (p == NULL || plen == 0)
+ goto err;
+
+ pkpeer = EVP_PKEY_new();
+ if (pkpeer == NULL
+ || !EVP_PKEY_copy_parameters(pkpeer, pk)
+ /*
+ * TODO(3.0): This is badly named!! Can we make this more
+ * generic and not TLS specific?
+ */
+ || !EVP_PKEY_set1_tls_encodedpoint(pkpeer, p, plen))
+ goto err;
+
+ if (EVP_PKEY_derive_set_peer(pctx, pkpeer) > 0)
+ rv = 1;
+ err:
+ ASN1_INTEGER_free(public_key);
+ EVP_PKEY_free(pkpeer);
+ return rv;
+}
+
+static int dh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri)
+{
+ int rv = 0;
+ X509_ALGOR *alg, *kekalg = NULL;
+ ASN1_OCTET_STRING *ukm;
+ const unsigned char *p;
+ unsigned char *dukm = NULL;
+ size_t dukmlen = 0;
+ int keylen, plen;
+ const EVP_CIPHER *kekcipher;
+ EVP_CIPHER_CTX *kekctx;
+
+ if (!CMS_RecipientInfo_kari_get0_alg(ri, &alg, &ukm))
+ goto err;
+
+ /*
+ * For DH we only have one OID permissible. If ever any more get defined
+ * we will need something cleverer.
+ */
+ if (OBJ_obj2nid(alg->algorithm) != NID_id_smime_alg_ESDH) {
+ CMSerr(0, CMS_R_KDF_PARAMETER_ERROR);
+ goto err;
+ }
+
+ if (EVP_PKEY_CTX_set_dh_kdf_type(pctx, EVP_PKEY_DH_KDF_X9_42) <= 0
+ || EVP_PKEY_CTX_set_dh_kdf_md(pctx, EVP_sha1()) <= 0)
+ goto err;
+
+ if (alg->parameter->type != V_ASN1_SEQUENCE)
+ goto err;
+
+ p = alg->parameter->value.sequence->data;
+ plen = alg->parameter->value.sequence->length;
+ kekalg = d2i_X509_ALGOR(NULL, &p, plen);
+ if (kekalg == NULL)
+ goto err;
+ kekctx = CMS_RecipientInfo_kari_get0_ctx(ri);
+ if (kekctx == NULL)
+ goto err;
+ kekcipher = EVP_get_cipherbyobj(kekalg->algorithm);
+ if (kekcipher == NULL || EVP_CIPHER_mode(kekcipher) != EVP_CIPH_WRAP_MODE)
+ goto err;
+ if (!EVP_EncryptInit_ex(kekctx, kekcipher, NULL, NULL, NULL))
+ goto err;
+ if (EVP_CIPHER_asn1_to_param(kekctx, kekalg->parameter) <= 0)
+ goto err;
+
+ keylen = EVP_CIPHER_CTX_key_length(kekctx);
+ if (EVP_PKEY_CTX_set_dh_kdf_outlen(pctx, keylen) <= 0)
+ goto err;
+ /* Use OBJ_nid2obj to ensure we use built in OID that isn't freed */
+ if (EVP_PKEY_CTX_set0_dh_kdf_oid(pctx,
+ OBJ_nid2obj(EVP_CIPHER_type(kekcipher)))
+ <= 0)
+ goto err;
+
+ if (ukm != NULL) {
+ dukmlen = ASN1_STRING_length(ukm);
+ dukm = OPENSSL_memdup(ASN1_STRING_get0_data(ukm), dukmlen);
+ if (dukm == NULL)
+ goto err;
+ }
+
+ if (EVP_PKEY_CTX_set0_dh_kdf_ukm(pctx, dukm, dukmlen) <= 0)
+ goto err;
+ dukm = NULL;
+
+ rv = 1;
+ err:
+ X509_ALGOR_free(kekalg);
+ OPENSSL_free(dukm);
+ return rv;
+}
+
+static int dh_cms_decrypt(CMS_RecipientInfo *ri)
+{
+ EVP_PKEY_CTX *pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
+
+ if (pctx == NULL)
+ return 0;
+ /* See if we need to set peer key */
+ if (!EVP_PKEY_CTX_get0_peerkey(pctx)) {
+ X509_ALGOR *alg;
+ ASN1_BIT_STRING *pubkey;
+
+ if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &alg, &pubkey,
+ NULL, NULL, NULL))
+ return 0;
+ if (alg == NULL || pubkey == NULL)
+ return 0;
+ if (!dh_cms_set_peerkey(pctx, alg, pubkey)) {
+ DHerr(DH_F_DH_CMS_DECRYPT, DH_R_PEER_KEY_ERROR);
+ return 0;
+ }
+ }
+ /* Set DH derivation parameters and initialise unwrap context */
+ if (!dh_cms_set_shared_info(pctx, ri)) {
+ DHerr(DH_F_DH_CMS_DECRYPT, DH_R_SHARED_INFO_ERROR);
+ return 0;
+ }
+ return 1;
+}
+
+static int dh_cms_encrypt(CMS_RecipientInfo *ri)
+{
+ EVP_PKEY_CTX *pctx;
+ EVP_PKEY *pkey;
+ EVP_CIPHER_CTX *ctx;
+ int keylen;
+ X509_ALGOR *talg, *wrap_alg = NULL;
+ const ASN1_OBJECT *aoid;
+ ASN1_BIT_STRING *pubkey;
+ ASN1_STRING *wrap_str;
+ ASN1_OCTET_STRING *ukm;
+ unsigned char *penc = NULL, *dukm = NULL;
+ int penclen;
+ size_t dukmlen = 0;
+ int rv = 0;
+ int kdf_type, wrap_nid;
+ const EVP_MD *kdf_md;
+
+ pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
+ if (pctx == NULL)
+ return 0;
+ /* Get ephemeral key */
+ pkey = EVP_PKEY_CTX_get0_pkey(pctx);
+ if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &talg, &pubkey,
+ NULL, NULL, NULL))
+ goto err;
+
+ /* Is everything uninitialised? */
+ X509_ALGOR_get0(&aoid, NULL, NULL, talg);
+ if (aoid == OBJ_nid2obj(NID_undef)) {
+ BIGNUM *bn_pub_key = NULL;
+ ASN1_INTEGER *pubk;
+
+ if (!EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PUB_KEY, &bn_pub_key))
+ goto err;
+
+ pubk = BN_to_ASN1_INTEGER(bn_pub_key, NULL);
+ BN_free(bn_pub_key);
+ if (pubk == NULL)
+ goto err;
+
+ /* Set the key */
+ penclen = i2d_ASN1_INTEGER(pubk, &penc);
+ ASN1_INTEGER_free(pubk);
+ if (penclen <= 0)
+ goto err;
+ ASN1_STRING_set0(pubkey, penc, penclen);
+ pubkey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
+ pubkey->flags |= ASN1_STRING_FLAG_BITS_LEFT;
+
+ penc = NULL;
+ X509_ALGOR_set0(talg, OBJ_nid2obj(NID_dhpublicnumber),
+ V_ASN1_UNDEF, NULL);
+ }
+
+ /* See if custom parameters set */
+ kdf_type = EVP_PKEY_CTX_get_dh_kdf_type(pctx);
+ if (kdf_type <= 0 || !EVP_PKEY_CTX_get_dh_kdf_md(pctx, &kdf_md))
+ goto err;
+
+ if (kdf_type == EVP_PKEY_DH_KDF_NONE) {
+ kdf_type = EVP_PKEY_DH_KDF_X9_42;
+ if (EVP_PKEY_CTX_set_dh_kdf_type(pctx, kdf_type) <= 0)
+ goto err;
+ } else if (kdf_type != EVP_PKEY_DH_KDF_X9_42)
+ /* Unknown KDF */
+ goto err;
+ if (kdf_md == NULL) {
+ /* Only SHA1 supported */
+ kdf_md = EVP_sha1();
+ if (EVP_PKEY_CTX_set_dh_kdf_md(pctx, kdf_md) <= 0)
+ goto err;
+ } else if (EVP_MD_type(kdf_md) != NID_sha1)
+ /* Unsupported digest */
+ goto err;
+
+ if (!CMS_RecipientInfo_kari_get0_alg(ri, &talg, &ukm))
+ goto err;
+
+ /* Get wrap NID */
+ ctx = CMS_RecipientInfo_kari_get0_ctx(ri);
+ wrap_nid = EVP_CIPHER_CTX_type(ctx);
+ if (EVP_PKEY_CTX_set0_dh_kdf_oid(pctx, OBJ_nid2obj(wrap_nid)) <= 0)
+ goto err;
+ keylen = EVP_CIPHER_CTX_key_length(ctx);
+
+ /* Package wrap algorithm in an AlgorithmIdentifier */
+
+ wrap_alg = X509_ALGOR_new();
+ if (wrap_alg == NULL)
+ goto err;
+ wrap_alg->algorithm = OBJ_nid2obj(wrap_nid);
+ wrap_alg->parameter = ASN1_TYPE_new();
+ if (wrap_alg->parameter == NULL)
+ goto err;
+ if (EVP_CIPHER_param_to_asn1(ctx, wrap_alg->parameter) <= 0)
+ goto err;
+ if (ASN1_TYPE_get(wrap_alg->parameter) == NID_undef) {
+ ASN1_TYPE_free(wrap_alg->parameter);
+ wrap_alg->parameter = NULL;
+ }
+
+ if (EVP_PKEY_CTX_set_dh_kdf_outlen(pctx, keylen) <= 0)
+ goto err;
+
+ if (ukm != NULL) {
+ dukmlen = ASN1_STRING_length(ukm);
+ dukm = OPENSSL_memdup(ASN1_STRING_get0_data(ukm), dukmlen);
+ if (dukm == NULL)
+ goto err;
+ }
+
+ if (EVP_PKEY_CTX_set0_dh_kdf_ukm(pctx, dukm, dukmlen) <= 0)
+ goto err;
+ dukm = NULL;
+
+ /*
+ * Now need to wrap encoding of wrap AlgorithmIdentifier into parameter
+ * of another AlgorithmIdentifier.
+ */
+ penc = NULL;
+ penclen = i2d_X509_ALGOR(wrap_alg, &penc);
+ if (penc == NULL || penclen == 0)
+ goto err;
+ wrap_str = ASN1_STRING_new();
+ if (wrap_str == NULL)
+ goto err;
+ ASN1_STRING_set0(wrap_str, penc, penclen);
+ penc = NULL;
+ X509_ALGOR_set0(talg, OBJ_nid2obj(NID_id_smime_alg_ESDH),
+ V_ASN1_SEQUENCE, wrap_str);
+
+ rv = 1;
+
+ err:
+ OPENSSL_free(penc);
+ X509_ALGOR_free(wrap_alg);
+ OPENSSL_free(dukm);
+ return rv;
+}
+
+int cms_dh_envelope(CMS_RecipientInfo *ri, int decrypt)
+{
+ assert(decrypt == 0 || decrypt == 1);
+
+ if (decrypt == 1)
+ return dh_cms_decrypt(ri);
+
+ if (decrypt == 0)
+ return dh_cms_encrypt(ri);
+
+ CMSerr(0, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
+ return 0;
+}
diff --git a/crypto/cms/cms_ec.c b/crypto/cms/cms_ec.c
new file mode 100644
index 0000000000..ca2294ebc3
--- /dev/null
+++ b/crypto/cms/cms_ec.c
@@ -0,0 +1,419 @@
+/*
+ * Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <assert.h>
+#include <openssl/cms.h>
+#include <openssl/err.h>
+#include <openssl/decoder.h>
+#include "cms_local.h"
+#include "crypto/evp.h"
+
+#ifndef OPENSSL_NO_EC
+static EVP_PKEY *pkey_type2param(int ptype, const void *pval,
+ OPENSSL_CTX *libctx, const char *propq)
+{
+ EVP_PKEY *pkey = NULL;
+ EVP_PKEY_CTX *pctx = NULL;
+
+ if (ptype == V_ASN1_SEQUENCE) {
+ const ASN1_STRING *pstr = pval;
+ const unsigned char *pm = pstr->data;
+ int pmlen = pstr->length;
+ OSSL_DECODER_CTX *ctx = NULL;
+ BIO *membio = NULL;
+
+ /* TODO(3.0): Need to be able to specify here that only params will do */
+ ctx = OSSL_DECODER_CTX_new_by_EVP_PKEY(&pkey, "DER", "EC", libctx,
+ propq);
+ if (ctx == NULL)
+ goto err;
+
+ membio = BIO_new_mem_buf(pm, pmlen);
+ if (membio == NULL) {
+ OSSL_DECODER_CTX_free(ctx);
+ goto err;
+ }
+ OSSL_DECODER_from_bio(ctx, membio);
+ BIO_free(membio);
+ OSSL_DECODER_CTX_free(ctx);
+ } else if (ptype == V_ASN1_OBJECT) {
+ const ASN1_OBJECT *poid = pval;
+ const char *groupname;
+
+ /* type == V_ASN1_OBJECT => the parameters are given by an asn1 OID */
+ pctx = EVP_PKEY_CTX_new_from_name(libctx, "EC", propq);
+ if (pctx == NULL || EVP_PKEY_paramgen_init(pctx) <= 0)
+ goto err;
+ groupname = OBJ_nid2sn(OBJ_obj2nid(poid));
+ if (groupname == NULL
+ || !EVP_PKEY_CTX_set_group_name(pctx, groupname)) {
+ CMSerr(0, CMS_R_DECODE_ERROR);
+ goto err;
+ }
+ if (EVP_PKEY_paramgen(pctx, &pkey) <= 0)
+ goto err;
+ } else {
+ CMSerr(0, CMS_R_DECODE_ERROR);
+ goto err;
+ }
+
+ return pkey;
+
+ err:
+ EVP_PKEY_free(pkey);
+ EVP_PKEY_CTX_free(pctx);
+ return NULL;
+}
+
+static int ecdh_cms_set_peerkey(EVP_PKEY_CTX *pctx,
+ X509_ALGOR *alg, ASN1_BIT_STRING *pubkey)
+{
+ const ASN1_OBJECT *aoid;
+ int atype;
+ const void *aval;
+ int rv = 0;
+ EVP_PKEY *pkpeer = NULL;
+ const unsigned char *p;
+ int plen;
+
+ X509_ALGOR_get0(&aoid, &atype, &aval, alg);
+ if (OBJ_obj2nid(aoid) != NID_X9_62_id_ecPublicKey)
+ goto err;
+
+ /* If absent parameters get group from main key */
+ if (atype == V_ASN1_UNDEF || atype == V_ASN1_NULL) {
+ EVP_PKEY *pk;
+
+ pk = EVP_PKEY_CTX_get0_pkey(pctx);
+ if (pk == NULL)
+ goto err;
+
+ pkpeer = EVP_PKEY_new();
+ if (pkpeer == NULL)
+ goto err;
+ if (!EVP_PKEY_copy_parameters(pkpeer, pk))
+ goto err;
+ } else {
+ pkpeer = pkey_type2param(atype, aval,
+ EVP_PKEY_CTX_get0_libctx(pctx),
+ EVP_PKEY_CTX_get0_propq(pctx));
+ if (pkpeer == NULL)
+ goto err;
+ }
+ /* We have parameters now set public key */
+ plen = ASN1_STRING_length(pubkey);
+ p = ASN1_STRING_get0_data(pubkey);
+ if (p == NULL || plen == 0)
+ goto err;
+
+ /* TODO(3.0): Terrible name. We need a non-tls specific name */
+ if (!EVP_PKEY_set1_tls_encodedpoint(pkpeer, p, plen))
+ goto err;
+
+ if (EVP_PKEY_derive_set_peer(pctx, pkpeer) > 0)
+ rv = 1;
+ err:
+ EVP_PKEY_free(pkpeer);
+ return rv;
+}
+
+/* Set KDF parameters based on KDF NID */
+static int ecdh_cms_set_kdf_param(EVP_PKEY_CTX *pctx, int eckdf_nid)
+{
+ int kdf_nid, kdfmd_nid, cofactor;
+ const EVP_MD *kdf_md;
+
+ if (eckdf_nid == NID_undef)
+ return 0;
+
+ /* Lookup KDF type, cofactor mode and digest */
+ if (!OBJ_find_sigid_algs(eckdf_nid, &kdfmd_nid, &kdf_nid))
+ return 0;
+
+ if (kdf_nid == NID_dh_std_kdf)
+ cofactor = 0;
+ else if (kdf_nid == NID_dh_cofactor_kdf)
+ cofactor = 1;
+ else
+ return 0;
+
+ if (EVP_PKEY_CTX_set_ecdh_cofactor_mode(pctx, cofactor) <= 0)
+ return 0;
+
+ if (EVP_PKEY_CTX_set_ecdh_kdf_type(pctx, EVP_PKEY_ECDH_KDF_X9_63) <= 0)
+ return 0;
+
+ kdf_md = EVP_get_digestbynid(kdfmd_nid);
+ if (!kdf_md)
+ return 0;
+
+ if (EVP_PKEY_CTX_set_ecdh_kdf_md(pctx, kdf_md) <= 0)
+ return 0;
+ return 1;
+}
+
+static int ecdh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri)
+{
+ int rv = 0;
+ X509_ALGOR *alg, *kekalg = NULL;
+ ASN1_OCTET_STRING *ukm;
+ const unsigned char *p;
+ unsigned char *der = NULL;
+ int plen, keylen;
+ EVP_CIPHER *kekcipher = NULL;
+ EVP_CIPHER_CTX *kekctx;
+ const char *name;
+
+ if (!CMS_RecipientInfo_kari_get0_alg(ri, &alg, &ukm))
+ return 0;
+
+ if (!ecdh_cms_set_kdf_param(pctx, OBJ_obj2nid(alg->algorithm))) {
+ CMSerr(0, CMS_R_KDF_PARAMETER_ERROR);
+ return 0;
+ }
+
+ if (alg->parameter->type != V_ASN1_SEQUENCE)
+ return 0;
+
+ p = alg->parameter->value.sequence->data;
+ plen = alg->parameter->value.sequence->length;
+ kekalg = d2i_X509_ALGOR(NULL, &p, plen);
+ if (kekalg == NULL)
+ goto err;
+ kekctx = CMS_RecipientInfo_kari_get0_ctx(ri);
+ if (kekctx == NULL)
+ goto err;
+ name = OBJ_nid2sn(OBJ_obj2nid(kekalg->algorithm));
+ kekcipher = EVP_CIPHER_fetch(pctx->libctx, name, pctx->propquery);
+ if (kekcipher == NULL || EVP_CIPHER_mode(kekcipher) != EVP_CIPH_WRAP_MODE)
+ goto err;
+ if (!EVP_EncryptInit_ex(kekctx, kekcipher, NULL, NULL, NULL))
+ goto err;
+ if (EVP_CIPHER_asn1_to_param(kekctx, kekalg->parameter) <= 0)
+ goto err;
+
+ keylen = EVP_CIPHER_CTX_key_length(kekctx);
+ if (EVP_PKEY_CTX_set_ecdh_kdf_outlen(pctx, keylen) <= 0)
+ goto err;
+
+ plen = CMS_SharedInfo_encode(&der, kekalg, ukm, keylen);
+
+ if (plen <= 0)
+ goto err;
+
+ if (EVP_PKEY_CTX_set0_ecdh_kdf_ukm(pctx, der, plen) <= 0)
+ goto err;
+ der = NULL;
+
+ rv = 1;
+ err:
+ EVP_CIPHER_free(kekcipher);
+ X509_ALGOR_free(kekalg);
+ OPENSSL_free(der);
+ return rv;
+}
+
+static int ecdh_cms_decrypt(CMS_RecipientInfo *ri)
+{
+ EVP_PKEY_CTX *pctx;
+
+ pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
+ if (pctx == NULL)
+ return 0;
+ /* See if we need to set peer key */
+ if (!EVP_PKEY_CTX_get0_peerkey(pctx)) {
+ X509_ALGOR *alg;
+ ASN1_BIT_STRING *pubkey;
+
+ if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &alg, &pubkey,
+ NULL, NULL, NULL))
+ return 0;
+ if (alg == NULL || pubkey == NULL)
+ return 0;
+ if (!ecdh_cms_set_peerkey(pctx, alg, pubkey)) {
+ CMSerr(0, CMS_R_PEER_KEY_ERROR);
+ return 0;
+ }
+ }
+ /* Set ECDH derivation parameters and initialise unwrap context */
+ if (!ecdh_cms_set_shared_info(pctx, ri)) {
+ CMSerr(0, CMS_R_SHARED_INFO_ERROR);
+ return 0;
+ }
+ return 1;
+}
+
+static int ecdh_cms_encrypt(CMS_RecipientInfo *ri)
+{
+ EVP_PKEY_CTX *pctx;
+ EVP_PKEY *pkey;
+ EVP_CIPHER_CTX *ctx;
+ int keylen;
+ X509_ALGOR *talg, *wrap_alg = NULL;
+ const ASN1_OBJECT *aoid;
+ ASN1_BIT_STRING *pubkey;
+ ASN1_STRING *wrap_str;
+ ASN1_OCTET_STRING *ukm;
+ unsigned char *penc = NULL;
+ size_t penclen;
+ int rv = 0;
+ int ecdh_nid, kdf_type, kdf_nid, wrap_nid;
+ const EVP_MD *kdf_md;
+
+ pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
+ if (pctx == NULL)
+ return 0;
+ /* Get ephemeral key */
+ pkey = EVP_PKEY_CTX_get0_pkey(pctx);
+ if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &talg, &pubkey,
+ NULL, NULL, NULL))
+ goto err;
+ X509_ALGOR_get0(&aoid, NULL, NULL, talg);
+ /* Is everything uninitialised? */
+ if (aoid == OBJ_nid2obj(NID_undef)) {
+ /* Set the key */
+
+ /* TODO(3.0): Terrible name. Needs a non TLS specific name */
+ penclen = EVP_PKEY_get1_tls_encodedpoint(pkey, &penc);
+ ASN1_STRING_set0(pubkey, penc, penclen);
+ pubkey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
+ pubkey->flags |= ASN1_STRING_FLAG_BITS_LEFT;
+
+ penc = NULL;
+ X509_ALGOR_set0(talg, OBJ_nid2obj(NID_X9_62_id_ecPublicKey),
+ V_ASN1_UNDEF, NULL);
+ }
+
+ /* See if custom parameters set */
+ kdf_type = EVP_PKEY_CTX_get_ecdh_kdf_type(pctx);
+ if (kdf_type <= 0)
+ goto err;
+ if (!EVP_PKEY_CTX_get_ecdh_kdf_md(pctx, &kdf_md))
+ goto err;
+ ecdh_nid = EVP_PKEY_CTX_get_ecdh_cofactor_mode(pctx);
+ if (ecdh_nid < 0)
+ goto err;
+ else if (ecdh_nid == 0)
+ ecdh_nid = NID_dh_std_kdf;
+ else if (ecdh_nid == 1)
+ ecdh_nid = NID_dh_cofactor_kdf;
+
+ if (kdf_type == EVP_PKEY_ECDH_KDF_NONE) {
+ kdf_type = EVP_PKEY_ECDH_KDF_X9_63;
+ if (EVP_PKEY_CTX_set_ecdh_kdf_type(pctx, kdf_type) <= 0)
+ goto err;
+ } else
+ /* Unknown KDF */
+ goto err;
+ if (kdf_md == NULL) {
+ /* Fixme later for better MD */
+ kdf_md = EVP_sha1();
+ if (EVP_PKEY_CTX_set_ecdh_kdf_md(pctx, kdf_md) <= 0)
+ goto err;
+ }
+
+ if (!CMS_RecipientInfo_kari_get0_alg(ri, &talg, &ukm))
+ goto err;
+
+ /* Lookup NID for KDF+cofactor+digest */
+
+ if (!OBJ_find_sigid_by_algs(&kdf_nid, EVP_MD_type(kdf_md), ecdh_nid))
+ goto err;
+ /* Get wrap NID */
+ ctx = CMS_RecipientInfo_kari_get0_ctx(ri);
+ wrap_nid = EVP_CIPHER_CTX_type(ctx);
+ keylen = EVP_CIPHER_CTX_key_length(ctx);
+
+ /* Package wrap algorithm in an AlgorithmIdentifier */
+
+ wrap_alg = X509_ALGOR_new();
+ if (wrap_alg == NULL)
+ goto err;
+ wrap_alg->algorithm = OBJ_nid2obj(wrap_nid);
+ wrap_alg->parameter = ASN1_TYPE_new();
+ if (wrap_alg->parameter == NULL)
+ goto err;
+ if (EVP_CIPHER_param_to_asn1(ctx, wrap_alg->parameter) <= 0)
+ goto err;
+ if (ASN1_TYPE_get(wrap_alg->parameter) == NID_undef) {
+ ASN1_TYPE_free(wrap_alg->parameter);
+ wrap_alg->parameter = NULL;
+ }
+
+ if (EVP_PKEY_CTX_set_ecdh_kdf_outlen(pctx, keylen) <= 0)
+ goto err;
+
+ penclen = CMS_SharedInfo_encode(&penc, wrap_alg, ukm, keylen);
+
+ if (penclen == 0)
+ goto err;
+
+ if (EVP_PKEY_CTX_set0_ecdh_kdf_ukm(pctx, penc, penclen) <= 0)
+ goto err;
+ penc = NULL;
+
+ /*
+ * Now need to wrap encoding of wrap AlgorithmIdentifier into parameter
+ * of another AlgorithmIdentifier.
+ */
+ penclen = i2d_X509_ALGOR(wrap_alg, &penc);
+ if (penc == NULL || penclen == 0)
+ goto err;
+ wrap_str = ASN1_STRING_new();
+ if (wrap_str == NULL)
+ goto err;
+ ASN1_STRING_set0(wrap_str, penc, penclen);
+ penc = NULL;
+ X509_ALGOR_set0(talg, OBJ_nid2obj(kdf_nid), V_ASN1_SEQUENCE, wrap_str);
+
+ rv = 1;
+
+ err:
+ OPENSSL_free(penc);
+ X509_ALGOR_free(wrap_alg);
+ return rv;
+}
+
+int cms_ecdh_envelope(CMS_RecipientInfo *ri, int decrypt)
+{
+ assert(decrypt == 0 || decrypt == 1);
+
+ if (decrypt == 1)
+ return ecdh_cms_decrypt(ri);
+
+ if (decrypt == 0)
+ return ecdh_cms_encrypt(ri);
+
+ CMSerr(0, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
+ return 0;
+}
+#endif
+
+/* ECDSA and DSA implementation is the same */
+int cms_ecdsa_dsa_sign(CMS_SignerInfo *si, int verify)
+{
+ assert(verify == 0 || verify == 1);
+
+ if (verify == 0) {
+ int snid, hnid;
+ X509_ALGOR *alg1, *alg2;
+ EVP_PKEY *pkey = si->pkey;
+
+ CMS_SignerInfo_get0_algs(si, NULL, NULL, &alg1, &alg2);
+ if (alg1 == NULL || alg1->algorithm == NULL)
+ return -1;
+ hnid = OBJ_obj2nid(alg1->algorithm);
+ if (hnid == NID_undef)
+ return -1;
+ if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
+ return -1;
+ X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
+ }
+ return 1;
+}
diff --git a/crypto/cms/cms_env.c b/crypto/cms/cms_env.c
index b1bba4c2d6..8f3e2db339 100644
--- a/crypto/cms/cms_env.c
+++ b/crypto/cms/cms_env.c
@@ -115,6 +115,21 @@ int cms_env_asn1_ctrl(CMS_RecipientInfo *ri, int cmd)
return 0;
} else
return 0;
+
+#ifndef OPENSSL_NO_DH
+ if (EVP_PKEY_is_a(pkey, "DHX"))
+ return cms_dh_envelope(ri, cmd);
+ else
+#endif
+#ifndef OPENSSL_NO_EC
+ if (EVP_PKEY_is_a(pkey, "EC"))
+ return cms_ecdh_envelope(ri, cmd);
+ else
+#endif
+ if (EVP_PKEY_is_a(pkey, "RSA"))
+ return cms_rsa_envelope(ri, cmd);
+
+ /* Something else? We'll give engines etc a chance to handle this */
if (pkey->ameth == NULL || pkey->ameth->pkey_ctrl == NULL)
return 1;
i = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_CMS_ENVELOPE, cmd, ri);
@@ -1288,6 +1303,20 @@ err:
*/
int cms_pkey_get_ri_type(EVP_PKEY *pk)
{
+ /* Check types that we know about */
+ if (EVP_PKEY_is_a(pk, "DH"))
+ return CMS_RECIPINFO_AGREE;
+ else if (EVP_PKEY_is_a(pk, "DSA"))
+ return CMS_RECIPINFO_NONE;
+ else if (EVP_PKEY_is_a(pk, "EC"))
+ return CMS_RECIPINFO_AGREE;
+ else if (EVP_PKEY_is_a(pk, "RSA"))
+ return CMS_RECIPINFO_TRANS;
+
+ /*
+ * Otherwise this might ben an engine implementation, so see if we can get
+ * the type from the ameth.
+ */
if (pk->ameth && pk->ameth->pkey_ctrl) {
int i, r;
i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_RI_TYPE, 0, &r);
diff --git a/crypto/cms/cms_err.c b/crypto/cms/cms_err.c
index da14c726c4..fdb2b7f5c8 100644
--- a/crypto/cms/cms_err.c
+++ b/crypto/cms/cms_err.c
@@ -47,6 +47,7 @@ static const ERR_STRING_DATA CMS_str_reasons[] = {
"content verify error"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CTRL_ERROR), "ctrl error"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CTRL_FAILURE), "ctrl failure"},
+ {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_DECODE_ERROR), "decode error"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_DECRYPT_ERROR), "decrypt error"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_ERROR_GETTING_PUBLIC_KEY),
"error getting public key"},
@@ -64,6 +65,11 @@ static const ERR_STRING_DATA CMS_str_reasons[] = {
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER),
"invalid key encryption parameter"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_INVALID_KEY_LENGTH), "invalid key length"},
+ {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_INVALID_LABEL), "invalid label"},
+ {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_INVALID_OAEP_PARAMETERS),
+ "invalid oaep parameters"},
+ {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_KDF_PARAMETER_ERROR),
+ "kdf parameter error"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_MD_BIO_INIT_ERROR), "md bio init error"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH),
"messagedigest attribute wrong length"},
@@ -102,11 +108,13 @@ static const ERR_STRING_DATA CMS_str_reasons[] = {
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_PUBLIC_KEY), "no public key"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_RECEIPT_REQUEST), "no receipt request"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_SIGNERS), "no signers"},
+ {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_PEER_KEY_ERROR), "peer key error"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE),
"private key does not match certificate"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_RECEIPT_DECODE_ERROR),
"receipt decode error"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_RECIPIENT_ERROR), "recipient error"},
+ {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_SHARED_INFO_ERROR), "shared info error"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_SIGNER_CERTIFICATE_NOT_FOUND),
"signer certificate not found"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_SIGNFINAL_ERROR), "signfinal error"},
@@ -131,10 +139,14 @@ static const ERR_STRING_DATA CMS_str_reasons[] = {
"unsupported compression algorithm"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_CONTENT_TYPE),
"unsupported content type"},
+ {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_ENCRYPTION_TYPE),
+ "unsupported encryption type"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_KEK_ALGORITHM),
"unsupported kek algorithm"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM),
"unsupported key encryption algorithm"},
+ {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_LABEL_SOURCE),
+ "unsupported label source"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_RECIPIENTINFO_TYPE),
"unsupported recipientinfo type"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_RECIPIENT_TYPE),
diff --git a/crypto/cms/cms_kari.c b/crypto/cms/cms_kari.c
index 82a03e6c6b..13f7e78d37 100644
--- a/crypto/cms/cms_kari.c
+++ b/crypto/cms/cms_kari.c
@@ -261,26 +261,6 @@ int CMS_RecipientInfo_kari_decrypt(CMS_ContentInfo *cms,
size_t ceklen;
CMS_EncryptedContentInfo *ec;
- {
- /*
- * TODO(3.0) Remove this when we have functionality to deserialize
- * parameters in EVP_PKEY form from an X509_ALGOR.
- * This is needed to be able to replace the EC_KEY specific decoding
- * that happens in ecdh_cms_set_peerkey() (crypto/ec/ec_ameth.c)
- *
- * THIS IS TEMPORARY
- */
- EVP_PKEY_CTX *pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
- EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(pctx);
-
- EVP_PKEY_get0(pkey);
- if (EVP_PKEY_id(pkey) == EVP_PKEY_NONE) {
- CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_DECRYPT,
- CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
- goto err;
- }
- }
-
enckeylen = rek->encryptedKey->length;
enckey = rek->encryptedKey->data;
/* Setup all parameters to derive KEK */
@@ -499,32 +479,6 @@ int cms_RecipientInfo_kari_encrypt(const CMS_ContentInfo *cms,
STACK_OF(CMS_RecipientEncryptedKey) *reks;
int i;
- {
- /*
- * TODO(3.0) Remove this when we have figured out all the details
- * need to set up encryption right. With legacy keys, a *lot* is
- * happening in the CMS specific EVP_PKEY_ASN1_METHOD functions,
- * such as automatically setting a default KDF type, KDF digest,
- * all that kind of stuff.
- * With EVP_SIGNATURE, setting a default digest is done by getting
- * the default MD for the key, and then inject that back into the
- * signature implementation... we could do something similar with
- * CMS, possibly using CMS specific OSSL_PARAM keys, just like we
- * have for certain AlgorithmIdentifier retrievals.
- *
- * THIS IS TEMPORARY
- */
- EVP_PKEY_CTX *pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
- EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(pctx);
-
- EVP_PKEY_get0(pkey);
- if (EVP_PKEY_id(pkey) == EVP_PKEY_NONE) {
- CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_ENCRYPT,
- CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
- return 0;
- }
- }
-
if (ri->type != CMS_RECIPINFO_AGREE) {
CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_ENCRYPT, CMS_R_NOT_KEY_AGREEMENT);
return 0;
diff --git a/crypto/cms/cms_local.h b/crypto/cms/cms_local.h
index 336c354655..0b663a9e88 100644
--- a/crypto/cms/cms_local.h
+++ b/crypto/cms/cms_local.h
@@ -471,6 +471,12 @@ void cms_SignerInfos_set_cmsctx(CMS_ContentInfo *cms);
/* ESS routines */
int ess_check_signing_certs(CMS_SignerInfo *si, STACK_OF(X509) *chain);
+int cms_dh_envelope(CMS_RecipientInfo *ri, int decrypt);
+int cms_ecdh_envelope(CMS_RecipientInfo *ri, int decrypt);
+int cms_rsa_envelope(CMS_RecipientInfo *ri, int decrypt);
+int cms_ecdsa_dsa_sign(CMS_SignerInfo *si, int verify);
+int cms_rsa_sign(CMS_SignerInfo *si, int verify);
+
DECLARE_ASN1_ITEM(CMS_CertificateChoices)
DECLARE_ASN1_ITEM(CMS_DigestedData)
DECLARE_ASN1_ITEM(CMS_EncryptedData)
diff --git a/crypto/cms/cms_rsa.c b/crypto/cms/cms_rsa.c
new file mode 100644
index 0000000000..88201d7b44
--- /dev/null
+++ b/crypto/cms/cms_rsa.c
@@ -0,0 +1,253 @@
+/*
+ * Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <assert.h>
+#include <openssl/cms.h>
+#include <openssl/err.h>
+#include "crypto/asn1.h"
+#include "crypto/rsa.h"
+#include "cms_local.h"
+
+static RSA_OAEP_PARAMS *rsa_oaep_decode(const X509_ALGOR *alg)
+{
+ RSA_OAEP_PARAMS *oaep;
+
+ oaep = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(RSA_OAEP_PARAMS),
+ alg->parameter);
+
+ if (oaep == NULL)
+ return NULL;
+
+ if (oaep->maskGenFunc != NULL) {
+ oaep->maskHash = x509_algor_mgf1_decode(oaep->maskGenFunc);
+ if (oaep->maskHash == NULL) {
+ RSA_OAEP_PARAMS_free(oaep);
+ return NULL;
+ }
+ }
+ return oaep;
+}
+
+static int rsa_cms_decrypt(CMS_RecipientInfo *ri)
+{
+ EVP_PKEY_CTX *pkctx;
+ X509_ALGOR *cmsalg;
+ int nid;
+ int rv = -1;
+ unsigned char *label = NULL;
+ int labellen = 0;
+ const EVP_MD *mgf1md = NULL, *md = NULL;
+ RSA_OAEP_PARAMS *oaep;
+
+ pkctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
+ if (pkctx == NULL)
+ return 0;
+ if (!CMS_RecipientInfo_ktri_get0_algs(ri, NULL, NULL, &cmsalg))
+ return -1;
+ nid = OBJ_obj2nid(cmsalg->algorithm);
+ if (nid == NID_rsaEncryption)
+ return 1;
+ if (nid != NID_rsaesOaep) {
+ CMSerr(0, CMS_R_UNSUPPORTED_ENCRYPTION_TYPE);
+ return -1;
+ }
+ /* Decode OAEP parameters */
+ oaep = rsa_oaep_decode(cmsalg);
+
+ if (oaep == NULL) {
+ CMSerr(0, CMS_R_INVALID_OAEP_PARAMETERS);
+ goto err;
+ }
+
+ mgf1md = x509_algor_get_md(oaep->maskHash);
+ if (mgf1md == NULL)
+ goto err;
+ md = x509_algor_get_md(oaep->hashFunc);
+ if (md == NULL)
+ goto err;
+
+ if (oaep->pSourceFunc != NULL) {
+ X509_ALGOR *plab = oaep->pSourceFunc;
+
+ if (OBJ_obj2nid(plab->algorithm) != NID_pSpecified) {
+ CMSerr(0, CMS_R_UNSUPPORTED_LABEL_SOURCE);
+ goto err;
+ }
+ if (plab->parameter->type != V_ASN1_OCTET_STRING) {
+ CMSerr(0, CMS_R_INVALID_LABEL);
+ goto err;
+ }
+
+ label = plab->parameter->value.octet_string->data;
+ /* Stop label being freed when OAEP parameters are freed */
+ plab->parameter->value.octet_string->data = NULL;
+ labellen = plab->parameter->value.octet_string->length;
+ }
+
+ if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_OAEP_PADDING) <= 0)
+ goto err;
+ if (EVP_PKEY_CTX_set_rsa_oaep_md(pkctx, md) <= 0)
+ goto err;
+ if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md) <= 0)
+ goto err;
+ if (label != NULL
+ && EVP_PKEY_CTX_set0_rsa_oaep_label(pkctx, label, labellen) <= 0)
+ goto err;
+ /* Carry on */
+ rv = 1;
+
+ err:
+ RSA_OAEP_PARAMS_free(oaep);
+ return rv;
+}
+
+static int rsa_cms_encrypt(CMS_RecipientInfo *ri)
+{
+ const EVP_MD *md, *mgf1md;
+ RSA_OAEP_PARAMS *oaep = NULL;
+ ASN1_STRING *os = NULL;
+ X509_ALGOR *alg;
+ EVP_PKEY_CTX *pkctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
+ int pad_mode = RSA_PKCS1_PADDING, rv = 0, labellen;
+ unsigned char *label;
+
+ if (CMS_RecipientInfo_ktri_get0_algs(ri, NULL, NULL, &alg) <= 0)
+ return 0;
+ if (pkctx != NULL) {
+ if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0)
+ return 0;
+ }
+ if (pad_mode == RSA_PKCS1_PADDING) {
+ X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0);
+ return 1;
+ }
+ /* Not supported */
+ if (pad_mode != RSA_PKCS1_OAEP_PADDING)
+ return 0;
+ if (EVP_PKEY_CTX_get_rsa_oaep_md(pkctx, &md) <= 0)
+ goto err;
+ if (EVP_PKEY_CTX_get_rsa_mgf1_md(pkctx, &mgf1md) <= 0)
+ goto err;
+ labellen = EVP_PKEY_CTX_get0_rsa_oaep_label(pkctx, &label);
+ if (labellen < 0)
+ goto err;
+ oaep = RSA_OAEP_PARAMS_new();
+ if (oaep == NULL)
+ goto err;
+ if (!x509_algor_new_from_md(&oaep->hashFunc, md))
+ goto err;
+ if (!x509_algor_md_to_mgf1(&oaep->maskGenFunc, mgf1md))
+ goto err;
+ if (labellen > 0) {
+ ASN1_OCTET_STRING *los;
+
+ oaep->pSourceFunc = X509_ALGOR_new();
+ if (oaep->pSourceFunc == NULL)
+ goto err;
+ los = ASN1_OCTET_STRING_new();
+ if (los == NULL)
+ goto err;
+ if (!ASN1_OCTET_STRING_set(los, label, labellen)) {
+ ASN1_OCTET_STRING_free(los);
+ goto err;
+ }
+ X509_ALGOR_set0(oaep->pSourceFunc, OBJ_nid2obj(NID_pSpecified),
+ V_ASN1_OCTET_STRING, los);
+ }
+ /* create string with pss parameter encoding. */
+ if (!ASN1_item_pack(oaep, ASN1_ITEM_rptr(RSA_OAEP_PARAMS), &os))
+ goto err;
+ X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaesOaep), V_ASN1_SEQUENCE, os);
+ os = NULL;
+ rv = 1;
+ err:
+ RSA_OAEP_PARAMS_free(oaep);
+ ASN1_STRING_free(os);
+ return rv;
+}
+
+int cms_rsa_envelope(CMS_RecipientInfo *ri, int decrypt)
+{
+ assert(decrypt == 0 || decrypt == 1);
+
+ if (decrypt == 1)
+ return rsa_cms_decrypt(ri);
+
+ if (decrypt == 0)
+ return rsa_cms_encrypt(ri);
+
+ CMSerr(0, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
+ return 0;
+}
+
+static int rsa_cms_sign(CMS_SignerInfo *si)
+{
+ int pad_mode = RSA_PKCS1_PADDING;
+ X509_ALGOR *alg;
+ EVP_PKEY_CTX *pkctx = CMS_SignerInfo_get0_pkey_ctx(si);
+ ASN1_STRING *os = NULL;
+
+ CMS_SignerInfo_get0_algs(si, NULL, NULL, NULL, &alg);
+ if (pkctx != NULL) {
+ if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0)
+ return 0;
+ }
+ if (pad_mode == RSA_PKCS1_PADDING) {
+ X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0);
+ return 1;
+ }
+ /* We don't support it */
+ if (pad_mode != RSA_PKCS1_PSS_PADDING)
+ return 0;
+ os = ossl_rsa_ctx_to_pss_string(pkctx);
+ if (os == NULL)
+ return 0;
+ X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_PKEY_RSA_PSS), V_ASN1_SEQUENCE, os);
+ return 1;
+}
+
+static int rsa_cms_verify(CMS_SignerInfo *si)
+{
+ int nid, nid2;
+ X509_ALGOR *alg;
+ EVP_PKEY_CTX *pkctx = CMS_SignerInfo_get0_pkey_ctx(si);
+ EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(pkctx);
+
+ CMS_SignerInfo_get0_algs(si, NULL, NULL, NULL, &alg);
+ nid = OBJ_obj2nid(alg->algorithm);
+ if (nid == EVP_PKEY_RSA_PSS)
+ return ossl_rsa_pss_to_ctx(NULL, pkctx, alg, NULL);
+ /* Only PSS allowed for PSS keys */
+ if (EVP_PKEY_is_a(pkey, "RSA-PSS")) {
+ RSAerr(RSA_F_RSA_CMS_VERIFY, RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE);
+ return 0;
+ }
+ if (nid == NID_rsaEncryption)
+ return 1;
+ /* Workaround for some implementation that use a signature OID */
+ if (OBJ_find_sigid_algs(nid, NULL, &nid2)) {
+ if (nid2 == NID_rsaEncryption)
+ return 1;
+ }
+ return 0;
+}
+
+int cms_rsa_sign(CMS_SignerInfo *si, int verify)
+{
+ assert(verify == 0 || verify == 1);
+
+ if (verify == 1)
+ return rsa_cms_verify(si);
+
+ if (verify == 0)
+ return rsa_cms_sign(si);
+
+ CMSerr(0, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
+ return 0;
+}
diff --git a/crypto/cms/cms_sd.c b/crypto/cms/cms_sd.c
index 1338211072..377fac5917 100644
--- a/crypto/cms/cms_sd.c
+++ b/crypto/cms/cms_sd.c
@@ -233,6 +233,15 @@ static int cms_sd_asn1_ctrl(CMS_SignerInfo *si, int cmd)
EVP_PKEY *pkey = si->pkey;
int i;
+#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_EC)
+ if (EVP_PKEY_is_a(pkey, "DSA") || EVP_PKEY_is_a(pkey, "EC"))
+ return cms_ecdsa_dsa_sign(si, cmd);
+ else
+#endif
+ if (EVP_PKEY_is_a(pkey, "RSA") || EVP_PKEY_is_a(pkey, "RSA-PSS"))
+ return cms_rsa_sign(si, cmd);
+
+ /* Something else? We'll give engines etc a chance to handle this */
if (pkey->ameth == NULL || pkey->ameth->pkey_ctrl == NULL)
return 1;
i = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_CMS_SIGN, cmd, si);
diff --git a/crypto/dh/dh_ameth.c b/crypto/dh/dh_ameth.c
index e32de78638..9ad75d2092 100644
--- a/crypto/dh/dh_ameth.c
+++ b/crypto/dh/dh_ameth.c
@@ -14,18 +14,17 @@
#include "internal/deprecated.h"
#include <stdio.h>
-#include "internal/cryptlib.h"
#include <openssl/x509.h>
#include <openssl/asn1.h>
-#include "dh_local.h"
#include <openssl/bn.h>
-#include "crypto/asn1.h"
-#include "crypto/dh.h"
-#include "crypto/evp.h"
-#include <openssl/cms.h>
#include <openssl/core_names.h>
#include <openssl/param_build.h>
#include "internal/ffc.h"
+#include "internal/cryptlib.h"
+#include "crypto/asn1.h"
+#include "crypto/dh.h"
+#include "crypto/evp.h"
+#include "dh_local.h"
/*
* i2d/d2i like DH parameter functions which use the appropriate routine for
@@ -434,11 +433,6 @@ int DHparams_print(BIO *bp, const DH *x)
return do_dh_print(bp, x, 4, 0);
}
-#ifndef OPENSSL_NO_CMS
-static int dh_cms_decrypt(CMS_RecipientInfo *ri);
-static int dh_cms_encrypt(CMS_RecipientInfo *ri);
-#endif
-
static int dh_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
{
switch (op) {
@@ -454,19 +448,6 @@ static int dh_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
static int dhx_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
{
switch (op) {
-#ifndef OPENSSL_NO_CMS
-
- case ASN1_PKEY_CTRL_CMS_ENVELOPE:
- if (arg1 == 1)
- return dh_cms_decrypt(arg2);
- else if (arg1 == 0)
- return dh_cms_encrypt(arg2);
- return -2;
-
- case ASN1_PKEY_CTRL_CMS_RI_TYPE:
- *(int *)arg2 = CMS_RECIPINFO_AGREE;
- return 1;
-#endif
default:
return -2;
}
@@ -675,308 +656,3 @@ const EVP_PKEY_ASN1_METHOD dhx_asn1_meth = {
dh_pkey_export_to,
dhx_pkey_import_from,
};
-
-#ifndef OPENSSL_NO_CMS
-
-static int dh_cms_set_peerkey(EVP_PKEY_CTX *pctx,
- X509_ALGOR *alg, ASN1_BIT_STRING *pubkey)
-{
- const ASN1_OBJECT *aoid;
- int atype;
- const void *aval;
- ASN1_INTEGER *public_key = NULL;
- int rv = 0;
- EVP_PKEY *pkpeer = NULL, *pk = NULL;
- DH *dhpeer = NULL;
- const unsigned char *p;
- int plen;
-
- X509_ALGOR_get0(&aoid, &atype, &aval, alg);
- if (OBJ_obj2nid(aoid) != NID_dhpublicnumber)
- goto err;
- /* Only absent parameters allowed in RFC XXXX */
- if (atype != V_ASN1_UNDEF && atype == V_ASN1_NULL)
- goto err;
-
- pk = EVP_PKEY_CTX_get0_pkey(pctx);
- if (pk == NULL)
- goto err;
- if (pk->type != EVP_PKEY_DHX)
- goto err;
- /* Get parameters from parent key */
- dhpeer = DHparams_dup(pk->pkey.dh);
- /* We have parameters now set public key */
- plen = ASN1_STRING_length(pubkey);
- p = ASN1_STRING_get0_data(pubkey);
- if (p == NULL || plen == 0)
- goto err;
-
- if ((public_key = d2i_ASN1_INTEGER(NULL, &p, plen)) == NULL) {
- DHerr(DH_F_DH_CMS_SET_PEERKEY, DH_R_DECODE_ERROR);
- goto err;
- }
-
- /* We have parameters now set public key */
- if ((dhpeer->pub_key = ASN1_INTEGER_to_BN(public_key, NULL)) == NULL) {
- DHerr(DH_F_DH_CMS_SET_PEERKEY, DH_R_BN_DECODE_ERROR);
- goto err;
- }
-
- pkpeer = EVP_PKEY_new();
- if (pkpeer == NULL)
- goto err;
- EVP_PKEY_assign(pkpeer, pk->ameth->pkey_id, dhpeer);
- dhpeer = NULL;
- if (EVP_PKEY_derive_set_peer(pctx, pkpeer) > 0)
- rv = 1;
- err:
- ASN1_INTEGER_free(public_key);
- EVP_PKEY_free(pkpeer);
- DH_free(dhpeer);
- return rv;
-}
-
-static int dh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri)
-{
- int rv = 0;
-
- X509_ALGOR *alg, *kekalg = NULL;
- ASN1_OCTET_STRING *ukm;
- const unsigned char *p;
- unsigned char *dukm = NULL;
- size_t dukmlen = 0;
- int keylen, plen;
- const EVP_CIPHER *kekcipher;
- EVP_CIPHER_CTX *kekctx;
-
- if (!CMS_RecipientInfo_kari_get0_alg(ri, &alg, &ukm))
- goto err;
-
- /*
- * For DH we only have one OID permissible. If ever any more get defined
- * we will need something cleverer.
- */
- if (OBJ_obj2nid(alg->algorithm) != NID_id_smime_alg_ESDH) {
- DHerr(DH_F_DH_CMS_SET_SHARED_INFO, DH_R_KDF_PARAMETER_ERROR);
- goto err;
- }
-
- if (EVP_PKEY_CTX_set_dh_kdf_type(pctx, EVP_PKEY_DH_KDF_X9_42) <= 0)
- goto err;
-
- if (EVP_PKEY_CTX_set_dh_kdf_md(pctx, EVP_sha1()) <= 0)
- goto err;
-
- if (alg->parameter->type != V_ASN1_SEQUENCE)
- goto err;
-
- p = alg->parameter->value.sequence->data;
- plen = alg->parameter->value.sequence->length;
- kekalg = d2i_X509_ALGOR(NULL, &p, plen);
- if (!kekalg)
- goto err;
- kekctx = CMS_RecipientInfo_kari_get0_ctx(ri);
- if (!kekctx)
- goto err;
- kekcipher = EVP_get_cipherbyobj(kekalg->algorithm);
- if (!kekcipher || EVP_CIPHER_mode(kekcipher) != EVP_CIPH_WRAP_MODE)
- goto err;
- if (!EVP_EncryptInit_ex(kekctx, kekcipher, NULL, NULL, NULL))
- goto err;
- if (EVP_CIPHER_asn1_to_param(kekctx, kekalg->parameter) <= 0)
- goto err;
-
- keylen = EVP_CIPHER_CTX_key_length(kekctx);
- if (EVP_PKEY_CTX_set_dh_kdf_outlen(pctx, keylen) <= 0)
- goto err;
- /* Use OBJ_nid2obj to ensure we use built in OID that isn't freed */
- if (EVP_PKEY_CTX_set0_dh_kdf_oid(pctx,
- OBJ_nid2obj(EVP_CIPHER_type(kekcipher)))
- <= 0)
- goto err;
-
- if (ukm) {
- dukmlen = ASN1_STRING_length(ukm);
- dukm = OPENSSL_memdup(ASN1_STRING_get0_data(ukm), dukmlen);
- if (!dukm)
- goto err;
- }
-
- if (EVP_PKEY_CTX_set0_dh_kdf_ukm(pctx, dukm, dukmlen) <= 0)
- goto err;
- dukm = NULL;
-
- rv = 1;
- err:
- X509_ALGOR_free(kekalg);
- OPENSSL_free(dukm);
- return rv;
-}
-
-static int dh_cms_decrypt(CMS_RecipientInfo *ri)
-{
- EVP_PKEY_CTX *pctx;
-
- pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
-
- if (pctx == NULL)
- return 0;
- /* See if we need to set peer key */
- if (!EVP_PKEY_CTX_get0_peerkey(pctx)) {
- X509_ALGOR *alg;
- ASN1_BIT_STRING *pubkey;
- if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &alg, &pubkey,
- NULL, NULL, NULL))
- return 0;
- if (!alg || !pubkey)
- return 0;
- if (!dh_cms_set_peerkey(pctx, alg, pubkey)) {
- DHerr(DH_F_DH_CMS_DECRYPT, DH_R_PEER_KEY_ERROR);
- return 0;
- }
- }
- /* Set DH derivation parameters and initialise unwrap context */
- if (!dh_cms_set_shared_info(pctx, ri)) {
- DHerr(DH_F_DH_CMS_DECRYPT, DH_R_SHARED_INFO_ERROR);
- return 0;
- }
- return 1;
-}
-
-static int dh_cms_encrypt(CMS_RecipientInfo *ri)
-{
- EVP_PKEY_CTX *pctx;
- EVP_PKEY *pkey;
- EVP_CIPHER_CTX *ctx;
- int keylen;
- X509_ALGOR *talg, *wrap_alg = NULL;
- const ASN1_OBJECT *aoid;
- ASN1_BIT_STRING *pubkey;
- ASN1_STRING *wrap_str;
- ASN1_OCTET_STRING *ukm;
- unsigned char *penc = NULL, *dukm = NULL;
- int penclen;
- size_t dukmlen = 0;
- int rv = 0;
- int kdf_type, wrap_nid;
- const EVP_MD *kdf_md;
-
- pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
- if (pctx == NULL)
- return 0;
- /* Get ephemeral key */
- pkey = EVP_PKEY_CTX_get0_pkey(pctx);
- if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &talg, &pubkey,
- NULL, NULL, NULL))
- goto err;
- X509_ALGOR_get0(&aoid, NULL, NULL, talg);
- /* Is everything uninitialised? */
- if (aoid == OBJ_nid2obj(NID_undef)) {
- ASN1_INTEGER *pubk = BN_to_ASN1_INTEGER(pkey->pkey.dh->pub_key, NULL);
-
- if (pubk == NULL)
- goto err;
- /* Set the key */
-
- penclen = i2d_ASN1_INTEGER(pubk, &penc);
- ASN1_INTEGER_free(pubk);
- if (penclen <= 0)
- goto err;
- ASN1_STRING_set0(pubkey, penc, penclen);
- pubkey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
- pubkey->flags |= ASN1_STRING_FLAG_BITS_LEFT;
-
- penc = NULL;
- X509_ALGOR_set0(talg, OBJ_nid2obj(NID_dhpublicnumber),
- V_ASN1_UNDEF, NULL);
- }
-
- /* See if custom parameters set */
- kdf_type = EVP_PKEY_CTX_get_dh_kdf_type(pctx);
- if (kdf_type <= 0)
- goto err;
- if (!EVP_PKEY_CTX_get_dh_kdf_md(pctx, &kdf_md))
- goto err;
-
- if (kdf_type == EVP_PKEY_DH_KDF_NONE) {
- kdf_type = EVP_PKEY_DH_KDF_X9_42;
- if (EVP_PKEY_CTX_set_dh_kdf_type(pctx, kdf_type) <= 0)
- goto err;
- } else if (kdf_type != EVP_PKEY_DH_KDF_X9_42)
- /* Unknown KDF */
- goto err;
- if (kdf_md == NULL) {
- /* Only SHA1 supported */
- kdf_md = EVP_sha1();
- if (EVP_PKEY_CTX_set_dh_kdf_md(pctx, kdf_md) <= 0)
- goto err;
- } else if (EVP_MD_type(kdf_md) != NID_sha1)
- /* Unsupported digest */
- goto err;
-
- if (!CMS_RecipientInfo_kari_get0_alg(ri, &talg, &ukm))
- goto err;
-
- /* Get wrap NID */
- ctx = CMS_RecipientInfo_kari_get0_ctx(ri);
- wrap_nid = EVP_CIPHER_CTX_type(ctx);
- if (EVP_PKEY_CTX_set0_dh_kdf_oid(pctx, OBJ_nid2obj(wrap_nid)) <= 0)
- goto err;
- keylen = EVP_CIPHER_CTX_key_length(ctx);
-
- /* Package wrap algorithm in an AlgorithmIdentifier */
-
- wrap_alg = X509_ALGOR_new();
- if (wrap_alg == NULL)
- goto err;
- wrap_alg->algorithm = OBJ_nid2obj(wrap_nid);
- wrap_alg->parameter = ASN1_TYPE_new();
- if (wrap_alg->parameter == NULL)
- goto err;
- if (EVP_CIPHER_param_to_asn1(ctx, wrap_alg->parameter) <= 0)
- goto err;
- if (ASN1_TYPE_get(wrap_alg->parameter) == NID_undef) {
- ASN1_TYPE_free(wrap_alg->parameter);
- wrap_alg->parameter = NULL;
- }
-
- if (EVP_PKEY_CTX_set_dh_kdf_outlen(pctx, keylen) <= 0)
- goto err;
-
- if (ukm) {
- dukmlen = ASN1_STRING_length(ukm);
- dukm = OPENSSL_memdup(ASN1_STRING_get0_data(ukm), dukmlen);
- if (!dukm)
- goto err;
- }
-
- if (EVP_PKEY_CTX_set0_dh_kdf_ukm(pctx, dukm, dukmlen) <= 0)
- goto err;
- dukm = NULL;
-
- /*
- * Now need to wrap encoding of wrap AlgorithmIdentifier into parameter
- * of another AlgorithmIdentifier.
- */
- penc = NULL;
- penclen = i2d_X509_ALGOR(wrap_alg, &penc);
- if (penc == NULL || penclen == 0)
- goto err;
- wrap_str = ASN1_STRING_new();
- if (wrap_str == NULL)
- goto err;
- ASN1_STRING_set0(wrap_str, penc, penclen);
- penc = NULL;
- X509_ALGOR_set0(talg, OBJ_nid2obj(NID_id_smime_alg_ESDH),
- V_ASN1_SEQUENCE, wrap_str);
-
- rv = 1;
-
- err:
- OPENSSL_free(penc);
- X509_ALGOR_free(wrap_alg);
- OPENSSL_free(dukm);
- return rv;
-}
-
-#endif
diff --git a/crypto/dsa/dsa_ameth.c b/crypto/dsa/dsa_ameth.c
index 7619c05b5e..98b531ea24 100644
--- a/crypto/dsa/dsa_ameth.c
+++ b/crypto/dsa/dsa_ameth.c
@@ -17,7 +17,6 @@
#include <openssl/x509.h>
#include <openssl/asn1.h>
#include <openssl/bn.h>
-#include <openssl/cms.h>
#include <openssl/core_names.h>
#include <openssl/param_build.h>
#include "internal/cryptlib.h"
@@ -481,27 +480,6 @@ static int dsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
}
return 1;
-#ifndef OPENSSL_NO_CMS
- case ASN1_PKEY_CTRL_CMS_SIGN:
- if (arg1 == 0) {
- int snid, hnid;
- X509_ALGOR *alg1, *alg2;
- CMS_SignerInfo_get0_algs(arg2, NULL, NULL, &alg1, &alg2);
- if (alg1 == NULL || alg1->algorithm == NULL)
- return -1;
- hnid = OBJ_obj2nid(alg1->algorithm);
- if (hnid == NID_undef)
- return -1;
- if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
- return -1;
- X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
- }
- return 1;
-
- case ASN1_PKEY_CTRL_CMS_RI_TYPE:
- *(int *)arg2 = CMS_RECIPINFO_NONE;
- return 1;
-#endif
case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
*(int *)arg2 = NID_sha256;
diff --git a/crypto/ec/ec_ameth.c b/crypto/ec/ec_ameth.c
index 4bbbabff07..caeb7f70cc 100644
--- a/crypto/ec/ec_ameth.c
+++ b/crypto/ec/ec_ameth.c
@@ -18,7 +18,6 @@
#include <openssl/x509.h>
#include <openssl/ec.h>
#include <openssl/bn.h>
-#include <openssl/cms.h>
#include <openssl/asn1t.h>
#include "crypto/asn1.h"
#include "crypto/evp.h"
@@ -27,11 +26,6 @@
#include "openssl/param_build.h"
#include "ec_local.h"
-#ifndef OPENSSL_NO_CMS
-static int ecdh_cms_decrypt(CMS_RecipientInfo *ri);
-static int ecdh_cms_encrypt(CMS_RecipientInfo *ri);
-#endif
-
static int eckey_param2type(int *pptype, void **ppval, const EC_KEY *ec_key)
{
const EC_GROUP *group;
@@ -494,34 +488,6 @@ static int ec_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
}
return 1;
-#ifndef OPENSSL_NO_CMS
- case ASN1_PKEY_CTRL_CMS_SIGN:
- if (arg1 == 0) {
- int snid, hnid;
- X509_ALGOR *alg1, *alg2;
- CMS_SignerInfo_get0_algs(arg2, NULL, NULL, &alg1, &alg2);
- if (alg1 == NULL || alg1->algorithm == NULL)
- return -1;
- hnid = OBJ_obj2nid(alg1->algorithm);
- if (hnid == NID_undef)
- return -1;
- if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
- return -1;
- X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
- }
- return 1;
-
- case ASN1_PKEY_CTRL_CMS_ENVELOPE:
- if (arg1 == 1)
- return ecdh_cms_decrypt(arg2);
- else if (arg1 == 0)
- return ecdh_cms_encrypt(arg2);
- return -2;
-
- case ASN1_PKEY_CTRL_CMS_RI_TYPE:
- *(int *)arg2 = CMS_RECIPINFO_AGREE;
- return 1;
-#endif
case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
if (EVP_PKEY_id(pkey) == EVP_PKEY_SM2) {
@@ -828,327 +794,3 @@ int ECParameters_print(BIO *bp, const EC_KEY *x)
{
return do_EC_KEY_print(bp, x, 4, EC_KEY_PRINT_PARAM);
}
-
-#ifndef OPENSSL_NO_CMS
-
-static int ecdh_cms_set_peerkey(EVP_PKEY_CTX *pctx,
- X509_ALGOR *alg, ASN1_BIT_STRING *pubkey)
-{
- const ASN1_OBJECT *aoid;
- int atype;
- const void *aval;
- int rv = 0;
- EVP_PKEY *pkpeer = NULL;
- EC_KEY *ecpeer = NULL;
- const unsigned char *p;
- int plen;
-
- X509_ALGOR_get0(&aoid, &atype, &aval, alg);
- if (OBJ_obj2nid(aoid) != NID_X9_62_id_ecPublicKey)
- goto err;
- /* If absent parameters get group from main key */
- if (atype == V_ASN1_UNDEF || atype == V_ASN1_NULL) {
- const EC_GROUP *grp;
- EVP_PKEY *pk;
- pk = EVP_PKEY_CTX_get0_pkey(pctx);
- if (pk == NULL)
- goto err;
- grp = EC_KEY_get0_group(pk->pkey.ec);
- ecpeer = EC_KEY_new();
- if (ecpeer == NULL)
- goto err;
- if (!EC_KEY_set_group(ecpeer, grp))
- goto err;
- } else {
- ecpeer = eckey_type2param(atype, aval, pctx->libctx, pctx->propquery);
- if (!ecpeer)
- goto err;
- }
- /* We have parameters now set public key */
- plen = ASN1_STRING_length(pubkey);
- p = ASN1_STRING_get0_data(pubkey);
- if (p == NULL || plen == 0)
- goto err;
- if (!o2i_ECPublicKey(&ecpeer, &p, plen))
- goto err;
- pkpeer = EVP_PKEY_new();
- if (pkpeer == NULL)
- goto err;
- EVP_PKEY_set1_EC_KEY(pkpeer, ecpeer);
- if (EVP_PKEY_derive_set_peer(pctx, pkpeer) > 0)
- rv = 1;
- err:
- EC_KEY_free(ecpeer);
- EVP_PKEY_free(pkpeer);
- return rv;
-}
-
-/* Set KDF parameters based on KDF NID */
-static int ecdh_cms_set_kdf_param(EVP_PKEY_CTX *pctx, int eckdf_nid)
-{
- int kdf_nid, kdfmd_nid, cofactor;
- const EVP_MD *kdf_md;
- if (eckdf_nid == NID_undef)
- return 0;
-
- /* Lookup KDF type, cofactor mode and digest */
- if (!OBJ_find_sigid_algs(eckdf_nid, &kdfmd_nid, &kdf_nid))
- return 0;
-
- if (kdf_nid == NID_dh_std_kdf)
- cofactor = 0;
- else if (kdf_nid == NID_dh_cofactor_kdf)
- cofactor = 1;
- else
- return 0;
-
- if (EVP_PKEY_CTX_set_ecdh_cofactor_mode(pctx, cofactor) <= 0)
- return 0;
-
- if (EVP_PKEY_CTX_set_ecdh_kdf_type(pctx, EVP_PKEY_ECDH_KDF_X9_63) <= 0)
- return 0;
-
- kdf_md = EVP_get_digestbynid(kdfmd_nid);
- if (!kdf_md)
- return 0;
-
- if (EVP_PKEY_CTX_set_ecdh_kdf_md(pctx, kdf_md) <= 0)
- return 0;
- return 1;
-}
-
-static int ecdh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri)
-{
- int rv = 0;
-
- X509_ALGOR *alg, *kekalg = NULL;
- ASN1_OCTET_STRING *ukm;
- const unsigned char *p;
- unsigned char *der = NULL;
- int plen, keylen;
- EVP_CIPHER *kekcipher = NULL;
- EVP_CIPHER_CTX *kekctx;
- const char *name;
-
- if (!CMS_RecipientInfo_kari_get0_alg(ri, &alg, &ukm))
- return 0;
-
- if (!ecdh_cms_set_kdf_param(pctx, OBJ_obj2nid(alg->algorithm))) {
- ECerr(EC_F_ECDH_CMS_SET_SHARED_INFO, EC_R_KDF_PARAMETER_ERROR);
- return 0;
- }
-
- if (alg->parameter->type != V_ASN1_SEQUENCE)
- return 0;
-
- p = alg->parameter->value.sequence->data;
- plen = alg->parameter->value.sequence->length;
- kekalg = d2i_X509_ALGOR(NULL, &p, plen);
- if (kekalg == NULL)
- goto err;
- kekctx = CMS_RecipientInfo_kari_get0_ctx(ri);
- if (kekctx == NULL)
- goto err;
- name = OBJ_nid2sn(OBJ_obj2nid(kekalg->algorithm));
- kekcipher = EVP_CIPHER_fetch(pctx->libctx, name, pctx->propquery);
- if (kekcipher == NULL || EVP_CIPHER_mode(kekcipher) != EVP_CIPH_WRAP_MODE)
- goto err;
- if (!EVP_EncryptInit_ex(kekctx, kekcipher, NULL, NULL, NULL))
- goto err;
- if (EVP_CIPHER_asn1_to_param(kekctx, kekalg->parameter) <= 0)
- goto err;
-
- keylen = EVP_CIPHER_CTX_key_length(kekctx);
- if (EVP_PKEY_CTX_set_ecdh_kdf_outlen(pctx, keylen) <= 0)
- goto err;
-
- plen = CMS_SharedInfo_encode(&der, kekalg, ukm, keylen);
-
- if (plen <= 0)
- goto err;
-
- if (EVP_PKEY_CTX_set0_ecdh_kdf_ukm(pctx, der, plen) <= 0)
- goto err;
- der = NULL;
-
- rv = 1;
- err:
- EVP_CIPHER_free(kekcipher);
- X509_ALGOR_free(kekalg);
- OPENSSL_free(der);
- return rv;
-}
-
-static int ecdh_cms_decrypt(CMS_RecipientInfo *ri)
-{
- EVP_PKEY_CTX *pctx;
-
- pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
- if (pctx == NULL)
- return 0;
- /* See if we need to set peer key */
- if (!EVP_PKEY_CTX_get0_peerkey(pctx)) {
- X509_ALGOR *alg;
- ASN1_BIT_STRING *pubkey;
-
- if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &alg, &pubkey,
- NULL, NULL, NULL))
- return 0;
- if (!alg || !pubkey)
- return 0;
- if (!ecdh_cms_set_peerkey(pctx, alg, pubkey)) {
- ECerr(EC_F_ECDH_CMS_DECRYPT, EC_R_PEER_KEY_ERROR);
- return 0;
- }
- }
- /* Set ECDH derivation parameters and initialise unwrap context */
- if (!ecdh_cms_set_shared_info(pctx, ri)) {
- ECerr(EC_F_ECDH_CMS_DECRYPT, EC_R_SHARED_INFO_ERROR);
- return 0;
- }
- return 1;
-}
-
-static int ecdh_cms_encrypt(CMS_RecipientInfo *ri)
-{
- EVP_PKEY_CTX *pctx;
- EVP_PKEY *pkey;
- EVP_CIPHER_CTX *ctx;
- int keylen;
- X509_ALGOR *talg, *wrap_alg = NULL;
- const ASN1_OBJECT *aoid;
- ASN1_BIT_STRING *pubkey;
- ASN1_STRING *wrap_str;
- ASN1_OCTET_STRING *ukm;
- unsigned char *penc = NULL;
- int penclen;
- int rv = 0;
- int ecdh_nid, kdf_type, kdf_nid, wrap_nid;
- const EVP_MD *kdf_md;
-
- pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
- if (pctx == NULL)
- return 0;
- /* Get ephemeral key */
- pkey = EVP_PKEY_CTX_get0_pkey(pctx);
- if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &talg, &pubkey,
- NULL, NULL, NULL))
- goto err;
- X509_ALGOR_get0(&aoid, NULL, NULL, talg);
- /* Is everything uninitialised? */
- if (aoid == OBJ_nid2obj(NID_undef)) {
-
- EC_KEY *eckey = pkey->pkey.ec;
- /* Set the key */
- unsigned char *p;
-
- penclen = i2o_ECPublicKey(eckey, NULL);
- if (penclen <= 0)
- goto err;
- penc = OPENSSL_malloc(penclen);
- if (penc == NULL)
- goto err;
- p = penc;
- penclen = i2o_ECPublicKey(eckey, &p);
- if (penclen <= 0)
- goto err;
- ASN1_STRING_set0(pubkey, penc, penclen);
- pubkey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
- pubkey->flags |= ASN1_STRING_FLAG_BITS_LEFT;
-
- penc = NULL;
- X509_ALGOR_set0(talg, OBJ_nid2obj(NID_X9_62_id_ecPublicKey),
- V_ASN1_UNDEF, NULL);
- }
-
- /* See if custom parameters set */
- kdf_type = EVP_PKEY_CTX_get_ecdh_kdf_type(pctx);
- if (kdf_type <= 0)
- goto err;
- if (!EVP_PKEY_CTX_get_ecdh_kdf_md(pctx, &kdf_md))
- goto err;
- ecdh_nid = EVP_PKEY_CTX_get_ecdh_cofactor_mode(pctx);
- if (ecdh_nid < 0)
- goto err;
- else if (ecdh_nid == 0)
- ecdh_nid = NID_dh_std_kdf;
- else if (ecdh_nid == 1)
- ecdh_nid = NID_dh_cofactor_kdf;
-
- if (kdf_type == EVP_PKEY_ECDH_KDF_NONE) {
- kdf_type = EVP_PKEY_ECDH_KDF_X9_63;
- if (EVP_PKEY_CTX_set_ecdh_kdf_type(pctx, kdf_type) <= 0)
- goto err;
- } else
- /* Unknown KDF */
- goto err;
- if (kdf_md == NULL) {
- /* Fixme later for better MD */
- kdf_md = EVP_sha1();
- if (EVP_PKEY_CTX_set_ecdh_kdf_md(pctx, kdf_md) <= 0)
- goto err;
- }
-
- if (!CMS_RecipientInfo_kari_get0_alg(ri, &talg, &ukm))
- goto err;
-
- /* Lookup NID for KDF+cofactor+digest */
-
- if (!OBJ_find_sigid_by_algs(&kdf_nid, EVP_MD_type(kdf_md), ecdh_nid))
- goto err;
- /* Get wrap NID */
- ctx = CMS_RecipientInfo_kari_get0_ctx(ri);
- wrap_nid = EVP_CIPHER_CTX_type(ctx);
- keylen = EVP_CIPHER_CTX_key_length(ctx);
-
- /* Package wrap algorithm in an AlgorithmIdentifier */
-
- wrap_alg = X509_ALGOR_new();
- if (wrap_alg == NULL)
- goto err;
- wrap_alg->algorithm = OBJ_nid2obj(wrap_nid);
- wrap_alg->parameter = ASN1_TYPE_new();
- if (wrap_alg->parameter == NULL)
- goto err;
- if (EVP_CIPHER_param_to_asn1(ctx, wrap_alg->parameter) <= 0)
- goto err;
- if (ASN1_TYPE_get(wrap_alg->parameter) == NID_undef) {
- ASN1_TYPE_free(wrap_alg->parameter);
- wrap_alg->parameter = NULL;
- }
-
- if (EVP_PKEY_CTX_set_ecdh_kdf_outlen(pctx, keylen) <= 0)
- goto err;
-
- penclen = CMS_SharedInfo_encode(&penc, wrap_alg, ukm, keylen);
-
- if (!penclen)
- goto err;
-
- if (EVP_PKEY_CTX_set0_ecdh_kdf_ukm(pctx, penc, penclen) <= 0)
- goto err;
- penc = NULL;
-
- /*
- * Now need to wrap encoding of wrap AlgorithmIdentifier into parameter
- * of another AlgorithmIdentifier.
- */
- penclen = i2d_X509_ALGOR(wrap_alg, &penc);
- if (!penc || !penclen)
- goto err;
- wrap_str = ASN1_STRING_new();
- if (wrap_str == NULL)
- goto err;
- ASN1_STRING_set0(wrap_str, penc, penclen);
- penc = NULL;
- X509_ALGOR_set0(talg, OBJ_nid2obj(kdf_nid), V_ASN1_SEQUENCE, wrap_str);
-
- rv = 1;
-
- err:
- OPENSSL_free(penc);
- X509_ALGOR_free(wrap_alg);
- return rv;
-}
-
-#endif
diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt
index 2aca84f838..7bb83593a6 100644
--- a/crypto/err/openssl.txt
+++ b/crypto/err/openssl.txt
@@ -1996,6 +1996,7 @@ ASN1_R_TYPE_NOT_CONSTRUCTED:156:type not constructed
ASN1_R_TYPE_NOT_PRIMITIVE:195:type not primitive
ASN1_R_UNEXPECTED_EOC:159:unexpected eoc
ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH:215:universalstring is wrong length
+ASN1_R_UNKNOWN_DIGEST:229:unknown digest
ASN1_R_UNKNOWN_FORMAT:160:unknown format
ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM:161:unknown message digest algorithm
ASN1_R_UNKNOWN_OBJECT_TYPE:162:unknown object type
@@ -2181,6 +2182,7 @@ CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA:108:content type not signed data
CMS_R_CONTENT_VERIFY_ERROR:109:content verify error
CMS_R_CTRL_ERROR:110:ctrl error
CMS_R_CTRL_FAILURE:111:ctrl failure
+CMS_R_DECODE_ERROR:187:decode error
CMS_R_DECRYPT_ERROR:112:decrypt error
CMS_R_ERROR_GETTING_PUBLIC_KEY:113:error getting public key
CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE:114:\
@@ -2192,6 +2194,9 @@ CMS_R_ESS_SIGNING_CERTID_MISMATCH_ERROR:183:ess signing certid mismatch error
CMS_R_INVALID_ENCRYPTED_KEY_LENGTH:117:invalid encrypted key length
CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER:176:invalid key encryption parameter
CMS_R_INVALID_KEY_LENGTH:118:invalid key length
+CMS_R_INVALID_LABEL:190:invalid label
+CMS_R_INVALID_OAEP_PARAMETERS:191:invalid oaep parameters
+CMS_R_KDF_PARAMETER_ERROR:186:kdf parameter error
CMS_R_MD_BIO_INIT_ERROR:119:md bio init error
CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH:120:\
messagedigest attribute wrong length
@@ -2223,10 +2228,12 @@ CMS_R_NO_PRIVATE_KEY:133:no private key
CMS_R_NO_PUBLIC_KEY:134:no public key
CMS_R_NO_RECEIPT_REQUEST:168:no receipt request
CMS_R_NO_SIGNERS:135:no signers
+CMS_R_PEER_KEY_ERROR:188:peer key error
CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE:136:\
private key does not match certificate
CMS_R_RECEIPT_DECODE_ERROR:169:receipt decode error
CMS_R_RECIPIENT_ERROR:137:recipient error
+CMS_R_SHARED_INFO_ERROR:189:shared info error
CMS_R_SIGNER_CERTIFICATE_NOT_FOUND:138:signer certificate not found
CMS_R_SIGNFINAL_ERROR:139:signfinal error
CMS_R_SMIME_TEXT_ERROR:140:smime text error
@@ -2242,9 +2249,11 @@ CMS_R_UNKNOWN_DIGEST_ALGORITHM:149:unknown digest algorithm
CMS_R_UNKNOWN_ID:150:unknown id
CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM:151:unsupported compression algorithm
CMS_R_UNSUPPORTED_CONTENT_TYPE:152:unsupported content type
+CMS_R_UNSUPPORTED_ENCRYPTION_TYPE:192:unsupported encryption type
CMS_R_UNSUPPORTED_KEK_ALGORITHM:153:unsupported kek algorithm
CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM:179:\
unsupported key encryption algorithm
+CMS_R_UNSUPPORTED_LABEL_SOURCE:193:unsupported label source
CMS_R_UNSUPPORTED_RECIPIENTINFO_TYPE:155:unsupported recipientinfo type
CMS_R_UNSUPPORTED_RECIPIENT_TYPE:154:unsupported recipient type
CMS_R_UNSUPPORTED_TYPE:156:unsupported type
diff --git a/crypto/evp/pmeth_lib.c b/crypto/evp/pmeth_lib.c
index fc06a101c8..042035a75a 100644
--- a/crypto/evp/pmeth_lib.c
+++ b/crypto/evp/pmeth_lib.c
@@ -1762,6 +1762,16 @@ int evp_pkey_ctx_use_cached_data(EVP_PKEY_CTX *ctx)
return ret;
}
+OPENSSL_CTX *EVP_PKEY_CTX_get0_libctx(EVP_PKEY_CTX *ctx)
+{
+ return ctx->libctx;
+}
+
+const char *EVP_PKEY_CTX_get0_propq(EVP_PKEY_CTX *ctx)
+{
+ return ctx->propquery;
+}
+
/* Utility functions to send a string of hex string to a ctrl */
int EVP_PKEY_CTX_str2ctrl(EVP_PKEY_CTX *ctx, int cmd, const char *str)
diff --git a/crypto/rsa/rsa_ameth.c b/crypto/rsa/rsa_ameth.c
index 6105b7849a..c693ca7e21 100644
--- a/crypto/rsa/rsa_ameth.c
+++ b/crypto/rsa/rsa_ameth.c
@@ -18,7 +18,6 @@
#include <openssl/asn1t.h>
#include <openssl/x509.h>
#include <openssl/bn.h>
-#include <openssl/cms.h>
#include <openssl/core_names.h>
#include <openssl/param_build.h>
#include "crypto/asn1.h"
@@ -26,13 +25,6 @@
#include "crypto/rsa.h"
#include "rsa_local.h"
-#ifndef OPENSSL_NO_CMS
-static int rsa_cms_sign(CMS_SignerInfo *si);
-static int rsa_cms_verify(CMS_SignerInfo *si);
-static int rsa_cms_decrypt(CMS_RecipientInfo *ri);
-static int rsa_cms_encrypt(CMS_RecipientInfo *ri);
-#endif
-
static RSA_PSS_PARAMS *rsa_pss_decode(const X509_ALGOR *alg);
static int rsa_sync_to_pss_params_30(RSA *rsa);
@@ -256,14 +248,6 @@ static void int_rsa_free(EVP_PKEY *pkey)
RSA_free(pkey->pkey.rsa);
}
-static X509_ALGOR *rsa_mgf1_decode(X509_ALGOR *alg)
-{
- if (OBJ_obj2nid(alg->algorithm) != NID_mgf1)
- return NULL;
- return ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(X509_ALGOR),
- alg->parameter);
-}
-
static int rsa_pss_param_print(BIO *bp, int pss_key, RSA_PSS_PARAMS *pss,
int indent)
{
@@ -315,7 +299,7 @@ static int rsa_pss_param_print(BIO *bp, int pss_key, RSA_PSS_PARAMS *pss,
goto err;
if (BIO_puts(bp, " with ") <= 0)
goto err;
- maskHash = rsa_mgf1_decode(pss->maskGenAlgorithm);
+ maskHash = x509_algor_mgf1_decode(pss->maskGenAlgorithm);
if (maskHash != NULL) {
if (i2a_ASN1_OBJECT(bp, maskHash->algorithm) <= 0)
goto err;
@@ -471,7 +455,7 @@ static RSA_PSS_PARAMS *rsa_pss_decode(const X509_ALGOR *alg)
return NULL;
if (pss->maskGenAlgorithm != NULL) {
- pss->maskHash = rsa_mgf1_decode(pss->maskGenAlgorithm);
+ pss->maskHash = x509_algor_mgf1_decode(pss->maskGenAlgorithm);
if (pss->maskHash == NULL) {
RSA_PSS_PARAMS_free(pss);
return NULL;
@@ -520,29 +504,6 @@ static int rsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
if (arg1 == 0)
PKCS7_RECIP_INFO_get0_alg(arg2, &alg);
break;
-#ifndef OPENSSL_NO_CMS
- case ASN1_PKEY_CTRL_CMS_SIGN:
- if (arg1 == 0)
- return rsa_cms_sign(arg2);
- else if (arg1 == 1)
- return rsa_cms_verify(arg2);
- break;
-
- case ASN1_PKEY_CTRL_CMS_ENVELOPE:
- if (pkey_is_pss(pkey))
- return -2;
- if (arg1 == 0)
- return rsa_cms_encrypt(arg2);
- else if (arg1 == 1)
- return rsa_cms_decrypt(arg2);
- break;
-
- case ASN1_PKEY_CTRL_CMS_RI_TYPE:
- if (pkey_is_pss(pkey))
- return -2;
- *(int *)arg2 = CMS_RECIPINFO_TRANS;
- return 1;
-#endif
case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
if (pkey->pkey.rsa->pss != NULL) {
@@ -570,58 +531,6 @@ static int rsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
}
-/* allocate and set algorithm ID from EVP_MD, default SHA1 */
-static int rsa_md_to_algor(X509_ALGOR **palg, const EVP_MD *md)
-{
- if (md == NULL || EVP_MD_type(md) == NID_sha1)
- return 1;
- *palg = X509_ALGOR_new();
- if (*palg == NULL)
- return 0;
- X509_ALGOR_set_md(*palg, md);
- return 1;
-}
-
-/* Allocate and set MGF1 algorithm ID from EVP_MD */
-static int rsa_md_to_mgf1(X509_ALGOR **palg, const EVP_MD *mgf1md)
-{
- X509_ALGOR *algtmp = NULL;
- ASN1_STRING *stmp = NULL;
-
- *palg = NULL;
- if (mgf1md == NULL || EVP_MD_type(mgf1md) == NID_sha1)
- return 1;
- /* 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) == NULL)
- goto err;
- *palg = X509_ALGOR_new();
- if (*palg == NULL)
- goto err;
- X509_ALGOR_set0(*palg, OBJ_nid2obj(NID_mgf1), V_ASN1_SEQUENCE, stmp);
- stmp = NULL;
- err:
- ASN1_STRING_free(stmp);
- X509_ALGOR_free(algtmp);
- if (*palg)
- return 1;
- return 0;
-}
-
-/* convert algorithm ID to EVP_MD, default SHA1 */
-static const EVP_MD *rsa_algor_to_md(X509_ALGOR *alg)
-{
- const EVP_MD *md;
-
- if (!alg)
- return EVP_sha1();
- md = EVP_get_digestbyobj(alg->algorithm);
- if (md == NULL)
- RSAerr(RSA_F_RSA_ALGOR_TO_MD, RSA_R_UNKNOWN_DIGEST);
- return md;
-}
-
/*
* Convert EVP_PKEY_CTX in PSS mode into corresponding algorithm parameter,
* suitable for setting an AlgorithmIdentifier.
@@ -631,7 +540,6 @@ static RSA_PSS_PARAMS *rsa_ctx_to_pss(EVP_PKEY_CTX *pkctx)
{
const EVP_MD *sigmd, *mgf1md;
EVP_PKEY *pk = EVP_PKEY_CTX_get0_pkey(pkctx);
- RSA *rsa = EVP_PKEY_get0_RSA(pk);
int saltlen;
if (EVP_PKEY_CTX_get_signature_md(pkctx, &sigmd) <= 0)
@@ -643,7 +551,7 @@ static RSA_PSS_PARAMS *rsa_ctx_to_pss(EVP_PKEY_CTX *pkctx)
if (saltlen == -1) {
saltlen = EVP_MD_size(sigmd);
} else if (saltlen == -2 || saltlen == -3) {
- saltlen = RSA_size(rsa) - EVP_MD_size(sigmd) - 2;
+ saltlen = EVP_PKEY_size(pk) - EVP_MD_size(sigmd) - 2;
if ((EVP_PKEY_bits(pk) & 0x7) == 1)
saltlen--;
if (saltlen < 0)
@@ -667,13 +575,13 @@ RSA_PSS_PARAMS *rsa_pss_params_create(const EVP_MD *sigmd,
if (!ASN1_INTEGER_set(pss->saltLength, saltlen))
goto err;
}
- if (!rsa_md_to_algor(&pss->hashAlgorithm, sigmd))
+ if (!x509_algor_new_from_md(&pss->hashAlgorithm, sigmd))
goto err;
if (mgf1md == NULL)
mgf1md = sigmd;
- if (!rsa_md_to_mgf1(&pss->maskGenAlgorithm, mgf1md))
+ if (!x509_algor_md_to_mgf1(&pss->maskGenAlgorithm, mgf1md))
goto err;
- if (!rsa_md_to_algor(&pss->maskHash, mgf1md))
+ if (!x509_algor_new_from_md(&pss->maskHash, mgf1md))
goto err;
return pss;
err:
@@ -681,7 +589,7 @@ RSA_PSS_PARAMS *rsa_pss_params_create(const EVP_MD *sigmd,
return NULL;
}
-static ASN1_STRING *rsa_ctx_to_pss_string(EVP_PKEY_CTX *pkctx)
+ASN1_STRING *ossl_rsa_ctx_to_pss_string(EVP_PKEY_CTX *pkctx)
{
RSA_PSS_PARAMS *pss = rsa_ctx_to_pss(pkctx);
ASN1_STRING *os;
@@ -700,8 +608,8 @@ static ASN1_STRING *rsa_ctx_to_pss_string(EVP_PKEY_CTX *pkctx)
* passed to pkctx instead.
*/
-static int rsa_pss_to_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pkctx,
- const X509_ALGOR *sigalg, EVP_PKEY *pkey)
+int ossl_rsa_pss_to_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pkctx,
+ const X509_ALGOR *sigalg, EVP_PKEY *pkey)
{
int rv = -1;
int saltlen;
@@ -710,14 +618,14 @@ static int rsa_pss_to_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pkctx,
/* Sanity check: make sure it is PSS */
if (OBJ_obj2nid(sigalg->algorithm) != EVP_PKEY_RSA_PSS) {
- RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_UNSUPPORTED_SIGNATURE_TYPE);
+ RSAerr(0, RSA_R_UNSUPPORTED_SIGNATURE_TYPE);
return -1;
}
/* Decode PSS parameters */
pss = rsa_pss_decode(sigalg);
if (!rsa_pss_get_param(pss, &md, &mgf1md, &saltlen)) {
- RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_INVALID_PSS_PARAMETERS);
+ RSAerr(0, RSA_R_INVALID_PSS_PARAMETERS);
goto err;
}
@@ -730,7 +638,7 @@ static int rsa_pss_to_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pkctx,
if (EVP_PKEY_CTX_get_signature_md(pkctx, &checkmd) <= 0)
goto err;
if (EVP_MD_type(md) != EVP_MD_type(checkmd)) {
- RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_DIGEST_DOES_NOT_MATCH);
+ RSAerr(0, RSA_R_DIGEST_DOES_NOT_MATCH);
goto err;
}
}
@@ -781,10 +689,10 @@ static int rsa_pss_get_param_unverified(const RSA_PSS_PARAMS *pss,
if (pss == NULL)
return 0;
- *pmd = rsa_algor_to_md(pss->hashAlgorithm);
+ *pmd = x509_algor_get_md(pss->hashAlgorithm);
if (*pmd == NULL)
return 0;
- *pmgf1md = rsa_algor_to_md(pss->maskHash);
+ *pmgf1md = x509_algor_get_md(pss->maskHash);
if (*pmgf1md == NULL)
return 0;
if (pss->saltLength)
@@ -851,33 +759,6 @@ static int rsa_sync_to_pss_params_30(RSA *rsa)
return 1;
}
-#ifndef OPENSSL_NO_CMS
-static int rsa_cms_verify(CMS_SignerInfo *si)
-{
- int nid, nid2;
- X509_ALGOR *alg;
- EVP_PKEY_CTX *pkctx = CMS_SignerInfo_get0_pkey_ctx(si);
-
- CMS_SignerInfo_get0_algs(si, NULL, NULL, NULL, &alg);
- nid = OBJ_obj2nid(alg->algorithm);
- if (nid == EVP_PKEY_RSA_PSS)
- return rsa_pss_to_ctx(NULL, pkctx, alg, NULL);
- /* Only PSS allowed for PSS keys */
- if (pkey_ctx_is_pss(pkctx)) {
- RSAerr(RSA_F_RSA_CMS_VERIFY, RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE);
- return 0;
- }
- if (nid == NID_rsaEncryption)
- return 1;
- /* Workaround for some implementation that use a signature OID */
- if (OBJ_find_sigid_algs(nid, NULL, &nid2)) {
- if (nid2 == NID_rsaEncryption)
- return 1;
- }
- return 0;
-}
-#endif
-
/*
* Customised RSA item verification routine. This is called when a signature
* is encountered requiring special handling. We currently only handle PSS.
@@ -892,41 +773,13 @@ static int rsa_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it,
RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNSUPPORTED_SIGNATURE_TYPE);
return -1;
}
- if (rsa_pss_to_ctx(ctx, NULL, sigalg, pkey) > 0) {
+ if (ossl_rsa_pss_to_ctx(ctx, NULL, sigalg, pkey) > 0) {
/* Carry on */
return 2;
}
return -1;
}
-#ifndef OPENSSL_NO_CMS
-static int rsa_cms_sign(CMS_SignerInfo *si)
-{
- int pad_mode = RSA_PKCS1_PADDING;
- X509_ALGOR *alg;
- EVP_PKEY_CTX *pkctx = CMS_SignerInfo_get0_pkey_ctx(si);
- ASN1_STRING *os = NULL;
-
- CMS_SignerInfo_get0_algs(si, NULL, NULL, NULL, &alg);
- if (pkctx) {
- if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0)
- return 0;
- }
- if (pad_mode == RSA_PKCS1_PADDING) {
- X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0);
- return 1;
- }
- /* We don't support it */
- if (pad_mode != RSA_PKCS1_PSS_PADDING)
- return 0;
- os = rsa_ctx_to_pss_string(pkctx);
- if (!os)
- return 0;
- X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_PKEY_RSA_PSS), V_ASN1_SEQUENCE, os);
- return 1;
-}
-#endif
-
static int rsa_item_sign(EVP_MD_CTX *ctx, const ASN1_ITEM *it, const void *asn,
X509_ALGOR *alg1, X509_ALGOR *alg2,
ASN1_BIT_STRING *sig)
@@ -940,7 +793,7 @@ static int rsa_item_sign(EVP_MD_CTX *ctx, const ASN1_ITEM *it, const void *asn,
return 2;
if (pad_mode == RSA_PKCS1_PSS_PADDING) {
ASN1_STRING *os1 = NULL;
- os1 = rsa_ctx_to_pss_string(pkctx);
+ os1 = ossl_rsa_ctx_to_pss_string(pkctx);
if (!os1)
return 0;
/* Duplicate parameters if we have to */
@@ -1013,165 +866,6 @@ static int rsa_sig_info_set(X509_SIG_INFO *siginf, const X509_ALGOR *sigalg,
return rv;
}
-#ifndef OPENSSL_NO_CMS
-static RSA_OAEP_PARAMS *rsa_oaep_decode(const X509_ALGOR *alg)
-{
- RSA_OAEP_PARAMS *oaep;
-
- oaep = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(RSA_OAEP_PARAMS),
- alg->parameter);
-
- if (oaep == NULL)
- return NULL;
-
- if (oaep->maskGenFunc != NULL) {
- oaep->maskHash = rsa_mgf1_decode(oaep->maskGenFunc);
- if (oaep->maskHash == NULL) {
- RSA_OAEP_PARAMS_free(oaep);
- return NULL;
- }
- }
- return oaep;
-}
-
-static int rsa_cms_decrypt(CMS_RecipientInfo *ri)
-{
- EVP_PKEY_CTX *pkctx;
- X509_ALGOR *cmsalg;
- int nid;
- int rv = -1;
- unsigned char *label = NULL;
- int labellen = 0;
- const EVP_MD *mgf1md = NULL, *md = NULL;
- RSA_OAEP_PARAMS *oaep;
-
- pkctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
- if (pkctx == NULL)
- return 0;
- if (!CMS_RecipientInfo_ktri_get0_algs(ri, NULL, NULL, &cmsalg))
- return -1;
- nid = OBJ_obj2nid(cmsalg->algorithm);
- if (nid == NID_rsaEncryption)
- return 1;
- if (nid != NID_rsaesOaep) {
- RSAerr(RSA_F_RSA_CMS_DECRYPT, RSA_R_UNSUPPORTED_ENCRYPTION_TYPE);
- return -1;
- }
- /* Decode OAEP parameters */
- oaep = rsa_oaep_decode(cmsalg);
-
- if (oaep == NULL) {
- RSAerr(RSA_F_RSA_CMS_DECRYPT, RSA_R_INVALID_OAEP_PARAMETERS);
- goto err;
- }
-
- mgf1md = rsa_algor_to_md(oaep->maskHash);
- if (mgf1md == NULL)
- goto err;
- md = rsa_algor_to_md(oaep->hashFunc);
- if (md == NULL)
- goto err;
-
- if (oaep->pSourceFunc != NULL) {
- X509_ALGOR *plab = oaep->pSourceFunc;
-
- if (OBJ_obj2nid(plab->algorithm) != NID_pSpecified) {
- RSAerr(RSA_F_RSA_CMS_DECRYPT, RSA_R_UNSUPPORTED_LABEL_SOURCE);
- goto err;
- }
- if (plab->parameter->type != V_ASN1_OCTET_STRING) {
- RSAerr(RSA_F_RSA_CMS_DECRYPT, RSA_R_INVALID_LABEL);
- goto err;
- }
-
- label = plab->parameter->value.octet_string->data;
- /* Stop label being freed when OAEP parameters are freed */
- plab->parameter->value.octet_string->data = NULL;
- labellen = plab->parameter->value.octet_string->length;
- }
-
- if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_OAEP_PADDING) <= 0)
- goto err;
- if (EVP_PKEY_CTX_set_rsa_oaep_md(pkctx, md) <= 0)
- goto err;
- if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md) <= 0)
- goto err;
- if (label != NULL
- && EVP_PKEY_CTX_set0_rsa_oaep_label(pkctx, label, labellen) <= 0)
- goto err;
- /* Carry on */
- rv = 1;
-
- err:
- RSA_OAEP_PARAMS_free(oaep);
- return rv;
-}
-
-static int rsa_cms_encrypt(CMS_RecipientInfo *ri)
-{
- const EVP_MD *md, *mgf1md;
- RSA_OAEP_PARAMS *oaep = NULL;
- ASN1_STRING *os = NULL;
- X509_ALGOR *alg;
- EVP_PKEY_CTX *pkctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
- int pad_mode = RSA_PKCS1_PADDING, rv = 0, labellen;
- unsigned char *label;
-
- if (CMS_RecipientInfo_ktri_get0_algs(ri, NULL, NULL, &alg) <= 0)
- return 0;
- if (pkctx) {
- if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0)
- return 0;
- }
- if (pad_mode == RSA_PKCS1_PADDING) {
- X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0);
- return 1;
- }
- /* Not supported */
- if (pad_mode != RSA_PKCS1_OAEP_PADDING)
- return 0;
- if (EVP_PKEY_CTX_get_rsa_oaep_md(pkctx, &md) <= 0)
- goto err;
- if (EVP_PKEY_CTX_get_rsa_mgf1_md(pkctx, &mgf1md) <= 0)
- goto err;
- labellen = EVP_PKEY_CTX_get0_rsa_oaep_label(pkctx, &label);
- if (labellen < 0)
- goto err;
- oaep = RSA_OAEP_PARAMS_new();
- if (oaep == NULL)
- goto err;
- if (!rsa_md_to_algor(&oaep->hashFunc, md))
- goto err;
- if (!rsa_md_to_mgf1(&oaep->maskGenFunc, mgf1md))
- goto err;
- if (labellen > 0) {
- ASN1_OCTET_STRING *los;
- oaep->pSourceFunc = X509_ALGOR_new();
- if (oaep->pSourceFunc == NULL)
- goto err;
- los = ASN1_OCTET_STRING_new();
- if (los == NULL)
- goto err;
- if (!ASN1_OCTET_STRING_set(los, label, labellen)) {
- ASN1_OCTET_STRING_free(los);
- goto err;
- }
- X509_ALGOR_set0(oaep->pSourceFunc, OBJ_nid2obj(NID_pSpecified),
- V_ASN1_OCTET_STRING, los);
- }
- /* create string with pss parameter encoding. */
- if (!ASN1_item_pack(oaep, ASN1_ITEM_rptr(RSA_OAEP_PARAMS), &os))
- goto err;
- X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaesOaep), V_ASN1_SEQUENCE, os);
- os = NULL;
- rv = 1;
- err:
- RSA_OAEP_PARAMS_free(oaep);
- ASN1_STRING_free(os);
- return rv;
-}
-#endif
-
static int rsa_pkey_check(const EVP_PKEY *pkey)
{
return RSA_check_key_ex(pkey->pkey.rsa, NULL);
diff --git a/doc/man3/EVP_PKEY_CTX_get0_libctx.pod b/doc/man3/EVP_PKEY_CTX_get0_libctx.pod
new file mode 100644
index 0000000000..2536ae820e
--- /dev/null
+++ b/doc/man3/EVP_PKEY_CTX_get0_libctx.pod
@@ -0,0 +1,45 @@
+=pod
+
+=head1 NAME
+
+EVP_PKEY_CTX_get0_libctx,
+EVP_PKEY_CTX_get0_propq
+- functions for getting OPENSSL_CTX and property query data from an EVP_PKEY_CTX
+
+=head1 SYNOPSIS
+
+ #include <openssl/evp.h>
+
+ OPENSSL_CTX *EVP_PKEY_CTX_get0_libctx(EVP_PKEY_CTX *ctx);
+ const char *EVP_PKEY_CTX_get0_propq(EVP_PKEY_CTX *ctx);
+
+=head1 DESCRIPTION
+
+The EVP_PKEY_CTX_get0_libctx() and EVP_PKEY_CTX_get0_propq() functions obtain
+the OPENSSL_CTX and property query string values respectively that were
+associated with the EVP_PKEY_CTX when it was constructed.
+
+=head1 RETURN VALUES
+
+EVP_PKEY_CTX_get0_libctx() and EVP_PKEY_CTX_get0_propq() functions return the
+OPENSSL_CTX and property query string associated with the EVP_PKEY_CTX or NULL
+if they are not set. The returned values should not be freed by the caller.
+
+=head1 SEE ALSO
+
+L<EVP_PKEY_CTX_new(3)>
+
+=head1 HISTORY
+
+All functions were added in OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
+
+Licensed under the Apache License 2.0 (the "License"). You may not use
+this file except in compliance with the License. You can obtain a copy
+in the file LICENSE in the source distribution or at
+L<https://www.openssl.org/source/license.html>.
+
+=cut
diff --git a/include/crypto/asn1.h b/include/crypto/asn1.h
index 5f6987e066..08018e4cf1 100644
--- a/include/crypto/asn1.h
+++ b/include/crypto/asn1.h
@@ -133,3 +133,8 @@ int asn1_type_set_octetstring_int(ASN1_TYPE *a, long num,
unsigned char *data, int len);
int asn1_type_get_octetstring_int(const ASN1_TYPE *a, long *num,
unsigned char *data, int max_len);
+
+int x509_algor_new_from_md(X509_ALGOR **palg, const EVP_MD *md);
+const EVP_MD *x509_algor_get_md(X509_ALGOR *alg);
+X509_ALGOR *x509_algor_mgf1_decode(X509_ALGOR *alg);
+int x509_algor_md_to_mgf1(X509_ALGOR **palg, const EVP_MD *mgf1md);
diff --git a/include/crypto/rsa.h b/include/crypto/rsa.h
index 85682aa55d..7ec745766f 100644
--- a/include/crypto/rsa.h
+++ b/include/crypto/rsa.h
@@ -93,6 +93,10 @@ extern const char *ossl_rsa_mp_factor_names[];
extern const char *ossl_rsa_mp_exp_names[];
extern const char *ossl_rsa_mp_coeff_names[];
+ASN1_STRING *ossl_rsa_ctx_to_pss_string(EVP_PKEY_CTX *pkctx);
+int ossl_rsa_pss_to_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pkctx,
+ const X509_ALGOR *sigalg, EVP_PKEY *pkey);
+
# if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS)
int rsa_acvp_test_gen_params_new(OSSL_PARAM **dst, const OSSL_PARAM src[]);
void rsa_acvp_test_gen_params_free(OSSL_PARAM *dst);
diff --git a/include/openssl/asn1err.h b/include/openssl/asn1err.h
index b58339ba47..a29722e868 100644
--- a/include/openssl/asn1err.h
+++ b/include/openssl/asn1err.h
@@ -244,6 +244,7 @@ int ERR_load_ASN1_strings(void);
# define ASN1_R_TYPE_NOT_PRIMITIVE 195
# define ASN1_R_UNEXPECTED_EOC 159
# define ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH 215
+# define ASN1_R_UNKNOWN_DIGEST 229
# define ASN1_R_UNKNOWN_FORMAT 160
# define ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM 161
# define ASN1_R_UNKNOWN_OBJECT_TYPE 162
diff --git a/include/openssl/cmserr.h b/include/openssl/cmserr.h
index 1e7daf044b..e234ad0126 100644
--- a/include/openssl/cmserr.h
+++ b/include/openssl/cmserr.h
@@ -146,6 +146,7 @@ int ERR_load_CMS_strings(void);
# define CMS_R_CONTENT_VERIFY_ERROR 109
# define CMS_R_CTRL_ERROR 110
# define CMS_R_CTRL_FAILURE 111
+# define CMS_R_DECODE_ERROR 187
# define CMS_R_DECRYPT_ERROR 112
# define CMS_R_ERROR_GETTING_PUBLIC_KEY 113
# define CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE 114
@@ -156,6 +157,9 @@ int ERR_load_CMS_strings(void);
# define CMS_R_INVALID_ENCRYPTED_KEY_LENGTH 117
# define CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER 176
# define CMS_R_INVALID_KEY_LENGTH 118
+# define CMS_R_INVALID_LABEL 190
+# define CMS_R_INVALID_OAEP_PARAMETERS 191
+# define CMS_R_KDF_PARAMETER_ERROR 186
# define CMS_R_MD_BIO_INIT_ERROR 119
# define CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH 120
# define CMS_R_MESSAGEDIGEST_WRONG_LENGTH 121
@@ -186,9 +190,11 @@ int ERR_load_CMS_strings(void);
# define CMS_R_NO_PUBLIC_KEY 134
# define CMS_R_NO_RECEIPT_REQUEST 168
# define CMS_R_NO_SIGNERS 135
+# define CMS_R_PEER_KEY_ERROR 188
# define CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 136
# define CMS_R_RECEIPT_DECODE_ERROR 169
# define CMS_R_RECIPIENT_ERROR 137
+# define CMS_R_SHARED_INFO_ERROR 189
# define CMS_R_SIGNER_CERTIFICATE_NOT_FOUND 138
# define CMS_R_SIGNFINAL_ERROR 139
# define CMS_R_SMIME_TEXT_ERROR 140
@@ -204,8 +210,10 @@ int ERR_load_CMS_strings(void);
# define CMS_R_UNKNOWN_ID 150
# define CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM 151
# define CMS_R_UNSUPPORTED_CONTENT_TYPE 152
+# define CMS_R_UNSUPPORTED_ENCRYPTION_TYPE 192
# define CMS_R_UNSUPPORTED_KEK_ALGORITHM 153
# define CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM 179
+# define CMS_R_UNSUPPORTED_LABEL_SOURCE 193
# define CMS_R_UNSUPPORTED_RECIPIENTINFO_TYPE 155
# define CMS_R_UNSUPPORTED_RECIPIENT_TYPE 154
# define CMS_R_UNSUPPORTED_TYPE 156
diff --git a/include/openssl/evp.h b/include/openssl/evp.h
index 8c2d00813c..5527709be0 100644
--- a/include/openssl/evp.h
+++ b/include/openssl/evp.h
@@ -1966,6 +1966,9 @@ int EVP_hex2ctrl(int (*cb)(void *ctx, int cmd, void *buf, size_t buflen),
int EVP_PKEY_CTX_set_group_name(EVP_PKEY_CTX *ctx, const char *name);
int EVP_PKEY_CTX_get_group_name(EVP_PKEY_CTX *ctx, char *name, size_t namelen);
+OPENSSL_CTX *EVP_PKEY_CTX_get0_libctx(EVP_PKEY_CTX *ctx);
+const char *EVP_PKEY_CTX_get0_propq(EVP_PKEY_CTX *ctx);
+
# ifdef __cplusplus
}
# endif
diff --git a/util/libcrypto.num b/util/libcrypto.num
index fb0069c9e8..12ba103689 100644
--- a/util/libcrypto.num
+++ b/util/libcrypto.num
@@ -5288,3 +5288,5 @@ PKCS7_type_is_other ? 3_0_0 EXIST::FUNCTION:
PKCS7_get_octet_string ? 3_0_0 EXIST::FUNCTION:
OSSL_DECODER_from_data ? 3_0_0 EXIST::FUNCTION:
OSSL_ENCODER_to_data ? 3_0_0 EXIST::FUNCTION:
+EVP_PKEY_CTX_get0_libctx ? 3_0_0 EXIST::FUNCTION:
+EVP_PKEY_CTX_get0_propq ? 3_0_0 EXIST::FUNCTION:
More information about the openssl-commits
mailing list