Move CMS enveloping code out of the algorithms and into CMS
authorMatt Caswell <matt@openssl.org>
Tue, 6 Oct 2020 15:02:43 +0000 (16:02 +0100)
committerMatt Caswell <matt@openssl.org>
Thu, 15 Oct 2020 09:00:19 +0000 (10:00 +0100)
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@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/13088)

18 files changed:
crypto/asn1/asn1_err.c
crypto/asn1/x_algor.c
crypto/cms/build.info
crypto/cms/cms_dh.c [new file with mode: 0644]
crypto/cms/cms_ecdh.c [new file with mode: 0644]
crypto/cms/cms_env.c
crypto/cms/cms_err.c
crypto/cms/cms_local.h
crypto/cms/cms_rsa.c [new file with mode: 0644]
crypto/dh/dh_ameth.c
crypto/ec/ec_ameth.c
crypto/err/openssl.txt
crypto/evp/pmeth_lib.c
crypto/rsa/rsa_ameth.c
include/crypto/asn1.h
include/crypto/evp.h
include/openssl/asn1err.h
include/openssl/cmserr.h

index 6a599bc067c60eef6c72d5fc86f5f5c872bca067..814cd91373e5670e1f3dd27335f69b2c99d2adec 100644 (file)
@@ -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"},
index f29d26d91ca5680fa5f7952205518376b9f61a01..c5453f9fd8f2462c9633b6f2a95eb9efbcd5693e 100644 (file)
@@ -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)
+        return 1;
+    return 0;
+}
index cb675436ef06e45167ffa31b490a6da5db2212a9..2f5b6533821c4585d670a6b218e540bb2fcf52d6 100644 (file)
@@ -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{ed} -}]
+  SOURCE[../../libcrypto]=cms_ecdh.c
+ENDIF
\ No newline at end of file
diff --git a/crypto/cms/cms_dh.c b/crypto/cms/cms_dh.c
new file mode 100644 (file)
index 0000000..aca6096
--- /dev/null
@@ -0,0 +1,322 @@
+/*
+ * 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 <openssl/cms.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)
+        goto err;
+    if (!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)
+        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 == 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;
+
+    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;
+    X509_ALGOR_get0(&aoid, NULL, NULL, talg);
+    /* Is everything uninitialised? */
+    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)
+        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 != 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)
+{
+    if (decrypt == 1)
+        return dh_cms_decrypt(ri);
+    else if (decrypt == 0)
+        return dh_cms_encrypt(ri);
+
+    CMSerr(0, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
+    return 0;
+}
\ No newline at end of file
diff --git a/crypto/cms/cms_ecdh.c b/crypto/cms/cms_ecdh.c
new file mode 100644 (file)
index 0000000..b88be91
--- /dev/null
@@ -0,0 +1,391 @@
+/*
+ * 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 <openssl/cms.h>
+#include <openssl/err.h>
+#include <openssl/decoder.h>
+#include "cms_local.h"
+#include "crypto/evp.h"
+
+
+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);
+        membio = BIO_new_mem_buf(pm, pmlen);
+        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)
+            goto err;
+        if (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) {
+            EVP_PKEY_free(pkey);
+            pkey = NULL;
+        }
+    } 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 {
+        /* TODO(3.0): Should the get0_libctx/propq calls actually be public API? */
+        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 || !pubkey)
+            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)
+        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;
+}
+
+int cms_ecdh_envelope(CMS_RecipientInfo *ri, int decrypt)
+{
+    if (decrypt == 1)
+        return ecdh_cms_decrypt(ri);
+    else if (decrypt == 0)
+        return ecdh_cms_encrypt(ri);
+
+    CMSerr(0, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
+    return 0;
+}
\ No newline at end of file
index b1bba4c2d62b8ef68f3f01f711ab4a9d0ef5db65..395e05ce55dda42605a3530f9b1670140c11c666 100644 (file)
@@ -115,6 +115,15 @@ int cms_env_asn1_ctrl(CMS_RecipientInfo *ri, int cmd)
             return 0;
     } else
         return 0;
