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