xref: /openssl/crypto/x509/x509_att.c (revision b0ebb87a)
1 /*
2  * Copyright 1995-2024 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) *ossl_x509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x,
83                                                 const 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 
93     if (*x == NULL) {
94         if ((sk = sk_X509_ATTRIBUTE_new_null()) == NULL) {
95             ERR_raise(ERR_LIB_X509, ERR_R_CRYPTO_LIB);
96             goto err;
97         }
98     } else {
99         sk = *x;
100     }
101 
102     if ((new_attr = X509_ATTRIBUTE_dup(attr)) == NULL)
103         goto err;
104     if (!sk_X509_ATTRIBUTE_push(sk, new_attr)) {
105         ERR_raise(ERR_LIB_X509, ERR_R_CRYPTO_LIB);
106         goto err;
107     }
108     if (*x == NULL)
109         *x = sk;
110     return sk;
111  err:
112     X509_ATTRIBUTE_free(new_attr);
113     if (*x == NULL)
114         sk_X509_ATTRIBUTE_free(sk);
115     return NULL;
116 }
117 
STACK_OF(X509_ATTRIBUTE)118 STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x,
119                                            X509_ATTRIBUTE *attr)
120 {
121     if (x == NULL || attr == NULL) {
122         ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER);
123         return NULL;
124     }
125     if (*x != NULL && X509at_get_attr_by_OBJ(*x, attr->object, -1) != -1) {
126         ERR_raise_data(ERR_LIB_X509, X509_R_DUPLICATE_ATTRIBUTE,
127                        "name=%s", OBJ_nid2sn(OBJ_obj2nid(attr->object)));
128         return NULL;
129     }
130 
131     return ossl_x509at_add1_attr(x, attr);
132 }
133 
STACK_OF(X509_ATTRIBUTE)134 STACK_OF(X509_ATTRIBUTE) *ossl_x509at_add1_attr_by_OBJ(STACK_OF(X509_ATTRIBUTE) **x,
135                                                        const ASN1_OBJECT *obj,
136                                                        int type,
137                                                        const unsigned char *bytes,
138                                                        int len)
139 {
140     X509_ATTRIBUTE *attr;
141     STACK_OF(X509_ATTRIBUTE) *ret;
142 
143     attr = X509_ATTRIBUTE_create_by_OBJ(NULL, obj, type, bytes, len);
144     if (attr == NULL)
145         return 0;
146     ret = ossl_x509at_add1_attr(x, attr);
147     X509_ATTRIBUTE_free(attr);
148     return ret;
149 }
150 
STACK_OF(X509_ATTRIBUTE)151 STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_OBJ(STACK_OF(X509_ATTRIBUTE)
152                                                   **x, const ASN1_OBJECT *obj,
153                                                   int type,
154                                                   const unsigned char *bytes,
155                                                   int len)
156 {
157     if (x == NULL || obj == NULL) {
158         ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER);
159         return NULL;
160     }
161     if (*x != NULL && X509at_get_attr_by_OBJ(*x, obj, -1) != -1) {
162         ERR_raise_data(ERR_LIB_X509, X509_R_DUPLICATE_ATTRIBUTE,
163                        "name=%s", OBJ_nid2sn(OBJ_obj2nid(obj)));
164         return NULL;
165     }
166 
167     return ossl_x509at_add1_attr_by_OBJ(x, obj, type, bytes, len);
168 }
169 
STACK_OF(X509_ATTRIBUTE)170 STACK_OF(X509_ATTRIBUTE) *ossl_x509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE) **x,
171                                                        int nid, int type,
172                                                        const unsigned char *bytes,
173                                                        int len)
174 {
175     X509_ATTRIBUTE *attr;
176     STACK_OF(X509_ATTRIBUTE) *ret;
177 
178     attr = X509_ATTRIBUTE_create_by_NID(NULL, nid, type, bytes, len);
179     if (attr == NULL)
180         return 0;
181     ret = ossl_x509at_add1_attr(x, attr);
182     X509_ATTRIBUTE_free(attr);
183     return ret;
184 }
185 
STACK_OF(X509_ATTRIBUTE)186 STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE)
187                                                   **x, int nid, int type,
188                                                   const unsigned char *bytes,
189                                                   int len)
190 {
191     if (x == NULL) {
192         ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER);
193         return NULL;
194     }
195     if (*x != NULL && X509at_get_attr_by_NID(*x, nid, -1) != -1) {
196         ERR_raise_data(ERR_LIB_X509, X509_R_DUPLICATE_ATTRIBUTE,
197                        "name=%s", OBJ_nid2sn(nid));
198         return NULL;
199     }
200 
201     return ossl_x509at_add1_attr_by_NID(x, nid, type, bytes, len);
202 }
203 
STACK_OF(X509_ATTRIBUTE)204 STACK_OF(X509_ATTRIBUTE) *ossl_x509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE) **x,
205                                                        const char *attrname,
206                                                        int type,
207                                                        const unsigned char *bytes,
208                                                        int len)
209 {
210     X509_ATTRIBUTE *attr;
211     STACK_OF(X509_ATTRIBUTE) *ret;
212 
213     attr = X509_ATTRIBUTE_create_by_txt(NULL, attrname, type, bytes, len);
214     if (attr == NULL)
215         return 0;
216     ret = ossl_x509at_add1_attr(x, attr);
217     X509_ATTRIBUTE_free(attr);
218     return ret;
219 }
220 
STACK_OF(X509_ATTRIBUTE)221 STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE)
222                                                   **x, const char *attrname,
223                                                   int type,
224                                                   const unsigned char *bytes,
225                                                   int len)
226 {
227     X509_ATTRIBUTE *attr;
228     STACK_OF(X509_ATTRIBUTE) *ret;
229 
230     attr = X509_ATTRIBUTE_create_by_txt(NULL, attrname, type, bytes, len);
231     if (attr == NULL)
232         return 0;
233     ret = X509at_add1_attr(x, attr);
234     X509_ATTRIBUTE_free(attr);
235     return ret;
236 }
237 
X509at_get0_data_by_OBJ(const STACK_OF (X509_ATTRIBUTE)* x,const ASN1_OBJECT * obj,int lastpos,int type)238 void *X509at_get0_data_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *x,
239                               const ASN1_OBJECT *obj, int lastpos, int type)
240 {
241     int i = X509at_get_attr_by_OBJ(x, obj, lastpos);
242     X509_ATTRIBUTE *at;
243 
244     if (i == -1)
245         return NULL;
246     if (lastpos <= -2 && X509at_get_attr_by_OBJ(x, obj, i) != -1)
247         return NULL;
248     at = X509at_get_attr(x, i);
249     if (lastpos <= -3 && X509_ATTRIBUTE_count(at) != 1)
250         return NULL;
251     return X509_ATTRIBUTE_get0_data(at, 0, type, NULL);
252 }
253 
STACK_OF(X509_ATTRIBUTE)254 STACK_OF(X509_ATTRIBUTE) *ossl_x509at_dup(const STACK_OF(X509_ATTRIBUTE) *x)
255 {
256     int i, n = sk_X509_ATTRIBUTE_num(x);
257     STACK_OF(X509_ATTRIBUTE) *sk = NULL;
258 
259     for (i = 0; i < n; ++i) {
260         if (X509at_add1_attr(&sk, sk_X509_ATTRIBUTE_value(x, i)) == NULL) {
261             sk_X509_ATTRIBUTE_pop_free(sk, X509_ATTRIBUTE_free);
262             return NULL;
263         }
264     }
265     return sk;
266 }
267 
X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE ** attr,int nid,int atrtype,const void * data,int len)268 X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid,
269                                              int atrtype, const void *data,
270                                              int len)
271 {
272     ASN1_OBJECT *obj = OBJ_nid2obj(nid);
273     X509_ATTRIBUTE *ret;
274 
275     if (obj == NULL) {
276         ERR_raise(ERR_LIB_X509, X509_R_UNKNOWN_NID);
277         return NULL;
278     }
279     ret = X509_ATTRIBUTE_create_by_OBJ(attr, obj, atrtype, data, len);
280     if (ret == NULL)
281         ASN1_OBJECT_free(obj);
282     return ret;
283 }
284 
X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE ** attr,const ASN1_OBJECT * obj,int atrtype,const void * data,int len)285 X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr,
286                                              const ASN1_OBJECT *obj,
287                                              int atrtype, const void *data,
288                                              int len)
289 {
290     X509_ATTRIBUTE *ret;
291 
292     if (attr == NULL || *attr == NULL) {
293         if ((ret = X509_ATTRIBUTE_new()) == NULL) {
294             ERR_raise(ERR_LIB_X509, ERR_R_ASN1_LIB);
295             return NULL;
296         }
297     } else {
298         ret = *attr;
299     }
300 
301     if (!X509_ATTRIBUTE_set1_object(ret, obj))
302         goto err;
303     if (!X509_ATTRIBUTE_set1_data(ret, atrtype, data, len))
304         goto err;
305 
306     if (attr != NULL && *attr == NULL)
307         *attr = ret;
308     return ret;
309  err:
310     if (attr == NULL || ret != *attr)
311         X509_ATTRIBUTE_free(ret);
312     return NULL;
313 }
314 
X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE ** attr,const char * atrname,int type,const unsigned char * bytes,int len)315 X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr,
316                                              const char *atrname, int type,
317                                              const unsigned char *bytes,
318                                              int len)
319 {
320     ASN1_OBJECT *obj = OBJ_txt2obj(atrname, 0);
321     X509_ATTRIBUTE *nattr;
322 
323     if (obj == NULL) {
324         ERR_raise_data(ERR_LIB_X509, X509_R_INVALID_FIELD_NAME,
325                        "name=%s", atrname);
326         return NULL;
327     }
328     nattr = X509_ATTRIBUTE_create_by_OBJ(attr, obj, type, bytes, len);
329     ASN1_OBJECT_free(obj);
330     return nattr;
331 }
332 
X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE * attr,const ASN1_OBJECT * obj)333 int X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, const ASN1_OBJECT *obj)
334 {
335     if (attr == NULL || obj == NULL) {
336         ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER);
337         return 0;
338     }
339     ASN1_OBJECT_free(attr->object);
340     attr->object = OBJ_dup(obj);
341     return attr->object != NULL;
342 }
343 
X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE * attr,int attrtype,const void * data,int len)344 int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype,
345                              const void *data, int len)
346 {
347     ASN1_TYPE *ttmp = NULL;
348     ASN1_STRING *stmp = NULL;
349     int atype = 0;
350 
351     if (attr == NULL) {
352         ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER);
353         return 0;
354     }
355     if ((attrtype & MBSTRING_FLAG) != 0) {
356         stmp = ASN1_STRING_set_by_NID(NULL, data, len, attrtype,
357                                       OBJ_obj2nid(attr->object));
358         if (stmp == NULL) {
359             ERR_raise(ERR_LIB_X509, ERR_R_ASN1_LIB);
360             return 0;
361         }
362         atype = stmp->type;
363     } else if (len != -1) {
364         if ((stmp = ASN1_STRING_type_new(attrtype)) == NULL
365             || !ASN1_STRING_set(stmp, data, len)) {
366             ERR_raise(ERR_LIB_X509, ERR_R_ASN1_LIB);
367             goto err;
368         }
369         atype = attrtype;
370     }
371     /*
372      * This is a bit naughty because the attribute should really have at
373      * least one value but some types use and zero length SET and require
374      * this.
375      */
376     if (attrtype == 0) {
377         ASN1_STRING_free(stmp);
378         return 1;
379     }
380     if ((ttmp = ASN1_TYPE_new()) == NULL) {
381         ERR_raise(ERR_LIB_X509, ERR_R_ASN1_LIB);
382         goto err;
383     }
384     if (len == -1 && (attrtype & MBSTRING_FLAG) == 0) {
385         if (!ASN1_TYPE_set1(ttmp, attrtype, data)) {
386             ERR_raise(ERR_LIB_X509, ERR_R_ASN1_LIB);
387             goto err;
388         }
389     } else {
390         ASN1_TYPE_set(ttmp, atype, stmp);
391         stmp = NULL;
392     }
393     if (!sk_ASN1_TYPE_push(attr->set, ttmp)) {
394         ERR_raise(ERR_LIB_X509, ERR_R_CRYPTO_LIB);
395         goto err;
396     }
397     return 1;
398  err:
399     ASN1_TYPE_free(ttmp);
400     ASN1_STRING_free(stmp);
401     return 0;
402 }
403 
X509_ATTRIBUTE_count(const X509_ATTRIBUTE * attr)404 int X509_ATTRIBUTE_count(const X509_ATTRIBUTE *attr)
405 {
406     if (attr == NULL)
407         return 0;
408     return sk_ASN1_TYPE_num(attr->set);
409 }
410 
X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE * attr)411 ASN1_OBJECT *X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr)
412 {
413     if (attr == NULL) {
414         ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER);
415         return NULL;
416     }
417     return attr->object;
418 }
419 
X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE * attr,int idx,int atrtype,void * data)420 void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx,
421                                int atrtype, void *data)
422 {
423     ASN1_TYPE *ttmp = X509_ATTRIBUTE_get0_type(attr, idx);
424 
425     if (ttmp == NULL)
426         return NULL;
427     if (atrtype == V_ASN1_BOOLEAN
428             || atrtype == V_ASN1_NULL
429             || atrtype != ASN1_TYPE_get(ttmp)) {
430         ERR_raise(ERR_LIB_X509, X509_R_WRONG_TYPE);
431         return NULL;
432     }
433     return ttmp->value.ptr;
434 }
435 
X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE * attr,int idx)436 ASN1_TYPE *X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx)
437 {
438     if (attr == NULL) {
439         ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER);
440         return NULL;
441     }
442     return sk_ASN1_TYPE_value(attr->set, idx);
443 }
444