iPXE
asn1.c File Reference

ASN.1 encoding. More...

#include <stdint.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <time.h>
#include <ipxe/tables.h>
#include <ipxe/image.h>
#include <ipxe/crypto.h>
#include <ipxe/asn1.h>

Go to the source code of this file.

Macros

#define EINVAL_ASN1_EMPTY    __einfo_error ( EINFO_EINVAL_ASN1_EMPTY )
#define EINFO_EINVAL_ASN1_EMPTY    __einfo_uniqify ( EINFO_EINVAL, 0x01, "Empty or underlength cursor" )
#define EINVAL_ASN1_LEN_LEN    __einfo_error ( EINFO_EINVAL_ASN1_LEN_LEN )
#define EINFO_EINVAL_ASN1_LEN_LEN    __einfo_uniqify ( EINFO_EINVAL, 0x02, "Length field overruns cursor" )
#define EINVAL_ASN1_LEN    __einfo_error ( EINFO_EINVAL_ASN1_LEN )
#define EINFO_EINVAL_ASN1_LEN    __einfo_uniqify ( EINFO_EINVAL, 0x03, "Field overruns cursor" )
#define EINVAL_ASN1_BOOLEAN    __einfo_error ( EINFO_EINVAL_ASN1_BOOLEAN )
#define EINFO_EINVAL_ASN1_BOOLEAN    __einfo_uniqify ( EINFO_EINVAL, 0x04, "Invalid boolean" )
#define EINVAL_ASN1_INTEGER    __einfo_error ( EINFO_EINVAL_ASN1_INTEGER )
#define EINFO_EINVAL_ASN1_INTEGER    __einfo_uniqify ( EINFO_EINVAL, 0x04, "Invalid integer" )
#define EINVAL_ASN1_TIME    __einfo_error ( EINFO_EINVAL_ASN1_TIME )
#define EINFO_EINVAL_ASN1_TIME    __einfo_uniqify ( EINFO_EINVAL, 0x05, "Invalid time" )
#define EINVAL_ASN1_ALGORITHM    __einfo_error ( EINFO_EINVAL_ASN1_ALGORITHM )
#define EINFO_EINVAL_ASN1_ALGORITHM    __einfo_uniqify ( EINFO_EINVAL, 0x06, "Invalid algorithm" )
#define EINVAL_BIT_STRING    __einfo_error ( EINFO_EINVAL_BIT_STRING )
#define EINFO_EINVAL_BIT_STRING    __einfo_uniqify ( EINFO_EINVAL, 0x07, "Invalid bit string" )
#define ENOTSUP_ALGORITHM    __einfo_error ( EINFO_ENOTSUP_ALGORITHM )
#define EINFO_ENOTSUP_ALGORITHM    __einfo_uniqify ( EINFO_ENOTSUP, 0x01, "Unsupported algorithm" )
#define ENOTTY_ALGORITHM    __einfo_error ( EINFO_ENOTTY_ALGORITHM )
#define EINFO_ENOTTY_ALGORITHM    __einfo_uniqify ( EINFO_ENOTTY, 0x01, "Inappropriate algorithm" )

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 FILE_SECBOOT (PERMITTED)
static int asn1_start (struct asn1_cursor *cursor, unsigned int type)
 Start parsing ASN.1 object.
int asn1_enter (struct asn1_cursor *cursor, unsigned int type)
 Enter ASN.1 object.
int asn1_skip_if_exists (struct asn1_cursor *cursor, unsigned int type)
 Skip ASN.1 object if present.
int asn1_skip (struct asn1_cursor *cursor, unsigned int type)
 Skip ASN.1 object.
int asn1_shrink (struct asn1_cursor *cursor, unsigned int type)
 Shrink ASN.1 cursor to fit object.
int asn1_enter_any (struct asn1_cursor *cursor)
 Enter ASN.1 object of any type.
int asn1_skip_any (struct asn1_cursor *cursor)
 Skip ASN.1 object of any type.
int asn1_shrink_any (struct asn1_cursor *cursor)
 Shrink ASN.1 object of any type.
int asn1_enter_bits (struct asn1_cursor *cursor, unsigned int *unused)
 Enter ASN.1 bit string.
int asn1_enter_unsigned (struct asn1_cursor *cursor)
 Enter ASN.1 unsigned integer.
int asn1_boolean (const struct asn1_cursor *cursor)
 Parse value of ASN.1 boolean.
int asn1_integer (const struct asn1_cursor *cursor, int *value)
 Parse value of ASN.1 integer.
int asn1_compare (const struct asn1_cursor *cursor1, const struct asn1_cursor *cursor2)
 Compare two ASN.1 objects.
static struct asn1_algorithmasn1_find_algorithm (const struct asn1_cursor *cursor)
 Identify ASN.1 algorithm by OID.
int asn1_algorithm (const struct asn1_cursor *cursor, struct asn1_algorithm **algorithm, struct asn1_cursor *params)
 Parse ASN.1 OID-identified algorithm.
int asn1_pubkey_algorithm (const struct asn1_cursor *cursor, struct asn1_algorithm **algorithm)
 Parse ASN.1 OID-identified public-key algorithm.
int asn1_digest_algorithm (const struct asn1_cursor *cursor, struct asn1_algorithm **algorithm)
 Parse ASN.1 OID-identified digest algorithm.
int asn1_cipher_algorithm (const struct asn1_cursor *cursor, struct asn1_algorithm **algorithm, struct asn1_cursor *params)
 Parse ASN.1 OID-identified cipher algorithm.
int asn1_signature_algorithm (const struct asn1_cursor *cursor, struct asn1_algorithm **algorithm)
 Parse ASN.1 OID-identified signature algorithm.
int asn1_curve_algorithm (const struct asn1_cursor *cursor, struct asn1_algorithm *wrapper, struct asn1_algorithm **algorithm)
 Parse ASN.1 OID-identified elliptic curve algorithm.
int asn1_check_algorithm (const struct asn1_cursor *cursor, struct asn1_algorithm *expected, struct asn1_cursor *params)
 Check ASN.1 OID-identified algorithm.
int asn1_parse_cbc (struct asn1_algorithm *algorithm, struct asn1_cursor *params)
 Parse ASN.1 CBC cipher parameters.
int asn1_parse_gcm (struct asn1_algorithm *algorithm __unused, struct asn1_cursor *params)
 Parse ASN.1 GCM cipher parameters.
int asn1_generalized_time (const struct asn1_cursor *cursor, time_t *time)
 Parse ASN.1 GeneralizedTime.
static size_t asn1_header (struct asn1_builder_header *header, unsigned int type, size_t len)
 Construct ASN.1 header.
int asn1_grow (struct asn1_builder *builder, size_t extra)
 Grow ASN.1 builder.
int asn1_prepend_raw (struct asn1_builder *builder, const void *data, size_t len)
 Prepend raw data to ASN.1 builder.
int asn1_prepend (struct asn1_builder *builder, unsigned int type, const void *data, size_t len)
 Prepend data to ASN.1 builder.
int asn1_wrap (struct asn1_builder *builder, unsigned int type)
 Wrap ASN.1 builder.
int image_asn1 (struct image *image, size_t offset, struct asn1_cursor **cursor)
 Extract ASN.1 object from image.
 REQUIRING_SYMBOL (image_asn1)
 REQUIRE_OBJECT (config_asn1)

Detailed Description

ASN.1 encoding.

Definition in file asn1.c.

Macro Definition Documentation

◆ EINVAL_ASN1_EMPTY

#define EINVAL_ASN1_EMPTY    __einfo_error ( EINFO_EINVAL_ASN1_EMPTY )

Definition at line 46 of file asn1.c.

46#define EINVAL_ASN1_EMPTY \
47 __einfo_error ( EINFO_EINVAL_ASN1_EMPTY )

Referenced by asn1_start().

◆ EINFO_EINVAL_ASN1_EMPTY

