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