155714Skris/* crypto/asn1/asn1_lib.c */ 255714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 355714Skris * All rights reserved. 455714Skris * 555714Skris * This package is an SSL implementation written 655714Skris * by Eric Young (eay@cryptsoft.com). 755714Skris * The implementation was written so as to conform with Netscapes SSL. 855714Skris * 955714Skris * This library is free for commercial and non-commercial use as long as 1055714Skris * the following conditions are aheared to. The following conditions 1155714Skris * apply to all code found in this distribution, be it the RC4, RSA, 1255714Skris * lhash, DES, etc., code; not just the SSL code. The SSL documentation 1355714Skris * included with this distribution is covered by the same copyright terms 1455714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com). 1555714Skris * 1655714Skris * Copyright remains Eric Young's, and as such any Copyright notices in 1755714Skris * the code are not to be removed. 1855714Skris * If this package is used in a product, Eric Young should be given attribution 1955714Skris * as the author of the parts of the library used. 2055714Skris * This can be in the form of a textual message at program startup or 2155714Skris * in documentation (online or textual) provided with the package. 2255714Skris * 2355714Skris * Redistribution and use in source and binary forms, with or without 2455714Skris * modification, are permitted provided that the following conditions 2555714Skris * are met: 2655714Skris * 1. Redistributions of source code must retain the copyright 2755714Skris * notice, this list of conditions and the following disclaimer. 2855714Skris * 2. Redistributions in binary form must reproduce the above copyright 2955714Skris * notice, this list of conditions and the following disclaimer in the 3055714Skris * documentation and/or other materials provided with the distribution. 3155714Skris * 3. All advertising materials mentioning features or use of this software 3255714Skris * must display the following acknowledgement: 3355714Skris * "This product includes cryptographic software written by 3455714Skris * Eric Young (eay@cryptsoft.com)" 3555714Skris * The word 'cryptographic' can be left out if the rouines from the library 3655714Skris * being used are not cryptographic related :-). 3755714Skris * 4. If you include any Windows specific code (or a derivative thereof) from 3855714Skris * the apps directory (application code) you must include an acknowledgement: 3955714Skris * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 4055714Skris * 4155714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 4255714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4355714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4455714Skris * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4555714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 4655714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4755714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 4955714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 5055714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5155714Skris * SUCH DAMAGE. 5255714Skris * 5355714Skris * The licence and distribution terms for any publically available version or 5455714Skris * derivative of this code cannot be changed. i.e. this code cannot simply be 5555714Skris * copied and put under another distribution licence 5655714Skris * [including the GNU Public Licence.] 5755714Skris */ 5855714Skris 5955714Skris#include <stdio.h> 6055714Skris#include <limits.h> 6155714Skris#include "cryptlib.h" 6255714Skris#include <openssl/asn1.h> 6355714Skris#include <openssl/asn1_mac.h> 6455714Skris 6555714Skrisstatic int asn1_get_length(const unsigned char **pp, int *inf, long *rl, 6655714Skris int max); 6755714Skrisstatic void asn1_put_length(unsigned char **pp, int length); 6855714Skrisconst char ASN1_version[] = "ASN.1" OPENSSL_VERSION_PTEXT; 6955714Skris 7055714Skrisstatic int _asn1_check_infinite_end(const unsigned char **p, long len) 7155714Skris{ 7255714Skris /* 7355714Skris * If there is 0 or 1 byte left, the length check should pick things up 7455714Skris */ 7555714Skris if (len <= 0) 7655714Skris return (1); 7755714Skris else if ((len >= 2) && ((*p)[0] == 0) && ((*p)[1] == 0)) { 7855714Skris (*p) += 2; 7955714Skris return (1); 8055714Skris } 8155714Skris return (0); 8255714Skris} 8355714Skris 8455714Skrisint ASN1_check_infinite_end(unsigned char **p, long len) 8555714Skris{ 8655714Skris return _asn1_check_infinite_end((const unsigned char **)p, len); 8755714Skris} 8855714Skris 8955714Skrisint ASN1_const_check_infinite_end(const unsigned char **p, long len) 9055714Skris{ 9155714Skris return _asn1_check_infinite_end(p, len); 9255714Skris} 9355714Skris 9455714Skrisint ASN1_get_object(const unsigned char **pp, long *plength, int *ptag, 9555714Skris int *pclass, long omax) 9655714Skris{ 9755714Skris int i, ret; 9855714Skris long l; 9955714Skris const unsigned char *p = *pp; 10055714Skris int tag, xclass, inf; 10155714Skris long max = omax; 10255714Skris 10355714Skris if (!max) 10455714Skris goto err; 10555714Skris ret = (*p & V_ASN1_CONSTRUCTED); 10655714Skris xclass = (*p & V_ASN1_PRIVATE); 10755714Skris i = *p & V_ASN1_PRIMITIVE_TAG; 10855714Skris if (i == V_ASN1_PRIMITIVE_TAG) { /* high-tag */ 10955714Skris p++; 11055714Skris if (--max == 0) 11155714Skris goto err; 11255714Skris l = 0; 11355714Skris while (*p & 0x80) { 11455714Skris l <<= 7L; 11555714Skris l |= *(p++) & 0x7f; 11655714Skris if (--max == 0) 11755714Skris goto err; 11855714Skris if (l > (INT_MAX >> 7L)) 11955714Skris goto err; 12055714Skris } 12155714Skris l <<= 7L; 12255714Skris l |= *(p++) & 0x7f; 12355714Skris tag = (int)l; 12455714Skris if (--max == 0) 12555714Skris goto err; 12655714Skris } else { 12755714Skris tag = i; 12855714Skris p++; 12955714Skris if (--max == 0) 13055714Skris goto err; 13155714Skris } 13255714Skris *ptag = tag; 13355714Skris *pclass = xclass; 13455714Skris if (!asn1_get_length(&p, &inf, plength, (int)max)) 13555714Skris goto err; 13655714Skris 13755714Skris if (inf && !(ret & V_ASN1_CONSTRUCTED)) 13855714Skris goto err; 13955714Skris 14055714Skris#if 0 14155714Skris fprintf(stderr, "p=%d + *plength=%ld > omax=%ld + *pp=%d (%d > %d)\n", 14255714Skris (int)p, *plength, omax, (int)*pp, (int)(p + *plength), 14355714Skris (int)(omax + *pp)); 14455714Skris 14555714Skris#endif 14655714Skris if (*plength > (omax - (p - *pp))) { 14755714Skris ASN1err(ASN1_F_ASN1_GET_OBJECT, ASN1_R_TOO_LONG); 14855714Skris /* 14955714Skris * Set this so that even if things are not long enough the values are 15055714Skris * set correctly 15155714Skris */ 15255714Skris ret |= 0x80; 15355714Skris } 15455714Skris *pp = p; 15555714Skris return (ret | inf); 15655714Skris err: 15755714Skris ASN1err(ASN1_F_ASN1_GET_OBJECT, ASN1_R_HEADER_TOO_LONG); 15855714Skris return (0x80); 15955714Skris} 16055714Skris 16155714Skrisstatic int asn1_get_length(const unsigned char **pp, int *inf, long *rl, 16255714Skris int max) 16355714Skris{ 16455714Skris const unsigned char *p = *pp; 16555714Skris unsigned long ret = 0; 16655714Skris unsigned int i; 16755714Skris 16855714Skris if (max-- < 1) 16955714Skris return (0); 17055714Skris if (*p == 0x80) { 17155714Skris *inf = 1; 17255714Skris ret = 0; 17355714Skris p++; 17455714Skris } else { 17555714Skris *inf = 0; 17655714Skris i = *p & 0x7f; 17755714Skris if (*(p++) & 0x80) { 17855714Skris if (i > sizeof(long)) 17955714Skris return 0; 18055714Skris if (max-- == 0) 18155714Skris return (0); 18255714Skris while (i-- > 0) { 18355714Skris ret <<= 8L; 18455714Skris ret |= *(p++); 18555714Skris if (max-- == 0) 18655714Skris return (0); 18755714Skris } 18855714Skris } else 18955714Skris ret = i; 19055714Skris } 19155714Skris if (ret > LONG_MAX) 19255714Skris return 0; 19355714Skris *pp = p; 19455714Skris *rl = (long)ret; 19555714Skris return (1); 19655714Skris} 19755714Skris 19855714Skris/* 19955714Skris * class 0 is constructed constructed == 2 for indefinite length constructed 20055714Skris */ 20155714Skrisvoid ASN1_put_object(unsigned char **pp, int constructed, int length, int tag, 20255714Skris int xclass) 20355714Skris{ 20455714Skris unsigned char *p = *pp; 20555714Skris int i, ttag; 20655714Skris 20755714Skris i = (constructed) ? V_ASN1_CONSTRUCTED : 0; 20855714Skris i |= (xclass & V_ASN1_PRIVATE); 20955714Skris if (tag < 31) 21055714Skris *(p++) = i | (tag & V_ASN1_PRIMITIVE_TAG); 21155714Skris else { 21255714Skris *(p++) = i | V_ASN1_PRIMITIVE_TAG; 21355714Skris for (i = 0, ttag = tag; ttag > 0; i++) 21455714Skris ttag >>= 7; 21555714Skris ttag = i; 21655714Skris while (i-- > 0) { 21755714Skris p[i] = tag & 0x7f; 21855714Skris if (i != (ttag - 1)) 21955714Skris p[i] |= 0x80; 22055714Skris tag >>= 7; 22155714Skris } 22255714Skris p += ttag; 22355714Skris } 22455714Skris if (constructed == 2) 22555714Skris *(p++) = 0x80; 22655714Skris else 22755714Skris asn1_put_length(&p, length); 22855714Skris *pp = p; 22955714Skris} 23055714Skris 23155714Skrisint ASN1_put_eoc(unsigned char **pp) 23255714Skris{ 23355714Skris unsigned char *p = *pp; 23455714Skris *p++ = 0; 23555714Skris *p++ = 0; 23655714Skris *pp = p; 23755714Skris return 2; 23855714Skris} 23955714Skris 24055714Skrisstatic void asn1_put_length(unsigned char **pp, int length) 24155714Skris{ 24255714Skris unsigned char *p = *pp; 24355714Skris int i, l; 24455714Skris if (length <= 127) 24555714Skris *(p++) = (unsigned char)length; 24655714Skris else { 24755714Skris l = length; 24855714Skris for (i = 0; l > 0; i++) 24955714Skris l >>= 8; 25055714Skris *(p++) = i | 0x80; 25155714Skris l = i; 25255714Skris while (i-- > 0) { 25355714Skris p[i] = length & 0xff; 25455714Skris length >>= 8; 25555714Skris } 25655714Skris p += l; 25755714Skris } 25855714Skris *pp = p; 25955714Skris} 26055714Skris 26155714Skrisint ASN1_object_size(int constructed, int length, int tag) 26255714Skris{ 26355714Skris int ret; 26455714Skris 26555714Skris ret = length; 26655714Skris ret++; 26755714Skris if (tag >= 31) { 26855714Skris while (tag > 0) { 26955714Skris tag >>= 7; 27055714Skris ret++; 27155714Skris } 27255714Skris } 27355714Skris if (constructed == 2) 27455714Skris return ret + 3; 27555714Skris ret++; 27655714Skris if (length > 127) { 27755714Skris while (length > 0) { 27855714Skris length >>= 8; 27955714Skris ret++; 28055714Skris } 28155714Skris } 28255714Skris return (ret); 28355714Skris} 28455714Skris 28555714Skrisstatic int _asn1_Finish(ASN1_const_CTX *c) 28655714Skris{ 28755714Skris if ((c->inf == (1 | V_ASN1_CONSTRUCTED)) && (!c->eos)) { 28855714Skris if (!ASN1_const_check_infinite_end(&c->p, c->slen)) { 28955714Skris c->error = ERR_R_MISSING_ASN1_EOS; 29055714Skris return (0); 29155714Skris } 29255714Skris } 29355714Skris if (((c->slen != 0) && !(c->inf & 1)) || ((c->slen < 0) && (c->inf & 1))) { 29455714Skris c->error = ERR_R_ASN1_LENGTH_MISMATCH; 29555714Skris return (0); 29655714Skris } 29755714Skris return (1); 29855714Skris} 29955714Skris 30055714Skrisint asn1_Finish(ASN1_CTX *c) 30155714Skris{ 30255714Skris return _asn1_Finish((ASN1_const_CTX *)c); 30355714Skris} 30455714Skris 30555714Skrisint asn1_const_Finish(ASN1_const_CTX *c) 30655714Skris{ 30755714Skris return _asn1_Finish(c); 30855714Skris} 30955714Skris 31055714Skrisint asn1_GetSequence(ASN1_const_CTX *c, long *length) 31155714Skris{ 31255714Skris const unsigned char *q; 31355714Skris 31455714Skris q = c->p; 31555714Skris c->inf = ASN1_get_object(&(c->p), &(c->slen), &(c->tag), &(c->xclass), 31655714Skris *length); 31755714Skris if (c->inf & 0x80) { 31855714Skris c->error = ERR_R_BAD_GET_ASN1_OBJECT_CALL; 31955714Skris return (0); 32055714Skris } 32155714Skris if (c->tag != V_ASN1_SEQUENCE) { 32255714Skris c->error = ERR_R_EXPECTING_AN_ASN1_SEQUENCE; 32355714Skris return (0); 32455714Skris } 32555714Skris (*length) -= (c->p - q); 32655714Skris if (c->max && (*length < 0)) { 32759191Skris c->error = ERR_R_ASN1_LENGTH_MISMATCH; 32859191Skris return (0); 32959191Skris } 33059191Skris if (c->inf == (1 | V_ASN1_CONSTRUCTED)) 33159191Skris c->slen = *length + *(c->pp) - c->p; 33259191Skris c->eos = 0; 33359191Skris return (1); 33459191Skris} 33559191Skris 33659191Skrisint ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str) 33759191Skris{ 33859191Skris if (str == NULL) 33959191Skris return 0; 34059191Skris dst->type = str->type; 34159191Skris if (!ASN1_STRING_set(dst, str->data, str->length)) 34259191Skris return 0; 34359191Skris dst->flags = str->flags; 34459191Skris return 1; 34559191Skris} 34659191Skris 34759191SkrisASN1_STRING *ASN1_STRING_dup(const ASN1_STRING *str) 34859191Skris{ 34959191Skris ASN1_STRING *ret; 35059191Skris if (!str) 35159191Skris return NULL; 35259191Skris ret = ASN1_STRING_new(); 35359191Skris if (!ret) 35459191Skris return NULL; 35559191Skris if (!ASN1_STRING_copy(ret, str)) { 35659191Skris ASN1_STRING_free(ret); 35759191Skris return NULL; 35859191Skris } 35959191Skris return ret; 36059191Skris} 36159191Skris 36259191Skrisint ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len) 36359191Skris{ 36459191Skris unsigned char *c; 36559191Skris const char *data = _data; 36659191Skris 36759191Skris if (len < 0) { 36859191Skris if (data == NULL) 36959191Skris return (0); 37059191Skris else 37159191Skris len = strlen(data); 37259191Skris } 37359191Skris if ((str->length < len) || (str->data == NULL)) { 37459191Skris c = str->data; 37559191Skris if (c == NULL) 37659191Skris str->data = OPENSSL_malloc(len + 1); 37759191Skris else 37859191Skris str->data = OPENSSL_realloc(c, len + 1); 37959191Skris 38059191Skris if (str->data == NULL) { 38159191Skris ASN1err(ASN1_F_ASN1_STRING_SET, ERR_R_MALLOC_FAILURE); 38259191Skris str->data = c; 38359191Skris return (0); 38459191Skris } 38559191Skris } 38659191Skris str->length = len; 38759191Skris if (data != NULL) { 38859191Skris memcpy(str->data, data, len); 38959191Skris /* an allowance for strings :-) */ 39059191Skris str->data[len] = '\0'; 39159191Skris } 39259191Skris return (1); 39359191Skris} 39459191Skris 39559191Skrisvoid ASN1_STRING_set0(ASN1_STRING *str, void *data, int len) 39659191Skris{ 39759191Skris if (str->data) 39859191Skris OPENSSL_free(str->data); 39959191Skris str->data = data; 40059191Skris str->length = len; 40159191Skris} 40259191Skris 40359191SkrisASN1_STRING *ASN1_STRING_new(void) 40459191Skris{ 40559191Skris return (ASN1_STRING_type_new(V_ASN1_OCTET_STRING)); 40659191Skris} 40759191Skris 40859191SkrisASN1_STRING *ASN1_STRING_type_new(int type) 40959191Skris{ 41059191Skris ASN1_STRING *ret; 41159191Skris 41259191Skris ret = (ASN1_STRING *)OPENSSL_malloc(sizeof(ASN1_STRING)); 41359191Skris if (ret == NULL) { 41459191Skris ASN1err(ASN1_F_ASN1_STRING_TYPE_NEW, ERR_R_MALLOC_FAILURE); 41559191Skris return (NULL); 41659191Skris } 417 ret->length = 0; 418 ret->type = type; 419 ret->data = NULL; 420 ret->flags = 0; 421 return (ret); 422} 423 424void ASN1_STRING_free(ASN1_STRING *a) 425{ 426 if (a == NULL) 427 return; 428 if (a->data && !(a->flags & ASN1_STRING_FLAG_NDEF)) 429 OPENSSL_free(a->data); 430 OPENSSL_free(a); 431} 432 433void ASN1_STRING_clear_free(ASN1_STRING *a) 434{ 435 if (a && a->data && !(a->flags & ASN1_STRING_FLAG_NDEF)) 436 OPENSSL_cleanse(a->data, a->length); 437 ASN1_STRING_free(a); 438} 439 440int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b) 441{ 442 int i; 443 444 i = (a->length - b->length); 445 if (i == 0) { 446 i = memcmp(a->data, b->data, a->length); 447 if (i == 0) 448 return (a->type - b->type); 449 else 450 return (i); 451 } else 452 return (i); 453} 454 455void asn1_add_error(const unsigned char *address, int offset) 456{ 457 char buf1[DECIMAL_SIZE(address) + 1], buf2[DECIMAL_SIZE(offset) + 1]; 458 459 BIO_snprintf(buf1, sizeof buf1, "%lu", (unsigned long)address); 460 BIO_snprintf(buf2, sizeof buf2, "%d", offset); 461 ERR_add_error_data(4, "address=", buf1, " offset=", buf2); 462} 463 464int ASN1_STRING_length(const ASN1_STRING *x) 465{ 466 return M_ASN1_STRING_length(x); 467} 468 469void ASN1_STRING_length_set(ASN1_STRING *x, int len) 470{ 471 M_ASN1_STRING_length_set(x, len); 472 return; 473} 474 475int ASN1_STRING_type(ASN1_STRING *x) 476{ 477 return M_ASN1_STRING_type(x); 478} 479 480unsigned char *ASN1_STRING_data(ASN1_STRING *x) 481{ 482 return M_ASN1_STRING_data(x); 483} 484