#define EINFO_EINVAL_ASN1_EMPTY    __einfo_uniqify ( EINFO_EINVAL, 0x01, "Empty or underlength cursor" )

Definition at line 48 of file asn1.c.

48#define EINFO_EINVAL_ASN1_EMPTY \
49 __einfo_uniqify ( EINFO_EINVAL, 0x01, "Empty or underlength cursor" )

◆ EINVAL_ASN1_LEN_LEN

#define EINVAL_ASN1_LEN_LEN    __einfo_error ( EINFO_EINVAL_ASN1_LEN_LEN )

Definition at line 50 of file asn1.c.

50#define EINVAL_ASN1_LEN_LEN \
51 __einfo_error ( EINFO_EINVAL_ASN1_LEN_LEN )

Referenced by asn1_start().

◆ EINFO_EINVAL_ASN1_LEN_LEN

#define EINFO_EINVAL_ASN1_LEN_LEN    __einfo_uniqify ( EINFO_EINVAL, 0x02, "Length field overruns cursor" )

Definition at line 52 of file asn1.c.

52#define EINFO_EINVAL_ASN1_LEN_LEN \
53 __einfo_uniqify ( EINFO_EINVAL, 0x02, "Length field overruns cursor" )

◆ EINVAL_ASN1_LEN

#define EINVAL_ASN1_LEN    __einfo_error ( EINFO_EINVAL_ASN1_LEN )

Definition at line 54 of file asn1.c.

54#define EINVAL_ASN1_LEN \
55 __einfo_error ( EINFO_EINVAL_ASN1_LEN )

Referenced by asn1_start().

◆ EINFO_EINVAL_ASN1_LEN

#define EINFO_EINVAL_ASN1_LEN    __einfo_uniqify ( EINFO_EINVAL, 0x03, "Field overruns cursor" )

Definition at line 56 of file asn1.c.

56#define EINFO_EINVAL_ASN1_LEN \
57 __einfo_uniqify ( EINFO_EINVAL, 0x03, "Field overruns cursor" )

◆ EINVAL_ASN1_BOOLEAN

#define EINVAL_ASN1_BOOLEAN    __einfo_error ( EINFO_EINVAL_ASN1_BOOLEAN )

Definition at line 58 of file asn1.c.

58#define EINVAL_ASN1_BOOLEAN \
59 __einfo_error ( EINFO_EINVAL_ASN1_BOOLEAN )

Referenced by asn1_boolean().

◆ EINFO_EINVAL_ASN1_BOOLEAN

#define EINFO_EINVAL_ASN1_BOOLEAN    __einfo_uniqify ( EINFO_EINVAL, 0x04, "Invalid boolean" )

Definition at line 60 of file asn1.c.

60#define EINFO_EINVAL_ASN1_BOOLEAN \
61 __einfo_uniqify ( EINFO_EINVAL, 0x04, "Invalid boolean" )

◆ EINVAL_ASN1_INTEGER

#define EINVAL_ASN1_INTEGER    __einfo_error ( EINFO_EINVAL_ASN1_INTEGER )

Definition at line 62 of file asn1.c.

62#define EINVAL_ASN1_INTEGER \
63 __einfo_error ( EINFO_EINVAL_ASN1_INTEGER )

Referenced by asn1_integer().

◆ EINFO_EINVAL_ASN1_INTEGER

#define EINFO_EINVAL_ASN1_INTEGER    __einfo_uniqify ( EINFO_EINVAL, 0x04, "Invalid integer" )

Definition at line 64 of file asn1.c.

64#define EINFO_EINVAL_ASN1_INTEGER \
65 __einfo_uniqify ( EINFO_EINVAL, 0x04, "Invalid integer" )

◆ EINVAL_ASN1_TIME

#define EINVAL_ASN1_TIME    __einfo_error ( EINFO_EINVAL_ASN1_TIME )

Definition at line 66 of file asn1.c.

66#define EINVAL_ASN1_TIME \
67 __einfo_error ( EINFO_EINVAL_ASN1_TIME )

Referenced by asn1_generalized_time().

◆ EINFO_EINVAL_ASN1_TIME

#define EINFO_EINVAL_ASN1_TIME    __einfo_uniqify ( EINFO_EINVAL, 0x05, "Invalid time" )

Definition at line 68 of file asn1.c.

68#define EINFO_EINVAL_ASN1_TIME \
69 __einfo_uniqify ( EINFO_EINVAL, 0x05, "Invalid time" )

◆ EINVAL_ASN1_ALGORITHM

#define EINVAL_ASN1_ALGORITHM    __einfo_error ( EINFO_EINVAL_ASN1_ALGORITHM )

Definition at line 70 of file asn1.c.

70#define EINVAL_ASN1_ALGORITHM \
71 __einfo_error ( EINFO_EINVAL_ASN1_ALGORITHM )

Referenced by asn1_algorithm().

◆ EINFO_EINVAL_ASN1_ALGORITHM

#define EINFO_EINVAL_ASN1_ALGORITHM    __einfo_uniqify ( EINFO_EINVAL, 0x06, "Invalid algorithm" )

Definition at line 72 of file asn1.c.

72#define EINFO_EINVAL_ASN1_ALGORITHM \
73 __einfo_uniqify ( EINFO_EINVAL, 0x06, "Invalid algorithm" )

◆ EINVAL_BIT_STRING

#define EINVAL_BIT_STRING    __einfo_error ( EINFO_EINVAL_BIT_STRING )

Definition at line 74 of file asn1.c.

74#define EINVAL_BIT_STRING \
75 __einfo_error ( EINFO_EINVAL_BIT_STRING )

Referenced by asn1_enter_bits().

◆ EINFO_EINVAL_BIT_STRING

#define EINFO_EINVAL_BIT_STRING    __einfo_uniqify ( EINFO_EINVAL, 0x07, "Invalid bit string" )

Definition at line 76 of file asn1.c.

76#define EINFO_EINVAL_BIT_STRING \
77 __einfo_uniqify ( EINFO_EINVAL, 0x07, "Invalid bit string" )

◆ ENOTSUP_ALGORITHM

#define ENOTSUP_ALGORITHM    __einfo_error ( EINFO_ENOTSUP_ALGORITHM )

Definition at line 78 of file asn1.c.

78#define ENOTSUP_ALGORITHM \
79 __einfo_error ( EINFO_ENOTSUP_ALGORITHM )

Referenced by asn1_algorithm(), and asn1_curve_algorithm().

◆ EINFO_ENOTSUP_ALGORITHM

#define EINFO_ENOTSUP_ALGORITHM    __einfo_uniqify ( EINFO_ENOTSUP, 0x01, "Unsupported algorithm" )

Definition at line 80 of file asn1.c.

80#define EINFO_ENOTSUP_ALGORITHM \
81 __einfo_uniqify ( EINFO_ENOTSUP, 0x01, "Unsupported algorithm" )

◆ ENOTTY_ALGORITHM

#define ENOTTY_ALGORITHM    __einfo_error ( EINFO_ENOTTY_ALGORITHM )

Definition at line 82 of file asn1.c.

82#define ENOTTY_ALGORITHM \
83 __einfo_error ( EINFO_ENOTTY_ALGORITHM )

Referenced by asn1_check_algorithm(), asn1_cipher_algorithm(), asn1_curve_algorithm(), asn1_digest_algorithm(), asn1_pubkey_algorithm(), and asn1_signature_algorithm().

◆ EINFO_ENOTTY_ALGORITHM

#define EINFO_ENOTTY_ALGORITHM    __einfo_uniqify ( EINFO_ENOTTY, 0x01, "Inappropriate algorithm" )

Definition at line 84 of file asn1.c.

84#define EINFO_ENOTTY_ALGORITHM \
85 __einfo_uniqify ( EINFO_ENOTTY, 0x01, "Inappropriate algorithm" )

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED )

◆ asn1_start()

int asn1_start ( struct asn1_cursor * cursor,
unsigned int type )
static

Start parsing ASN.1 object.