+
+    if (EVP_PKEY_is_a(pkey, "DHX"))
+        return cms_dh_envelope(ri, cmd);
+    else if (EVP_PKEY_is_a(pkey, "EC"))
+        return cms_ecdh_envelope(ri, cmd);
+    else 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);
index da14c726c40e6ae7c072daacc856fd4ab1a2e02f..fdb2b7f5c879f78994962cabd6d501961ed37cd9 100644 (file)
@@ -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),
index 336c354655948f530dfa485d4666ae96aed14d22..e162ea13ad2876a84a2ca8b97eb5166983730783 100644 (file)
@@ -471,6 +471,10 @@ 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);
+
 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 (file)
index 0000000..82d36d9
--- /dev/null
@@ -0,0 +1,182 @@
+/*
+ * 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 <openssl/cms.h>
+#include <openssl/err.h>
+#include "crypto/asn1.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) {
+        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)
+{
+    if (decrypt == 1)
+        return rsa_cms_decrypt(ri);
+    else if (decrypt == 0)
+        return rsa_cms_encrypt(ri);
+
+    CMSerr(0, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
+    return 0;
+}
\ No newline at end of file
index e32de78638e4251307162b7b97fe011ab1ea0740..46a2fdd881b7f864cdca6ec9cb963106a2cb050d 100644 (file)
 #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 <openssl/cms.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 +434,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) {
@@ -455,14 +450,6 @@ 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;
@@ -675,308 +662,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
index 4bbbabff0753b380af33772234d8169aa22357b5..25644577cdef71f54f8cb31ee34d7e359e66a59a 100644 (file)
 #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;
@@ -511,13 +506,6 @@ static int ec_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
         }
         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;
@@ -828,327 +816,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
index 2aca84f8383f6211d6af80b6a7a6a5d3a80dc5c4..7bb83593a6b5130ddf166c7b9bf6f41837d7dca8 100644 (file)
@@ -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
index fc06a101c8a4bf2652fcbe764e16ad1b3a69c6ad..8cd95956f898df4524b4432aa729d4a50700cd07 100644 (file)
@@ -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)
index 6105b7849a20f51371c48955f97abd6c16f24de4..562f307bcb0610abd2b756ad76d29caf92e2d1ab 100644 (file)
@@ -29,8 +29,6 @@
 #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);
@@ -256,14 +254,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 +305,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 +461,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;
@@ -528,15 +518,6 @@ static int rsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
             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;
@@ -570,58 +551,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.
@@ -667,13 +596,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:
@@ -781,10 +710,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)
@@ -1013,165 +942,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);
index 5f6987e06686e22f8621715e328b70ac2a384292..72e105276f692e229cc47dffd602eb3c7b0b2128 100644 (file)
@@ -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);
\ No newline at end of file
index ac20b5b51209ed81e51aeed1959adb8281e2e13e..86b85960e7d2f4b5be7879c7442dd6838565356c 100644 (file)
@@ -835,6 +835,8 @@ int evp_pkey_ctx_get1_id_len_prov(EVP_PKEY_CTX *ctx, size_t *id_len);
 
 int evp_pkey_ctx_use_cached_data(EVP_PKEY_CTX *ctx);
 #endif /* !defined(FIPS_MODULE) */
+OPENSSL_CTX *evp_pkey_ctx_get0_libctx(EVP_PKEY_CTX *ctx);
+const char *evp_pkey_ctx_get0_propq(EVP_PKEY_CTX *ctx);
 void evp_method_store_flush(OPENSSL_CTX *libctx);
 int evp_set_default_properties_int(OPENSSL_CTX *libctx, const char *propq,
                                    int loadconfig);
index b58339ba47bbdcbb2917aebeb21bdabd0c60b563..a29722e86834d5b21db8fd71b72bd9eec0e4642f 100644 (file)
@@ -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
index 1e7daf044ba36651507d9f158c76d9f413a011b2..e234ad0126af626bb80a9b7d6c8eb8254e272820 100644 (file)
@@ -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