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