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