PolarSSL v1.3.8
asn1parse.c
Go to the documentation of this file.
1 /*
2  * Generic ASN.1 parsing
3  *
4  * Copyright (C) 2006-2014, 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 #if !defined(POLARSSL_CONFIG_FILE)
27 #include "polarssl/config.h"
28 #else
29 #include POLARSSL_CONFIG_FILE
30 #endif
31 
32 #if defined(POLARSSL_ASN1_PARSE_C)
33 
34 #include "polarssl/asn1.h"
35 
36 #if defined(POLARSSL_BIGNUM_C)
37 #include "polarssl/bignum.h"
38 #endif
39 
40 #if defined(POLARSSL_PLATFORM_C)
41 #include "polarssl/platform.h"
42 #else
43 #define polarssl_malloc malloc
44 #define polarssl_free free
45 #endif
46 
47 #include <string.h>
48 #include <stdlib.h>
49 
50 /*
51  * ASN.1 DER decoding routines
52  */
53 int asn1_get_len( unsigned char **p,
54  const unsigned char *end,
55  size_t *len )
56 {
57  if( ( end - *p ) < 1 )
59 
60  if( ( **p & 0x80 ) == 0 )
61  *len = *(*p)++;
62  else
63  {
64  switch( **p & 0x7F )
65  {
66  case 1:
67  if( ( end - *p ) < 2 )
69 
70  *len = (*p)[1];
71  (*p) += 2;
72  break;
73 
74  case 2:
75  if( ( end - *p ) < 3 )
77 
78  *len = ( (*p)[1] << 8 ) | (*p)[2];
79  (*p) += 3;
80  break;
81 
82  case 3:
83  if( ( end - *p ) < 4 )
85 
86  *len = ( (*p)[1] << 16 ) | ( (*p)[2] << 8 ) | (*p)[3];
87  (*p) += 4;
88  break;
89 
90  case 4:
91  if( ( end - *p ) < 5 )
93 
94  *len = ( (*p)[1] << 24 ) | ( (*p)[2] << 16 ) | ( (*p)[3] << 8 ) |
95  (*p)[4];
96  (*p) += 5;
97  break;
98 
99  default:
101  }
102  }
103 
104  if( *len > (size_t) ( end - *p ) )
106 
107  return( 0 );
108 }
109 
110 int asn1_get_tag( unsigned char **p,
111  const unsigned char *end,
112  size_t *len, int tag )
113 {
114  if( ( end - *p ) < 1 )
116 
117  if( **p != tag )
119 
120  (*p)++;
121 
122  return( asn1_get_len( p, end, len ) );
123 }
124 
125 int asn1_get_bool( unsigned char **p,
126  const unsigned char *end,
127  int *val )
128 {
129  int ret;
130  size_t len;
131 
132  if( ( ret = asn1_get_tag( p, end, &len, ASN1_BOOLEAN ) ) != 0 )
133  return( ret );
134 
135  if( len != 1 )
137 
138  *val = ( **p != 0 ) ? 1 : 0;
139  (*p)++;
140 
141  return( 0 );
142 }
143 
144 int asn1_get_int( unsigned char **p,
145  const unsigned char *end,
146  int *val )
147 {
148  int ret;
149  size_t len;
150 
151  if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 )
152  return( ret );
153 
154  if( len > sizeof( int ) || ( **p & 0x80 ) != 0 )
156 
157  *val = 0;
158 
159  while( len-- > 0 )
160  {
161  *val = ( *val << 8 ) | **p;
162  (*p)++;
163  }
164 
165  return( 0 );
166 }
167 
168 #if defined(POLARSSL_BIGNUM_C)
169 int asn1_get_mpi( unsigned char **p,
170  const unsigned char *end,
171  mpi *X )
172 {
173  int ret;
174  size_t len;
175 
176  if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 )
177  return( ret );
178 
179  ret = mpi_read_binary( X, *p, len );
180 
181  *p += len;
182 
183  return( ret );
184 }
185 #endif /* POLARSSL_BIGNUM_C */
186 
187 int asn1_get_bitstring( unsigned char **p, const unsigned char *end,
188  asn1_bitstring *bs)
189 {
190  int ret;
191 
192  /* Certificate type is a single byte bitstring */
193  if( ( ret = asn1_get_tag( p, end, &bs->len, ASN1_BIT_STRING ) ) != 0 )
194  return( ret );
195 
196  /* Check length, subtract one for actual bit string length */
197  if( bs->len < 1 )
199  bs->len -= 1;
200 
201  /* Get number of unused bits, ensure unused bits <= 7 */
202  bs->unused_bits = **p;
203  if( bs->unused_bits > 7 )
205  (*p)++;
206 
207  /* Get actual bitstring */
208  bs->p = *p;
209  *p += bs->len;
210 
211  if( *p != end )
213 
214  return( 0 );
215 }
216 
217 /*
218  * Get a bit string without unused bits
219  */
220 int asn1_get_bitstring_null( unsigned char **p, const unsigned char *end,
221  size_t *len )
222 {
223  int ret;
224 
225  if( ( ret = asn1_get_tag( p, end, len, ASN1_BIT_STRING ) ) != 0 )
226  return( ret );
227 
228  if( (*len)-- < 2 || *(*p)++ != 0 )
230 
231  return( 0 );
232 }
233 
234 
235 
236 /*
237  * Parses and splits an ASN.1 "SEQUENCE OF <tag>"
238  */
239 int asn1_get_sequence_of( unsigned char **p,
240  const unsigned char *end,
241  asn1_sequence *cur,
242  int tag)
243 {
244  int ret;
245  size_t len;
246  asn1_buf *buf;
247 
248  /* Get main sequence tag */
249  if( ( ret = asn1_get_tag( p, end, &len,
250  ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
251  return( ret );
252 
253  if( *p + len != end )
255 
256  while( *p < end )
257  {
258  buf = &(cur->buf);
259  buf->tag = **p;
260 
261  if( ( ret = asn1_get_tag( p, end, &buf->len, tag ) ) != 0 )
262  return( ret );
263 
264  buf->p = *p;
265  *p += buf->len;
266 
267  /* Allocate and assign next pointer */
268  if( *p < end )
269  {
271  sizeof( asn1_sequence ) );
272 
273  if( cur->next == NULL )
275 
276  cur = cur->next;
277  }
278  }
279 
280  /* Set final sequence entry's next pointer to NULL */
281  cur->next = NULL;
282 
283  if( *p != end )
285 
286  return( 0 );
287 }
288 
289 int asn1_get_alg( unsigned char **p,
290  const unsigned char *end,
291  asn1_buf *alg, asn1_buf *params )
292 {
293  int ret;
294  size_t len;
295 
296  if( ( ret = asn1_get_tag( p, end, &len,
297  ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
298  return( ret );
299 
300  if( ( end - *p ) < 1 )
302 
303  alg->tag = **p;
304  end = *p + len;
305 
306  if( ( ret = asn1_get_tag( p, end, &alg->len, ASN1_OID ) ) != 0 )
307  return( ret );
308 
309  alg->p = *p;
310  *p += alg->len;
311 
312  if( *p == end )
313  {
314  memset( params, 0, sizeof(asn1_buf) );
315  return( 0 );
316  }
317 
318  params->tag = **p;
319  (*p)++;
320 
321  if( ( ret = asn1_get_len( p, end, &params->len ) ) != 0 )
322  return( ret );
323 
324  params->p = *p;
325  *p += params->len;
326 
327  if( *p != end )
329 
330  return( 0 );
331 }
332 
333 int asn1_get_alg_null( unsigned char **p,
334  const unsigned char *end,
335  asn1_buf *alg )
336 {
337  int ret;
338  asn1_buf params;
339 
340  memset( &params, 0, sizeof(asn1_buf) );
341 
342  if( ( ret = asn1_get_alg( p, end, alg, &params ) ) != 0 )
343  return( ret );
344 
345  if( ( params.tag != ASN1_NULL && params.tag != 0 ) || params.len != 0 )
347 
348  return( 0 );
349 }
350 
352 {
353  if( cur == NULL )
354  return;
355 
356  polarssl_free( cur->oid.p );
357  polarssl_free( cur->val.p );
358 
359  memset( cur, 0, sizeof( asn1_named_data ) );
360 }
361 
363 {
364  asn1_named_data *cur;
365 
366  while( ( cur = *head ) != NULL )
367  {
368  *head = cur->next;
369  asn1_free_named_data( cur );
370  polarssl_free( cur );
371  }
372 }
373 
375  const char *oid, size_t len )
376 {
377  while( list != NULL )
378  {
379  if( list->oid.len == len &&
380  memcmp( list->oid.p, oid, len ) == 0 )
381  {
382  break;
383  }
384 
385  list = list->next;
386  }
387 
388  return( list );
389 }
390 
391 #endif /* POLARSSL_ASN1_PARSE_C */
#define ASN1_NULL
Definition: asn1.h:79
int asn1_get_sequence_of(unsigned char **p, const unsigned char *end, asn1_sequence *cur, int tag)
Parses and splits an ASN.1 "SEQUENCE OF " Updated the pointer to immediately behind the full seq...
#define ASN1_OID
Definition: asn1.h:80
asn1_buf buf
Buffer containing the given ASN.1 item.
Definition: asn1.h:148
#define POLARSSL_ERR_ASN1_LENGTH_MISMATCH
Actual length differs from expected length.
Definition: asn1.h:57
#define polarssl_malloc
#define polarssl_free
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:137
#define ASN1_SEQUENCE
Definition: asn1.h:82
Configuration options (set of defines)
#define POLARSSL_ERR_ASN1_INVALID_DATA
Data is invalid.
Definition: asn1.h:58
#define ASN1_CONSTRUCTED
Definition: asn1.h:92
unsigned char unused_bits
Number of unused bits at the end of the string.
Definition: asn1.h:138
MPI structure.
Definition: bignum.h:182
PolarSSL Platform abstraction layer.
#define POLARSSL_ERR_ASN1_INVALID_LENGTH
Error when trying to determine the length or invalid length.
Definition: asn1.h:56
Container for ASN1 bit strings.
Definition: asn1.h:135
Multi-precision integer library.
asn1_buf val
The named value.
Definition: asn1.h:159
Container for a sequence of ASN.1 items.
Definition: asn1.h:146
unsigned char * p
Raw ASN1 data for the bit string.
Definition: asn1.h:139
Generic ASN.1 parsing.
asn1_buf oid
The object identifier.
Definition: asn1.h:158
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:76
unsigned char * p
ASN1 data, e.g.
Definition: asn1.h:128
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:126
#define POLARSSL_ERR_ASN1_OUT_OF_DATA
Out of data when parsing an ASN1 data structure.
Definition: asn1.h:54
void asn1_free_named_data(asn1_named_data *entry)
Free a asn1_named_data entry.
#define ASN1_BIT_STRING
Definition: asn1.h:77
#define POLARSSL_ERR_ASN1_MALLOC_FAILED
Memory allocation failed.
Definition: asn1.h:59
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 'named' ASN.1 data items.
Definition: asn1.h:156
Type-length-value structure that allows for ASN1 using DER.
Definition: asn1.h:124
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:127
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:75
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:160
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:55
struct _asn1_sequence * next
The next entry in the sequence.
Definition: asn1.h:149