1 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
2 * All rights reserved.
3 *
4 * This package is an SSL implementation written
5 * by Eric Young (eay@cryptsoft.com).
6 * The implementation was written so as to conform with Netscapes SSL.
7 *
8 * This library is free for commercial and non-commercial use as long as
9 * the following conditions are aheared to. The following conditions
10 * apply to all code found in this distribution, be it the RC4, RSA,
11 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
12 * included with this distribution is covered by the same copyright terms
13 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
14 *
15 * Copyright remains Eric Young's, and as such any Copyright notices in
16 * the code are not to be removed.
17 * If this package is used in a product, Eric Young should be given attribution
18 * as the author of the parts of the library used.
19 * This can be in the form of a textual message at program startup or
20 * in documentation (online or textual) provided with the package.
21 *
22 * Redistribution and use in source and binary forms, with or without
23 * modification, are permitted provided that the following conditions
24 * are met:
25 * 1. Redistributions of source code must retain the copyright
26 * notice, this list of conditions and the following disclaimer.
27 * 2. Redistributions in binary form must reproduce the above copyright
28 * notice, this list of conditions and the following disclaimer in the
29 * documentation and/or other materials provided with the distribution.
30 * 3. All advertising materials mentioning features or use of this software
31 * must display the following acknowledgement:
32 * "This product includes cryptographic software written by
33 * Eric Young (eay@cryptsoft.com)"
34 * The word 'cryptographic' can be left out if the rouines from the library
35 * being used are not cryptographic related :-).
36 * 4. If you include any Windows specific code (or a derivative thereof) from
37 * the apps directory (application code) you must include an acknowledgement:
38 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
39 *
40 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50 * SUCH DAMAGE.
51 *
52 * The licence and distribution terms for any publically available version or
53 * derivative of this code cannot be changed. i.e. this code cannot simply be
54 * copied and put under another distribution licence
55 * [including the GNU Public Licence.] */
56
57 #include <openssl/asn1.h>
58
59 #include <limits.h>
60 #include <string.h>
61
62 #include <openssl/asn1_mac.h>
63 #include <openssl/err.h>
64 #include <openssl/mem.h>
65
66
67 /* Used in asn1_mac.h.
68 * TODO(davidben): Remove this once asn1_mac.h is gone or trimmed. */
69 OPENSSL_DECLARE_ERROR_REASON(ASN1, MALLOC_FAILURE);
70
71 /* Cross-module errors from crypto/x509/i2d_pr.c */
72 OPENSSL_DECLARE_ERROR_FUNCTION(ASN1, i2d_PrivateKey);
73 OPENSSL_DECLARE_ERROR_REASON(ASN1, UNSUPPORTED_PUBLIC_KEY_TYPE);
74
75 /* Cross-module errors from crypto/x509/asn1_gen.c.
76 * TODO(davidben): Remove these once asn1_gen.c is gone. */
77 OPENSSL_DECLARE_ERROR_FUNCTION(ASN1, ASN1_generate_v3);
78 OPENSSL_DECLARE_ERROR_FUNCTION(ASN1, asn1_cb);
79 OPENSSL_DECLARE_ERROR_FUNCTION(ASN1, parse_tagging);
80 OPENSSL_DECLARE_ERROR_FUNCTION(ASN1, append_exp);
81 OPENSSL_DECLARE_ERROR_FUNCTION(ASN1, asn1_str2type);
82 OPENSSL_DECLARE_ERROR_FUNCTION(ASN1, bitstr_cb);
83 OPENSSL_DECLARE_ERROR_REASON(ASN1, DEPTH_EXCEEDED);
84 OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_BITSTRING_FORMAT);
85 OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_BOOLEAN);
86 OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_FORMAT);
87 OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_HEX);
88 OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_IMPLICIT_TAG);
89 OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_INTEGER);
90 OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_NESTED_TAGGING);
91 OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_NULL_VALUE);
92 OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_OBJECT);
93 OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_TIME_VALUE);
94 OPENSSL_DECLARE_ERROR_REASON(ASN1, INTEGER_NOT_ASCII_FORMAT);
95 OPENSSL_DECLARE_ERROR_REASON(ASN1, INVALID_MODIFIER);
96 OPENSSL_DECLARE_ERROR_REASON(ASN1, INVALID_NUMBER);
97 OPENSSL_DECLARE_ERROR_REASON(ASN1, LIST_ERROR);
98 OPENSSL_DECLARE_ERROR_REASON(ASN1, MISSING_VALUE);
99 OPENSSL_DECLARE_ERROR_REASON(ASN1, NOT_ASCII_FORMAT);
100 OPENSSL_DECLARE_ERROR_REASON(ASN1, OBJECT_NOT_ASCII_FORMAT);
101 OPENSSL_DECLARE_ERROR_REASON(ASN1, SEQUENCE_OR_SET_NEEDS_CONFIG);
102 OPENSSL_DECLARE_ERROR_REASON(ASN1, TIME_NOT_ASCII_FORMAT);
103 OPENSSL_DECLARE_ERROR_REASON(ASN1, UNKNOWN_FORMAT);
104 OPENSSL_DECLARE_ERROR_REASON(ASN1, UNKNOWN_TAG);
105 OPENSSL_DECLARE_ERROR_REASON(ASN1, UNSUPPORTED_TYPE);
106
107 static int asn1_get_length(const unsigned char **pp,int *inf,long *rl,int max);
108 static void asn1_put_length(unsigned char **pp, int length);
109
_asn1_check_infinite_end(const unsigned char ** p,long len)110 static int _asn1_check_infinite_end(const unsigned char **p, long len)
111 {
112 /* If there is 0 or 1 byte left, the length check should pick
113 * things up */
114 if (len <= 0)
115 return(1);
116 else if ((len >= 2) && ((*p)[0] == 0) && ((*p)[1] == 0))
117 {
118 (*p)+=2;
119 return(1);
120 }
121 return(0);
122 }
123
ASN1_check_infinite_end(unsigned char ** p,long len)124 int ASN1_check_infinite_end(unsigned char **p, long len)
125 {
126 return _asn1_check_infinite_end((const unsigned char **)p, len);
127 }
128
ASN1_const_check_infinite_end(const unsigned char ** p,long len)129 int ASN1_const_check_infinite_end(const unsigned char **p, long len)
130 {
131 return _asn1_check_infinite_end(p, len);
132 }
133
134
ASN1_get_object(const unsigned char ** pp,long * plength,int * ptag,int * pclass,long omax)135 int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag,
136 int *pclass, long omax)
137 {
138 int i,ret;
139 long l;
140 const unsigned char *p= *pp;
141 int tag,xclass,inf;
142 long max=omax;
143
144 if (!max) goto err;
145 ret=(*p&V_ASN1_CONSTRUCTED);
146 xclass=(*p&V_ASN1_PRIVATE);
147 i= *p&V_ASN1_PRIMITIVE_TAG;
148 if (i == V_ASN1_PRIMITIVE_TAG)
149 { /* high-tag */
150 p++;
151 if (--max == 0) goto err;
152 l=0;
153 while (*p&0x80)
154 {
155 l<<=7L;
156 l|= *(p++)&0x7f;
157 if (--max == 0) goto err;
158 if (l > (INT_MAX >> 7L)) goto err;
159 }
160 l<<=7L;
161 l|= *(p++)&0x7f;
162 tag=(int)l;
163 if (--max == 0) goto err;
164 }
165 else
166 {
167 tag=i;
168 p++;
169 if (--max == 0) goto err;
170 }
171 *ptag=tag;
172 *pclass=xclass;
173 if (!asn1_get_length(&p,&inf,plength,(int)max)) goto err;
174
175 if (inf && !(ret & V_ASN1_CONSTRUCTED))
176 goto err;
177
178 #if 0
179 fprintf(stderr,"p=%d + *plength=%ld > omax=%ld + *pp=%d (%d > %d)\n",
180 (int)p,*plength,omax,(int)*pp,(int)(p+ *plength),
181 (int)(omax+ *pp));
182
183 #endif
184 if (*plength > (omax - (p - *pp)))
185 {
186 OPENSSL_PUT_ERROR(ASN1, ASN1_get_object, ASN1_R_TOO_LONG);
187 /* Set this so that even if things are not long enough
188 * the values are set correctly */
189 ret|=0x80;
190 }
191 *pp=p;
192 return(ret|inf);
193 err:
194 OPENSSL_PUT_ERROR(ASN1, ASN1_get_object, ASN1_R_HEADER_TOO_LONG);
195 return(0x80);
196 }
197
asn1_get_length(const unsigned char ** pp,int * inf,long * rl,int max)198 static int asn1_get_length(const unsigned char **pp, int *inf, long *rl, int max)
199 {
200 const unsigned char *p= *pp;
201 unsigned long ret=0;
202 unsigned int i;
203
204 if (max-- < 1) return(0);
205 if (*p == 0x80)
206 {
207 *inf=1;
208 ret=0;
209 p++;
210 }
211 else
212 {
213 *inf=0;
214 i= *p&0x7f;
215 if (*(p++) & 0x80)
216 {
217 if (i > sizeof(long))
218 return 0;
219 if (max-- == 0) return(0);
220 while (i-- > 0)
221 {
222 ret<<=8L;
223 ret|= *(p++);
224 if (max-- == 0) return(0);
225 }
226 }
227 else
228 ret=i;
229 }
230 if (ret > LONG_MAX)
231 return 0;
232 *pp=p;
233 *rl=(long)ret;
234 return(1);
235 }
236
237 /* class 0 is constructed
238 * constructed == 2 for indefinite length constructed */
ASN1_put_object(unsigned char ** pp,int constructed,int length,int tag,int xclass)239 void ASN1_put_object(unsigned char **pp, int constructed, int length, int tag,
240 int xclass)
241 {
242 unsigned char *p= *pp;
243 int i, ttag;
244
245 i=(constructed)?V_ASN1_CONSTRUCTED:0;
246 i|=(xclass&V_ASN1_PRIVATE);
247 if (tag < 31)
248 *(p++)=i|(tag&V_ASN1_PRIMITIVE_TAG);
249 else
250 {
251 *(p++)=i|V_ASN1_PRIMITIVE_TAG;
252 for(i = 0, ttag = tag; ttag > 0; i++) ttag >>=7;
253 ttag = i;
254 while(i-- > 0)
255 {
256 p[i] = tag & 0x7f;
257 if(i != (ttag - 1)) p[i] |= 0x80;
258 tag >>= 7;
259 }
260 p += ttag;
261 }
262 if (constructed == 2)
263 *(p++)=0x80;
264 else
265 asn1_put_length(&p,length);
266 *pp=p;
267 }
268
ASN1_put_eoc(unsigned char ** pp)269 int ASN1_put_eoc(unsigned char **pp)
270 {
271 unsigned char *p = *pp;
272 *p++ = 0;
273 *p++ = 0;
274 *pp = p;
275 return 2;
276 }
277
asn1_put_length(unsigned char ** pp,int length)278 static void asn1_put_length(unsigned char **pp, int length)
279 {
280 unsigned char *p= *pp;
281 int i,l;
282 if (length <= 127)
283 *(p++)=(unsigned char)length;
284 else
285 {
286 l=length;
287 for (i=0; l > 0; i++)
288 l>>=8;
289 *(p++)=i|0x80;
290 l=i;
291 while (i-- > 0)
292 {
293 p[i]=length&0xff;
294 length>>=8;
295 }
296 p+=l;
297 }
298 *pp=p;
299 }
300
ASN1_object_size(int constructed,int length,int tag)301 int ASN1_object_size(int constructed, int length, int tag)
302 {
303 int ret;
304
305 ret=length;
306 ret++;
307 if (tag >= 31)
308 {
309 while (tag > 0)
310 {
311 tag>>=7;
312 ret++;
313 }
314 }
315 if (constructed == 2)
316 return ret + 3;
317 ret++;
318 if (length > 127)
319 {
320 while (length > 0)
321 {
322 length>>=8;
323 ret++;
324 }
325 }
326 return(ret);
327 }
328
_asn1_Finish(ASN1_const_CTX * c)329 static int _asn1_Finish(ASN1_const_CTX *c)
330 {
331 if ((c->inf == (1|V_ASN1_CONSTRUCTED)) && (!c->eos))
332 {
333 if (!ASN1_const_check_infinite_end(&c->p,c->slen))
334 {
335 c->error=ASN1_R_MISSING_ASN1_EOS;
336 return(0);
337 }
338 }
339 if ( ((c->slen != 0) && !(c->inf & 1)) ||
340 ((c->slen < 0) && (c->inf & 1)))
341 {
342 c->error=ASN1_R_ASN1_LENGTH_MISMATCH;
343 return(0);
344 }
345 return(1);
346 }
347
asn1_Finish(ASN1_CTX * c)348 int asn1_Finish(ASN1_CTX *c)
349 {
350 return _asn1_Finish((ASN1_const_CTX *)c);
351 }
352
asn1_const_Finish(ASN1_const_CTX * c)353 int asn1_const_Finish(ASN1_const_CTX *c)
354 {
355 return _asn1_Finish(c);
356 }
357
asn1_GetSequence(ASN1_const_CTX * c,long * length)358 int asn1_GetSequence(ASN1_const_CTX *c, long *length)
359 {
360 const unsigned char *q;
361
362 q=c->p;
363 c->inf=ASN1_get_object(&(c->p),&(c->slen),&(c->tag),&(c->xclass),
364 *length);
365 if (c->inf & 0x80)
366 {
367 c->error=ASN1_R_BAD_GET_ASN1_OBJECT_CALL;
368 return(0);
369 }
370 if (c->tag != V_ASN1_SEQUENCE)
371 {
372 c->error=ASN1_R_EXPECTING_AN_ASN1_SEQUENCE;
373 return(0);
374 }
375 (*length)-=(c->p-q);
376 if (c->max && (*length < 0))
377 {
378 c->error=ASN1_R_ASN1_LENGTH_MISMATCH;
379 return(0);
380 }
381 if (c->inf == (1|V_ASN1_CONSTRUCTED))
382 c->slen= *length+ *(c->pp)-c->p;
383 c->eos=0;
384 return(1);
385 }
386
ASN1_STRING_copy(ASN1_STRING * dst,const ASN1_STRING * str)387 int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str)
388 {
389 if (str == NULL)
390 return 0;
391 dst->type = str->type;
392 if (!ASN1_STRING_set(dst,str->data,str->length))
393 return 0;
394 dst->flags = str->flags;
395 return 1;
396 }
397
ASN1_STRING_dup(const ASN1_STRING * str)398 ASN1_STRING *ASN1_STRING_dup(const ASN1_STRING *str)
399 {
400 ASN1_STRING *ret;
401 if (!str)
402 return NULL;
403 ret=ASN1_STRING_new();
404 if (!ret)
405 return NULL;
406 if (!ASN1_STRING_copy(ret,str))
407 {
408 ASN1_STRING_free(ret);
409 return NULL;
410 }
411 return ret;
412 }
413
ASN1_STRING_set(ASN1_STRING * str,const void * _data,int len)414 int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len)
415 {
416 unsigned char *c;
417 const char *data=_data;
418
419 if (len < 0)
420 {
421 if (data == NULL)
422 return(0);
423 else
424 len=strlen(data);
425 }
426 if ((str->length < len) || (str->data == NULL))
427 {
428 c=str->data;
429 if (c == NULL)
430 str->data=OPENSSL_malloc(len+1);
431 else
432 str->data=OPENSSL_realloc(c,len+1);
433
434 if (str->data == NULL)
435 {
436 OPENSSL_PUT_ERROR(ASN1, ASN1_STRING_set, ERR_R_MALLOC_FAILURE);
437 str->data=c;
438 return(0);
439 }
440 }
441 str->length=len;
442 if (data != NULL)
443 {
444 memcpy(str->data,data,len);
445 /* an allowance for strings :-) */
446 str->data[len]='\0';
447 }
448 return(1);
449 }
450
ASN1_STRING_set0(ASN1_STRING * str,void * data,int len)451 void ASN1_STRING_set0(ASN1_STRING *str, void *data, int len)
452 {
453 if (str->data)
454 OPENSSL_free(str->data);
455 str->data = data;
456 str->length = len;
457 }
458
ASN1_STRING_new(void)459 ASN1_STRING *ASN1_STRING_new(void)
460 {
461 return(ASN1_STRING_type_new(V_ASN1_OCTET_STRING));
462 }
463
464
ASN1_STRING_type_new(int type)465 ASN1_STRING *ASN1_STRING_type_new(int type)
466 {
467 ASN1_STRING *ret;
468
469 ret=(ASN1_STRING *)OPENSSL_malloc(sizeof(ASN1_STRING));
470 if (ret == NULL)
471 {
472 OPENSSL_PUT_ERROR(ASN1, ASN1_STRING_type_new, ERR_R_MALLOC_FAILURE);
473 return(NULL);
474 }
475 ret->length=0;
476 ret->type=type;
477 ret->data=NULL;
478 ret->flags=0;
479 return(ret);
480 }
481
ASN1_STRING_free(ASN1_STRING * a)482 void ASN1_STRING_free(ASN1_STRING *a)
483 {
484 if (a == NULL) return;
485 if (a->data && !(a->flags & ASN1_STRING_FLAG_NDEF))
486 OPENSSL_free(a->data);
487 OPENSSL_free(a);
488 }
489
ASN1_STRING_cmp(const ASN1_STRING * a,const ASN1_STRING * b)490 int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b)
491 {
492 int i;
493
494 i=(a->length-b->length);
495 if (i == 0)
496 {
497 i=memcmp(a->data,b->data,a->length);
498 if (i == 0)
499 return(a->type-b->type);
500 else
501 return(i);
502 }
503 else
504 return(i);
505 }
506
ASN1_STRING_length(const ASN1_STRING * x)507 int ASN1_STRING_length(const ASN1_STRING *x)
508 { return M_ASN1_STRING_length(x); }
509
ASN1_STRING_length_set(ASN1_STRING * x,int len)510 void ASN1_STRING_length_set(ASN1_STRING *x, int len)
511 { M_ASN1_STRING_length_set(x, len); return; }
512
ASN1_STRING_type(ASN1_STRING * x)513 int ASN1_STRING_type(ASN1_STRING *x)
514 { return M_ASN1_STRING_type(x); }
515
ASN1_STRING_data(ASN1_STRING * x)516 unsigned char * ASN1_STRING_data(ASN1_STRING *x)
517 { return M_ASN1_STRING_data(x); }
518