]> git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/asn1/a_object.c
6e4ae3b0730a89790482ca1744e3f0fcc8102fd1
[thirdparty/openssl.git] / crypto / asn1 / a_object.c
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
66 int i2d_ASN1_OBJECT(ASN1_OBJECT *a, unsigned char **pp)
67 {
68 unsigned char *p;
69 int objsize;
70
71 if ((a == NULL) || (a->data == NULL)) return(0);
72
73 objsize = ASN1_object_size(0,a->length,V_ASN1_OBJECT);
74 if (pp == NULL) return objsize;
75
76 p= *pp;
77 ASN1_put_object(&p,0,a->length,V_ASN1_OBJECT,V_ASN1_UNIVERSAL);
78 memcpy(p,a->data,a->length);
79 p+=a->length;
80
81 *pp=p;
82 return(objsize);
83 }
84
85 int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num)
86 {
87 int i,first,len=0,c, use_bn;
88 char ftmp[24], *tmp = ftmp;
89 int tmpsize = sizeof ftmp;
90 const char *p;
91 unsigned long l;
92 BIGNUM *bl = NULL;
93
94 if (num == 0)
95 return(0);
96 else if (num == -1)
97 num=strlen(buf);
98
99 p=buf;
100 c= *(p++);
101 num--;
102 if ((c >= '0') && (c <= '2'))
103 {
104 first= c-'0';
105 }
106 else
107 {
108 ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_FIRST_NUM_TOO_LARGE);
109 goto err;
110 }
111
112 if (num <= 0)
113 {
114 ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_MISSING_SECOND_NUMBER);
115 goto err;
116 }
117 c= *(p++);
118 num--;
119 for (;;)
120 {
121 if (num <= 0) break;
122 if ((c != '.') && (c != ' '))
123 {
124 ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_INVALID_SEPARATOR);
125 goto err;
126 }
127 l=0;
128 use_bn = 0;
129 for (;;)
130 {
131 if (num <= 0) break;
132 num--;
133 c= *(p++);
134 if ((c == ' ') || (c == '.'))
135 break;
136 if ((c < '0') || (c > '9'))
137 {
138 ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_INVALID_DIGIT);
139 goto err;
140 }
141 if (!use_bn && l > (ULONG_MAX / 10L))
142 {
143 use_bn = 1;
144 if (!bl)
145 bl = BN_new();
146 if (!bl || !BN_set_word(bl, l))
147 goto err;
148 }
149 if (use_bn)
150 {
151 if (!BN_mul_word(bl, 10L)
152 || !BN_add_word(bl, c-'0'))
153 goto err;
154 }
155 else
156 l=l*10L+(long)(c-'0');
157 }
158 if (len == 0)
159 {
160 if ((first < 2) && (l >= 40))
161 {
162 ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_SECOND_NUMBER_TOO_LARGE);
163 goto err;
164 }
165 if (use_bn)
166 {
167 if (!BN_add_word(bl, first * 40))
168 goto err;
169 }
170 else
171 l+=(long)first*40;
172 }
173 i=0;
174 if (use_bn)
175 {
176 int blsize;
177 blsize = BN_num_bits(bl);
178 blsize = (blsize + 6)/7;
179 if (blsize > tmpsize)
180 {
181 if (tmp != ftmp)
182 OPENSSL_free(tmp);
183 tmpsize = blsize + 32;
184 tmp = OPENSSL_malloc(tmpsize);
185 if (!tmp)
186 goto err;
187 }
188 while(blsize--)
189 tmp[i++] = (unsigned char)BN_div_word(bl, 0x80L);
190 }
191 else
192 {
193
194 for (;;)
195 {
196 tmp[i++]=(unsigned char)l&0x7f;
197 l>>=7L;
198 if (l == 0L) break;
199 }
200
201 }
202 if (out != NULL)
203 {
204 if (len+i > olen)
205 {
206 ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_BUFFER_TOO_SMALL);
207 goto err;
208 }
209 while (--i > 0)
210 out[len++]=tmp[i]|0x80;
211 out[len++]=tmp[0];
212 }
213 else
214 len+=i;
215 }
216 if (tmp != ftmp)
217 OPENSSL_free(tmp);
218 if (bl)
219 BN_free(bl);
220 return(len);
221 err:
222 if (tmp != ftmp)
223 OPENSSL_free(tmp);
224 if (bl)
225 BN_free(bl);
226 return(0);
227 }
228
229 int i2t_ASN1_OBJECT(char *buf, int buf_len, ASN1_OBJECT *a)
230 {
231 return OBJ_obj2txt(buf, buf_len, a, 0);
232 }
233
234 int i2a_ASN1_OBJECT(BIO *bp, ASN1_OBJECT *a)
235 {
236 char buf[80], *p = buf;
237 int i;
238
239 if ((a == NULL) || (a->data == NULL))
240 return(BIO_write(bp,"NULL",4));
241 i=i2t_ASN1_OBJECT(buf,sizeof buf,a);
242 if (i > (int)(sizeof(buf) - 1))
243 {
244 p = OPENSSL_malloc(i + 1);
245 if (!p)
246 return -1;
247 i2t_ASN1_OBJECT(p,i + 1,a);
248 }
249 if (i <= 0)
250 return BIO_write(bp, "<INVALID>", 9);
251 BIO_write(bp,p,i);
252 if (p != buf)
253 OPENSSL_free(p);
254 return(i);
255 }
256
257 ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
258 long length)
259 {
260 const unsigned char *p;
261 long len;
262 int tag,xclass;
263 int inf,i;
264 ASN1_OBJECT *ret = NULL;
265 p= *pp;
266 inf=ASN1_get_object(&p,&len,&tag,&xclass,length);
267 if (inf & 0x80)
268 {
269 i=ASN1_R_BAD_OBJECT_HEADER;
270 goto err;
271 }
272
273 if (tag != V_ASN1_OBJECT)
274 {
275 i=ASN1_R_EXPECTING_AN_OBJECT;
276 goto err;
277 }
278 ret = c2i_ASN1_OBJECT(a, &p, len);
279 if(ret) *pp = p;
280 return ret;
281 err:
282 ASN1err(ASN1_F_D2I_ASN1_OBJECT,i);
283 return(NULL);
284 }
285 ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
286 long len)
287 {
288 ASN1_OBJECT *ret=NULL;
289 const unsigned char *p;
290 unsigned char *data;
291 int i;
292
293 /* only the ASN1_OBJECTs from the 'table' will have values
294 * for ->sn or ->ln */
295 if ((a == NULL) || ((*a) == NULL) ||
296 !((*a)->flags & ASN1_OBJECT_FLAG_DYNAMIC))
297 {
298 if ((ret=ASN1_OBJECT_new()) == NULL) return(NULL);
299 }
300 else ret=(*a);
301
302 p= *pp;
303 /* detach data from object */
304 data = (unsigned char *)ret->data;
305 ret->data = NULL;
306 /* once detached we can change it */
307 if ((data == NULL) || (ret->length < len))
308 {
309 ret->length=0;
310 if (data != NULL) OPENSSL_free(data);
311 data=(unsigned char *)OPENSSL_malloc(len ? (int)len : 1);
312 if (data == NULL)
313 { i=ERR_R_MALLOC_FAILURE; goto err; }
314 ret->flags|=ASN1_OBJECT_FLAG_DYNAMIC_DATA;
315 }
316 memcpy(data,p,(int)len);
317 /* reattach data to object, after which it remains const */
318 ret->data =data;
319 ret->length=(int)len;
320 ret->sn=NULL;
321 ret->ln=NULL;
322 /* ret->flags=ASN1_OBJECT_FLAG_DYNAMIC; we know it is dynamic */
323 p+=len;
324
325 if (a != NULL) (*a)=ret;
326 *pp=p;
327 return(ret);
328 err:
329 ASN1err(ASN1_F_C2I_ASN1_OBJECT,i);
330 if ((ret != NULL) && ((a == NULL) || (*a != ret)))
331 ASN1_OBJECT_free(ret);
332 return(NULL);
333 }
334
335 ASN1_OBJECT *ASN1_OBJECT_new(void)
336 {
337 ASN1_OBJECT *ret;
338
339 ret=(ASN1_OBJECT *)OPENSSL_malloc(sizeof(ASN1_OBJECT));
340 if (ret == NULL)
341 {
342 ASN1err(ASN1_F_ASN1_OBJECT_NEW,ERR_R_MALLOC_FAILURE);
343 return(NULL);
344 }
345 ret->length=0;
346 ret->data=NULL;
347 ret->nid=0;
348 ret->sn=NULL;
349 ret->ln=NULL;
350 ret->flags=ASN1_OBJECT_FLAG_DYNAMIC;
351 return(ret);
352 }
353
354 void ASN1_OBJECT_free(ASN1_OBJECT *a)
355 {
356 if (a == NULL) return;
357 if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_STRINGS)
358 {
359 #ifndef CONST_STRICT /* disable purely for compile-time strict const checking. Doing this on a "real" compile will cause memory leaks */
360 if (a->sn != NULL) OPENSSL_free((void *)a->sn);
361 if (a->ln != NULL) OPENSSL_free((void *)a->ln);
362 #endif
363 a->sn=a->ln=NULL;
364 }
365 if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_DATA)
366 {
367 if (a->data != NULL) OPENSSL_free((void *)a->data);
368 a->data=NULL;
369 a->length=0;
370 }
371 if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC)
372 OPENSSL_free(a);
373 }
374
375 ASN1_OBJECT *ASN1_OBJECT_create(int nid, unsigned char *data, int len,
376 const char *sn, const char *ln)
377 {
378 ASN1_OBJECT o;
379
380 o.sn=sn;
381 o.ln=ln;
382 o.data=data;
383 o.nid=nid;
384 o.length=len;
385 o.flags=ASN1_OBJECT_FLAG_DYNAMIC|ASN1_OBJECT_FLAG_DYNAMIC_STRINGS|
386 ASN1_OBJECT_FLAG_DYNAMIC_DATA;
387 return(OBJ_dup(&o));
388 }
389
390 IMPLEMENT_STACK_OF(ASN1_OBJECT)
391 IMPLEMENT_ASN1_SET_OF(ASN1_OBJECT)