1e1051a39Sopenharmony_ci/*
2e1051a39Sopenharmony_ci * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
3e1051a39Sopenharmony_ci *
4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License").  You may not use
5e1051a39Sopenharmony_ci * this file except in compliance with the License.  You can obtain a copy
6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at
7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html
8e1051a39Sopenharmony_ci */
9e1051a39Sopenharmony_ci
10e1051a39Sopenharmony_ci#include <stdio.h>
11e1051a39Sopenharmony_ci#include "internal/cryptlib.h"
12e1051a39Sopenharmony_ci#include <openssl/objects.h>
13e1051a39Sopenharmony_ci#include <openssl/x509.h>
14e1051a39Sopenharmony_ci#include <openssl/pkcs7.h>
15e1051a39Sopenharmony_ci#include "crypto/asn1.h"
16e1051a39Sopenharmony_ci#include "crypto/evp.h"
17e1051a39Sopenharmony_ci#include "crypto/x509.h" /* for sk_X509_add1_cert() */
18e1051a39Sopenharmony_ci#include "pk7_local.h"
19e1051a39Sopenharmony_ci
20e1051a39Sopenharmony_cilong PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg)
21e1051a39Sopenharmony_ci{
22e1051a39Sopenharmony_ci    int nid;
23e1051a39Sopenharmony_ci    long ret;
24e1051a39Sopenharmony_ci
25e1051a39Sopenharmony_ci    nid = OBJ_obj2nid(p7->type);
26e1051a39Sopenharmony_ci
27e1051a39Sopenharmony_ci    switch (cmd) {
28e1051a39Sopenharmony_ci    /* NOTE(emilia): does not support detached digested data. */
29e1051a39Sopenharmony_ci    case PKCS7_OP_SET_DETACHED_SIGNATURE:
30e1051a39Sopenharmony_ci        if (nid == NID_pkcs7_signed) {
31e1051a39Sopenharmony_ci            ret = p7->detached = (int)larg;
32e1051a39Sopenharmony_ci            if (ret && PKCS7_type_is_data(p7->d.sign->contents)) {
33e1051a39Sopenharmony_ci                ASN1_OCTET_STRING *os;
34e1051a39Sopenharmony_ci                os = p7->d.sign->contents->d.data;
35e1051a39Sopenharmony_ci                ASN1_OCTET_STRING_free(os);
36e1051a39Sopenharmony_ci                p7->d.sign->contents->d.data = NULL;
37e1051a39Sopenharmony_ci            }
38e1051a39Sopenharmony_ci        } else {
39e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_PKCS7,
40e1051a39Sopenharmony_ci                      PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE);
41e1051a39Sopenharmony_ci            ret = 0;
42e1051a39Sopenharmony_ci        }
43e1051a39Sopenharmony_ci        break;
44e1051a39Sopenharmony_ci    case PKCS7_OP_GET_DETACHED_SIGNATURE:
45e1051a39Sopenharmony_ci        if (nid == NID_pkcs7_signed) {
46e1051a39Sopenharmony_ci            if (p7->d.sign == NULL || p7->d.sign->contents->d.ptr == NULL)
47e1051a39Sopenharmony_ci                ret = 1;
48e1051a39Sopenharmony_ci            else
49e1051a39Sopenharmony_ci                ret = 0;
50e1051a39Sopenharmony_ci
51e1051a39Sopenharmony_ci            p7->detached = ret;
52e1051a39Sopenharmony_ci        } else {
53e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_PKCS7,
54e1051a39Sopenharmony_ci                      PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE);
55e1051a39Sopenharmony_ci            ret = 0;
56e1051a39Sopenharmony_ci        }
57e1051a39Sopenharmony_ci
58e1051a39Sopenharmony_ci        break;
59e1051a39Sopenharmony_ci    default:
60e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_PKCS7, PKCS7_R_UNKNOWN_OPERATION);
61e1051a39Sopenharmony_ci        ret = 0;
62e1051a39Sopenharmony_ci    }
63e1051a39Sopenharmony_ci    return ret;
64e1051a39Sopenharmony_ci}
65e1051a39Sopenharmony_ci
66e1051a39Sopenharmony_ciint PKCS7_content_new(PKCS7 *p7, int type)
67e1051a39Sopenharmony_ci{
68e1051a39Sopenharmony_ci    PKCS7 *ret = NULL;
69e1051a39Sopenharmony_ci
70e1051a39Sopenharmony_ci    if ((ret = PKCS7_new()) == NULL)
71e1051a39Sopenharmony_ci        goto err;
72e1051a39Sopenharmony_ci    if (!PKCS7_set_type(ret, type))
73e1051a39Sopenharmony_ci        goto err;
74e1051a39Sopenharmony_ci    if (!PKCS7_set_content(p7, ret))
75e1051a39Sopenharmony_ci        goto err;
76e1051a39Sopenharmony_ci
77e1051a39Sopenharmony_ci    return 1;
78e1051a39Sopenharmony_ci err:
79e1051a39Sopenharmony_ci    PKCS7_free(ret);
80e1051a39Sopenharmony_ci    return 0;
81e1051a39Sopenharmony_ci}
82e1051a39Sopenharmony_ci
83e1051a39Sopenharmony_ciint PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data)
84e1051a39Sopenharmony_ci{
85e1051a39Sopenharmony_ci    int i;
86e1051a39Sopenharmony_ci
87e1051a39Sopenharmony_ci    i = OBJ_obj2nid(p7->type);
88e1051a39Sopenharmony_ci    switch (i) {
89e1051a39Sopenharmony_ci    case NID_pkcs7_signed:
90e1051a39Sopenharmony_ci        PKCS7_free(p7->d.sign->contents);
91e1051a39Sopenharmony_ci        p7->d.sign->contents = p7_data;
92e1051a39Sopenharmony_ci        break;
93e1051a39Sopenharmony_ci    case NID_pkcs7_digest:
94e1051a39Sopenharmony_ci        PKCS7_free(p7->d.digest->contents);
95e1051a39Sopenharmony_ci        p7->d.digest->contents = p7_data;
96e1051a39Sopenharmony_ci        break;
97e1051a39Sopenharmony_ci    case NID_pkcs7_data:
98e1051a39Sopenharmony_ci    case NID_pkcs7_enveloped:
99e1051a39Sopenharmony_ci    case NID_pkcs7_signedAndEnveloped:
100e1051a39Sopenharmony_ci    case NID_pkcs7_encrypted:
101e1051a39Sopenharmony_ci    default:
102e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_PKCS7, PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
103e1051a39Sopenharmony_ci        goto err;
104e1051a39Sopenharmony_ci    }
105e1051a39Sopenharmony_ci    return 1;
106e1051a39Sopenharmony_ci err:
107e1051a39Sopenharmony_ci    return 0;
108e1051a39Sopenharmony_ci}
109e1051a39Sopenharmony_ci
110e1051a39Sopenharmony_ciint PKCS7_set_type(PKCS7 *p7, int type)
111e1051a39Sopenharmony_ci{
112e1051a39Sopenharmony_ci    ASN1_OBJECT *obj;
113e1051a39Sopenharmony_ci
114e1051a39Sopenharmony_ci    /*
115e1051a39Sopenharmony_ci     * PKCS7_content_free(p7);
116e1051a39Sopenharmony_ci     */
117e1051a39Sopenharmony_ci    obj = OBJ_nid2obj(type);    /* will not fail */
118e1051a39Sopenharmony_ci
119e1051a39Sopenharmony_ci    switch (type) {
120e1051a39Sopenharmony_ci    case NID_pkcs7_signed:
121e1051a39Sopenharmony_ci        p7->type = obj;
122e1051a39Sopenharmony_ci        if ((p7->d.sign = PKCS7_SIGNED_new()) == NULL)
123e1051a39Sopenharmony_ci            goto err;
124e1051a39Sopenharmony_ci        if (!ASN1_INTEGER_set(p7->d.sign->version, 1)) {
125e1051a39Sopenharmony_ci            PKCS7_SIGNED_free(p7->d.sign);
126e1051a39Sopenharmony_ci            p7->d.sign = NULL;
127e1051a39Sopenharmony_ci            goto err;
128e1051a39Sopenharmony_ci        }
129e1051a39Sopenharmony_ci        break;
130e1051a39Sopenharmony_ci    case NID_pkcs7_data:
131e1051a39Sopenharmony_ci        p7->type = obj;
132e1051a39Sopenharmony_ci        if ((p7->d.data = ASN1_OCTET_STRING_new()) == NULL)
133e1051a39Sopenharmony_ci            goto err;
134e1051a39Sopenharmony_ci        break;
135e1051a39Sopenharmony_ci    case NID_pkcs7_signedAndEnveloped:
136e1051a39Sopenharmony_ci        p7->type = obj;
137e1051a39Sopenharmony_ci        if ((p7->d.signed_and_enveloped = PKCS7_SIGN_ENVELOPE_new())
138e1051a39Sopenharmony_ci            == NULL)
139e1051a39Sopenharmony_ci            goto err;
140e1051a39Sopenharmony_ci        if (!ASN1_INTEGER_set(p7->d.signed_and_enveloped->version, 1))
141e1051a39Sopenharmony_ci            goto err;
142e1051a39Sopenharmony_ci        p7->d.signed_and_enveloped->enc_data->content_type
143e1051a39Sopenharmony_ci            = OBJ_nid2obj(NID_pkcs7_data);
144e1051a39Sopenharmony_ci        break;
145e1051a39Sopenharmony_ci    case NID_pkcs7_enveloped:
146e1051a39Sopenharmony_ci        p7->type = obj;
147e1051a39Sopenharmony_ci        if ((p7->d.enveloped = PKCS7_ENVELOPE_new())
148e1051a39Sopenharmony_ci            == NULL)
149e1051a39Sopenharmony_ci            goto err;
150e1051a39Sopenharmony_ci        if (!ASN1_INTEGER_set(p7->d.enveloped->version, 0))
151e1051a39Sopenharmony_ci            goto err;
152e1051a39Sopenharmony_ci        p7->d.enveloped->enc_data->content_type = OBJ_nid2obj(NID_pkcs7_data);
153e1051a39Sopenharmony_ci        break;
154e1051a39Sopenharmony_ci    case NID_pkcs7_encrypted:
155e1051a39Sopenharmony_ci        p7->type = obj;
156e1051a39Sopenharmony_ci        if ((p7->d.encrypted = PKCS7_ENCRYPT_new())
157e1051a39Sopenharmony_ci            == NULL)
158e1051a39Sopenharmony_ci            goto err;
159e1051a39Sopenharmony_ci        if (!ASN1_INTEGER_set(p7->d.encrypted->version, 0))
160e1051a39Sopenharmony_ci            goto err;
161e1051a39Sopenharmony_ci        p7->d.encrypted->enc_data->content_type = OBJ_nid2obj(NID_pkcs7_data);
162e1051a39Sopenharmony_ci        break;
163e1051a39Sopenharmony_ci
164e1051a39Sopenharmony_ci    case NID_pkcs7_digest:
165e1051a39Sopenharmony_ci        p7->type = obj;
166e1051a39Sopenharmony_ci        if ((p7->d.digest = PKCS7_DIGEST_new())
167e1051a39Sopenharmony_ci            == NULL)
168e1051a39Sopenharmony_ci            goto err;
169e1051a39Sopenharmony_ci        if (!ASN1_INTEGER_set(p7->d.digest->version, 0))
170e1051a39Sopenharmony_ci            goto err;
171e1051a39Sopenharmony_ci        break;
172e1051a39Sopenharmony_ci    default:
173e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_PKCS7, PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
174e1051a39Sopenharmony_ci        goto err;
175e1051a39Sopenharmony_ci    }
176e1051a39Sopenharmony_ci    return 1;
177e1051a39Sopenharmony_ci err:
178e1051a39Sopenharmony_ci    return 0;
179e1051a39Sopenharmony_ci}
180e1051a39Sopenharmony_ci
181e1051a39Sopenharmony_ciint PKCS7_set0_type_other(PKCS7 *p7, int type, ASN1_TYPE *other)
182e1051a39Sopenharmony_ci{
183e1051a39Sopenharmony_ci    p7->type = OBJ_nid2obj(type);
184e1051a39Sopenharmony_ci    p7->d.other = other;
185e1051a39Sopenharmony_ci    return 1;
186e1051a39Sopenharmony_ci}
187e1051a39Sopenharmony_ci
188e1051a39Sopenharmony_ciint PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *psi)
189e1051a39Sopenharmony_ci{
190e1051a39Sopenharmony_ci    int i, j;
191e1051a39Sopenharmony_ci    ASN1_OBJECT *obj;
192e1051a39Sopenharmony_ci    X509_ALGOR *alg;
193e1051a39Sopenharmony_ci    STACK_OF(PKCS7_SIGNER_INFO) *signer_sk;
194e1051a39Sopenharmony_ci    STACK_OF(X509_ALGOR) *md_sk;
195e1051a39Sopenharmony_ci
196e1051a39Sopenharmony_ci    i = OBJ_obj2nid(p7->type);
197e1051a39Sopenharmony_ci    switch (i) {
198e1051a39Sopenharmony_ci    case NID_pkcs7_signed:
199e1051a39Sopenharmony_ci        signer_sk = p7->d.sign->signer_info;
200e1051a39Sopenharmony_ci        md_sk = p7->d.sign->md_algs;
201e1051a39Sopenharmony_ci        break;
202e1051a39Sopenharmony_ci    case NID_pkcs7_signedAndEnveloped:
203e1051a39Sopenharmony_ci        signer_sk = p7->d.signed_and_enveloped->signer_info;
204e1051a39Sopenharmony_ci        md_sk = p7->d.signed_and_enveloped->md_algs;
205e1051a39Sopenharmony_ci        break;
206e1051a39Sopenharmony_ci    default:
207e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_PKCS7, PKCS7_R_WRONG_CONTENT_TYPE);
208e1051a39Sopenharmony_ci        return 0;
209e1051a39Sopenharmony_ci    }
210e1051a39Sopenharmony_ci
211e1051a39Sopenharmony_ci    obj = psi->digest_alg->algorithm;
212e1051a39Sopenharmony_ci    /* If the digest is not currently listed, add it */
213e1051a39Sopenharmony_ci    j = 0;
214e1051a39Sopenharmony_ci    for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++) {
215e1051a39Sopenharmony_ci        alg = sk_X509_ALGOR_value(md_sk, i);
216e1051a39Sopenharmony_ci        if (OBJ_cmp(obj, alg->algorithm) == 0) {
217e1051a39Sopenharmony_ci            j = 1;
218e1051a39Sopenharmony_ci            break;
219e1051a39Sopenharmony_ci        }
220e1051a39Sopenharmony_ci    }
221e1051a39Sopenharmony_ci    if (!j) {                   /* we need to add another algorithm */
222e1051a39Sopenharmony_ci        int nid;
223e1051a39Sopenharmony_ci
224e1051a39Sopenharmony_ci        if ((alg = X509_ALGOR_new()) == NULL
225e1051a39Sopenharmony_ci            || (alg->parameter = ASN1_TYPE_new()) == NULL) {
226e1051a39Sopenharmony_ci            X509_ALGOR_free(alg);
227e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE);
228e1051a39Sopenharmony_ci            return 0;
229e1051a39Sopenharmony_ci        }
230e1051a39Sopenharmony_ci        /*
231e1051a39Sopenharmony_ci         * If there is a constant copy of the ASN1 OBJECT in libcrypto, then
232e1051a39Sopenharmony_ci         * use that.  Otherwise, use a dynamically duplicated copy
233e1051a39Sopenharmony_ci         */
234e1051a39Sopenharmony_ci        if ((nid = OBJ_obj2nid(obj)) != NID_undef)
235e1051a39Sopenharmony_ci            alg->algorithm = OBJ_nid2obj(nid);
236e1051a39Sopenharmony_ci        else
237e1051a39Sopenharmony_ci            alg->algorithm = OBJ_dup(obj);
238e1051a39Sopenharmony_ci        alg->parameter->type = V_ASN1_NULL;
239e1051a39Sopenharmony_ci        if (alg->algorithm == NULL || !sk_X509_ALGOR_push(md_sk, alg)) {
240e1051a39Sopenharmony_ci            X509_ALGOR_free(alg);
241e1051a39Sopenharmony_ci            return 0;
242e1051a39Sopenharmony_ci        }
243e1051a39Sopenharmony_ci    }
244e1051a39Sopenharmony_ci
245e1051a39Sopenharmony_ci    psi->ctx = ossl_pkcs7_get0_ctx(p7);
246e1051a39Sopenharmony_ci    if (!sk_PKCS7_SIGNER_INFO_push(signer_sk, psi))
247e1051a39Sopenharmony_ci        return 0;
248e1051a39Sopenharmony_ci    return 1;
249e1051a39Sopenharmony_ci}
250e1051a39Sopenharmony_ci
251e1051a39Sopenharmony_ciint PKCS7_add_certificate(PKCS7 *p7, X509 *x509)
252e1051a39Sopenharmony_ci{
253e1051a39Sopenharmony_ci    int i;
254e1051a39Sopenharmony_ci    STACK_OF(X509) **sk;
255e1051a39Sopenharmony_ci
256e1051a39Sopenharmony_ci    i = OBJ_obj2nid(p7->type);
257e1051a39Sopenharmony_ci    switch (i) {
258e1051a39Sopenharmony_ci    case NID_pkcs7_signed:
259e1051a39Sopenharmony_ci        sk = &(p7->d.sign->cert);
260e1051a39Sopenharmony_ci        break;
261e1051a39Sopenharmony_ci    case NID_pkcs7_signedAndEnveloped:
262e1051a39Sopenharmony_ci        sk = &(p7->d.signed_and_enveloped->cert);
263e1051a39Sopenharmony_ci        break;
264e1051a39Sopenharmony_ci    default:
265e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_PKCS7, PKCS7_R_WRONG_CONTENT_TYPE);
266e1051a39Sopenharmony_ci        return 0;
267e1051a39Sopenharmony_ci    }
268e1051a39Sopenharmony_ci
269e1051a39Sopenharmony_ci    return ossl_x509_add_cert_new(sk, x509, X509_ADD_FLAG_UP_REF);
270e1051a39Sopenharmony_ci}
271e1051a39Sopenharmony_ci
272e1051a39Sopenharmony_ciint PKCS7_add_crl(PKCS7 *p7, X509_CRL *crl)
273e1051a39Sopenharmony_ci{
274e1051a39Sopenharmony_ci    int i;
275e1051a39Sopenharmony_ci    STACK_OF(X509_CRL) **sk;
276e1051a39Sopenharmony_ci
277e1051a39Sopenharmony_ci    i = OBJ_obj2nid(p7->type);
278e1051a39Sopenharmony_ci    switch (i) {
279e1051a39Sopenharmony_ci    case NID_pkcs7_signed:
280e1051a39Sopenharmony_ci        sk = &(p7->d.sign->crl);
281e1051a39Sopenharmony_ci        break;
282e1051a39Sopenharmony_ci    case NID_pkcs7_signedAndEnveloped:
283e1051a39Sopenharmony_ci        sk = &(p7->d.signed_and_enveloped->crl);
284e1051a39Sopenharmony_ci        break;
285e1051a39Sopenharmony_ci    default:
286e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_PKCS7, PKCS7_R_WRONG_CONTENT_TYPE);
287e1051a39Sopenharmony_ci        return 0;
288e1051a39Sopenharmony_ci    }
289e1051a39Sopenharmony_ci
290e1051a39Sopenharmony_ci    if (*sk == NULL)
291e1051a39Sopenharmony_ci        *sk = sk_X509_CRL_new_null();
292e1051a39Sopenharmony_ci    if (*sk == NULL) {
293e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE);
294e1051a39Sopenharmony_ci        return 0;
295e1051a39Sopenharmony_ci    }
296e1051a39Sopenharmony_ci
297e1051a39Sopenharmony_ci    X509_CRL_up_ref(crl);
298e1051a39Sopenharmony_ci    if (!sk_X509_CRL_push(*sk, crl)) {
299e1051a39Sopenharmony_ci        X509_CRL_free(crl);
300e1051a39Sopenharmony_ci        return 0;
301e1051a39Sopenharmony_ci    }
302e1051a39Sopenharmony_ci    return 1;
303e1051a39Sopenharmony_ci}
304e1051a39Sopenharmony_ci
305e1051a39Sopenharmony_cistatic int pkcs7_ecdsa_or_dsa_sign_verify_setup(PKCS7_SIGNER_INFO *si,
306e1051a39Sopenharmony_ci                                                int verify)
307e1051a39Sopenharmony_ci{
308e1051a39Sopenharmony_ci    if (verify == 0) {
309e1051a39Sopenharmony_ci        int snid, hnid;
310e1051a39Sopenharmony_ci        X509_ALGOR *alg1, *alg2;
311e1051a39Sopenharmony_ci        EVP_PKEY *pkey = si->pkey;
312e1051a39Sopenharmony_ci
313e1051a39Sopenharmony_ci        PKCS7_SIGNER_INFO_get0_algs(si, NULL, &alg1, &alg2);
314e1051a39Sopenharmony_ci        if (alg1 == NULL || alg1->algorithm == NULL)
315e1051a39Sopenharmony_ci            return -1;
316e1051a39Sopenharmony_ci        hnid = OBJ_obj2nid(alg1->algorithm);
317e1051a39Sopenharmony_ci        if (hnid == NID_undef)
318e1051a39Sopenharmony_ci            return -1;
319e1051a39Sopenharmony_ci        if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_get_id(pkey)))
320e1051a39Sopenharmony_ci            return -1;
321e1051a39Sopenharmony_ci        X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
322e1051a39Sopenharmony_ci    }
323e1051a39Sopenharmony_ci    return 1;
324e1051a39Sopenharmony_ci}
325e1051a39Sopenharmony_ci
326e1051a39Sopenharmony_cistatic int pkcs7_rsa_sign_verify_setup(PKCS7_SIGNER_INFO *si, int verify)
327e1051a39Sopenharmony_ci{
328e1051a39Sopenharmony_ci    if (verify == 0) {
329e1051a39Sopenharmony_ci        X509_ALGOR *alg = NULL;
330e1051a39Sopenharmony_ci
331e1051a39Sopenharmony_ci        PKCS7_SIGNER_INFO_get0_algs(si, NULL, NULL, &alg);
332e1051a39Sopenharmony_ci        if (alg != NULL)
333e1051a39Sopenharmony_ci            X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0);
334e1051a39Sopenharmony_ci    }
335e1051a39Sopenharmony_ci    return 1;
336e1051a39Sopenharmony_ci}
337e1051a39Sopenharmony_ci
338e1051a39Sopenharmony_ciint PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey,
339e1051a39Sopenharmony_ci                          const EVP_MD *dgst)
340e1051a39Sopenharmony_ci{
341e1051a39Sopenharmony_ci    int ret;
342e1051a39Sopenharmony_ci
343e1051a39Sopenharmony_ci    /* We now need to add another PKCS7_SIGNER_INFO entry */
344e1051a39Sopenharmony_ci    if (!ASN1_INTEGER_set(p7i->version, 1))
345e1051a39Sopenharmony_ci        goto err;
346e1051a39Sopenharmony_ci    if (!X509_NAME_set(&p7i->issuer_and_serial->issuer,
347e1051a39Sopenharmony_ci                       X509_get_issuer_name(x509)))
348e1051a39Sopenharmony_ci        goto err;
349e1051a39Sopenharmony_ci
350e1051a39Sopenharmony_ci    /*
351e1051a39Sopenharmony_ci     * because ASN1_INTEGER_set is used to set a 'long' we will do things the
352e1051a39Sopenharmony_ci     * ugly way.
353e1051a39Sopenharmony_ci     */
354e1051a39Sopenharmony_ci    ASN1_INTEGER_free(p7i->issuer_and_serial->serial);
355e1051a39Sopenharmony_ci    if (!(p7i->issuer_and_serial->serial =
356e1051a39Sopenharmony_ci          ASN1_INTEGER_dup(X509_get0_serialNumber(x509))))
357e1051a39Sopenharmony_ci        goto err;
358e1051a39Sopenharmony_ci
359e1051a39Sopenharmony_ci    /* lets keep the pkey around for a while */
360e1051a39Sopenharmony_ci    EVP_PKEY_up_ref(pkey);
361e1051a39Sopenharmony_ci    p7i->pkey = pkey;
362e1051a39Sopenharmony_ci
363e1051a39Sopenharmony_ci    /* Set the algorithms */
364e1051a39Sopenharmony_ci
365e1051a39Sopenharmony_ci    X509_ALGOR_set0(p7i->digest_alg, OBJ_nid2obj(EVP_MD_get_type(dgst)),
366e1051a39Sopenharmony_ci                    V_ASN1_NULL, NULL);
367e1051a39Sopenharmony_ci
368e1051a39Sopenharmony_ci    if (EVP_PKEY_is_a(pkey, "EC") || EVP_PKEY_is_a(pkey, "DSA"))
369e1051a39Sopenharmony_ci        return pkcs7_ecdsa_or_dsa_sign_verify_setup(p7i, 0);
370e1051a39Sopenharmony_ci    if (EVP_PKEY_is_a(pkey, "RSA"))
371e1051a39Sopenharmony_ci        return pkcs7_rsa_sign_verify_setup(p7i, 0);
372e1051a39Sopenharmony_ci
373e1051a39Sopenharmony_ci    if (pkey->ameth != NULL && pkey->ameth->pkey_ctrl != NULL) {
374e1051a39Sopenharmony_ci        ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_SIGN, 0, p7i);
375e1051a39Sopenharmony_ci        if (ret > 0)
376e1051a39Sopenharmony_ci            return 1;
377e1051a39Sopenharmony_ci        if (ret != -2) {
378e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_PKCS7, PKCS7_R_SIGNING_CTRL_FAILURE);
379e1051a39Sopenharmony_ci            return 0;
380e1051a39Sopenharmony_ci        }
381e1051a39Sopenharmony_ci    }
382e1051a39Sopenharmony_ci    ERR_raise(ERR_LIB_PKCS7, PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
383e1051a39Sopenharmony_ci err:
384e1051a39Sopenharmony_ci    return 0;
385e1051a39Sopenharmony_ci}
386e1051a39Sopenharmony_ci
387e1051a39Sopenharmony_ciPKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509, EVP_PKEY *pkey,
388e1051a39Sopenharmony_ci                                       const EVP_MD *dgst)
389e1051a39Sopenharmony_ci{
390e1051a39Sopenharmony_ci    PKCS7_SIGNER_INFO *si = NULL;
391e1051a39Sopenharmony_ci
392e1051a39Sopenharmony_ci    if (dgst == NULL) {
393e1051a39Sopenharmony_ci        int def_nid;
394e1051a39Sopenharmony_ci        if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) <= 0)
395e1051a39Sopenharmony_ci            goto err;
396e1051a39Sopenharmony_ci        dgst = EVP_get_digestbynid(def_nid);
397e1051a39Sopenharmony_ci        if (dgst == NULL) {
398e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_PKCS7, PKCS7_R_NO_DEFAULT_DIGEST);
399e1051a39Sopenharmony_ci            goto err;
400e1051a39Sopenharmony_ci        }
401e1051a39Sopenharmony_ci    }
402e1051a39Sopenharmony_ci
403e1051a39Sopenharmony_ci    if ((si = PKCS7_SIGNER_INFO_new()) == NULL)
404e1051a39Sopenharmony_ci        goto err;
405e1051a39Sopenharmony_ci    if (PKCS7_SIGNER_INFO_set(si, x509, pkey, dgst) <= 0)
406e1051a39Sopenharmony_ci        goto err;
407e1051a39Sopenharmony_ci    if (!PKCS7_add_signer(p7, si))
408e1051a39Sopenharmony_ci        goto err;
409e1051a39Sopenharmony_ci    return si;
410e1051a39Sopenharmony_ci err:
411e1051a39Sopenharmony_ci    PKCS7_SIGNER_INFO_free(si);
412e1051a39Sopenharmony_ci    return NULL;
413e1051a39Sopenharmony_ci}
414e1051a39Sopenharmony_ci
415e1051a39Sopenharmony_cistatic STACK_OF(X509) *pkcs7_get_signer_certs(const PKCS7 *p7)
416e1051a39Sopenharmony_ci{
417e1051a39Sopenharmony_ci    if (p7->d.ptr == NULL)
418e1051a39Sopenharmony_ci        return NULL;
419e1051a39Sopenharmony_ci    if (PKCS7_type_is_signed(p7))
420e1051a39Sopenharmony_ci        return p7->d.sign->cert;
421e1051a39Sopenharmony_ci    if (PKCS7_type_is_signedAndEnveloped(p7))
422e1051a39Sopenharmony_ci        return p7->d.signed_and_enveloped->cert;
423e1051a39Sopenharmony_ci    return NULL;
424e1051a39Sopenharmony_ci}
425e1051a39Sopenharmony_ci
426e1051a39Sopenharmony_cistatic STACK_OF(PKCS7_RECIP_INFO) *pkcs7_get_recipient_info(const PKCS7 *p7)
427e1051a39Sopenharmony_ci{
428e1051a39Sopenharmony_ci    if (p7->d.ptr == NULL)
429e1051a39Sopenharmony_ci        return NULL;
430e1051a39Sopenharmony_ci    if (PKCS7_type_is_signedAndEnveloped(p7))
431e1051a39Sopenharmony_ci        return p7->d.signed_and_enveloped->recipientinfo;
432e1051a39Sopenharmony_ci    if (PKCS7_type_is_enveloped(p7))
433e1051a39Sopenharmony_ci        return p7->d.enveloped->recipientinfo;
434e1051a39Sopenharmony_ci    return NULL;
435e1051a39Sopenharmony_ci}
436e1051a39Sopenharmony_ci
437e1051a39Sopenharmony_ci/*
438e1051a39Sopenharmony_ci * Set up the library context into any loaded structure that needs it.
439e1051a39Sopenharmony_ci * i.e loaded X509 objects.
440e1051a39Sopenharmony_ci */
441e1051a39Sopenharmony_civoid ossl_pkcs7_resolve_libctx(PKCS7 *p7)
442e1051a39Sopenharmony_ci{
443e1051a39Sopenharmony_ci    int i;
444e1051a39Sopenharmony_ci    const PKCS7_CTX *ctx = ossl_pkcs7_get0_ctx(p7);
445e1051a39Sopenharmony_ci    OSSL_LIB_CTX *libctx = ossl_pkcs7_ctx_get0_libctx(ctx);
446e1051a39Sopenharmony_ci    const char *propq = ossl_pkcs7_ctx_get0_propq(ctx);
447e1051a39Sopenharmony_ci    STACK_OF(PKCS7_RECIP_INFO) *rinfos;
448e1051a39Sopenharmony_ci    STACK_OF(PKCS7_SIGNER_INFO) *sinfos;
449e1051a39Sopenharmony_ci    STACK_OF(X509) *certs;
450e1051a39Sopenharmony_ci
451e1051a39Sopenharmony_ci    if (ctx == NULL || p7->d.ptr == NULL)
452e1051a39Sopenharmony_ci        return;
453e1051a39Sopenharmony_ci
454e1051a39Sopenharmony_ci    rinfos = pkcs7_get_recipient_info(p7);
455e1051a39Sopenharmony_ci    sinfos = PKCS7_get_signer_info(p7);
456e1051a39Sopenharmony_ci    certs = pkcs7_get_signer_certs(p7);
457e1051a39Sopenharmony_ci
458e1051a39Sopenharmony_ci    for (i = 0; i < sk_X509_num(certs); i++)
459e1051a39Sopenharmony_ci        ossl_x509_set0_libctx(sk_X509_value(certs, i), libctx, propq);
460e1051a39Sopenharmony_ci
461e1051a39Sopenharmony_ci    for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rinfos); i++) {
462e1051a39Sopenharmony_ci        PKCS7_RECIP_INFO *ri = sk_PKCS7_RECIP_INFO_value(rinfos, i);
463e1051a39Sopenharmony_ci
464e1051a39Sopenharmony_ci        ossl_x509_set0_libctx(ri->cert, libctx, propq);
465e1051a39Sopenharmony_ci    }
466e1051a39Sopenharmony_ci
467e1051a39Sopenharmony_ci    for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) {
468e1051a39Sopenharmony_ci        PKCS7_SIGNER_INFO *si = sk_PKCS7_SIGNER_INFO_value(sinfos, i);
469e1051a39Sopenharmony_ci
470e1051a39Sopenharmony_ci        if (si != NULL)
471e1051a39Sopenharmony_ci            si->ctx = ctx;
472e1051a39Sopenharmony_ci    }
473e1051a39Sopenharmony_ci}
474e1051a39Sopenharmony_ci
475e1051a39Sopenharmony_ciconst PKCS7_CTX *ossl_pkcs7_get0_ctx(const PKCS7 *p7)
476e1051a39Sopenharmony_ci{
477e1051a39Sopenharmony_ci    return p7 != NULL ? &p7->ctx : NULL;
478e1051a39Sopenharmony_ci}
479e1051a39Sopenharmony_ci
480e1051a39Sopenharmony_civoid ossl_pkcs7_set0_libctx(PKCS7 *p7, OSSL_LIB_CTX *ctx)
481e1051a39Sopenharmony_ci{
482e1051a39Sopenharmony_ci    p7->ctx.libctx = ctx;
483e1051a39Sopenharmony_ci}
484e1051a39Sopenharmony_ci
485e1051a39Sopenharmony_ciint ossl_pkcs7_set1_propq(PKCS7 *p7, const char *propq)
486e1051a39Sopenharmony_ci{
487e1051a39Sopenharmony_ci    if (p7->ctx.propq != NULL) {
488e1051a39Sopenharmony_ci        OPENSSL_free(p7->ctx.propq);
489e1051a39Sopenharmony_ci        p7->ctx.propq = NULL;
490e1051a39Sopenharmony_ci    }
491e1051a39Sopenharmony_ci    if (propq != NULL) {
492e1051a39Sopenharmony_ci        p7->ctx.propq = OPENSSL_strdup(propq);
493e1051a39Sopenharmony_ci        if (p7->ctx.propq == NULL) {
494e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
495e1051a39Sopenharmony_ci            return 0;
496e1051a39Sopenharmony_ci        }
497e1051a39Sopenharmony_ci    }
498e1051a39Sopenharmony_ci    return 1;
499e1051a39Sopenharmony_ci}
500e1051a39Sopenharmony_ci
501e1051a39Sopenharmony_ciint ossl_pkcs7_ctx_propagate(const PKCS7 *from, PKCS7 *to)
502e1051a39Sopenharmony_ci{
503e1051a39Sopenharmony_ci    ossl_pkcs7_set0_libctx(to, from->ctx.libctx);
504e1051a39Sopenharmony_ci    if (!ossl_pkcs7_set1_propq(to, from->ctx.propq))
505e1051a39Sopenharmony_ci        return 0;
506e1051a39Sopenharmony_ci
507e1051a39Sopenharmony_ci    ossl_pkcs7_resolve_libctx(to);
508e1051a39Sopenharmony_ci    return 1;
509e1051a39Sopenharmony_ci}
510e1051a39Sopenharmony_ci
511e1051a39Sopenharmony_ciOSSL_LIB_CTX *ossl_pkcs7_ctx_get0_libctx(const PKCS7_CTX *ctx)
512e1051a39Sopenharmony_ci{
513e1051a39Sopenharmony_ci    return ctx != NULL ? ctx->libctx : NULL;
514e1051a39Sopenharmony_ci}
515e1051a39Sopenharmony_ciconst char *ossl_pkcs7_ctx_get0_propq(const PKCS7_CTX *ctx)
516e1051a39Sopenharmony_ci{
517e1051a39Sopenharmony_ci    return ctx != NULL ? ctx->propq : NULL;
518e1051a39Sopenharmony_ci}
519e1051a39Sopenharmony_ci
520e1051a39Sopenharmony_ciint PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md)
521e1051a39Sopenharmony_ci{
522e1051a39Sopenharmony_ci    if (PKCS7_type_is_digest(p7)) {
523e1051a39Sopenharmony_ci        if ((p7->d.digest->md->parameter = ASN1_TYPE_new()) == NULL) {
524e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE);
525e1051a39Sopenharmony_ci            return 0;
526e1051a39Sopenharmony_ci        }
527e1051a39Sopenharmony_ci        p7->d.digest->md->parameter->type = V_ASN1_NULL;
528e1051a39Sopenharmony_ci        p7->d.digest->md->algorithm = OBJ_nid2obj(EVP_MD_nid(md));
529e1051a39Sopenharmony_ci        return 1;
530e1051a39Sopenharmony_ci    }
531e1051a39Sopenharmony_ci
532e1051a39Sopenharmony_ci    ERR_raise(ERR_LIB_PKCS7, PKCS7_R_WRONG_CONTENT_TYPE);
533e1051a39Sopenharmony_ci    return 1;
534e1051a39Sopenharmony_ci}
535e1051a39Sopenharmony_ci
536e1051a39Sopenharmony_ciSTACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7)
537e1051a39Sopenharmony_ci{
538e1051a39Sopenharmony_ci    if (p7 == NULL || p7->d.ptr == NULL)
539e1051a39Sopenharmony_ci        return NULL;
540e1051a39Sopenharmony_ci    if (PKCS7_type_is_signed(p7)) {
541e1051a39Sopenharmony_ci        return p7->d.sign->signer_info;
542e1051a39Sopenharmony_ci    } else if (PKCS7_type_is_signedAndEnveloped(p7)) {
543e1051a39Sopenharmony_ci        return p7->d.signed_and_enveloped->signer_info;
544e1051a39Sopenharmony_ci    } else
545e1051a39Sopenharmony_ci        return NULL;
546e1051a39Sopenharmony_ci}
547e1051a39Sopenharmony_ci
548e1051a39Sopenharmony_civoid PKCS7_SIGNER_INFO_get0_algs(PKCS7_SIGNER_INFO *si, EVP_PKEY **pk,
549e1051a39Sopenharmony_ci                                 X509_ALGOR **pdig, X509_ALGOR **psig)
550e1051a39Sopenharmony_ci{
551e1051a39Sopenharmony_ci    if (pk)
552e1051a39Sopenharmony_ci        *pk = si->pkey;
553e1051a39Sopenharmony_ci    if (pdig)
554e1051a39Sopenharmony_ci        *pdig = si->digest_alg;
555e1051a39Sopenharmony_ci    if (psig)
556e1051a39Sopenharmony_ci        *psig = si->digest_enc_alg;
557e1051a39Sopenharmony_ci}
558e1051a39Sopenharmony_ci
559e1051a39Sopenharmony_civoid PKCS7_RECIP_INFO_get0_alg(PKCS7_RECIP_INFO *ri, X509_ALGOR **penc)
560e1051a39Sopenharmony_ci{
561e1051a39Sopenharmony_ci    if (penc)
562e1051a39Sopenharmony_ci        *penc = ri->key_enc_algor;
563e1051a39Sopenharmony_ci}
564e1051a39Sopenharmony_ci
565e1051a39Sopenharmony_ciPKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509)
566e1051a39Sopenharmony_ci{
567e1051a39Sopenharmony_ci    PKCS7_RECIP_INFO *ri;
568e1051a39Sopenharmony_ci
569e1051a39Sopenharmony_ci    if ((ri = PKCS7_RECIP_INFO_new()) == NULL)
570e1051a39Sopenharmony_ci        goto err;
571e1051a39Sopenharmony_ci    if (PKCS7_RECIP_INFO_set(ri, x509) <= 0)
572e1051a39Sopenharmony_ci        goto err;
573e1051a39Sopenharmony_ci    if (!PKCS7_add_recipient_info(p7, ri))
574e1051a39Sopenharmony_ci        goto err;
575e1051a39Sopenharmony_ci    ri->ctx = ossl_pkcs7_get0_ctx(p7);
576e1051a39Sopenharmony_ci    return ri;
577e1051a39Sopenharmony_ci err:
578e1051a39Sopenharmony_ci    PKCS7_RECIP_INFO_free(ri);
579e1051a39Sopenharmony_ci    return NULL;
580e1051a39Sopenharmony_ci}
581e1051a39Sopenharmony_ci
582e1051a39Sopenharmony_ciint PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri)
583e1051a39Sopenharmony_ci{
584e1051a39Sopenharmony_ci    int i;
585e1051a39Sopenharmony_ci    STACK_OF(PKCS7_RECIP_INFO) *sk;
586e1051a39Sopenharmony_ci
587e1051a39Sopenharmony_ci    i = OBJ_obj2nid(p7->type);
588e1051a39Sopenharmony_ci    switch (i) {
589e1051a39Sopenharmony_ci    case NID_pkcs7_signedAndEnveloped:
590e1051a39Sopenharmony_ci        sk = p7->d.signed_and_enveloped->recipientinfo;
591e1051a39Sopenharmony_ci        break;
592e1051a39Sopenharmony_ci    case NID_pkcs7_enveloped:
593e1051a39Sopenharmony_ci        sk = p7->d.enveloped->recipientinfo;
594e1051a39Sopenharmony_ci        break;
595e1051a39Sopenharmony_ci    default:
596e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_PKCS7, PKCS7_R_WRONG_CONTENT_TYPE);
597e1051a39Sopenharmony_ci        return 0;
598e1051a39Sopenharmony_ci    }
599e1051a39Sopenharmony_ci
600e1051a39Sopenharmony_ci    if (!sk_PKCS7_RECIP_INFO_push(sk, ri))
601e1051a39Sopenharmony_ci        return 0;
602e1051a39Sopenharmony_ci    return 1;
603e1051a39Sopenharmony_ci}
604e1051a39Sopenharmony_ci
605e1051a39Sopenharmony_cistatic int pkcs7_rsa_encrypt_decrypt_setup(PKCS7_RECIP_INFO *ri, int decrypt)
606e1051a39Sopenharmony_ci{
607e1051a39Sopenharmony_ci    X509_ALGOR *alg = NULL;
608e1051a39Sopenharmony_ci
609e1051a39Sopenharmony_ci    if (decrypt == 0) {
610e1051a39Sopenharmony_ci        PKCS7_RECIP_INFO_get0_alg(ri, &alg);
611e1051a39Sopenharmony_ci        if (alg != NULL)
612e1051a39Sopenharmony_ci            X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0);
613e1051a39Sopenharmony_ci    }
614e1051a39Sopenharmony_ci    return 1;
615e1051a39Sopenharmony_ci}
616e1051a39Sopenharmony_ci
617e1051a39Sopenharmony_ciint PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509)
618e1051a39Sopenharmony_ci{
619e1051a39Sopenharmony_ci    int ret;
620e1051a39Sopenharmony_ci    EVP_PKEY *pkey = NULL;
621e1051a39Sopenharmony_ci    if (!ASN1_INTEGER_set(p7i->version, 0))
622e1051a39Sopenharmony_ci        return 0;
623e1051a39Sopenharmony_ci    if (!X509_NAME_set(&p7i->issuer_and_serial->issuer,
624e1051a39Sopenharmony_ci                       X509_get_issuer_name(x509)))
625e1051a39Sopenharmony_ci        return 0;
626e1051a39Sopenharmony_ci
627e1051a39Sopenharmony_ci    ASN1_INTEGER_free(p7i->issuer_and_serial->serial);
628e1051a39Sopenharmony_ci    if (!(p7i->issuer_and_serial->serial =
629e1051a39Sopenharmony_ci          ASN1_INTEGER_dup(X509_get0_serialNumber(x509))))
630e1051a39Sopenharmony_ci        return 0;
631e1051a39Sopenharmony_ci
632e1051a39Sopenharmony_ci    pkey = X509_get0_pubkey(x509);
633e1051a39Sopenharmony_ci    if (pkey == NULL)
634e1051a39Sopenharmony_ci        return 0;
635e1051a39Sopenharmony_ci
636e1051a39Sopenharmony_ci    if (EVP_PKEY_is_a(pkey, "RSA-PSS"))
637e1051a39Sopenharmony_ci        return -2;
638e1051a39Sopenharmony_ci    if (EVP_PKEY_is_a(pkey, "RSA")) {
639e1051a39Sopenharmony_ci        if (pkcs7_rsa_encrypt_decrypt_setup(p7i, 0) <= 0)
640e1051a39Sopenharmony_ci            goto err;
641e1051a39Sopenharmony_ci        goto finished;
642e1051a39Sopenharmony_ci    }
643e1051a39Sopenharmony_ci
644e1051a39Sopenharmony_ci    if (pkey->ameth == NULL || pkey->ameth->pkey_ctrl == NULL) {
645e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_PKCS7,
646e1051a39Sopenharmony_ci                  PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
647e1051a39Sopenharmony_ci        goto err;
648e1051a39Sopenharmony_ci    }
649e1051a39Sopenharmony_ci
650e1051a39Sopenharmony_ci    ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_ENCRYPT, 0, p7i);
651e1051a39Sopenharmony_ci    if (ret == -2) {
652e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_PKCS7,
653e1051a39Sopenharmony_ci                  PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
654e1051a39Sopenharmony_ci        goto err;
655e1051a39Sopenharmony_ci    }
656e1051a39Sopenharmony_ci    if (ret <= 0) {
657e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_PKCS7, PKCS7_R_ENCRYPTION_CTRL_FAILURE);
658e1051a39Sopenharmony_ci        goto err;
659e1051a39Sopenharmony_ci    }
660e1051a39Sopenharmony_cifinished:
661e1051a39Sopenharmony_ci    X509_up_ref(x509);
662e1051a39Sopenharmony_ci    p7i->cert = x509;
663e1051a39Sopenharmony_ci
664e1051a39Sopenharmony_ci    return 1;
665e1051a39Sopenharmony_ci
666e1051a39Sopenharmony_ci err:
667e1051a39Sopenharmony_ci    return 0;
668e1051a39Sopenharmony_ci}
669e1051a39Sopenharmony_ci
670e1051a39Sopenharmony_ciX509 *PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si)
671e1051a39Sopenharmony_ci{
672e1051a39Sopenharmony_ci    if (PKCS7_type_is_signed(p7))
673e1051a39Sopenharmony_ci        return (X509_find_by_issuer_and_serial(p7->d.sign->cert,
674e1051a39Sopenharmony_ci                                               si->issuer_and_serial->issuer,
675e1051a39Sopenharmony_ci                                               si->
676e1051a39Sopenharmony_ci                                               issuer_and_serial->serial));
677e1051a39Sopenharmony_ci    else
678e1051a39Sopenharmony_ci        return NULL;
679e1051a39Sopenharmony_ci}
680e1051a39Sopenharmony_ci
681e1051a39Sopenharmony_ciint PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher)
682e1051a39Sopenharmony_ci{
683e1051a39Sopenharmony_ci    int i;
684e1051a39Sopenharmony_ci    PKCS7_ENC_CONTENT *ec;
685e1051a39Sopenharmony_ci
686e1051a39Sopenharmony_ci    i = OBJ_obj2nid(p7->type);
687e1051a39Sopenharmony_ci    switch (i) {
688e1051a39Sopenharmony_ci    case NID_pkcs7_signedAndEnveloped:
689e1051a39Sopenharmony_ci        ec = p7->d.signed_and_enveloped->enc_data;
690e1051a39Sopenharmony_ci        break;
691e1051a39Sopenharmony_ci    case NID_pkcs7_enveloped:
692e1051a39Sopenharmony_ci        ec = p7->d.enveloped->enc_data;
693e1051a39Sopenharmony_ci        break;
694e1051a39Sopenharmony_ci    default:
695e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_PKCS7, PKCS7_R_WRONG_CONTENT_TYPE);
696e1051a39Sopenharmony_ci        return 0;
697e1051a39Sopenharmony_ci    }
698e1051a39Sopenharmony_ci
699e1051a39Sopenharmony_ci    /* Check cipher OID exists and has data in it */
700e1051a39Sopenharmony_ci    i = EVP_CIPHER_get_type(cipher);
701e1051a39Sopenharmony_ci    if (i == NID_undef) {
702e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_PKCS7, PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
703e1051a39Sopenharmony_ci        return 0;
704e1051a39Sopenharmony_ci    }
705e1051a39Sopenharmony_ci
706e1051a39Sopenharmony_ci    ec->cipher = cipher;
707e1051a39Sopenharmony_ci    ec->ctx = ossl_pkcs7_get0_ctx(p7);
708e1051a39Sopenharmony_ci    return 1;
709e1051a39Sopenharmony_ci}
710e1051a39Sopenharmony_ci
711e1051a39Sopenharmony_ci/* unfortunately cannot constify BIO_new_NDEF() due to this and CMS_stream() */
712e1051a39Sopenharmony_ciint PKCS7_stream(unsigned char ***boundary, PKCS7 *p7)
713e1051a39Sopenharmony_ci{
714e1051a39Sopenharmony_ci    ASN1_OCTET_STRING *os = NULL;
715e1051a39Sopenharmony_ci
716e1051a39Sopenharmony_ci    switch (OBJ_obj2nid(p7->type)) {
717e1051a39Sopenharmony_ci    case NID_pkcs7_data:
718e1051a39Sopenharmony_ci        os = p7->d.data;
719e1051a39Sopenharmony_ci        break;
720e1051a39Sopenharmony_ci
721e1051a39Sopenharmony_ci    case NID_pkcs7_signedAndEnveloped:
722e1051a39Sopenharmony_ci        os = p7->d.signed_and_enveloped->enc_data->enc_data;
723e1051a39Sopenharmony_ci        if (os == NULL) {
724e1051a39Sopenharmony_ci            os = ASN1_OCTET_STRING_new();
725e1051a39Sopenharmony_ci            p7->d.signed_and_enveloped->enc_data->enc_data = os;
726e1051a39Sopenharmony_ci        }
727e1051a39Sopenharmony_ci        break;
728e1051a39Sopenharmony_ci
729e1051a39Sopenharmony_ci    case NID_pkcs7_enveloped:
730e1051a39Sopenharmony_ci        os = p7->d.enveloped->enc_data->enc_data;
731e1051a39Sopenharmony_ci        if (os == NULL) {
732e1051a39Sopenharmony_ci            os = ASN1_OCTET_STRING_new();
733e1051a39Sopenharmony_ci            p7->d.enveloped->enc_data->enc_data = os;
734e1051a39Sopenharmony_ci        }
735e1051a39Sopenharmony_ci        break;
736e1051a39Sopenharmony_ci
737e1051a39Sopenharmony_ci    case NID_pkcs7_signed:
738e1051a39Sopenharmony_ci        os = p7->d.sign->contents->d.data;
739e1051a39Sopenharmony_ci        break;
740e1051a39Sopenharmony_ci
741e1051a39Sopenharmony_ci    default:
742e1051a39Sopenharmony_ci        os = NULL;
743e1051a39Sopenharmony_ci        break;
744e1051a39Sopenharmony_ci    }
745e1051a39Sopenharmony_ci
746e1051a39Sopenharmony_ci    if (os == NULL)
747e1051a39Sopenharmony_ci        return 0;
748e1051a39Sopenharmony_ci
749e1051a39Sopenharmony_ci    os->flags |= ASN1_STRING_FLAG_NDEF;
750e1051a39Sopenharmony_ci    *boundary = &os->data;
751e1051a39Sopenharmony_ci
752e1051a39Sopenharmony_ci    return 1;
753e1051a39Sopenharmony_ci}
754