Parameters
cursorASN.1 object cursor
typeExpected type, or ASN1_ANY
Return values
lenLength of object body, or negative error

The object cursor will be updated to point to the start of the object body (i.e. the first byte following the length byte(s)), and the length of the object body (i.e. the number of bytes until the following object tag, if any) is returned.

If the expected type is not found, the object cursor will not be modified. If any other error occurs, the object cursor will be invalidated.

Definition at line 103 of file asn1.c.

103 {
104 unsigned int len_len;
105 unsigned int len;
106
107 /* Sanity check */
108 if ( cursor->len < 2 /* Tag byte and first length byte */ ) {
109 if ( cursor->len )
110 DBGC ( cursor, "ASN1 %p too short\n", cursor );
111 asn1_invalidate_cursor ( cursor );
112 return -EINVAL_ASN1_EMPTY;
113 }
114
115 /* Check the tag byte */
116 if ( ( type != ASN1_ANY ) && ( type != asn1_type ( cursor ) ) ) {
117 DBGC ( cursor, "ASN1 %p type mismatch (expected %d, got %d)\n",
118 cursor, type, *( ( uint8_t * ) cursor->data ) );
119 return -ENXIO;
120 }
121 cursor->data++;
122 cursor->len--;
123
124 /* Extract length of the length field and sanity check */
125 len_len = *( ( uint8_t * ) cursor->data );
126 if ( len_len & 0x80 ) {
127 len_len = ( len_len & 0x7f );
128 cursor->data++;
129 cursor->len--;
130 } else {
131 len_len = 1;
132 }
133 if ( cursor->len < len_len ) {
134 DBGC ( cursor, "ASN1 %p bad length field length %d (max "
135 "%zd)\n", cursor, len_len, cursor->len );
136 asn1_invalidate_cursor ( cursor );
137 return -EINVAL_ASN1_LEN_LEN;
138 }
139
140 /* Extract the length and sanity check */
141 for ( len = 0 ; len_len ; len_len-- ) {
142 len <<= 8;
143 len |= *( ( uint8_t * ) cursor->data );
144 cursor->data++;
145 cursor->len--;
146 }
147 if ( cursor->len < len ) {
148 DBGC ( cursor, "ASN1 %p bad length %d (max %zd)\n",
149 cursor, len, cursor->len );
150 asn1_invalidate_cursor ( cursor );
151 return -EINVAL_ASN1_LEN;
152 }
153
154 return len;
155}
unsigned char uint8_t
Definition stdint.h:10
#define EINVAL_ASN1_LEN_LEN
Definition asn1.c:50
#define EINVAL_ASN1_EMPTY
Definition asn1.c:46
#define EINVAL_ASN1_LEN
Definition asn1.c:54
#define ASN1_ANY
ASN.1 "any tag" magic value.
Definition asn1.h:102
static void asn1_invalidate_cursor(struct asn1_cursor *cursor)
Invalidate ASN.1 object cursor.
Definition asn1.h:468
static unsigned int asn1_type(const struct asn1_cursor *cursor)
Extract ASN.1 type.
Definition asn1.h:479
ring len
Length.
Definition dwmac.h:226
uint32_t type
Operating system type.
Definition ena.h:1
#define DBGC(...)
Definition compiler.h:505
#define ENXIO
No such device or address.
Definition errno.h:600
const void * data
Start of data.
Definition asn1.h:23
size_t len
Length of data.
Definition asn1.h:25

References ASN1_ANY, asn1_invalidate_cursor(), asn1_type(), asn1_cursor::data, DBGC, EINVAL_ASN1_EMPTY, EINVAL_ASN1_LEN, EINVAL_ASN1_LEN_LEN, ENXIO, asn1_cursor::len, len, and type.

Referenced by asn1_enter(), asn1_shrink(), and asn1_skip_if_exists().

◆ asn1_enter()

int asn1_enter ( struct asn1_cursor * cursor,
unsigned int type )

Enter ASN.1 object.

Parameters
cursorASN.1 object cursor
typeExpected type, or ASN1_ANY
Return values
rcReturn status code

The object cursor will be updated to point to the body of the current ASN.1 object.

If any error occurs, the object cursor will be invalidated.

Definition at line 169 of file asn1.c.

169 {
170 int len;
171
172 /* Parse current object */
173 len = asn1_start ( cursor, type );
174 if ( len < 0 ) {
175 asn1_invalidate_cursor ( cursor );
176 return len;
177 }
178
179 /* Update cursor */
180 if ( ( ( size_t ) len ) <= cursor->len )
181 cursor->len = len;
182
183 DBGC ( cursor, "ASN1 %p entered object type %02x (len %x)\n",
184 cursor, type, len );
185 return 0;
186}
static int asn1_start(struct asn1_cursor *cursor, unsigned int type)
Start parsing ASN.1 object.
Definition asn1.c:103

References asn1_invalidate_cursor(), asn1_start(), DBGC, asn1_cursor::len, len, and type.

Referenced by asn1_algorithm(), asn1_boolean(), asn1_curve_algorithm(), asn1_enter_any(), asn1_enter_bits(), asn1_enter_unsigned(), asn1_generalized_time(), asn1_integer(), asn1_parse_cbc(), asn1_parse_gcm(), cms_parse(), cms_parse_certificates(), cms_parse_content_type(), cms_parse_encrypted(), cms_parse_enveloped(), cms_parse_identifier(), cms_parse_mac(), cms_parse_participant(), cms_parse_participants(), cms_parse_signed(), cms_parse_value(), ecdsa_parse_key(), ecdsa_verify(), ocsp_compare_responder_key_hash(), ocsp_parse_basic_response(), ocsp_parse_cert_id(), ocsp_parse_certs(), ocsp_parse_response(), ocsp_parse_response_bytes(), ocsp_parse_response_status(), ocsp_parse_response_type(), ocsp_parse_responses(), ocsp_parse_tbs_response_data(), ocsp_request(), rsa_parse_mod_exp(), validator_append(), x509_parse(), x509_parse_access_description(), x509_parse_authority_info_access(), x509_parse_basic_constraints(), x509_parse_common_name(), x509_parse_extended_key_usage(), x509_parse_extension(), x509_parse_extensions(), x509_parse_key_purpose(), x509_parse_ocsp(), x509_parse_public_key(), x509_parse_subject_alt_name(), x509_parse_tbscertificate(), x509_parse_validity(), and x509_parse_version().

◆ asn1_skip_if_exists()

int asn1_skip_if_exists ( struct asn1_cursor * cursor,
unsigned int type )

Skip ASN.1 object if present.

Parameters
cursorASN.1 object cursor
typeExpected type, or ASN1_ANY
Return values
rcReturn status code

The object cursor will be updated to point to the next ASN.1 object.

If the expected type is not found, the object cursor will not be modified. If any other error occurs, the object cursor will be invalidated.

Definition at line 202 of file asn1.c.

202 {
203 int len;
204
205 /* Parse current object */
206 len = asn1_start ( cursor, type );
207 if ( len < 0 )
208 return len;
209
210 /* Update cursor */
211 cursor->data += len;
212 cursor->len -= len;
213
214 DBGC ( cursor, "ASN1 %p skipped object type %02x (len %x)\n",
215 cursor, type, len );
216 return 0;
217}

References asn1_start(), asn1_cursor::data, DBGC, asn1_cursor::len, len, and type.

Referenced by asn1_skip(), cms_parse_enveloped(), cms_parse_participant(), cms_parse_signed(), and ocsp_parse_tbs_response_data().

◆ asn1_skip()

int asn1_skip ( struct asn1_cursor * cursor,
unsigned int type )

Skip ASN.1 object.

Parameters
cursorASN.1 object cursor
typeExpected type, or ASN1_ANY
Return values
rcReturn status code

The object cursor will be updated to point to the next ASN.1 object.

If any error occurs, the object cursor will be invalidated.

Definition at line 231 of file asn1.c.

