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