PolarSSL v1.3.4
asn1parse.c
Go to the documentation of this file.
1 /*
2  * Generic ASN.1 parsing
3  *
4  * Copyright (C) 2006-2013, Brainspark B.V.
5  *
6  * This file is part of PolarSSL (http://www.polarssl.org)
7  * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
8  *
9  * All rights reserved.
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License along
22  * with this program; if not, write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24  */
25 
26 #include "polarssl/config.h"
27 
28 #if defined(POLARSSL_ASN1_PARSE_C)
29 
30 #include "polarssl/asn1.h"
31 
32 #if defined(POLARSSL_BIGNUM_C)
33 #include "polarssl/bignum.h"
34 #endif
35 
36 #if defined(POLARSSL_MEMORY_C)
37 #include "polarssl/memory.h"
38 #else
39 #define polarssl_malloc malloc
40 #define polarssl_free free
41 #endif
42 
43 #include <string.h>
44 #include <stdlib.h>
45 
46 /*
47  * ASN.1 DER decoding routines
48  */
49 int asn1_get_len( unsigned char **p,
50  const unsigned char *end,
51  size_t *len )
52 {
53  if( ( end - *p ) < 1 )
55 
56  if( ( **p & 0x80 ) == 0 )
57  *len = *(*p)++;
58  else
59  {
60  switch( **p & 0x7F )
61  {
62  case 1:
63  if( ( end - *p ) < 2 )
65 
66  *len = (*p)[1];
67  (*p) += 2;
68  break;
69 
70  case 2:
71  if( ( end - *p ) < 3 )
73 
74  *len = ( (*p)[1] << 8 ) | (*p)[2];
75  (*p) += 3;
76  break;
77 
78  case 3:
79  if( ( end - *p ) < 4 )
81 
82  *len = ( (*p)[1] << 16 ) | ( (*p)[2] << 8 ) | (*p)[3];
83  (*p) += 4;
84  break;
85 
86  case 4:
87  if( ( end - *p ) < 5 )
89 
90  *len = ( (*p)[1] << 24 ) | ( (*p)[2] << 16 ) | ( (*p)[3] << 8 ) | (*p)[4];
91  (*p) += 5;
92  break;
93 
94  default:
96  }
97  }
98 
99  if( *len > (size_t) ( end - *p ) )
101 
102  return( 0 );
103 }
104 
105 int asn1_get_tag( unsigned char **p,
106  const unsigned char *end,
107  size_t *len, int tag )
108 {
109  if( ( end - *p ) < 1 )
111 
112  if( **p != tag )
114 
115  (*p)++;
116 
117  return( asn1_get_len( p, end, len ) );
118 }
119 
120 int asn1_get_bool( unsigned char **p,
121  const unsigned char *end,
122  int *val )
123 {
124  int ret;
125  size_t len;
126 
127  if( ( ret = asn1_get_tag( p, end, &len, ASN1_BOOLEAN ) ) != 0 )
128  return( ret );
129 
130  if( len != 1 )
132 
133  *val = ( **p != 0 ) ? 1 : 0;
134  (*p)++;
135 
136  return( 0 );
137 }
138 
139 int asn1_get_int( unsigned char **p,
140  const unsigned char *end,
141  int *val )
142 {
143  int ret;
144  size_t len;
145 
146  if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 )
147  return( ret );
148 
149  if( len > sizeof( int ) || ( **p & 0x80 ) != 0 )
151 
152  *val = 0;
153 
154  while( len-- > 0 )
155  {
156  *val = ( *val << 8 ) | **p;
157  (*p)++;
158  }
159 
160  return( 0 );
161 }
162 
163 #if defined(POLARSSL_BIGNUM_C)
164 int asn1_get_mpi( unsigned char **p,
165  const unsigned char *end,
166  mpi *X )
167 {
168  int ret;
169  size_t len;
170 
171  if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 )
172  return( ret );
173 
174  ret = mpi_read_binary( X, *p, len );
175 
176  *p += len;
177 
178  return( ret );
179 }
180 #endif /* POLARSSL_BIGNUM_C */
181 
182 int asn1_get_bitstring( unsigned char **p, const unsigned char *end,
183  asn1_bitstring *bs)
184 {
185  int ret;
186 
187  /* Certificate type is a single byte bitstring */
188  if( ( ret = asn1_get_tag( p, end, &bs->len, ASN1_BIT_STRING ) ) != 0 )
189  return( ret );
190 
191  /* Check length, subtract one for actual bit string length */
192  if ( bs->len < 1 )
194  bs->len -= 1;
195 
196  /* Get number of unused bits, ensure unused bits <= 7 */
197  bs->unused_bits = **p;
198  if( bs->unused_bits > 7 )
200  (*p)++;
201 
202  /* Get actual bitstring */
203  bs->p = *p;
204  *p += bs->len;
205 
206  if( *p != end )
208 
209  return 0;
210 }
211 
212 /*
213  * Get a bit string without unused bits
214  */
215 int asn1_get_bitstring_null( unsigned char **p, const unsigned char *end,
216  size_t *len )
217 {
218  int ret;
219 
220  if( ( ret = asn1_get_tag( p, end, len, ASN1_BIT_STRING ) ) != 0 )
221  return( ret );
222 
223  if( (*len)-- < 2 || *(*p)++ != 0 )
225 
226  return( 0 );
227 }
228 
229 
230 
231 /*
232  * Parses and splits an ASN.1 "SEQUENCE OF <tag>"
233  */
234 int asn1_get_sequence_of( unsigned char **p,
235  const unsigned char *end,
236  asn1_sequence *cur,
237  int tag)
238 {
239  int ret;
240  size_t len;
241  asn1_buf *buf;
242 
243  /* Get main sequence tag */
244  if( ( ret = asn1_get_tag( p, end, &len,
245  ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
246  return( ret );
247 
248  if( *p + len != end )
250 
251  while( *p < end )
252  {
253  buf = &(cur->buf);
254  buf->tag = **p;
255 
256  if( ( ret = asn1_get_tag( p, end, &buf->len, tag ) ) != 0 )
257  return( ret );
258 
259  buf->p = *p;
260  *p += buf->len;
261 
262  /* Allocate and assign next pointer */
263  if (*p < end)
264  {
266  sizeof( asn1_sequence ) );
267 
268  if( cur->next == NULL )
270 
271  cur = cur->next;
272  }
273  }
274 
275  /* Set final sequence entry's next pointer to NULL */
276  cur->next = NULL;
277 
278  if( *p != end )
280 
281  return( 0 );
282 }
283 
284 int asn1_get_alg( unsigned char **p,
285  const unsigned char *end,
286  asn1_buf *alg, asn1_buf *params )
287 {
288  int ret;
289  size_t len;
290 
291  if( ( ret = asn1_get_tag( p, end, &len,
292  ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
293  return( ret );
294 
295  if( ( end - *p ) < 1 )
297 
298  alg->tag = **p;
299  end = *p + len;
300 
301  if( ( ret = asn1_get_tag( p, end, &alg->len, ASN1_OID ) ) != 0 )
302  return( ret );
303 
304  alg->p = *p;
305  *p += alg->len;
306 
307  if( *p == end )
308  {
309  memset( params, 0, sizeof(asn1_buf) );
310  return( 0 );
311  }
312 
313  params->tag = **p;
314  (*p)++;
315 
316  if( ( ret = asn1_get_len( p, end, &params->len ) ) != 0 )
317  return( ret );
318 
319  params->p = *p;
320  *p += params->len;
321 
322  if( *p != end )
324 
325  return( 0 );
326 }
327 
328 int asn1_get_alg_null( unsigned char **p,
329  const unsigned char *end,
330  asn1_buf *alg )
331 {
332  int ret;
333  asn1_buf params;
334 
335  memset( &params, 0, sizeof(asn1_buf) );
336 
337  if( ( ret = asn1_get_alg( p, end, alg, &params ) ) != 0 )
338  return( ret );
339 
340  if( ( params.tag != ASN1_NULL && params.tag != 0 ) || params.len != 0 )
342 
343  return( 0 );
344 }
345 
347 {
348  if( cur == NULL )
349  return;
350 
351  polarssl_free( cur->oid.p );
352  polarssl_free( cur->val.p );
353 
354  memset( cur, 0, sizeof( asn1_named_data ) );
355 }
356 
358 {
359  asn1_named_data *cur;
360 
361  while( ( cur = *head ) != NULL )
362  {
363  *head = cur->next;
364  asn1_free_named_data( cur );
365  polarssl_free( cur );
366  }
367 }
368 
370  const char *oid, size_t len )
371 {
372  while( list != NULL )
373  {
374  if( list->oid.len == len &&
375  memcmp( list->oid.p, oid, len ) == 0 )
376  {
377  break;
378  }
379 
380  list = list->next;
381  }
382 
383  return( list );
384 }
385 
386 #endif
#define ASN1_NULL
Definition: asn1.h:75
int asn1_get_sequence_of(unsigned char **p, const unsigned char *end, asn1_sequence *cur, int tag)
Parses and splits an ASN.1 &quot;SEQUENCE OF &lt;tag&gt;&quot; Updated the pointer to immediately behind the full seq...
Memory allocation layer.
#define ASN1_OID
Definition: asn1.h:76
void *(* polarssl_malloc)(size_t len)
asn1_buf buf
Buffer containing the given ASN.1 item.
Definition: asn1.h:140
#define POLARSSL_ERR_ASN1_LENGTH_MISMATCH
Actual length differs from expected length.
Definition: asn1.h:53
int asn1_get_int(unsigned char **p, const unsigned char *end, int *val)
Retrieve an integer ASN.1 tag and its value.
size_t len
ASN1 length, e.g.
Definition: asn1.h:129
#define ASN1_SEQUENCE
Definition: asn1.h:78
Configuration options (set of defines)
#define POLARSSL_ERR_ASN1_INVALID_DATA
Data is invalid.
Definition: asn1.h:54
#define ASN1_CONSTRUCTED
Definition: asn1.h:88
unsigned char unused_bits
Number of unused bits at the end of the string.
Definition: asn1.h:130
MPI structure.
Definition: bignum.h:177
#define POLARSSL_ERR_ASN1_INVALID_LENGTH
Error when trying to determine the length or invalid length.
Definition: asn1.h:52
Container for ASN1 bit strings.
Definition: asn1.h:127
Multi-precision integer library.
asn1_buf val
The named value.
Definition: asn1.h:151
Container for a sequence of ASN.1 items.
Definition: asn1.h:138
unsigned char * p
Raw ASN1 data for the bit string.
Definition: asn1.h:131
Generic ASN.1 parsing.
asn1_buf oid
The object identifier.
Definition: asn1.h:150
int asn1_get_alg_null(unsigned char **p, const unsigned char *end, asn1_buf *alg)
Retrieve an AlgorithmIdentifier ASN.1 sequence with NULL or no params.
int asn1_get_alg(unsigned char **p, const unsigned char *end, asn1_buf *alg, asn1_buf *params)
Retrieve an AlgorithmIdentifier ASN.1 sequence.
#define ASN1_INTEGER
Definition: asn1.h:72
void(* polarssl_free)(void *ptr)
unsigned char * p
ASN1 data, e.g.
Definition: asn1.h:120
int asn1_get_bool(unsigned char **p, const unsigned char *end, int *val)
Retrieve a boolean ASN.1 tag and its value.
int tag
ASN1 type, e.g.
Definition: asn1.h:118
#define POLARSSL_ERR_ASN1_OUT_OF_DATA
Out of data when parsing an ASN1 data structure.
Definition: asn1.h:50
void asn1_free_named_data(asn1_named_data *entry)
Free a asn1_named_data entry.
#define ASN1_BIT_STRING
Definition: asn1.h:73
#define POLARSSL_ERR_ASN1_MALLOC_FAILED
Memory allocation failed.
Definition: asn1.h:55
int mpi_read_binary(mpi *X, const unsigned char *buf, size_t buflen)
Import X from unsigned binary data, big endian.
Container for a sequence or list of &#39;named&#39; ASN.1 data items.
Definition: asn1.h:148
Type-length-value structure that allows for ASN1 using DER.
Definition: asn1.h:116
int asn1_get_bitstring_null(unsigned char **p, const unsigned char *end, size_t *len)
Retrieve a bitstring ASN.1 tag without unused bits and its value.
size_t len
ASN1 length, e.g.
Definition: asn1.h:119
void asn1_free_named_data_list(asn1_named_data **head)
Free all entries in a asn1_named_data list Head will be set to NULL.
#define ASN1_BOOLEAN
Definition: asn1.h:71
int asn1_get_len(unsigned char **p, const unsigned char *end, size_t *len)
Get the length of an ASN.1 element.
int asn1_get_tag(unsigned char **p, const unsigned char *end, size_t *len, int tag)
Get the tag and length of the tag.
asn1_named_data * asn1_find_named_data(asn1_named_data *list, const char *oid, size_t len)
Find a specific named_data entry in a sequence or list based on the OID.
int asn1_get_bitstring(unsigned char **p, const unsigned char *end, asn1_bitstring *bs)
Retrieve a bitstring ASN.1 tag and its value.
struct _asn1_named_data * next
The next entry in the sequence.
Definition: asn1.h:152
int asn1_get_mpi(unsigned char **p, const unsigned char *end, mpi *X)
Retrieve a MPI value from an integer ASN.1 tag.
#define POLARSSL_ERR_ASN1_UNEXPECTED_TAG
ASN1 tag was of an unexpected value.
Definition: asn1.h:51
struct _asn1_sequence * next
The next entry in the sequence.
Definition: asn1.h:141