231 {
232 int rc;
233
234 if ( ( rc = asn1_skip_if_exists ( cursor, type ) ) != 0 ) {
235 asn1_invalidate_cursor ( cursor );
236 return rc;
237 }
238
239 return 0;
240}
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
int asn1_skip_if_exists(struct asn1_cursor *cursor, unsigned int type)
Skip ASN.1 object if present.
Definition asn1.c:202

References asn1_invalidate_cursor(), asn1_skip_if_exists(), rc, and type.

Referenced by asn1_skip_any(), cms_parse_encrypted(), cms_parse_enveloped(), cms_parse_participant(), cms_parse_signed(), der_image_probe(), ecdsa_parse_key(), ocsp_parse_cert_id(), ocsp_request(), and rsa_parse_mod_exp().

◆ asn1_shrink()

int asn1_shrink ( struct asn1_cursor * cursor,
unsigned int type )

Shrink ASN.1 cursor to fit object.

Parameters
cursorASN.1 object cursor
typeExpected type, or ASN1_ANY
Return values
rcReturn status code

The object cursor will be shrunk to contain only the current ASN.1 object.

If any error occurs, the object cursor will be invalidated.

Definition at line 254 of file asn1.c.

254 {
255 struct asn1_cursor temp;
256 const void *end;
257 int len;
258
259 /* Find end of object */
260 memcpy ( &temp, cursor, sizeof ( temp ) );
261 len = asn1_start ( &temp, type );
262 if ( len < 0 ) {
263 asn1_invalidate_cursor ( cursor );
264 return len;
265 }
266 end = ( temp.data + len );
267
268 /* Shrink original cursor to contain only its first object */
269 cursor->len = ( end - cursor->data );
270
271 return 0;
272}
void * memcpy(void *dest, const void *src, size_t len) __nonnull
uint32_t end
Ending offset.
Definition netvsc.h:7
An ASN.1 object cursor.
Definition asn1.h:21

References asn1_invalidate_cursor(), asn1_start(), asn1_cursor::data, end, asn1_cursor::len, len, memcpy(), and type.

Referenced by asn1_shrink_any(), cms_parse_identifier(), ocsp_parse_cert_id(), x509_parse_issuer(), and x509_parse_serial().

◆ asn1_enter_any()

int asn1_enter_any ( struct asn1_cursor * cursor)

Enter ASN.1 object of any type.

Parameters
cursorASN.1 object cursor
Return values
rcReturn status code

Definition at line 280 of file asn1.c.

280 {
281 return asn1_enter ( cursor, ASN1_ANY );
282}
int asn1_enter(struct asn1_cursor *cursor, unsigned int type)
Enter ASN.1 object.
Definition asn1.c:169

References ASN1_ANY, and asn1_enter().

Referenced by ecdsa_parse_key(), ocsp_parse_responder_id(), x509_check_alt_name(), and x509_parse_common_name().

◆ asn1_skip_any()

◆ asn1_shrink_any()

int asn1_shrink_any ( struct asn1_cursor * cursor)

Shrink ASN.1 object of any type.

Parameters
cursorASN.1 object cursor
Return values
rcReturn status code

Definition at line 300 of file asn1.c.

300 {
301 return asn1_shrink ( cursor, ASN1_ANY );
302}
int asn1_shrink(struct asn1_cursor *cursor, unsigned int type)
Shrink ASN.1 cursor to fit object.
Definition asn1.c:254

References ASN1_ANY, and asn1_shrink().

Referenced by cms_message(), der_asn1(), ocsp_parse_tbs_response_data(), x509_certificate(), x509_parse_public_key(), x509_parse_subject(), and x509_parse_tbscertificate().

◆ asn1_enter_bits()

int asn1_enter_bits ( struct asn1_cursor * cursor,
unsigned int * unused )

Enter ASN.1 bit string.

Parameters
cursorASN.1 cursor
unusedUnused bits to fill in (or NULL to require all used)
Return values
rcReturn status code

Definition at line 311 of file asn1.c.

311 {
312 const struct {
314 uint8_t data[0];
315 } __attribute__ (( packed )) *bit_string;
316 const uint8_t *last;
317 unsigned int unused_bits;
318 uint8_t unused_mask;
319 int rc;
320
321 /* Enter bit string */
322 if ( ( rc = asn1_enter ( cursor, ASN1_BIT_STRING ) ) != 0 )
323 return rc;
324
325 /* Check that bit string header exists */
326 if ( cursor->len < sizeof ( *bit_string ) ) {
327 DBGC ( cursor, "ASN1 %p invalid bit string:\n", cursor );
328 DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
329 asn1_invalidate_cursor ( cursor );
330 return -EINVAL_BIT_STRING;
331 }
332 bit_string = cursor->data;
333 cursor->data = &bit_string->data;
334 cursor->len -= offsetof ( typeof ( *bit_string ), data );
335 unused_bits = bit_string->unused;
336
337 /* Check validity of unused bits */
338 unused_mask = ( 0xff >> ( 8 - unused_bits ) );
339 last = ( cursor->data + cursor->len - 1 );
340 if ( ( unused_bits >= 8 ) ||
341 ( ( unused_bits > 0 ) && ( cursor->len == 0 ) ) ||
342 ( ( *last & unused_mask ) != 0 ) ) {
343 DBGC ( cursor, "ASN1 %p invalid bit string:\n", cursor );
344 DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
345 asn1_invalidate_cursor ( cursor );
346 return -EINVAL_BIT_STRING;
347 }
348
349 /* Record or check number of unused bits, as applicable */
350 if ( unused ) {
351 *unused = unused_bits;
352 } else if ( unused_bits ) {
353 DBGC ( cursor, "ASN1 %p invalid integral bit string:\n",
354 cursor );
355 DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
356 asn1_invalidate_cursor ( cursor );
357 return -EINVAL_BIT_STRING;
358 }
359
360 return 0;
361}
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition acpi.c:48
#define EINVAL_BIT_STRING
Definition asn1.c:74
#define ASN1_BIT_STRING
ASN.1 bit string.
Definition asn1.h:66
uint8_t data[48]
Additional event data.
Definition ena.h:11
#define DBGC_HDA(...)
Definition compiler.h:506
#define __attribute__(x)
Definition compiler.h:10
uint8_t unused
Unused.
Definition librm.h:5
#define offsetof(type, field)
Get offset of a field within a structure.
Definition stddef.h:25

References __attribute__, ASN1_BIT_STRING, asn1_enter(), asn1_invalidate_cursor(), asn1_cursor::data, data, DBGC, DBGC_HDA, EINVAL_BIT_STRING, asn1_cursor::len, offsetof, rc, typeof(), and unused.

Referenced by ecdsa_parse_key(), ocsp_parse_basic_response(), rsa_parse_mod_exp(), x509_parse(), x509_parse_key_usage(), and x509_parse_public_key().

◆ asn1_enter_unsigned()

int asn1_enter_unsigned ( struct asn1_cursor * cursor)

Enter ASN.1 unsigned integer.

Parameters
cursorASN.1 object cursor
Return values
rcReturn status code

Definition at line 369 of file asn1.c.

369 {
370 int rc;
371
372 /* Enter integer */
373 if ( ( rc = asn1_enter ( cursor, ASN1_INTEGER ) ) != 0 )
374 return rc;
375
376 /* Skip initial positive sign byte if applicable */
377 if ( ( cursor->len > 1 ) &&
378 ( *( ( uint8_t * ) cursor->data ) == 0x00 ) ) {
379 cursor->data++;
380 cursor->len--;
381 }
382
383 return 0;
384}
#define ASN1_INTEGER
ASN.1 integer.
Definition asn1.h:63

References asn1_enter(), ASN1_INTEGER, asn1_cursor::data, asn1_cursor::len, and rc.

Referenced by ecdsa_parse_signature(), and rsa_parse_mod_exp().

◆ asn1_boolean()

int asn1_boolean ( const struct asn1_cursor * cursor)

Parse value of ASN.1 boolean.

