xref: /third_party/openssl/crypto/cms/cms_io.c (revision e1051a39)
1e1051a39Sopenharmony_ci/*
2e1051a39Sopenharmony_ci * Copyright 2008-2022 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 <openssl/asn1t.h>
11e1051a39Sopenharmony_ci#include <openssl/x509.h>
12e1051a39Sopenharmony_ci#include <openssl/err.h>
13e1051a39Sopenharmony_ci#include <openssl/pem.h>
14e1051a39Sopenharmony_ci#include <openssl/cms.h>
15e1051a39Sopenharmony_ci#include "cms_local.h"
16e1051a39Sopenharmony_ci
17e1051a39Sopenharmony_ci/* unfortunately cannot constify BIO_new_NDEF() due to this and PKCS7_stream() */
18e1051a39Sopenharmony_ciint CMS_stream(unsigned char ***boundary, CMS_ContentInfo *cms)
19e1051a39Sopenharmony_ci{
20e1051a39Sopenharmony_ci    ASN1_OCTET_STRING **pos;
21e1051a39Sopenharmony_ci    pos = CMS_get0_content(cms);
22e1051a39Sopenharmony_ci    if (pos == NULL)
23e1051a39Sopenharmony_ci        return 0;
24e1051a39Sopenharmony_ci    if (*pos == NULL)
25e1051a39Sopenharmony_ci        *pos = ASN1_OCTET_STRING_new();
26e1051a39Sopenharmony_ci    if (*pos != NULL) {
27e1051a39Sopenharmony_ci        (*pos)->flags |= ASN1_STRING_FLAG_NDEF;
28e1051a39Sopenharmony_ci        (*pos)->flags &= ~ASN1_STRING_FLAG_CONT;
29e1051a39Sopenharmony_ci        *boundary = &(*pos)->data;
30e1051a39Sopenharmony_ci        return 1;
31e1051a39Sopenharmony_ci    }
32e1051a39Sopenharmony_ci    ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE);
33e1051a39Sopenharmony_ci    return 0;
34e1051a39Sopenharmony_ci}
35e1051a39Sopenharmony_ci
36e1051a39Sopenharmony_ciCMS_ContentInfo *d2i_CMS_bio(BIO *bp, CMS_ContentInfo **cms)
37e1051a39Sopenharmony_ci{
38e1051a39Sopenharmony_ci    CMS_ContentInfo *ci;
39e1051a39Sopenharmony_ci    const CMS_CTX *ctx = ossl_cms_get0_cmsctx(cms == NULL ? NULL : *cms);
40e1051a39Sopenharmony_ci
41e1051a39Sopenharmony_ci    ci = ASN1_item_d2i_bio_ex(ASN1_ITEM_rptr(CMS_ContentInfo), bp, cms,
42e1051a39Sopenharmony_ci                              ossl_cms_ctx_get0_libctx(ctx),
43e1051a39Sopenharmony_ci                              ossl_cms_ctx_get0_propq(ctx));
44e1051a39Sopenharmony_ci    if (ci != NULL) {
45e1051a39Sopenharmony_ci        ERR_set_mark();
46e1051a39Sopenharmony_ci        ossl_cms_resolve_libctx(ci);
47e1051a39Sopenharmony_ci        ERR_pop_to_mark();
48e1051a39Sopenharmony_ci    }
49e1051a39Sopenharmony_ci    return ci;
50e1051a39Sopenharmony_ci}
51e1051a39Sopenharmony_ci
52e1051a39Sopenharmony_ciint i2d_CMS_bio(BIO *bp, CMS_ContentInfo *cms)
53e1051a39Sopenharmony_ci{
54e1051a39Sopenharmony_ci    return ASN1_item_i2d_bio(ASN1_ITEM_rptr(CMS_ContentInfo), bp, cms);
55e1051a39Sopenharmony_ci}
56e1051a39Sopenharmony_ci
57e1051a39Sopenharmony_ciIMPLEMENT_PEM_rw(CMS, CMS_ContentInfo, PEM_STRING_CMS, CMS_ContentInfo)
58e1051a39Sopenharmony_ci
59e1051a39Sopenharmony_ciBIO *BIO_new_CMS(BIO *out, CMS_ContentInfo *cms)
60e1051a39Sopenharmony_ci{
61e1051a39Sopenharmony_ci    return BIO_new_NDEF(out, (ASN1_VALUE *)cms,
62e1051a39Sopenharmony_ci                        ASN1_ITEM_rptr(CMS_ContentInfo));
63e1051a39Sopenharmony_ci}
64e1051a39Sopenharmony_ci
65e1051a39Sopenharmony_ci/* CMS wrappers round generalised stream and MIME routines */
66e1051a39Sopenharmony_ci
67e1051a39Sopenharmony_ciint i2d_CMS_bio_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, int flags)
68e1051a39Sopenharmony_ci{
69e1051a39Sopenharmony_ci    return i2d_ASN1_bio_stream(out, (ASN1_VALUE *)cms, in, flags,
70e1051a39Sopenharmony_ci                               ASN1_ITEM_rptr(CMS_ContentInfo));
71e1051a39Sopenharmony_ci}
72e1051a39Sopenharmony_ci
73e1051a39Sopenharmony_ciint PEM_write_bio_CMS_stream(BIO *out, CMS_ContentInfo *cms, BIO *in,
74e1051a39Sopenharmony_ci                             int flags)
75e1051a39Sopenharmony_ci{
76e1051a39Sopenharmony_ci    return PEM_write_bio_ASN1_stream(out, (ASN1_VALUE *)cms, in, flags,
77e1051a39Sopenharmony_ci                                     "CMS", ASN1_ITEM_rptr(CMS_ContentInfo));
78e1051a39Sopenharmony_ci}
79e1051a39Sopenharmony_ci
80e1051a39Sopenharmony_ciint SMIME_write_CMS(BIO *bio, CMS_ContentInfo *cms, BIO *data, int flags)
81e1051a39Sopenharmony_ci{
82e1051a39Sopenharmony_ci    STACK_OF(X509_ALGOR) *mdalgs;
83e1051a39Sopenharmony_ci    int ctype_nid = OBJ_obj2nid(cms->contentType);
84e1051a39Sopenharmony_ci    int econt_nid = OBJ_obj2nid(CMS_get0_eContentType(cms));
85e1051a39Sopenharmony_ci    const CMS_CTX *ctx = ossl_cms_get0_cmsctx(cms);
86e1051a39Sopenharmony_ci
87e1051a39Sopenharmony_ci    if (ctype_nid == NID_pkcs7_signed)
88e1051a39Sopenharmony_ci        mdalgs = cms->d.signedData->digestAlgorithms;
89e1051a39Sopenharmony_ci    else
90e1051a39Sopenharmony_ci        mdalgs = NULL;
91e1051a39Sopenharmony_ci
92e1051a39Sopenharmony_ci    return SMIME_write_ASN1_ex(bio, (ASN1_VALUE *)cms, data, flags, ctype_nid,
93e1051a39Sopenharmony_ci                               econt_nid, mdalgs,
94e1051a39Sopenharmony_ci                               ASN1_ITEM_rptr(CMS_ContentInfo),
95e1051a39Sopenharmony_ci                               ossl_cms_ctx_get0_libctx(ctx),
96e1051a39Sopenharmony_ci                               ossl_cms_ctx_get0_propq(ctx));
97e1051a39Sopenharmony_ci}
98e1051a39Sopenharmony_ci
99e1051a39Sopenharmony_ciCMS_ContentInfo *SMIME_read_CMS_ex(BIO *bio, int flags, BIO **bcont,
100e1051a39Sopenharmony_ci                                   CMS_ContentInfo **cms)
101e1051a39Sopenharmony_ci{
102e1051a39Sopenharmony_ci    CMS_ContentInfo *ci;
103e1051a39Sopenharmony_ci    const CMS_CTX *ctx = ossl_cms_get0_cmsctx(cms == NULL ? NULL : *cms);
104e1051a39Sopenharmony_ci
105e1051a39Sopenharmony_ci    ci = (CMS_ContentInfo *)SMIME_read_ASN1_ex(bio, flags, bcont,
106e1051a39Sopenharmony_ci                                               ASN1_ITEM_rptr(CMS_ContentInfo),
107e1051a39Sopenharmony_ci                                               (ASN1_VALUE **)cms,
108e1051a39Sopenharmony_ci                                               ossl_cms_ctx_get0_libctx(ctx),
109e1051a39Sopenharmony_ci                                               ossl_cms_ctx_get0_propq(ctx));
110e1051a39Sopenharmony_ci    if (ci != NULL) {
111e1051a39Sopenharmony_ci        ERR_set_mark();
112e1051a39Sopenharmony_ci        ossl_cms_resolve_libctx(ci);
113e1051a39Sopenharmony_ci        ERR_pop_to_mark();
114e1051a39Sopenharmony_ci    }
115e1051a39Sopenharmony_ci    return ci;
116e1051a39Sopenharmony_ci}
117e1051a39Sopenharmony_ci
118e1051a39Sopenharmony_ciCMS_ContentInfo *SMIME_read_CMS(BIO *bio, BIO **bcont)
119e1051a39Sopenharmony_ci{
120e1051a39Sopenharmony_ci    return SMIME_read_CMS_ex(bio, 0, bcont, NULL);
121e1051a39Sopenharmony_ci}
122