xref: /third_party/openssl/crypto/x509/x509_v3.c (revision e1051a39)
1e1051a39Sopenharmony_ci/*
2e1051a39Sopenharmony_ci * Copyright 1995-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 "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 "x509_local.h"
19e1051a39Sopenharmony_ci
20e1051a39Sopenharmony_ciint X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x)
21e1051a39Sopenharmony_ci{
22e1051a39Sopenharmony_ci    int ret;
23e1051a39Sopenharmony_ci
24e1051a39Sopenharmony_ci    if (x == NULL)
25e1051a39Sopenharmony_ci        return 0;
26e1051a39Sopenharmony_ci    ret = sk_X509_EXTENSION_num(x);
27e1051a39Sopenharmony_ci    return ret > 0 ? ret : 0;
28e1051a39Sopenharmony_ci}
29e1051a39Sopenharmony_ci
30e1051a39Sopenharmony_ciint X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x, int nid,
31e1051a39Sopenharmony_ci                          int lastpos)
32e1051a39Sopenharmony_ci{
33e1051a39Sopenharmony_ci    ASN1_OBJECT *obj;
34e1051a39Sopenharmony_ci
35e1051a39Sopenharmony_ci    obj = OBJ_nid2obj(nid);
36e1051a39Sopenharmony_ci    if (obj == NULL)
37e1051a39Sopenharmony_ci        return -2;
38e1051a39Sopenharmony_ci    return X509v3_get_ext_by_OBJ(x, obj, lastpos);
39e1051a39Sopenharmony_ci}
40e1051a39Sopenharmony_ci
41e1051a39Sopenharmony_ciint X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *sk,
42e1051a39Sopenharmony_ci                          const ASN1_OBJECT *obj, int lastpos)
43e1051a39Sopenharmony_ci{
44e1051a39Sopenharmony_ci    int n;
45e1051a39Sopenharmony_ci    X509_EXTENSION *ex;
46e1051a39Sopenharmony_ci
47e1051a39Sopenharmony_ci    if (sk == NULL)
48e1051a39Sopenharmony_ci        return -1;
49e1051a39Sopenharmony_ci    lastpos++;
50e1051a39Sopenharmony_ci    if (lastpos < 0)
51e1051a39Sopenharmony_ci        lastpos = 0;
52e1051a39Sopenharmony_ci    n = sk_X509_EXTENSION_num(sk);
53e1051a39Sopenharmony_ci    for (; lastpos < n; lastpos++) {
54e1051a39Sopenharmony_ci        ex = sk_X509_EXTENSION_value(sk, lastpos);
55e1051a39Sopenharmony_ci        if (OBJ_cmp(ex->object, obj) == 0)
56e1051a39Sopenharmony_ci            return lastpos;
57e1051a39Sopenharmony_ci    }
58e1051a39Sopenharmony_ci    return -1;
59e1051a39Sopenharmony_ci}
60e1051a39Sopenharmony_ci
61e1051a39Sopenharmony_ciint X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *sk, int crit,
62e1051a39Sopenharmony_ci                               int lastpos)
63e1051a39Sopenharmony_ci{
64e1051a39Sopenharmony_ci    int n;
65e1051a39Sopenharmony_ci    X509_EXTENSION *ex;
66e1051a39Sopenharmony_ci
67e1051a39Sopenharmony_ci    if (sk == NULL)
68e1051a39Sopenharmony_ci        return -1;
69e1051a39Sopenharmony_ci    lastpos++;
70e1051a39Sopenharmony_ci    if (lastpos < 0)
71e1051a39Sopenharmony_ci        lastpos = 0;
72e1051a39Sopenharmony_ci    n = sk_X509_EXTENSION_num(sk);
73e1051a39Sopenharmony_ci    for (; lastpos < n; lastpos++) {
74e1051a39Sopenharmony_ci        ex = sk_X509_EXTENSION_value(sk, lastpos);
75e1051a39Sopenharmony_ci        if (((ex->critical > 0) && crit) || ((ex->critical <= 0) && !crit))
76e1051a39Sopenharmony_ci            return lastpos;
77e1051a39Sopenharmony_ci    }
78e1051a39Sopenharmony_ci    return -1;
79e1051a39Sopenharmony_ci}
80e1051a39Sopenharmony_ci
81e1051a39Sopenharmony_ciX509_EXTENSION *X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, int loc)
82e1051a39Sopenharmony_ci{
83e1051a39Sopenharmony_ci    if (x == NULL || sk_X509_EXTENSION_num(x) <= loc || loc < 0)
84e1051a39Sopenharmony_ci        return NULL;
85e1051a39Sopenharmony_ci    else
86e1051a39Sopenharmony_ci        return sk_X509_EXTENSION_value(x, loc);
87e1051a39Sopenharmony_ci}
88e1051a39Sopenharmony_ci
89e1051a39Sopenharmony_ciX509_EXTENSION *X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc)
90e1051a39Sopenharmony_ci{
91e1051a39Sopenharmony_ci    X509_EXTENSION *ret;
92e1051a39Sopenharmony_ci
93e1051a39Sopenharmony_ci    if (x == NULL || sk_X509_EXTENSION_num(x) <= loc || loc < 0)
94e1051a39Sopenharmony_ci        return NULL;
95e1051a39Sopenharmony_ci    ret = sk_X509_EXTENSION_delete(x, loc);
96e1051a39Sopenharmony_ci    return ret;
97e1051a39Sopenharmony_ci}
98e1051a39Sopenharmony_ci
99e1051a39Sopenharmony_ciSTACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x,
100e1051a39Sopenharmony_ci                                         X509_EXTENSION *ex, int loc)
101e1051a39Sopenharmony_ci{
102e1051a39Sopenharmony_ci    X509_EXTENSION *new_ex = NULL;
103e1051a39Sopenharmony_ci    int n;
104e1051a39Sopenharmony_ci    STACK_OF(X509_EXTENSION) *sk = NULL;
105e1051a39Sopenharmony_ci
106e1051a39Sopenharmony_ci    if (x == NULL) {
107e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER);
108e1051a39Sopenharmony_ci        goto err2;
109e1051a39Sopenharmony_ci    }
110e1051a39Sopenharmony_ci
111e1051a39Sopenharmony_ci    if (*x == NULL) {
112e1051a39Sopenharmony_ci        if ((sk = sk_X509_EXTENSION_new_null()) == NULL)
113e1051a39Sopenharmony_ci            goto err;
114e1051a39Sopenharmony_ci    } else
115e1051a39Sopenharmony_ci        sk = *x;
116e1051a39Sopenharmony_ci
117e1051a39Sopenharmony_ci    n = sk_X509_EXTENSION_num(sk);
118e1051a39Sopenharmony_ci    if (loc > n)
119e1051a39Sopenharmony_ci        loc = n;
120e1051a39Sopenharmony_ci    else if (loc < 0)
121e1051a39Sopenharmony_ci        loc = n;
122e1051a39Sopenharmony_ci
123e1051a39Sopenharmony_ci    if ((new_ex = X509_EXTENSION_dup(ex)) == NULL)
124e1051a39Sopenharmony_ci        goto err2;
125e1051a39Sopenharmony_ci    if (!sk_X509_EXTENSION_insert(sk, new_ex, loc))
126e1051a39Sopenharmony_ci        goto err;
127e1051a39Sopenharmony_ci    if (*x == NULL)
128e1051a39Sopenharmony_ci        *x = sk;
129e1051a39Sopenharmony_ci    return sk;
130e1051a39Sopenharmony_ci err:
131e1051a39Sopenharmony_ci    ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE);
132e1051a39Sopenharmony_ci err2:
133e1051a39Sopenharmony_ci    X509_EXTENSION_free(new_ex);
134e1051a39Sopenharmony_ci    if (x != NULL && *x == NULL)
135e1051a39Sopenharmony_ci        sk_X509_EXTENSION_free(sk);
136e1051a39Sopenharmony_ci    return NULL;
137e1051a39Sopenharmony_ci}
138e1051a39Sopenharmony_ci
139e1051a39Sopenharmony_ciX509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex, int nid,
140e1051a39Sopenharmony_ci                                             int crit,
141e1051a39Sopenharmony_ci                                             ASN1_OCTET_STRING *data)
142e1051a39Sopenharmony_ci{
143e1051a39Sopenharmony_ci    ASN1_OBJECT *obj;
144e1051a39Sopenharmony_ci    X509_EXTENSION *ret;
145e1051a39Sopenharmony_ci
146e1051a39Sopenharmony_ci    obj = OBJ_nid2obj(nid);
147e1051a39Sopenharmony_ci    if (obj == NULL) {
148e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_X509, X509_R_UNKNOWN_NID);
149e1051a39Sopenharmony_ci        return NULL;
150e1051a39Sopenharmony_ci    }
151e1051a39Sopenharmony_ci    ret = X509_EXTENSION_create_by_OBJ(ex, obj, crit, data);
152e1051a39Sopenharmony_ci    if (ret == NULL)
153e1051a39Sopenharmony_ci        ASN1_OBJECT_free(obj);
154e1051a39Sopenharmony_ci    return ret;
155e1051a39Sopenharmony_ci}
156e1051a39Sopenharmony_ci
157e1051a39Sopenharmony_ciX509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex,
158e1051a39Sopenharmony_ci                                             const ASN1_OBJECT *obj, int crit,
159e1051a39Sopenharmony_ci                                             ASN1_OCTET_STRING *data)
160e1051a39Sopenharmony_ci{
161e1051a39Sopenharmony_ci    X509_EXTENSION *ret;
162e1051a39Sopenharmony_ci
163e1051a39Sopenharmony_ci    if ((ex == NULL) || (*ex == NULL)) {
164e1051a39Sopenharmony_ci        if ((ret = X509_EXTENSION_new()) == NULL) {
165e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE);
166e1051a39Sopenharmony_ci            return NULL;
167e1051a39Sopenharmony_ci        }
168e1051a39Sopenharmony_ci    } else
169e1051a39Sopenharmony_ci        ret = *ex;
170e1051a39Sopenharmony_ci
171e1051a39Sopenharmony_ci    if (!X509_EXTENSION_set_object(ret, obj))
172e1051a39Sopenharmony_ci        goto err;
173e1051a39Sopenharmony_ci    if (!X509_EXTENSION_set_critical(ret, crit))
174e1051a39Sopenharmony_ci        goto err;
175e1051a39Sopenharmony_ci    if (!X509_EXTENSION_set_data(ret, data))
176e1051a39Sopenharmony_ci        goto err;
177e1051a39Sopenharmony_ci
178e1051a39Sopenharmony_ci    if ((ex != NULL) && (*ex == NULL))
179e1051a39Sopenharmony_ci        *ex = ret;
180e1051a39Sopenharmony_ci    return ret;
181e1051a39Sopenharmony_ci err:
182e1051a39Sopenharmony_ci    if ((ex == NULL) || (ret != *ex))
183e1051a39Sopenharmony_ci        X509_EXTENSION_free(ret);
184e1051a39Sopenharmony_ci    return NULL;
185e1051a39Sopenharmony_ci}
186e1051a39Sopenharmony_ci
187e1051a39Sopenharmony_ciint X509_EXTENSION_set_object(X509_EXTENSION *ex, const ASN1_OBJECT *obj)
188e1051a39Sopenharmony_ci{
189e1051a39Sopenharmony_ci    if ((ex == NULL) || (obj == NULL))
190e1051a39Sopenharmony_ci        return 0;
191e1051a39Sopenharmony_ci    ASN1_OBJECT_free(ex->object);
192e1051a39Sopenharmony_ci    ex->object = OBJ_dup(obj);
193e1051a39Sopenharmony_ci    return ex->object != NULL;
194e1051a39Sopenharmony_ci}
195e1051a39Sopenharmony_ci
196e1051a39Sopenharmony_ciint X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit)
197e1051a39Sopenharmony_ci{
198e1051a39Sopenharmony_ci    if (ex == NULL)
199e1051a39Sopenharmony_ci        return 0;
200e1051a39Sopenharmony_ci    ex->critical = (crit) ? 0xFF : -1;
201e1051a39Sopenharmony_ci    return 1;
202e1051a39Sopenharmony_ci}
203e1051a39Sopenharmony_ci
204e1051a39Sopenharmony_ciint X509_EXTENSION_set_data(X509_EXTENSION *ex, ASN1_OCTET_STRING *data)
205e1051a39Sopenharmony_ci{
206e1051a39Sopenharmony_ci    int i;
207e1051a39Sopenharmony_ci
208e1051a39Sopenharmony_ci    if (ex == NULL)
209e1051a39Sopenharmony_ci        return 0;
210e1051a39Sopenharmony_ci    i = ASN1_OCTET_STRING_set(&ex->value, data->data, data->length);
211e1051a39Sopenharmony_ci    if (!i)
212e1051a39Sopenharmony_ci        return 0;
213e1051a39Sopenharmony_ci    return 1;
214e1051a39Sopenharmony_ci}
215e1051a39Sopenharmony_ci
216e1051a39Sopenharmony_ciASN1_OBJECT *X509_EXTENSION_get_object(X509_EXTENSION *ex)
217e1051a39Sopenharmony_ci{
218e1051a39Sopenharmony_ci    if (ex == NULL)
219e1051a39Sopenharmony_ci        return NULL;
220e1051a39Sopenharmony_ci    return ex->object;
221e1051a39Sopenharmony_ci}
222e1051a39Sopenharmony_ci
223e1051a39Sopenharmony_ciASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *ex)
224e1051a39Sopenharmony_ci{
225e1051a39Sopenharmony_ci    if (ex == NULL)
226e1051a39Sopenharmony_ci        return NULL;
227e1051a39Sopenharmony_ci    return &ex->value;
228e1051a39Sopenharmony_ci}
229e1051a39Sopenharmony_ci
230e1051a39Sopenharmony_ciint X509_EXTENSION_get_critical(const X509_EXTENSION *ex)
231e1051a39Sopenharmony_ci{
232e1051a39Sopenharmony_ci    if (ex == NULL)
233e1051a39Sopenharmony_ci        return 0;
234e1051a39Sopenharmony_ci    if (ex->critical > 0)
235e1051a39Sopenharmony_ci        return 1;
236e1051a39Sopenharmony_ci    return 0;
237e1051a39Sopenharmony_ci}
238