Parameters
cursorASN.1 object cursor
Return values
valueValue, or negative error

Definition at line 392 of file asn1.c.

392 {
393 struct asn1_cursor contents;
394 const struct {
396 } __attribute__ (( packed )) *boolean;
397
398 /* Enter boolean */
399 memcpy ( &contents, cursor, sizeof ( contents ) );
400 asn1_enter ( &contents, ASN1_BOOLEAN );
401 if ( contents.len != sizeof ( *boolean ) )
402 return -EINVAL_ASN1_BOOLEAN;
403
404 /* Extract value */
405 boolean = contents.data;
406 return boolean->value;
407}
pseudo_bit_t value[0x00020]
Definition arbel.h:2
#define EINVAL_ASN1_BOOLEAN
Definition asn1.c:58
#define ASN1_BOOLEAN
ASN.1 boolean.
Definition asn1.h:60

References __attribute__, ASN1_BOOLEAN, asn1_enter(), asn1_cursor::data, EINVAL_ASN1_BOOLEAN, asn1_cursor::len, memcpy(), and value.

Referenced by x509_parse_basic_constraints(), and x509_parse_extension().

◆ asn1_integer()

int asn1_integer ( const struct asn1_cursor * cursor,
int * value )

Parse value of ASN.1 integer.

Parameters
cursorASN.1 object cursor
valueValue to fill in
Return values
rcReturn status code

Definition at line 416 of file asn1.c.

416 {
417 struct asn1_cursor contents;
418 uint8_t high_byte;
419 int rc;
420
421 /* Enter integer */
422 memcpy ( &contents, cursor, sizeof ( contents ) );
423 if ( ( rc = asn1_enter ( &contents, ASN1_INTEGER ) ) != 0 )
424 return rc;
425 if ( contents.len < 1 )
426 return -EINVAL_ASN1_INTEGER;
427
428 /* Initialise value according to sign byte */
429 *value = *( ( int8_t * ) contents.data );
430 contents.data++;
431 contents.len--;
432
433 /* Process value */
434 while ( contents.len ) {
435 high_byte = ( (*value) >> ( 8 * ( sizeof ( *value ) - 1 ) ) );
436 if ( ( high_byte != 0x00 ) && ( high_byte != 0xff ) ) {
437 DBGC ( cursor, "ASN1 %p integer overflow\n", cursor );
438 return -EINVAL_ASN1_INTEGER;
439 }
440 *value = ( ( *value << 8 ) | *( ( uint8_t * ) contents.data ) );
441 contents.data++;
442 contents.len--;
443 }
444
445 return 0;
446}
signed char int8_t
Definition stdint.h:15
#define EINVAL_ASN1_INTEGER
Definition asn1.c:62

References asn1_enter(), ASN1_INTEGER, asn1_cursor::data, DBGC, EINVAL_ASN1_INTEGER, asn1_cursor::len, memcpy(), rc, and value.

Referenced by x509_parse_basic_constraints(), and x509_parse_version().

◆ asn1_compare()

int asn1_compare ( const struct asn1_cursor * cursor1,
const struct asn1_cursor * cursor2 )

Compare two ASN.1 objects.

Parameters
cursor1ASN.1 object cursor
cursor2ASN.1 object cursor
Return values
differenceDifference as returned by memcmp()

Note that invalid and empty cursors will compare as equal with each other.

Definition at line 458 of file asn1.c.

459 {
460 int difference;
461
462 difference = ( cursor2->len - cursor1->len );
463 return ( difference ? difference :
464 memcmp ( cursor1->data, cursor2->data, cursor1->len ) );
465}
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition string.c:115

References asn1_cursor::data, asn1_cursor::len, and memcmp().

Referenced by asn1_find_algorithm(), cms_parse_content_type(), ocsp_compare_responder_name(), ocsp_parse_cert_id(), ocsp_parse_response_type(), pubkey_okx(), pubkey_sign_okx(), rsa_match(), x509_check_issuer(), x509_find(), x509_find_access_method(), x509_find_extension(), x509_find_issuer_serial(), x509_find_subject(), x509_is_self_signed(), x509_parse_common_name(), and x509_parse_key_purpose().

◆ asn1_find_algorithm()

struct asn1_algorithm * asn1_find_algorithm ( const struct asn1_cursor * cursor)
static

Identify ASN.1 algorithm by OID.

Parameters
cursorASN.1 object cursor
Return values
algorithmAlgorithm, or NULL

Definition at line 475 of file asn1.c.

475 {
477
479 if ( asn1_compare ( &algorithm->oid, cursor ) == 0 )
480 return algorithm;
481 }
482
483 return NULL;
484}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
int asn1_compare(const struct asn1_cursor *cursor1, const struct asn1_cursor *cursor2)
Compare two ASN.1 objects.
Definition asn1.c:458
#define ASN1_ALGORITHMS
ASN.1 OID-identified algorithms.
Definition asn1.h:433
u16 algorithm
Authentication algorithm (Open System or Shared Key)
Definition ieee80211.h:1
An ASN.1 OID-identified algorithm.
Definition asn1.h:408
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition tables.h:386

References algorithm, ASN1_ALGORITHMS, asn1_compare(), for_each_table_entry, and NULL.

Referenced by asn1_algorithm(), and asn1_curve_algorithm().

◆ asn1_algorithm()

int asn1_algorithm ( const struct asn1_cursor * cursor,
struct asn1_algorithm ** algorithm,
struct asn1_cursor * params )

Parse ASN.1 OID-identified algorithm.

Parameters
cursorASN.1 object cursor
Return values
algorithmAlgorithm
paramsAlgorithm parameters, or NULL
rcReturn status code

Definition at line 494 of file asn1.c.

496 {
497 struct asn1_cursor contents;
498 int rc;
499
500 /* Enter algorithm */
501 memcpy ( &contents, cursor, sizeof ( contents ) );
502 asn1_enter ( &contents, ASN1_SEQUENCE );
503
504 /* Get raw parameters, if applicable */
505 if ( params ) {
506 memcpy ( params, &contents, sizeof ( *params ) );
507 asn1_skip_any ( params );
508 }
509
510 /* Enter algorithm identifier */
511 if ( ( rc = asn1_enter ( &contents, ASN1_OID ) ) != 0 ) {
512 DBGC ( cursor, "ASN1 %p cannot locate algorithm OID:\n",
513 cursor );
514 DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
515 return -EINVAL_ASN1_ALGORITHM;
516 }
517
518 /* Identify algorithm */
519 *algorithm = asn1_find_algorithm ( &contents );
520 if ( ! *algorithm ) {
521 DBGC ( cursor, "ASN1 %p unrecognised algorithm:\n", cursor );
522 DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
523 return -ENOTSUP_ALGORITHM;
524 }
525
526 /* Parse parameters, if applicable */
527 if ( params && (*algorithm)->parse &&
528 ( ( rc = (*algorithm)->parse ( *algorithm, params ) ) != 0 ) ) {
529 DBGC ( cursor, "ASN1 %p cannot parse %s parameters: %s\n",
530 cursor, (*algorithm)->name, strerror ( rc ) );
531 return rc;
532 }
533
534 return 0;
535}
int asn1_skip_any(struct asn1_cursor *cursor)
Skip ASN.1 object of any type.
Definition asn1.c:290
#define ENOTSUP_ALGORITHM
Definition asn1.c:78
#define EINVAL_ASN1_ALGORITHM
Definition asn1.c:70
static struct asn1_algorithm * asn1_find_algorithm(const struct asn1_cursor *cursor)
Identify ASN.1 algorithm by OID.
Definition asn1.c:475
#define ASN1_OID
ASN.1 object identifier.
Definition asn1.h:75
#define ASN1_SEQUENCE
ASN.1 sequence.
Definition asn1.h:90
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79

References algorithm, asn1_enter(), asn1_find_algorithm(), ASN1_OID, ASN1_SEQUENCE, asn1_skip_any(), asn1_cursor::data, DBGC, DBGC_HDA, EINVAL_ASN1_ALGORITHM, ENOTSUP_ALGORITHM, asn1_cursor::len, memcpy(), rc, and strerror().

