xref: /third_party/openssl/crypto/x509/x509_att.c (revision e1051a39)
1e1051a39Sopenharmony_ci/*
2e1051a39Sopenharmony_ci * Copyright 1995-2021 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/safestack.h>
13e1051a39Sopenharmony_ci#include <openssl/asn1.h>
14e1051a39Sopenharmony_ci#include <openssl/objects.h>
15e1051a39Sopenharmony_ci#include <openssl/evp.h>
16e1051a39Sopenharmony_ci#include <openssl/x509.h>
17e1051a39Sopenharmony_ci#include <openssl/x509v3.h>
18e1051a39Sopenharmony_ci#include "crypto/x509.h"
19e1051a39Sopenharmony_ci#include "x509_local.h"
20e1051a39Sopenharmony_ci
21e1051a39Sopenharmony_ciint X509at_get_attr_count(const STACK_OF(X509_ATTRIBUTE) *x)
22e1051a39Sopenharmony_ci{
23e1051a39Sopenharmony_ci    return sk_X509_ATTRIBUTE_num(x);
24e1051a39Sopenharmony_ci}
25e1051a39Sopenharmony_ci
26e1051a39Sopenharmony_ciint X509at_get_attr_by_NID(const STACK_OF(X509_ATTRIBUTE) *x, int nid,
27e1051a39Sopenharmony_ci                           int lastpos)
28e1051a39Sopenharmony_ci{
29e1051a39Sopenharmony_ci    const ASN1_OBJECT *obj = OBJ_nid2obj(nid);
30e1051a39Sopenharmony_ci
31e1051a39Sopenharmony_ci    if (obj == NULL)
32e1051a39Sopenharmony_ci        return -2;
33e1051a39Sopenharmony_ci    return X509at_get_attr_by_OBJ(x, obj, lastpos);
34e1051a39Sopenharmony_ci}
35e1051a39Sopenharmony_ci
36e1051a39Sopenharmony_ciint X509at_get_attr_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *sk,
37e1051a39Sopenharmony_ci                           const ASN1_OBJECT *obj, int lastpos)
38e1051a39Sopenharmony_ci{
39e1051a39Sopenharmony_ci    int n;
40e1051a39Sopenharmony_ci    X509_ATTRIBUTE *ex;
41e1051a39Sopenharmony_ci
42e1051a39Sopenharmony_ci    if (sk == NULL)
43e1051a39Sopenharmony_ci        return -1;
44e1051a39Sopenharmony_ci    lastpos++;
45e1051a39Sopenharmony_ci    if (lastpos < 0)
46e1051a39Sopenharmony_ci        lastpos = 0;
47e1051a39Sopenharmony_ci    n = sk_X509_ATTRIBUTE_num(sk);
48e1051a39Sopenharmony_ci    for (; lastpos < n; lastpos++) {
49e1051a39Sopenharmony_ci        ex = sk_X509_ATTRIBUTE_value(sk, lastpos);
50e1051a39Sopenharmony_ci        if (OBJ_cmp(ex->object, obj) == 0)
51e1051a39Sopenharmony_ci            return lastpos;
52e1051a39Sopenharmony_ci    }
53e1051a39Sopenharmony_ci    return -1;
54e1051a39Sopenharmony_ci}
55e1051a39Sopenharmony_ci
56e1051a39Sopenharmony_ciX509_ATTRIBUTE *X509at_get_attr(const STACK_OF(X509_ATTRIBUTE) *x, int loc)
57e1051a39Sopenharmony_ci{
58e1051a39Sopenharmony_ci    if (x == NULL || sk_X509_ATTRIBUTE_num(x) <= loc || loc < 0)
59e1051a39Sopenharmony_ci        return NULL;
60e1051a39Sopenharmony_ci
61e1051a39Sopenharmony_ci    return sk_X509_ATTRIBUTE_value(x, loc);
62e1051a39Sopenharmony_ci}
63e1051a39Sopenharmony_ci
64e1051a39Sopenharmony_ciX509_ATTRIBUTE *X509at_delete_attr(STACK_OF(X509_ATTRIBUTE) *x, int loc)
65e1051a39Sopenharmony_ci{
66e1051a39Sopenharmony_ci    X509_ATTRIBUTE *ret;
67e1051a39Sopenharmony_ci
68e1051a39Sopenharmony_ci    if (x == NULL || sk_X509_ATTRIBUTE_num(x) <= loc || loc < 0)
69e1051a39Sopenharmony_ci        return NULL;
70e1051a39Sopenharmony_ci    ret = sk_X509_ATTRIBUTE_delete(x, loc);
71e1051a39Sopenharmony_ci    return ret;
72e1051a39Sopenharmony_ci}
73e1051a39Sopenharmony_ci
74e1051a39Sopenharmony_ciSTACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x,
75e1051a39Sopenharmony_ci                                           X509_ATTRIBUTE *attr)
76e1051a39Sopenharmony_ci{
77e1051a39Sopenharmony_ci    X509_ATTRIBUTE *new_attr = NULL;
78e1051a39Sopenharmony_ci    STACK_OF(X509_ATTRIBUTE) *sk = NULL;
79e1051a39Sopenharmony_ci
80e1051a39Sopenharmony_ci    if (x == NULL) {
81e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER);
82e1051a39Sopenharmony_ci        return NULL;
83e1051a39Sopenharmony_ci    }
84e1051a39Sopenharmony_ci
85e1051a39Sopenharmony_ci    if (*x == NULL) {
86e1051a39Sopenharmony_ci        if ((sk = sk_X509_ATTRIBUTE_new_null()) == NULL)
87e1051a39Sopenharmony_ci            goto err;
88e1051a39Sopenharmony_ci    } else {
89e1051a39Sopenharmony_ci        sk = *x;
90e1051a39Sopenharmony_ci    }
91e1051a39Sopenharmony_ci
92e1051a39Sopenharmony_ci    if ((new_attr = X509_ATTRIBUTE_dup(attr)) == NULL)
93e1051a39Sopenharmony_ci        goto err2;
94e1051a39Sopenharmony_ci    if (!sk_X509_ATTRIBUTE_push(sk, new_attr))
95e1051a39Sopenharmony_ci        goto err;
96e1051a39Sopenharmony_ci    if (*x == NULL)
97e1051a39Sopenharmony_ci        *x = sk;
98e1051a39Sopenharmony_ci    return sk;
99e1051a39Sopenharmony_ci err:
100e1051a39Sopenharmony_ci    ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE);
101e1051a39Sopenharmony_ci err2:
102e1051a39Sopenharmony_ci    X509_ATTRIBUTE_free(new_attr);
103e1051a39Sopenharmony_ci    if (*x == NULL)
104e1051a39Sopenharmony_ci        sk_X509_ATTRIBUTE_free(sk);
105e1051a39Sopenharmony_ci    return NULL;
106e1051a39Sopenharmony_ci}
107e1051a39Sopenharmony_ci
108e1051a39Sopenharmony_ciSTACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_OBJ(STACK_OF(X509_ATTRIBUTE)
109e1051a39Sopenharmony_ci                                                  **x, const ASN1_OBJECT *obj,
110e1051a39Sopenharmony_ci                                                  int type,
111e1051a39Sopenharmony_ci                                                  const unsigned char *bytes,
112e1051a39Sopenharmony_ci                                                  int len)
113e1051a39Sopenharmony_ci{
114e1051a39Sopenharmony_ci    X509_ATTRIBUTE *attr;
115e1051a39Sopenharmony_ci    STACK_OF(X509_ATTRIBUTE) *ret;
116e1051a39Sopenharmony_ci    attr = X509_ATTRIBUTE_create_by_OBJ(NULL, obj, type, bytes, len);
117e1051a39Sopenharmony_ci    if (!attr)
118e1051a39Sopenharmony_ci        return 0;
119e1051a39Sopenharmony_ci    ret = X509at_add1_attr(x, attr);
120e1051a39Sopenharmony_ci    X509_ATTRIBUTE_free(attr);
121e1051a39Sopenharmony_ci    return ret;
122e1051a39Sopenharmony_ci}
123e1051a39Sopenharmony_ci
124e1051a39Sopenharmony_ciSTACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE)
125e1051a39Sopenharmony_ci                                                  **x, int nid, int type,
126e1051a39Sopenharmony_ci                                                  const unsigned char *bytes,
127e1051a39Sopenharmony_ci                                                  int len)
128e1051a39Sopenharmony_ci{
129e1051a39Sopenharmony_ci    X509_ATTRIBUTE *attr;
130e1051a39Sopenharmony_ci    STACK_OF(X509_ATTRIBUTE) *ret;
131e1051a39Sopenharmony_ci    attr = X509_ATTRIBUTE_create_by_NID(NULL, nid, type, bytes, len);
132e1051a39Sopenharmony_ci    if (!attr)
133e1051a39Sopenharmony_ci        return 0;
134e1051a39Sopenharmony_ci    ret = X509at_add1_attr(x, attr);
135e1051a39Sopenharmony_ci    X509_ATTRIBUTE_free(attr);
136e1051a39Sopenharmony_ci    return ret;
137e1051a39Sopenharmony_ci}
138e1051a39Sopenharmony_ci
139e1051a39Sopenharmony_ciSTACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE)
140e1051a39Sopenharmony_ci                                                  **x, const char *attrname,
141e1051a39Sopenharmony_ci                                                  int type,
142e1051a39Sopenharmony_ci                                                  const unsigned char *bytes,
143e1051a39Sopenharmony_ci                                                  int len)
144e1051a39Sopenharmony_ci{
145e1051a39Sopenharmony_ci    X509_ATTRIBUTE *attr;
146e1051a39Sopenharmony_ci    STACK_OF(X509_ATTRIBUTE) *ret;
147e1051a39Sopenharmony_ci    attr = X509_ATTRIBUTE_create_by_txt(NULL, attrname, type, bytes, len);
148e1051a39Sopenharmony_ci    if (!attr)
149e1051a39Sopenharmony_ci        return 0;
150e1051a39Sopenharmony_ci    ret = X509at_add1_attr(x, attr);
151e1051a39Sopenharmony_ci    X509_ATTRIBUTE_free(attr);
152e1051a39Sopenharmony_ci    return ret;
153e1051a39Sopenharmony_ci}
154e1051a39Sopenharmony_ci
155e1051a39Sopenharmony_civoid *X509at_get0_data_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *x,
156e1051a39Sopenharmony_ci                              const ASN1_OBJECT *obj, int lastpos, int type)
157e1051a39Sopenharmony_ci{
158e1051a39Sopenharmony_ci    int i;
159e1051a39Sopenharmony_ci    X509_ATTRIBUTE *at;
160e1051a39Sopenharmony_ci    i = X509at_get_attr_by_OBJ(x, obj, lastpos);
161e1051a39Sopenharmony_ci    if (i == -1)
162e1051a39Sopenharmony_ci        return NULL;
163e1051a39Sopenharmony_ci    if ((lastpos <= -2) && (X509at_get_attr_by_OBJ(x, obj, i) != -1))
164e1051a39Sopenharmony_ci        return NULL;
165e1051a39Sopenharmony_ci    at = X509at_get_attr(x, i);
166e1051a39Sopenharmony_ci    if (lastpos <= -3 && (X509_ATTRIBUTE_count(at) != 1))
167e1051a39Sopenharmony_ci        return NULL;
168e1051a39Sopenharmony_ci    return X509_ATTRIBUTE_get0_data(at, 0, type, NULL);
169e1051a39Sopenharmony_ci}
170e1051a39Sopenharmony_ci
171e1051a39Sopenharmony_ciSTACK_OF(X509_ATTRIBUTE) *ossl_x509at_dup(const STACK_OF(X509_ATTRIBUTE) *x)
172e1051a39Sopenharmony_ci{
173e1051a39Sopenharmony_ci    int i, n;
174e1051a39Sopenharmony_ci    STACK_OF(X509_ATTRIBUTE) *sk = NULL;
175e1051a39Sopenharmony_ci
176e1051a39Sopenharmony_ci    n = sk_X509_ATTRIBUTE_num(x);
177e1051a39Sopenharmony_ci    for (i = 0; i < n; ++i) {
178e1051a39Sopenharmony_ci        X509_ATTRIBUTE *attr = sk_X509_ATTRIBUTE_value(x, i);
179e1051a39Sopenharmony_ci
180e1051a39Sopenharmony_ci        if (X509at_add1_attr(&sk, attr) == NULL) {
181e1051a39Sopenharmony_ci            sk_X509_ATTRIBUTE_pop_free(sk, X509_ATTRIBUTE_free);
182e1051a39Sopenharmony_ci            return NULL;
183e1051a39Sopenharmony_ci        }
184e1051a39Sopenharmony_ci    }
185e1051a39Sopenharmony_ci    return sk;
186e1051a39Sopenharmony_ci}
187e1051a39Sopenharmony_ci
188e1051a39Sopenharmony_ciX509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid,
189e1051a39Sopenharmony_ci                                             int atrtype, const void *data,
190e1051a39Sopenharmony_ci                                             int len)
191e1051a39Sopenharmony_ci{
192e1051a39Sopenharmony_ci    ASN1_OBJECT *obj;
193e1051a39Sopenharmony_ci    X509_ATTRIBUTE *ret;
194e1051a39Sopenharmony_ci
195e1051a39Sopenharmony_ci    obj = OBJ_nid2obj(nid);
196e1051a39Sopenharmony_ci    if (obj == NULL) {
197e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_X509, X509_R_UNKNOWN_NID);
198e1051a39Sopenharmony_ci        return NULL;
199e1051a39Sopenharmony_ci    }
200e1051a39Sopenharmony_ci    ret = X509_ATTRIBUTE_create_by_OBJ(attr, obj, atrtype, data, len);
201e1051a39Sopenharmony_ci    if (ret == NULL)
202e1051a39Sopenharmony_ci        ASN1_OBJECT_free(obj);
203e1051a39Sopenharmony_ci    return ret;
204e1051a39Sopenharmony_ci}
205e1051a39Sopenharmony_ci
206e1051a39Sopenharmony_ciX509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr,
207e1051a39Sopenharmony_ci                                             const ASN1_OBJECT *obj,
208e1051a39Sopenharmony_ci                                             int atrtype, const void *data,
209e1051a39Sopenharmony_ci                                             int len)
210e1051a39Sopenharmony_ci{
211e1051a39Sopenharmony_ci    X509_ATTRIBUTE *ret;
212e1051a39Sopenharmony_ci
213e1051a39Sopenharmony_ci    if ((attr == NULL) || (*attr == NULL)) {
214e1051a39Sopenharmony_ci        if ((ret = X509_ATTRIBUTE_new()) == NULL) {
215e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE);
216e1051a39Sopenharmony_ci            return NULL;
217e1051a39Sopenharmony_ci        }
218e1051a39Sopenharmony_ci    } else
219e1051a39Sopenharmony_ci        ret = *attr;
220e1051a39Sopenharmony_ci
221e1051a39Sopenharmony_ci    if (!X509_ATTRIBUTE_set1_object(ret, obj))
222e1051a39Sopenharmony_ci        goto err;
223e1051a39Sopenharmony_ci    if (!X509_ATTRIBUTE_set1_data(ret, atrtype, data, len))
224e1051a39Sopenharmony_ci        goto err;
225e1051a39Sopenharmony_ci
226e1051a39Sopenharmony_ci    if ((attr != NULL) && (*attr == NULL))
227e1051a39Sopenharmony_ci        *attr = ret;
228e1051a39Sopenharmony_ci    return ret;
229e1051a39Sopenharmony_ci err:
230e1051a39Sopenharmony_ci    if ((attr == NULL) || (ret != *attr))
231e1051a39Sopenharmony_ci        X509_ATTRIBUTE_free(ret);
232e1051a39Sopenharmony_ci    return NULL;
233e1051a39Sopenharmony_ci}
234e1051a39Sopenharmony_ci
235e1051a39Sopenharmony_ciX509_ATTRIBUTE *X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr,
236e1051a39Sopenharmony_ci                                             const char *atrname, int type,
237e1051a39Sopenharmony_ci                                             const unsigned char *bytes,
238e1051a39Sopenharmony_ci                                             int len)
239e1051a39Sopenharmony_ci{
240e1051a39Sopenharmony_ci    ASN1_OBJECT *obj;
241e1051a39Sopenharmony_ci    X509_ATTRIBUTE *nattr;
242e1051a39Sopenharmony_ci
243e1051a39Sopenharmony_ci    obj = OBJ_txt2obj(atrname, 0);
244e1051a39Sopenharmony_ci    if (obj == NULL) {
245e1051a39Sopenharmony_ci        ERR_raise_data(ERR_LIB_X509, X509_R_INVALID_FIELD_NAME,
246e1051a39Sopenharmony_ci                       "name=%s", atrname);
247e1051a39Sopenharmony_ci        return NULL;
248e1051a39Sopenharmony_ci    }
249e1051a39Sopenharmony_ci    nattr = X509_ATTRIBUTE_create_by_OBJ(attr, obj, type, bytes, len);
250e1051a39Sopenharmony_ci    ASN1_OBJECT_free(obj);
251e1051a39Sopenharmony_ci    return nattr;
252e1051a39Sopenharmony_ci}
253e1051a39Sopenharmony_ci
254e1051a39Sopenharmony_ciint X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, const ASN1_OBJECT *obj)
255e1051a39Sopenharmony_ci{
256e1051a39Sopenharmony_ci    if ((attr == NULL) || (obj == NULL))
257e1051a39Sopenharmony_ci        return 0;
258e1051a39Sopenharmony_ci    ASN1_OBJECT_free(attr->object);
259e1051a39Sopenharmony_ci    attr->object = OBJ_dup(obj);
260e1051a39Sopenharmony_ci    return attr->object != NULL;
261e1051a39Sopenharmony_ci}
262e1051a39Sopenharmony_ci
263e1051a39Sopenharmony_ciint X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype,
264e1051a39Sopenharmony_ci                             const void *data, int len)
265e1051a39Sopenharmony_ci{
266e1051a39Sopenharmony_ci    ASN1_TYPE *ttmp = NULL;
267e1051a39Sopenharmony_ci    ASN1_STRING *stmp = NULL;
268e1051a39Sopenharmony_ci    int atype = 0;
269e1051a39Sopenharmony_ci    if (!attr)
270e1051a39Sopenharmony_ci        return 0;
271e1051a39Sopenharmony_ci    if (attrtype & MBSTRING_FLAG) {
272e1051a39Sopenharmony_ci        stmp = ASN1_STRING_set_by_NID(NULL, data, len, attrtype,
273e1051a39Sopenharmony_ci                                      OBJ_obj2nid(attr->object));
274e1051a39Sopenharmony_ci        if (!stmp) {
275e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_X509, ERR_R_ASN1_LIB);
276e1051a39Sopenharmony_ci            return 0;
277e1051a39Sopenharmony_ci        }
278e1051a39Sopenharmony_ci        atype = stmp->type;
279e1051a39Sopenharmony_ci    } else if (len != -1) {
280e1051a39Sopenharmony_ci        if ((stmp = ASN1_STRING_type_new(attrtype)) == NULL)
281e1051a39Sopenharmony_ci            goto err;
282e1051a39Sopenharmony_ci        if (!ASN1_STRING_set(stmp, data, len))
283e1051a39Sopenharmony_ci            goto err;
284e1051a39Sopenharmony_ci        atype = attrtype;
285e1051a39Sopenharmony_ci    }
286e1051a39Sopenharmony_ci    /*
287e1051a39Sopenharmony_ci     * This is a bit naughty because the attribute should really have at
288e1051a39Sopenharmony_ci     * least one value but some types use and zero length SET and require
289e1051a39Sopenharmony_ci     * this.
290e1051a39Sopenharmony_ci     */
291e1051a39Sopenharmony_ci    if (attrtype == 0) {
292e1051a39Sopenharmony_ci        ASN1_STRING_free(stmp);
293e1051a39Sopenharmony_ci        return 1;
294e1051a39Sopenharmony_ci    }
295e1051a39Sopenharmony_ci    if ((ttmp = ASN1_TYPE_new()) == NULL)
296e1051a39Sopenharmony_ci        goto err;
297e1051a39Sopenharmony_ci    if ((len == -1) && !(attrtype & MBSTRING_FLAG)) {
298e1051a39Sopenharmony_ci        if (!ASN1_TYPE_set1(ttmp, attrtype, data))
299e1051a39Sopenharmony_ci            goto err;
300e1051a39Sopenharmony_ci    } else {
301e1051a39Sopenharmony_ci        ASN1_TYPE_set(ttmp, atype, stmp);
302e1051a39Sopenharmony_ci        stmp = NULL;
303e1051a39Sopenharmony_ci    }
304e1051a39Sopenharmony_ci    if (!sk_ASN1_TYPE_push(attr->set, ttmp))
305e1051a39Sopenharmony_ci        goto err;
306e1051a39Sopenharmony_ci    return 1;
307e1051a39Sopenharmony_ci err:
308e1051a39Sopenharmony_ci    ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE);
309e1051a39Sopenharmony_ci    ASN1_TYPE_free(ttmp);
310e1051a39Sopenharmony_ci    ASN1_STRING_free(stmp);
311e1051a39Sopenharmony_ci    return 0;
312e1051a39Sopenharmony_ci}
313e1051a39Sopenharmony_ci
314e1051a39Sopenharmony_ciint X509_ATTRIBUTE_count(const X509_ATTRIBUTE *attr)
315e1051a39Sopenharmony_ci{
316e1051a39Sopenharmony_ci    if (attr == NULL)
317e1051a39Sopenharmony_ci        return 0;
318e1051a39Sopenharmony_ci    return sk_ASN1_TYPE_num(attr->set);
319e1051a39Sopenharmony_ci}
320e1051a39Sopenharmony_ci
321e1051a39Sopenharmony_ciASN1_OBJECT *X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr)
322e1051a39Sopenharmony_ci{
323e1051a39Sopenharmony_ci    if (attr == NULL)
324e1051a39Sopenharmony_ci        return NULL;
325e1051a39Sopenharmony_ci    return attr->object;
326e1051a39Sopenharmony_ci}
327e1051a39Sopenharmony_ci
328e1051a39Sopenharmony_civoid *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx,
329e1051a39Sopenharmony_ci                               int atrtype, void *data)
330e1051a39Sopenharmony_ci{
331e1051a39Sopenharmony_ci    ASN1_TYPE *ttmp;
332e1051a39Sopenharmony_ci    ttmp = X509_ATTRIBUTE_get0_type(attr, idx);
333e1051a39Sopenharmony_ci    if (!ttmp)
334e1051a39Sopenharmony_ci        return NULL;
335e1051a39Sopenharmony_ci    if (atrtype == V_ASN1_BOOLEAN
336e1051a39Sopenharmony_ci            || atrtype == V_ASN1_NULL
337e1051a39Sopenharmony_ci            || atrtype != ASN1_TYPE_get(ttmp)) {
338e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_X509, X509_R_WRONG_TYPE);
339e1051a39Sopenharmony_ci        return NULL;
340e1051a39Sopenharmony_ci    }
341e1051a39Sopenharmony_ci    return ttmp->value.ptr;
342e1051a39Sopenharmony_ci}
343e1051a39Sopenharmony_ci
344e1051a39Sopenharmony_ciASN1_TYPE *X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx)
345e1051a39Sopenharmony_ci{
346e1051a39Sopenharmony_ci    if (attr == NULL)
347e1051a39Sopenharmony_ci        return NULL;
348e1051a39Sopenharmony_ci    return sk_ASN1_TYPE_value(attr->set, idx);
349e1051a39Sopenharmony_ci}
350