Line data Source code
1 : /* crypto/asn1/a_object.c */
2 : /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 : * All rights reserved.
4 : *
5 : * This package is an SSL implementation written
6 : * by Eric Young (eay@cryptsoft.com).
7 : * The implementation was written so as to conform with Netscapes SSL.
8 : *
9 : * This library is free for commercial and non-commercial use as long as
10 : * the following conditions are aheared to. The following conditions
11 : * apply to all code found in this distribution, be it the RC4, RSA,
12 : * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 : * included with this distribution is covered by the same copyright terms
14 : * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 : *
16 : * Copyright remains Eric Young's, and as such any Copyright notices in
17 : * the code are not to be removed.
18 : * If this package is used in a product, Eric Young should be given attribution
19 : * as the author of the parts of the library used.
20 : * This can be in the form of a textual message at program startup or
21 : * in documentation (online or textual) provided with the package.
22 : *
23 : * Redistribution and use in source and binary forms, with or without
24 : * modification, are permitted provided that the following conditions
25 : * are met:
26 : * 1. Redistributions of source code must retain the copyright
27 : * notice, this list of conditions and the following disclaimer.
28 : * 2. Redistributions in binary form must reproduce the above copyright
29 : * notice, this list of conditions and the following disclaimer in the
30 : * documentation and/or other materials provided with the distribution.
31 : * 3. All advertising materials mentioning features or use of this software
32 : * must display the following acknowledgement:
33 : * "This product includes cryptographic software written by
34 : * Eric Young (eay@cryptsoft.com)"
35 : * The word 'cryptographic' can be left out if the rouines from the library
36 : * being used are not cryptographic related :-).
37 : * 4. If you include any Windows specific code (or a derivative thereof) from
38 : * the apps directory (application code) you must include an acknowledgement:
39 : * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 : *
41 : * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 : * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 : * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 : * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 : * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 : * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 : * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 : * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 : * SUCH DAMAGE.
52 : *
53 : * The licence and distribution terms for any publically available version or
54 : * derivative of this code cannot be changed. i.e. this code cannot simply be
55 : * copied and put under another distribution licence
56 : * [including the GNU Public Licence.]
57 : */
58 :
59 : #include <stdio.h>
60 : #include <limits.h>
61 : #include "cryptlib.h"
62 : #include <openssl/buffer.h>
63 : #include <openssl/asn1.h>
64 : #include <openssl/objects.h>
65 : #include <openssl/bn.h>
66 :
67 0 : int i2d_ASN1_OBJECT(ASN1_OBJECT *a, unsigned char **pp)
68 : {
69 : unsigned char *p;
70 : int objsize;
71 :
72 0 : if ((a == NULL) || (a->data == NULL))
73 : return (0);
74 :
75 0 : objsize = ASN1_object_size(0, a->length, V_ASN1_OBJECT);
76 0 : if (pp == NULL)
77 : return objsize;
78 :
79 0 : p = *pp;
80 0 : ASN1_put_object(&p, 0, a->length, V_ASN1_OBJECT, V_ASN1_UNIVERSAL);
81 0 : memcpy(p, a->data, a->length);
82 0 : p += a->length;
83 :
84 0 : *pp = p;
85 0 : return (objsize);
86 : }
87 :
88 0 : int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num)
89 : {
90 : int i, first, len = 0, c, use_bn;
91 : char ftmp[24], *tmp = ftmp;
92 : int tmpsize = sizeof ftmp;
93 : const char *p;
94 : unsigned long l;
95 : BIGNUM *bl = NULL;
96 :
97 0 : if (num == 0)
98 : return (0);
99 0 : else if (num == -1)
100 0 : num = strlen(buf);
101 :
102 : p = buf;
103 0 : c = *(p++);
104 0 : num--;
105 0 : if ((c >= '0') && (c <= '2')) {
106 0 : first = c - '0';
107 : } else {
108 0 : ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_FIRST_NUM_TOO_LARGE);
109 0 : goto err;
110 : }
111 :
112 0 : if (num <= 0) {
113 0 : ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_MISSING_SECOND_NUMBER);
114 0 : goto err;
115 : }
116 0 : c = *(p++);
117 0 : num--;
118 : for (;;) {
119 0 : if (num <= 0)
120 : break;
121 0 : if ((c != '.') && (c != ' ')) {
122 0 : ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_INVALID_SEPARATOR);
123 0 : goto err;
124 : }
125 : l = 0;
126 : use_bn = 0;
127 : for (;;) {
128 0 : if (num <= 0)
129 : break;
130 0 : num--;
131 0 : c = *(p++);
132 0 : if ((c == ' ') || (c == '.'))
133 : break;
134 0 : if ((c < '0') || (c > '9')) {
135 0 : ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_INVALID_DIGIT);
136 0 : goto err;
137 : }
138 0 : if (!use_bn && l >= ((ULONG_MAX - 80) / 10L)) {
139 : use_bn = 1;
140 0 : if (!bl)
141 0 : bl = BN_new();
142 0 : if (!bl || !BN_set_word(bl, l))
143 : goto err;
144 : }
145 0 : if (use_bn) {
146 0 : if (!BN_mul_word(bl, 10L)
147 0 : || !BN_add_word(bl, c - '0'))
148 : goto err;
149 : } else
150 0 : l = l * 10L + (long)(c - '0');
151 : }
152 0 : if (len == 0) {
153 0 : if ((first < 2) && (l >= 40)) {
154 0 : ASN1err(ASN1_F_A2D_ASN1_OBJECT,
155 : ASN1_R_SECOND_NUMBER_TOO_LARGE);
156 0 : goto err;
157 : }
158 0 : if (use_bn) {
159 0 : if (!BN_add_word(bl, first * 40))
160 : goto err;
161 : } else
162 0 : l += (long)first *40;
163 : }
164 : i = 0;
165 0 : if (use_bn) {
166 : int blsize;
167 0 : blsize = BN_num_bits(bl);
168 0 : blsize = (blsize + 6) / 7;
169 0 : if (blsize > tmpsize) {
170 0 : if (tmp != ftmp)
171 0 : OPENSSL_free(tmp);
172 0 : tmpsize = blsize + 32;
173 0 : tmp = OPENSSL_malloc(tmpsize);
174 0 : if (!tmp)
175 : goto err;
176 : }
177 0 : while (blsize--)
178 0 : tmp[i++] = (unsigned char)BN_div_word(bl, 0x80L);
179 : } else {
180 :
181 : for (;;) {
182 0 : tmp[i++] = (unsigned char)l & 0x7f;
183 0 : l >>= 7L;
184 0 : if (l == 0L)
185 : break;
186 : }
187 :
188 : }
189 0 : if (out != NULL) {
190 0 : if (len + i > olen) {
191 0 : ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_BUFFER_TOO_SMALL);
192 0 : goto err;
193 : }
194 0 : while (--i > 0)
195 0 : out[len++] = tmp[i] | 0x80;
196 0 : out[len++] = tmp[0];
197 : } else
198 0 : len += i;
199 : }
200 0 : if (tmp != ftmp)
201 0 : OPENSSL_free(tmp);
202 0 : if (bl)
203 0 : BN_free(bl);
204 0 : return (len);
205 : err:
206 0 : if (tmp != ftmp)
207 0 : OPENSSL_free(tmp);
208 0 : if (bl)
209 0 : BN_free(bl);
210 : return (0);
211 : }
212 :
213 0 : int i2t_ASN1_OBJECT(char *buf, int buf_len, ASN1_OBJECT *a)
214 : {
215 0 : return OBJ_obj2txt(buf, buf_len, a, 0);
216 : }
217 :
218 0 : int i2a_ASN1_OBJECT(BIO *bp, ASN1_OBJECT *a)
219 : {
220 : char buf[80], *p = buf;
221 : int i;
222 :
223 0 : if ((a == NULL) || (a->data == NULL))
224 0 : return (BIO_write(bp, "NULL", 4));
225 : i = i2t_ASN1_OBJECT(buf, sizeof buf, a);
226 0 : if (i > (int)(sizeof(buf) - 1)) {
227 0 : p = OPENSSL_malloc(i + 1);
228 0 : if (!p)
229 : return -1;
230 : i2t_ASN1_OBJECT(p, i + 1, a);
231 : }
232 0 : if (i <= 0)
233 0 : return BIO_write(bp, "<INVALID>", 9);
234 0 : BIO_write(bp, p, i);
235 0 : if (p != buf)
236 0 : OPENSSL_free(p);
237 0 : return (i);
238 : }
239 :
240 0 : ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
241 : long length)
242 : {
243 : const unsigned char *p;
244 : long len;
245 : int tag, xclass;
246 : int inf, i;
247 : ASN1_OBJECT *ret = NULL;
248 0 : p = *pp;
249 0 : inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
250 0 : if (inf & 0x80) {
251 : i = ASN1_R_BAD_OBJECT_HEADER;
252 : goto err;
253 : }
254 :
255 0 : if (tag != V_ASN1_OBJECT) {
256 : i = ASN1_R_EXPECTING_AN_OBJECT;
257 : goto err;
258 : }
259 0 : ret = c2i_ASN1_OBJECT(a, &p, len);
260 0 : if (ret)
261 0 : *pp = p;
262 0 : return ret;
263 : err:
264 0 : ASN1err(ASN1_F_D2I_ASN1_OBJECT, i);
265 0 : return (NULL);
266 : }
267 :
268 24230 : ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
269 : long len)
270 : {
271 : ASN1_OBJECT *ret = NULL;
272 : const unsigned char *p;
273 : unsigned char *data;
274 : int i, length;
275 :
276 : /*
277 : * Sanity check OID encoding. Need at least one content octet. MSB must
278 : * be clear in the last octet. can't have leading 0x80 in subidentifiers,
279 : * see: X.690 8.19.2
280 : */
281 48460 : if (len <= 0 || len > INT_MAX || pp == NULL || (p = *pp) == NULL ||
282 24230 : p[len - 1] & 0x80) {
283 0 : ASN1err(ASN1_F_C2I_ASN1_OBJECT, ASN1_R_INVALID_OBJECT_ENCODING);
284 0 : return NULL;
285 : }
286 : /* Now 0 < len <= INT_MAX, so the cast is safe. */
287 24230 : length = (int)len;
288 130240 : for (i = 0; i < length; i++, p++) {
289 106010 : if (*p == 0x80 && (!i || !(p[-1] & 0x80))) {
290 0 : ASN1err(ASN1_F_C2I_ASN1_OBJECT, ASN1_R_INVALID_OBJECT_ENCODING);
291 0 : return NULL;
292 : }
293 : }
294 :
295 : /*
296 : * only the ASN1_OBJECTs from the 'table' will have values for ->sn or
297 : * ->ln
298 : */
299 48460 : if ((a == NULL) || ((*a) == NULL) ||
300 24230 : !((*a)->flags & ASN1_OBJECT_FLAG_DYNAMIC)) {
301 24230 : if ((ret = ASN1_OBJECT_new()) == NULL)
302 : return (NULL);
303 : } else
304 : ret = (*a);
305 :
306 24230 : p = *pp;
307 : /* detach data from object */
308 24230 : data = (unsigned char *)ret->data;
309 24230 : ret->data = NULL;
310 : /* once detached we can change it */
311 24230 : if ((data == NULL) || (ret->length < length)) {
312 24230 : ret->length = 0;
313 24230 : if (data != NULL)
314 0 : OPENSSL_free(data);
315 24230 : data = (unsigned char *)OPENSSL_malloc(length);
316 24230 : if (data == NULL) {
317 : i = ERR_R_MALLOC_FAILURE;
318 : goto err;
319 : }
320 24230 : ret->flags |= ASN1_OBJECT_FLAG_DYNAMIC_DATA;
321 : }
322 24230 : memcpy(data, p, length);
323 : /* reattach data to object, after which it remains const */
324 24230 : ret->data = data;
325 24230 : ret->length = length;
326 24230 : ret->sn = NULL;
327 24230 : ret->ln = NULL;
328 : /* ret->flags=ASN1_OBJECT_FLAG_DYNAMIC; we know it is dynamic */
329 24230 : p += length;
330 :
331 24230 : if (a != NULL)
332 24230 : (*a) = ret;
333 24230 : *pp = p;
334 24230 : return (ret);
335 : err:
336 0 : ASN1err(ASN1_F_C2I_ASN1_OBJECT, i);
337 0 : if ((ret != NULL) && ((a == NULL) || (*a != ret)))
338 0 : ASN1_OBJECT_free(ret);
339 : return (NULL);
340 : }
341 :
342 38922 : ASN1_OBJECT *ASN1_OBJECT_new(void)
343 : {
344 : ASN1_OBJECT *ret;
345 :
346 38922 : ret = (ASN1_OBJECT *)OPENSSL_malloc(sizeof(ASN1_OBJECT));
347 38922 : if (ret == NULL) {
348 0 : ASN1err(ASN1_F_ASN1_OBJECT_NEW, ERR_R_MALLOC_FAILURE);
349 0 : return (NULL);
350 : }
351 38922 : ret->length = 0;
352 38922 : ret->data = NULL;
353 38922 : ret->nid = 0;
354 38922 : ret->sn = NULL;
355 38922 : ret->ln = NULL;
356 38922 : ret->flags = ASN1_OBJECT_FLAG_DYNAMIC;
357 38922 : return (ret);
358 : }
359 :
360 38920 : void ASN1_OBJECT_free(ASN1_OBJECT *a)
361 : {
362 38920 : if (a == NULL)
363 38922 : return;
364 38919 : if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_STRINGS) {
365 : #ifndef CONST_STRICT /* disable purely for compile-time strict
366 : * const checking. Doing this on a "real"
367 : * compile will cause memory leaks */
368 14692 : if (a->sn != NULL)
369 0 : OPENSSL_free((void *)a->sn);
370 14692 : if (a->ln != NULL)
371 0 : OPENSSL_free((void *)a->ln);
372 : #endif
373 14692 : a->sn = a->ln = NULL;
374 : }
375 38919 : if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_DATA) {
376 38919 : if (a->data != NULL)
377 38919 : OPENSSL_free((void *)a->data);
378 38921 : a->data = NULL;
379 38921 : a->length = 0;
380 : }
381 38921 : if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC)
382 38921 : OPENSSL_free(a);
383 : }
384 :
385 0 : ASN1_OBJECT *ASN1_OBJECT_create(int nid, unsigned char *data, int len,
386 : const char *sn, const char *ln)
387 : {
388 : ASN1_OBJECT o;
389 :
390 0 : o.sn = sn;
391 0 : o.ln = ln;
392 0 : o.data = data;
393 0 : o.nid = nid;
394 0 : o.length = len;
395 0 : o.flags = ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS |
396 : ASN1_OBJECT_FLAG_DYNAMIC_DATA;
397 0 : return (OBJ_dup(&o));
398 : }
399 :
400 : IMPLEMENT_STACK_OF(ASN1_OBJECT)
401 :
402 : IMPLEMENT_ASN1_SET_OF(ASN1_OBJECT)
|