◆ asn1_pubkey_algorithm()

int asn1_pubkey_algorithm ( const struct asn1_cursor * cursor,
struct asn1_algorithm ** algorithm )

Parse ASN.1 OID-identified public-key algorithm.

Parameters
cursorASN.1 object cursor
Return values
algorithmAlgorithm
rcReturn status code

Definition at line 544 of file asn1.c.

545 {
546 int rc;
547
548 /* Parse algorithm */
549 if ( ( rc = asn1_algorithm ( cursor, algorithm, NULL ) ) != 0 )
550 return rc;
551
552 /* Check algorithm has a public key */
553 if ( ! (*algorithm)->pubkey ) {
554 DBGC ( cursor, "ASN1 %p algorithm %s is not a public-key "
555 "algorithm:\n", cursor, (*algorithm)->name );
556 DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
557 return -ENOTTY_ALGORITHM;
558 }
559
560 return 0;
561}
#define ENOTTY_ALGORITHM
Definition asn1.c:82

References algorithm, asn1_cursor::data, DBGC, DBGC_HDA, ENOTTY_ALGORITHM, asn1_cursor::len, NULL, and rc.

Referenced by cms_parse_pubkey_algorithm(), and x509_parse_public_key().

◆ asn1_digest_algorithm()

int asn1_digest_algorithm ( const struct asn1_cursor * cursor,
struct asn1_algorithm ** algorithm )

Parse ASN.1 OID-identified digest algorithm.

Parameters
cursorASN.1 object cursor
Return values
algorithmAlgorithm
rcReturn status code

Definition at line 570 of file asn1.c.

571 {
572 int rc;
573
574 /* Parse algorithm */
575 if ( ( rc = asn1_algorithm ( cursor, algorithm, NULL ) ) != 0 )
576 return rc;
577
578 /* Check algorithm has a digest */
579 if ( ! (*algorithm)->digest ) {
580 DBGC ( cursor, "ASN1 %p algorithm %s is not a digest "
581 "algorithm:\n", cursor, (*algorithm)->name );
582 DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
583 return -ENOTTY_ALGORITHM;
584 }
585
586 return 0;
587}

References algorithm, asn1_cursor::data, DBGC, DBGC_HDA, ENOTTY_ALGORITHM, asn1_cursor::len, NULL, and rc.

Referenced by cms_parse_digest_algorithm().

◆ asn1_cipher_algorithm()

int asn1_cipher_algorithm ( const struct asn1_cursor * cursor,
struct asn1_algorithm ** algorithm,
struct asn1_cursor * params )

Parse ASN.1 OID-identified cipher algorithm.

Parameters
cursorASN.1 object cursor
Return values
algorithmAlgorithm
paramsAlgorithm parameters, or NULL
rcReturn status code

Definition at line 597 of file asn1.c.

599 {
600 int rc;
601
602 /* Parse algorithm */
603 if ( ( rc = asn1_algorithm ( cursor, algorithm, params ) ) != 0 )
604 return rc;
605
606 /* Check algorithm has a cipher */
607 if ( ! (*algorithm)->cipher ) {
608 DBGC ( cursor, "ASN1 %p algorithm %s is not a cipher "
609 "algorithm:\n", cursor, (*algorithm)->name );
610 DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
611 return -ENOTTY_ALGORITHM;
612 }
613
614 return 0;
615}

References algorithm, asn1_cursor::data, DBGC, DBGC_HDA, ENOTTY_ALGORITHM, asn1_cursor::len, and rc.

Referenced by cms_parse_cipher_algorithm().

◆ asn1_signature_algorithm()

int asn1_signature_algorithm ( const struct asn1_cursor * cursor,
struct asn1_algorithm ** algorithm )

Parse ASN.1 OID-identified signature algorithm.

Parameters
cursorASN.1 object cursor
Return values
algorithmAlgorithm
rcReturn status code

Definition at line 624 of file asn1.c.

625 {
626 int rc;
627
628 /* Parse algorithm */
629 if ( ( rc = asn1_algorithm ( cursor, algorithm, NULL ) ) != 0 )
630 return rc;
631
632 /* Check algorithm has a public key */
633 if ( ! (*algorithm)->pubkey ) {
634 DBGC ( cursor, "ASN1 %p algorithm %s is not a signature "
635 "algorithm:\n", cursor, (*algorithm)->name );
636 DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
637 return -ENOTTY_ALGORITHM;
638 }
639
640 /* Check algorithm has a digest */
641 if ( ! (*algorithm)->digest ) {
642 DBGC ( cursor, "ASN1 %p algorithm %s is not a signature "
643 "algorithm:\n", cursor, (*algorithm)->name );
644 DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
645 return -ENOTTY_ALGORITHM;
646 }
647
648 return 0;
649}

References algorithm, asn1_cursor::data, DBGC, DBGC_HDA, ENOTTY_ALGORITHM, asn1_cursor::len, NULL, and rc.

Referenced by ocsp_parse_basic_response(), x509_parse(), and x509_parse_tbscertificate().

◆ asn1_curve_algorithm()

int asn1_curve_algorithm ( const struct asn1_cursor * cursor,
struct asn1_algorithm * wrapper,
struct asn1_algorithm ** algorithm )

Parse ASN.1 OID-identified elliptic curve algorithm.

Parameters
cursorASN.1 object cursor
wrapperOptional wrapper algorithm, or NULL
Return values
algorithmAlgorithm
rcReturn status code

Definition at line 659 of file asn1.c.

661 {
662 struct asn1_cursor curve;
663
664 /* Elliptic curves are identified as either:
665 *
666 * - a wrapper algorithm "id-ecPublicKey" with the actual
667 * curve specified in the algorithm parameters, or
668 *
669 * - a standalone object identifier for the curve
670 */
671 if ( ( wrapper == NULL ) ||
672 ( asn1_check_algorithm ( cursor, wrapper, &curve ) != 0 ) ) {
673 memcpy ( &curve, cursor, sizeof ( curve ) );
674 }
675
676 /* Identify curve */
677 asn1_enter ( &curve, ASN1_OID );
678 *algorithm = asn1_find_algorithm ( &curve );
679 if ( ! *algorithm ) {
680 DBGC ( cursor, "ASN1 %p unrecognised EC algorithm:\n",
681 cursor );
682 DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
683 return -ENOTSUP_ALGORITHM;
684 }
685
686 /* Check algorithm has an elliptic curve */
687 if ( ! (*algorithm)->curve ) {
688 DBGC ( cursor, "ASN1 %p algorithm %s is not an elliptic curve "
689 "algorithm:\n", cursor, (*algorithm)->name );
690 DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
691 return -ENOTTY_ALGORITHM;
692 }
693
694 return 0;
695}
int asn1_check_algorithm(const struct asn1_cursor *cursor, struct asn1_algorithm *expected, struct asn1_cursor *params)
Check ASN.1 OID-identified algorithm.
Definition asn1.c:705

References algorithm, asn1_check_algorithm(), asn1_enter(), asn1_find_algorithm(), ASN1_OID, asn1_cursor::data, DBGC, DBGC_HDA, ENOTSUP_ALGORITHM, ENOTTY_ALGORITHM, asn1_cursor::len, memcpy(), and NULL.

Referenced by ecdsa_parse_key().

◆ asn1_check_algorithm()

int asn1_check_algorithm ( const struct asn1_cursor * cursor,
struct asn1_algorithm * expected,
struct asn1_cursor * params )

Check ASN.1 OID-identified algorithm.

Parameters
cursorASN.1 object cursor
expectedExpected algorithm
Return values
paramsAlgorithm parameters, or NULL
rcReturn status code

Definition at line 705 of file asn1.c.

