source: bootcd/isolinux/syslinux-6.03/gpxe/src/crypto/asn1.c @ 26ffad7

Last change on this file since 26ffad7 was e16e8f2, checked in by Edwin Eefting <edwin@datux.nl>, 3 years ago

bootstuff

  • Property mode set to 100644
File size: 4.1 KB
Line 
1/*
2 * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18
19FILE_LICENCE ( GPL2_OR_LATER );
20
21#include <stdint.h>
22#include <stddef.h>
23#include <errno.h>
24#include <gpxe/asn1.h>
25
26/** @file
27 *
28 * ASN.1 encoding
29 *
30 */
31
32/**
33 * Start parsing ASN.1 object
34 *
35 * @v cursor            ASN.1 object cursor
36 * @v type              Expected type
37 * @ret len             Length of object body, or negative error
38 *
39 * The object cursor will be updated to point to the start of the
40 * object body (i.e. the first byte following the length byte(s)), and
41 * the length of the object body (i.e. the number of bytes until the
42 * following object tag, if any) is returned.
43 *
44 * If any error occurs (i.e. if the object is not of the expected
45 * type, or if we overflow beyond the end of the ASN.1 object), then
46 * the cursor will be invalidated and a negative value will be
47 * returned.
48 */
49static int asn1_start ( struct asn1_cursor *cursor,
50                               unsigned int type ) {
51        unsigned int len_len;
52        unsigned int len;
53        int rc;
54
55        /* Sanity check */
56        if ( cursor->len < 2 /* Tag byte and first length byte */ ) {
57                if ( cursor->len )
58                        DBGC ( cursor, "ASN1 %p too short\n", cursor );
59                rc = -EINVAL;
60                goto notfound;
61        }
62
63        /* Check the tag byte */
64        if ( *( ( uint8_t * ) cursor->data ) != type ) {
65                DBGC ( cursor, "ASN1 %p type mismatch (expected %d, got %d)\n",
66                       cursor, type, *( ( uint8_t * ) cursor->data ) );
67                rc = -ENXIO;
68                goto notfound;
69        }
70        cursor->data++;
71        cursor->len--;
72
73        /* Extract length of the length field and sanity check */
74        len_len = *( ( uint8_t * ) cursor->data );
75        if ( len_len & 0x80 ) {
76                len_len = ( len_len & 0x7f );
77                cursor->data++;
78                cursor->len--;
79        } else {
80                len_len = 1;
81        }
82        if ( cursor->len < len_len ) {
83                DBGC ( cursor, "ASN1 %p bad length field length %d (max "
84                       "%zd)\n", cursor, len_len, cursor->len );
85                rc = -EINVAL;
86                goto notfound;
87        }
88
89        /* Extract the length and sanity check */
90        for ( len = 0 ; len_len ; len_len-- ) {
91                len <<= 8;
92                len |= *( ( uint8_t * ) cursor->data );
93                cursor->data++;
94                cursor->len--;
95        }
96        if ( cursor->len < len ) {
97                DBGC ( cursor, "ASN1 %p bad length %d (max %zd)\n",
98                       cursor, len, cursor->len );
99                rc = -EINVAL;
100                goto notfound;
101        }
102
103        return len;
104
105 notfound:
106        cursor->data = NULL;
107        cursor->len = 0;
108        return rc;
109}
110
111/**
112 * Enter ASN.1 object
113 *
114 * @v cursor            ASN.1 object cursor
115 * @v type              Expected type
116 * @ret rc              Return status code
117 *
118 * The object cursor will be updated to point to the body of the
119 * current ASN.1 object.  If any error occurs, the object cursor will
120 * be invalidated.
121 */
122int asn1_enter ( struct asn1_cursor *cursor, unsigned int type ) {
123        int len;
124
125        len = asn1_start ( cursor, type );
126        if ( len < 0 )
127                return len;
128
129        cursor->len = len;
130        DBGC ( cursor, "ASN1 %p entered object type %02x (len %x)\n",
131               cursor, type, len );
132
133        return 0;
134}
135
136/**
137 * Skip ASN.1 object
138 *
139 * @v cursor            ASN.1 object cursor
140 * @v type              Expected type
141 * @ret rc              Return status code
142 *
143 * The object cursor will be updated to point to the next ASN.1
144 * object.  If any error occurs, the object cursor will be
145 * invalidated.
146 */
147int asn1_skip ( struct asn1_cursor *cursor, unsigned int type ) {
148        int len;
149
150        len = asn1_start ( cursor, type );
151        if ( len < 0 )
152                return len;
153
154        cursor->data += len;
155        cursor->len -= len;
156        DBGC ( cursor, "ASN1 %p skipped object type %02x (len %x)\n",
157               cursor, type, len );
158
159        if ( ! cursor->len ) {
160                DBGC ( cursor, "ASN1 %p reached end of object\n", cursor );
161                cursor->data = NULL;
162                return -ENOENT;
163        }
164
165        return 0;
166}
Note: See TracBrowser for help on using the repository browser.