PolarSSL v1.1.4
|
00001 /* 00002 * Generic ASN.1 parsing 00003 * 00004 * Copyright (C) 2006-2011, Brainspark B.V. 00005 * 00006 * This file is part of PolarSSL (http://www.polarssl.org) 00007 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org> 00008 * 00009 * All rights reserved. 00010 * 00011 * This program is free software; you can redistribute it and/or modify 00012 * it under the terms of the GNU General Public License as published by 00013 * the Free Software Foundation; either version 2 of the License, or 00014 * (at your option) any later version. 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU General Public License along 00022 * with this program; if not, write to the Free Software Foundation, Inc., 00023 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00024 */ 00025 00026 #include "polarssl/config.h" 00027 00028 #if defined(POLARSSL_ASN1_PARSE_C) 00029 00030 #include "polarssl/asn1.h" 00031 00032 #if defined(POLARSSL_BIGNUM_C) 00033 #include "polarssl/bignum.h" 00034 #endif 00035 00036 #include <string.h> 00037 #include <stdlib.h> 00038 #include <time.h> 00039 00040 /* 00041 * ASN.1 DER decoding routines 00042 */ 00043 int asn1_get_len( unsigned char **p, 00044 const unsigned char *end, 00045 size_t *len ) 00046 { 00047 if( ( end - *p ) < 1 ) 00048 return( POLARSSL_ERR_ASN1_OUT_OF_DATA ); 00049 00050 if( ( **p & 0x80 ) == 0 ) 00051 *len = *(*p)++; 00052 else 00053 { 00054 switch( **p & 0x7F ) 00055 { 00056 case 1: 00057 if( ( end - *p ) < 2 ) 00058 return( POLARSSL_ERR_ASN1_OUT_OF_DATA ); 00059 00060 *len = (*p)[1]; 00061 (*p) += 2; 00062 break; 00063 00064 case 2: 00065 if( ( end - *p ) < 3 ) 00066 return( POLARSSL_ERR_ASN1_OUT_OF_DATA ); 00067 00068 *len = ( (*p)[1] << 8 ) | (*p)[2]; 00069 (*p) += 3; 00070 break; 00071 00072 case 3: 00073 if( ( end - *p ) < 4 ) 00074 return( POLARSSL_ERR_ASN1_OUT_OF_DATA ); 00075 00076 *len = ( (*p)[1] << 16 ) | ( (*p)[2] << 8 ) | (*p)[3]; 00077 (*p) += 4; 00078 break; 00079 00080 case 4: 00081 if( ( end - *p ) < 5 ) 00082 return( POLARSSL_ERR_ASN1_OUT_OF_DATA ); 00083 00084 *len = ( (*p)[1] << 24 ) | ( (*p)[2] << 16 ) | ( (*p)[3] << 8 ) | (*p)[4]; 00085 (*p) += 5; 00086 break; 00087 00088 default: 00089 return( POLARSSL_ERR_ASN1_INVALID_LENGTH ); 00090 } 00091 } 00092 00093 if( *len > (size_t) ( end - *p ) ) 00094 return( POLARSSL_ERR_ASN1_OUT_OF_DATA ); 00095 00096 return( 0 ); 00097 } 00098 00099 int asn1_get_tag( unsigned char **p, 00100 const unsigned char *end, 00101 size_t *len, int tag ) 00102 { 00103 if( ( end - *p ) < 1 ) 00104 return( POLARSSL_ERR_ASN1_OUT_OF_DATA ); 00105 00106 if( **p != tag ) 00107 return( POLARSSL_ERR_ASN1_UNEXPECTED_TAG ); 00108 00109 (*p)++; 00110 00111 return( asn1_get_len( p, end, len ) ); 00112 } 00113 00114 int asn1_get_bool( unsigned char **p, 00115 const unsigned char *end, 00116 int *val ) 00117 { 00118 int ret; 00119 size_t len; 00120 00121 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BOOLEAN ) ) != 0 ) 00122 return( ret ); 00123 00124 if( len != 1 ) 00125 return( POLARSSL_ERR_ASN1_INVALID_LENGTH ); 00126 00127 *val = ( **p != 0 ) ? 1 : 0; 00128 (*p)++; 00129 00130 return( 0 ); 00131 } 00132 00133 int asn1_get_int( unsigned char **p, 00134 const unsigned char *end, 00135 int *val ) 00136 { 00137 int ret; 00138 size_t len; 00139 00140 if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 ) 00141 return( ret ); 00142 00143 if( len > sizeof( int ) || ( **p & 0x80 ) != 0 ) 00144 return( POLARSSL_ERR_ASN1_INVALID_LENGTH ); 00145 00146 *val = 0; 00147 00148 while( len-- > 0 ) 00149 { 00150 *val = ( *val << 8 ) | **p; 00151 (*p)++; 00152 } 00153 00154 return( 0 ); 00155 } 00156 00157 #if defined(POLARSSL_BIGNUM_C) 00158 int asn1_get_mpi( unsigned char **p, 00159 const unsigned char *end, 00160 mpi *X ) 00161 { 00162 int ret; 00163 size_t len; 00164 00165 if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 ) 00166 return( ret ); 00167 00168 ret = mpi_read_binary( X, *p, len ); 00169 00170 *p += len; 00171 00172 return( ret ); 00173 } 00174 #endif /* POLARSSL_BIGNUM_C */ 00175 00176 int asn1_get_bitstring( unsigned char **p, const unsigned char *end, 00177 asn1_bitstring *bs) 00178 { 00179 int ret; 00180 00181 /* Certificate type is a single byte bitstring */ 00182 if( ( ret = asn1_get_tag( p, end, &bs->len, ASN1_BIT_STRING ) ) != 0 ) 00183 return( ret ); 00184 00185 /* Check length, subtract one for actual bit string length */ 00186 if ( bs->len < 1 ) 00187 return( POLARSSL_ERR_ASN1_OUT_OF_DATA ); 00188 bs->len -= 1; 00189 00190 /* Get number of unused bits, ensure unused bits <= 7 */ 00191 bs->unused_bits = **p; 00192 if( bs->unused_bits > 7 ) 00193 return( POLARSSL_ERR_ASN1_INVALID_LENGTH ); 00194 (*p)++; 00195 00196 /* Get actual bitstring */ 00197 bs->p = *p; 00198 *p += bs->len; 00199 00200 if( *p != end ) 00201 return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); 00202 00203 return 0; 00204 } 00205 00206 00207 /* 00208 * Parses and splits an ASN.1 "SEQUENCE OF <tag>" 00209 */ 00210 int asn1_get_sequence_of( unsigned char **p, 00211 const unsigned char *end, 00212 asn1_sequence *cur, 00213 int tag) 00214 { 00215 int ret; 00216 size_t len; 00217 asn1_buf *buf; 00218 00219 /* Get main sequence tag */ 00220 if( ( ret = asn1_get_tag( p, end, &len, 00221 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) 00222 return( ret ); 00223 00224 if( *p + len != end ) 00225 return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); 00226 00227 while( *p < end ) 00228 { 00229 buf = &(cur->buf); 00230 buf->tag = **p; 00231 00232 if( ( ret = asn1_get_tag( p, end, &buf->len, tag ) ) != 0 ) 00233 return( ret ); 00234 00235 buf->p = *p; 00236 *p += buf->len; 00237 00238 /* Allocate and assign next pointer */ 00239 if (*p < end) 00240 { 00241 cur->next = (asn1_sequence *) malloc( 00242 sizeof( asn1_sequence ) ); 00243 00244 if( cur->next == NULL ) 00245 return( POLARSSL_ERR_ASN1_MALLOC_FAILED ); 00246 00247 cur = cur->next; 00248 } 00249 } 00250 00251 /* Set final sequence entry's next pointer to NULL */ 00252 cur->next = NULL; 00253 00254 if( *p != end ) 00255 return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); 00256 00257 return( 0 ); 00258 } 00259 00260 #endif