707 {
708 struct asn1_algorithm *actual;
709 int rc;
710
711 /* Parse algorithm */
712 if ( ( rc = asn1_algorithm ( cursor, &actual, params ) ) != 0 )
713 return rc;
714
715 /* Check algorithm matches */
716 if ( actual != expected ) {
717 DBGC ( cursor, "ASN1 %p algorithm %s does not match %s\n",
718 cursor, actual->name, expected->name );
719 return -ENOTTY_ALGORITHM;
720 }
721
722 return 0;
723}
const char * name
Name.
Definition asn1.h:410

References DBGC, ENOTTY_ALGORITHM, asn1_algorithm::name, and rc.

Referenced by asn1_curve_algorithm(), and rsa_parse_mod_exp().

◆ asn1_parse_cbc()

int asn1_parse_cbc ( struct asn1_algorithm * algorithm,
struct asn1_cursor * params )

Parse ASN.1 CBC cipher parameters.

Parameters
algorithmAlgorithm
paramParameters to parse
Return values
rcReturn status code

Definition at line 732 of file asn1.c.

733 {
734 struct cipher_algorithm *cipher = algorithm->cipher;
735
736 /* Sanity check */
737 assert ( cipher != NULL );
738
739 /* Enter parameters */
740 asn1_enter ( params, ASN1_OCTET_STRING );
741
742 /* Check length */
743 if ( params->len != cipher->blocksize )
744 return -EINVAL;
745
746 return 0;
747}
#define ASN1_OCTET_STRING
ASN.1 octet string.
Definition asn1.h:69
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
#define EINVAL
Invalid argument.
Definition errno.h:429
A cipher algorithm.
Definition crypto.h:51
size_t blocksize
Block size.
Definition crypto.h:61

References algorithm, asn1_enter(), ASN1_OCTET_STRING, assert, cipher_algorithm::blocksize, EINVAL, asn1_cursor::len, and NULL.

◆ asn1_parse_gcm()

int asn1_parse_gcm ( struct asn1_algorithm *algorithm __unused,
struct asn1_cursor * params )

Parse ASN.1 GCM cipher parameters.

Parameters
algorithmAlgorithm
paramParameters to parse
Return values
rcReturn status code

Definition at line 756 of file asn1.c.

757 {
758
759 /* Enter parameters */
760 asn1_enter ( params, ASN1_SEQUENCE );
761
762 /* Enter nonce */
763 return asn1_enter ( params, ASN1_OCTET_STRING );
764}

References __unused, algorithm, asn1_enter(), ASN1_OCTET_STRING, and ASN1_SEQUENCE.

◆ asn1_generalized_time()

int asn1_generalized_time ( const struct asn1_cursor * cursor,
time_t * time )

Parse ASN.1 GeneralizedTime.

Parameters
cursorASN.1 cursor
timeTime to fill in
Return values
rcReturn status code

RFC 5280 section 4.1.2.5 places several restrictions on the allowed formats for UTCTime and GeneralizedTime, and mandates the interpretation of centuryless year values.

Definition at line 777 of file asn1.c.

777 {
778 struct asn1_cursor contents;
779 unsigned int have_century;
780 unsigned int type;
781 union {
782 struct {
786 uint8_t day;
787 uint8_t hour;
788 uint8_t minute;
789 uint8_t second;
790 } __attribute__ (( packed )) named;
791 uint8_t raw[7];
792 } pairs;
793 struct tm tm;
794 const uint8_t *data;
795 size_t remaining;
796 unsigned int tens;
797 unsigned int units;
798 unsigned int i;
799 int rc;
800
801 /* Determine time format utcTime/generalizedTime */
802 memcpy ( &contents, cursor, sizeof ( contents ) );
803 type = asn1_type ( &contents );
804 switch ( type ) {
805 case ASN1_UTC_TIME:
806 have_century = 0;
807 break;
809 have_century = 1;
810 break;
811 default:
812 DBGC ( cursor, "ASN1 %p invalid time type %02x\n",
813 cursor, type );
814 DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
815 return -EINVAL_ASN1_TIME;
816 }
817
818 /* Enter utcTime/generalizedTime */
819 if ( ( rc = asn1_enter ( &contents, type ) ) != 0 ) {
820 DBGC ( cursor, "ASN1 %p cannot locate %s time:\n", cursor,
821 ( ( type == ASN1_UTC_TIME ) ? "UTC" : "generalized" ) );
822 DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
823 return rc;
824 }
825
826 /* Parse digit string a pair at a time */
827 memset ( &pairs, 0, sizeof ( pairs ) );
828 data = contents.data;
829 remaining = contents.len;
830 for ( i = ( have_century ? 0 : 1 ) ; i < sizeof ( pairs.raw ) ; i++ ) {
831 if ( remaining < 2 ) {
832 /* Some certificates violate the X.509 RFC by
833 * omitting the "seconds" value.
834 */
835 if ( i == ( sizeof ( pairs.raw ) - 1 ) )
836 break;
837 DBGC ( cursor, "ASN1 %p invalid time:\n", cursor );
838 DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
839 return -EINVAL_ASN1_TIME;
840 }
841 tens = data[0];
842 units = data[1];
843 if ( ! ( isdigit ( tens ) && isdigit ( units ) ) ) {
844 DBGC ( cursor, "ASN1 %p invalid time:\n", cursor );
845 DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
846 return -EINVAL_ASN1_TIME;
847 }
848 pairs.raw[i] = ( ( 10 * ( tens - '0' ) ) + ( units - '0' ) );
849 data += 2;
850 remaining -= 2;
851 }
852
853 /* Determine century if applicable */
854 if ( ! have_century )
855 pairs.named.century = ( ( pairs.named.year >= 50 ) ? 19 : 20 );
856
857 /* Check for trailing "Z" */
858 if ( ( remaining != 1 ) || ( data[0] != 'Z' ) ) {
859 DBGC ( cursor, "ASN1 %p invalid time:\n", cursor );
860 DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
861 return -EINVAL_ASN1_TIME;
862 }
863
864 /* Fill in time */
865 tm.tm_year = ( ( ( pairs.named.century - 19 ) * 100 ) +
866 pairs.named.year );
867 tm.tm_mon = ( pairs.named.month - 1 );
868 tm.tm_mday = pairs.named.day;
869 tm.tm_hour = pairs.named.hour;
870 tm.tm_min = pairs.named.minute;
871 tm.tm_sec = pairs.named.second;
872
873 /* Convert to seconds since the Epoch */
874 *time = mktime ( &tm );
875
876 return 0;
877}
__be32 raw[7]
Definition CIB_PRM.h:0
#define EINVAL_ASN1_TIME
Definition asn1.c:66
#define ASN1_UTC_TIME
ASN.1 UTC time.
Definition asn1.h:84
#define ASN1_GENERALIZED_TIME
ASN.1 generalized time.
Definition asn1.h:87
static int isdigit(int character)
Check if character is a decimal digit.
Definition ctype.h:30
void * memset(void *dest, int character, size_t len) __nonnull
Broken-down time.
Definition time.h:16
int tm_mon
Month of year [0,11].
Definition time.h:26
int tm_year
Years since 1900.
Definition time.h:28
int tm_hour
Hour [0,23].
Definition time.h:22
int tm_sec
Seconds [0,60].
Definition time.h:18
int tm_mday
Day of month [1,31].
Definition time.h:24
int tm_min
Minutes [0,59].
Definition time.h:20
time_t mktime(struct tm *tm)
Calculate seconds since the Epoch.
Definition time.c:118
uint8_t month
Month (BCD)
Definition ucode.h:7
uint8_t day
Day (BCD)
Definition ucode.h:5
uint8_t year
Year (BCD)
Definition ucode.h:1
uint8_t century
Century (BCD)
Definition ucode.h:3

References __attribute__, asn1_enter(), ASN1_GENERALIZED_TIME, asn1_type(), ASN1_UTC_TIME, century, asn1_cursor::data, data, day, DBGC, DBGC_HDA, EINVAL_ASN1_TIME, isdigit(), asn1_cursor::len, memcpy(), memset(), mktime(), month, raw, rc, tm::tm_hour, tm::tm_mday, tm::tm_min, tm::tm_mon, tm::tm_sec, tm::tm_year, type, and year.

