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