xref: /third_party/openssl/crypto/pkcs7/pk7_attr.c (revision e1051a39)
1e1051a39Sopenharmony_ci/*
2e1051a39Sopenharmony_ci * Copyright 1999-2020 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 <stdlib.h>
12e1051a39Sopenharmony_ci#include <openssl/bio.h>
13e1051a39Sopenharmony_ci#include <openssl/asn1.h>
14e1051a39Sopenharmony_ci#include <openssl/asn1t.h>
15e1051a39Sopenharmony_ci#include <openssl/pem.h>
16e1051a39Sopenharmony_ci#include <openssl/pkcs7.h>
17e1051a39Sopenharmony_ci#include <openssl/x509.h>
18e1051a39Sopenharmony_ci#include <openssl/err.h>
19e1051a39Sopenharmony_ci
20e1051a39Sopenharmony_ciint PKCS7_add_attrib_smimecap(PKCS7_SIGNER_INFO *si,
21e1051a39Sopenharmony_ci                              STACK_OF(X509_ALGOR) *cap)
22e1051a39Sopenharmony_ci{
23e1051a39Sopenharmony_ci    ASN1_STRING *seq;
24e1051a39Sopenharmony_ci
25e1051a39Sopenharmony_ci    if ((seq = ASN1_STRING_new()) == NULL) {
26e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE);
27e1051a39Sopenharmony_ci        return 0;
28e1051a39Sopenharmony_ci    }
29e1051a39Sopenharmony_ci    seq->length = ASN1_item_i2d((ASN1_VALUE *)cap, &seq->data,
30e1051a39Sopenharmony_ci                                ASN1_ITEM_rptr(X509_ALGORS));
31e1051a39Sopenharmony_ci    return PKCS7_add_signed_attribute(si, NID_SMIMECapabilities,
32e1051a39Sopenharmony_ci                                      V_ASN1_SEQUENCE, seq);
33e1051a39Sopenharmony_ci}
34e1051a39Sopenharmony_ci
35e1051a39Sopenharmony_ciSTACK_OF(X509_ALGOR) *PKCS7_get_smimecap(PKCS7_SIGNER_INFO *si)
36e1051a39Sopenharmony_ci{
37e1051a39Sopenharmony_ci    ASN1_TYPE *cap;
38e1051a39Sopenharmony_ci    const unsigned char *p;
39e1051a39Sopenharmony_ci
40e1051a39Sopenharmony_ci    cap = PKCS7_get_signed_attribute(si, NID_SMIMECapabilities);
41e1051a39Sopenharmony_ci    if (cap == NULL || (cap->type != V_ASN1_SEQUENCE))
42e1051a39Sopenharmony_ci        return NULL;
43e1051a39Sopenharmony_ci    p = cap->value.sequence->data;
44e1051a39Sopenharmony_ci    return (STACK_OF(X509_ALGOR) *)
45e1051a39Sopenharmony_ci        ASN1_item_d2i(NULL, &p, cap->value.sequence->length,
46e1051a39Sopenharmony_ci                      ASN1_ITEM_rptr(X509_ALGORS));
47e1051a39Sopenharmony_ci}
48e1051a39Sopenharmony_ci
49e1051a39Sopenharmony_ci/* Basic smime-capabilities OID and optional integer arg */
50e1051a39Sopenharmony_ciint PKCS7_simple_smimecap(STACK_OF(X509_ALGOR) *sk, int nid, int arg)
51e1051a39Sopenharmony_ci{
52e1051a39Sopenharmony_ci    ASN1_INTEGER *nbit = NULL;
53e1051a39Sopenharmony_ci    X509_ALGOR *alg;
54e1051a39Sopenharmony_ci
55e1051a39Sopenharmony_ci    if ((alg = X509_ALGOR_new()) == NULL) {
56e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE);
57e1051a39Sopenharmony_ci        return 0;
58e1051a39Sopenharmony_ci    }
59e1051a39Sopenharmony_ci    ASN1_OBJECT_free(alg->algorithm);
60e1051a39Sopenharmony_ci    alg->algorithm = OBJ_nid2obj(nid);
61e1051a39Sopenharmony_ci    if (arg > 0) {
62e1051a39Sopenharmony_ci        if ((alg->parameter = ASN1_TYPE_new()) == NULL) {
63e1051a39Sopenharmony_ci            goto err;
64e1051a39Sopenharmony_ci        }
65e1051a39Sopenharmony_ci        if ((nbit = ASN1_INTEGER_new()) == NULL) {
66e1051a39Sopenharmony_ci            goto err;
67e1051a39Sopenharmony_ci        }
68e1051a39Sopenharmony_ci        if (!ASN1_INTEGER_set(nbit, arg)) {
69e1051a39Sopenharmony_ci            goto err;
70e1051a39Sopenharmony_ci        }
71e1051a39Sopenharmony_ci        alg->parameter->value.integer = nbit;
72e1051a39Sopenharmony_ci        alg->parameter->type = V_ASN1_INTEGER;
73e1051a39Sopenharmony_ci        nbit = NULL;
74e1051a39Sopenharmony_ci    }
75e1051a39Sopenharmony_ci    if (!sk_X509_ALGOR_push(sk, alg)) {
76e1051a39Sopenharmony_ci        goto err;
77e1051a39Sopenharmony_ci    }
78e1051a39Sopenharmony_ci    return 1;
79e1051a39Sopenharmony_cierr:
80e1051a39Sopenharmony_ci    ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE);
81e1051a39Sopenharmony_ci    ASN1_INTEGER_free(nbit);
82e1051a39Sopenharmony_ci    X509_ALGOR_free(alg);
83e1051a39Sopenharmony_ci    return 0;
84e1051a39Sopenharmony_ci}
85e1051a39Sopenharmony_ci
86e1051a39Sopenharmony_ciint PKCS7_add_attrib_content_type(PKCS7_SIGNER_INFO *si, ASN1_OBJECT *coid)
87e1051a39Sopenharmony_ci{
88e1051a39Sopenharmony_ci    if (PKCS7_get_signed_attribute(si, NID_pkcs9_contentType))
89e1051a39Sopenharmony_ci        return 0;
90e1051a39Sopenharmony_ci    if (!coid)
91e1051a39Sopenharmony_ci        coid = OBJ_nid2obj(NID_pkcs7_data);
92e1051a39Sopenharmony_ci    return PKCS7_add_signed_attribute(si, NID_pkcs9_contentType,
93e1051a39Sopenharmony_ci                                      V_ASN1_OBJECT, coid);
94e1051a39Sopenharmony_ci}
95e1051a39Sopenharmony_ci
96e1051a39Sopenharmony_ciint PKCS7_add0_attrib_signing_time(PKCS7_SIGNER_INFO *si, ASN1_TIME *t)
97e1051a39Sopenharmony_ci{
98e1051a39Sopenharmony_ci    if (t == NULL && (t = X509_gmtime_adj(NULL, 0)) == NULL) {
99e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE);
100e1051a39Sopenharmony_ci        return 0;
101e1051a39Sopenharmony_ci    }
102e1051a39Sopenharmony_ci    return PKCS7_add_signed_attribute(si, NID_pkcs9_signingTime,
103e1051a39Sopenharmony_ci                                      V_ASN1_UTCTIME, t);
104e1051a39Sopenharmony_ci}
105e1051a39Sopenharmony_ci
106e1051a39Sopenharmony_ciint PKCS7_add1_attrib_digest(PKCS7_SIGNER_INFO *si,
107e1051a39Sopenharmony_ci                             const unsigned char *md, int mdlen)
108e1051a39Sopenharmony_ci{
109e1051a39Sopenharmony_ci    ASN1_OCTET_STRING *os;
110e1051a39Sopenharmony_ci    os = ASN1_OCTET_STRING_new();
111e1051a39Sopenharmony_ci    if (os == NULL)
112e1051a39Sopenharmony_ci        return 0;
113e1051a39Sopenharmony_ci    if (!ASN1_STRING_set(os, md, mdlen)
114e1051a39Sopenharmony_ci        || !PKCS7_add_signed_attribute(si, NID_pkcs9_messageDigest,
115e1051a39Sopenharmony_ci                                       V_ASN1_OCTET_STRING, os)) {
116e1051a39Sopenharmony_ci        ASN1_OCTET_STRING_free(os);
117e1051a39Sopenharmony_ci        return 0;
118e1051a39Sopenharmony_ci    }
119e1051a39Sopenharmony_ci    return 1;
120e1051a39Sopenharmony_ci}
121