Referenced by ocsp_parse_responses(), and x509_parse_validity().

◆ asn1_header()

size_t asn1_header ( struct asn1_builder_header * header,
unsigned int type,
size_t len )
static

Construct ASN.1 header.

Parameters
headerASN.1 builder header
typeType
lenContent length
Return values
header_lenHeader length

Definition at line 887 of file asn1.c.

888 {
889 unsigned int header_len = 2;
890 unsigned int len_len = 0;
891 size_t temp;
892
893 /* Construct header */
894 header->type = type;
895 if ( len < 0x80 ) {
896 header->length[0] = len;
897 } else {
898 for ( temp = len ; temp ; temp >>= 8 )
899 len_len++;
900 header->length[0] = ( 0x80 | len_len );
901 header_len += len_len;
902 for ( temp = len ; temp ; temp >>= 8 )
903 header->length[len_len--] = ( temp & 0xff );
904 }
905
906 return header_len;
907}
struct ena_llq_option header
Header locations.
Definition ena.h:5

References header, len, and type.

Referenced by asn1_prepend(), and asn1_wrap().

◆ asn1_grow()

int asn1_grow ( struct asn1_builder * builder,
size_t extra )

Grow ASN.1 builder.

Parameters
builderASN.1 builder
extraExtra space to prepend
Return values
rcReturn status code

Definition at line 916 of file asn1.c.

916 {
917 size_t new_len;
918 void *new;
919
920 /* As with the ASN1 parsing functions, make errors permanent */
921 if ( builder->len && ! builder->data )
922 return -ENOMEM;
923
924 /* Reallocate data buffer */
925 new_len = ( builder->len + extra );
926 new = realloc ( builder->data, new_len );
927 if ( ! new ) {
928 free ( builder->data );
929 builder->data = NULL;
930 return -ENOMEM;
931 }
932 builder->data = new;
933
934 /* Move existing data to end of buffer */
935 memmove ( ( builder->data + extra ), builder->data, builder->len );
936 builder->len = new_len;
937
938 return 0;
939}
#define ENOMEM
Not enough space.
Definition errno.h:535
uint8_t extra
Signature extra byte.
Definition smbios.h:6
void * memmove(void *dest, const void *src, size_t len) __nonnull
void * realloc(void *old_ptr, size_t new_size)
Reallocate memory.
Definition malloc.c:607
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
void * data
Data.
Definition asn1.h:36
size_t len
Length of data.
Definition asn1.h:38

References asn1_builder::data, ENOMEM, extra, free, asn1_builder::len, memmove(), NULL, and realloc().

Referenced by asn1_prepend(), asn1_prepend_raw(), asn1_wrap(), rsa_decrypt(), rsa_encrypt(), and rsa_sign().

◆ asn1_prepend_raw()

int asn1_prepend_raw ( struct asn1_builder * builder,
const void * data,
size_t len )

Prepend raw data to ASN.1 builder.

Parameters
builderASN.1 builder
dataData to prepend
lenLength of data to prepend
Return values
rcReturn status code

Definition at line 949 of file asn1.c.

950 {
951 int rc;
952
953 /* Grow buffer */
954 if ( ( rc = asn1_grow ( builder, len ) ) != 0 )
955 return rc;
956
957 /* Populate data buffer */
958 memcpy ( builder->data, data, len );
959
960 return 0;
961}
int asn1_grow(struct asn1_builder *builder, size_t extra)
Grow ASN.1 builder.
Definition asn1.c:916

References asn1_grow(), asn1_builder::data, data, len, memcpy(), and rc.

Referenced by icert_cert(), icert_certs(), ocsp_request(), tls_send_certificate_verify(), and tls_send_client_key_exchange_pubkey().

◆ asn1_prepend()

int asn1_prepend ( struct asn1_builder * builder,
unsigned int type,
const void * data,
size_t len )

Prepend data to ASN.1 builder.

Parameters
builderASN.1 builder
typeType
dataData to prepend
lenLength of data to prepend
Return values
rcReturn status code

Definition at line 972 of file asn1.c.

973 {
975 size_t header_len;
976 int rc;
977
978 /* Construct header */
979 header_len = asn1_header ( &header, type, len );
980
981 /* Grow buffer */
982 if ( ( rc = asn1_grow ( builder, header_len + len ) ) != 0 )
983 return rc;
984
985 /* Populate data buffer */
986 memcpy ( builder->data, &header, header_len );
987 memcpy ( ( builder->data + header_len ), data, len );
988
989 return 0;
990}
static size_t asn1_header(struct asn1_builder_header *header, unsigned int type, size_t len)
Construct ASN.1 header.
Definition asn1.c:887
An ASN.1 header.
Definition asn1.h:49

References asn1_grow(), asn1_header(), asn1_builder::data, data, header, len, memcpy(), rc, and type.

Referenced by ecdsa_prepend_signature(), icert_certs(), and ocsp_request().

◆ asn1_wrap()

int asn1_wrap ( struct asn1_builder * builder,
unsigned int type )

Wrap ASN.1 builder.

Parameters
builderASN.1 builder
typeType
Return values
rcReturn status code

Definition at line 999 of file asn1.c.

999 {
1001 size_t header_len;
1002 int rc;
1003
1004 /* Construct header */
1005 header_len = asn1_header ( &header, type, builder->len );
1006
1007 /* Grow buffer */
1008 if ( ( rc = asn1_grow ( builder, header_len ) ) != 0 )
1009 return rc;
1010
1011 /* Populate data buffer */
1012 memcpy ( builder->data, &header, header_len );
1013
1014 return 0;
1015}

References asn1_grow(), asn1_header(), asn1_builder::data, header, asn1_builder::len, memcpy(), rc, and type.

Referenced by ecdsa_sign(), icert_cert(), icert_certs(), and ocsp_request().

◆ image_asn1()

int image_asn1 ( struct image * image,
size_t offset,
struct asn1_cursor ** cursor )

Extract ASN.1 object from image.

Parameters
imageImage
offsetOffset within image
cursorASN.1 cursor to fill in
Return values
nextOffset to next image, or negative error

The caller is responsible for eventually calling free() on the allocated ASN.1 cursor.

Definition at line 1028 of file asn1.c.

1029 {
1030 int next;
1031 int rc;
1032
1033 /* Sanity check */
1035
1036 /* Check that this image can be used to extract an ASN.1 object */
1037 if ( ! ( image->type && image->type->asn1 ) )
1038 return -ENOTSUP;
1039
1040 /* Try creating ASN.1 cursor */
1041 next = image->type->asn1 ( image, offset, cursor );
1042 if ( next < 0 ) {
1043 rc = next;
1044 DBGC ( image, "IMAGE %s could not extract ASN.1 object: %s\n",
1045 image->name, strerror ( rc ) );
1046 return rc;
1047 }
1048
1049 return next;
1050}
uint16_t offset
Offset to command line.
Definition bzimage.h:3
uint32_t next
Next descriptor address.
Definition dwmac.h:11
#define ENOTSUP
Operation not supported.
Definition errno.h:590
int(* asn1)(struct image *image, size_t offset, struct asn1_cursor **cursor)
Extract ASN.1 object from image.
Definition image.h:133
An executable image.
Definition image.h:24
struct image_type * type
Image type, if known.
Definition image.h:59
char * name
Name.
Definition image.h:38

References image_type::asn1, assert, DBGC, ENOTSUP, len, image::name, next, offset, rc, strerror(), and image::type.

Referenced by asn1_okx(), cms_message(), image_x509(), and REQUIRING_SYMBOL().

◆ REQUIRING_SYMBOL()

REQUIRING_SYMBOL ( image_asn1 )

References image_asn1().

◆ REQUIRE_OBJECT()

REQUIRE_OBJECT ( config_asn1 )