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

Variables

static uint8_t oid_ecpublickey [] = { ASN1_OID_ECPUBLICKEY }
 "ecPublicKey" object identifier More...
 
struct asn1_algorithm ecpubkey_algorithm __asn1_algorithm
 Generic elliptic curve container algorithm. More...
 

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 45 of file asn1.c.

◆ EINFO_EINVAL_ASN1_EMPTY

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

Definition at line 47 of file asn1.c.

◆ EINVAL_ASN1_LEN_LEN

#define EINVAL_ASN1_LEN_LEN   __einfo_error ( EINFO_EINVAL_ASN1_LEN_LEN )

Definition at line 49 of file asn1.c.

◆ EINFO_EINVAL_ASN1_LEN_LEN

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

Definition at line 51 of file asn1.c.

◆ EINVAL_ASN1_LEN

#define EINVAL_ASN1_LEN   __einfo_error ( EINFO_EINVAL_ASN1_LEN )

Definition at line 53 of file asn1.c.

◆ EINFO_EINVAL_ASN1_LEN

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

Definition at line 55 of file asn1.c.

◆ EINVAL_ASN1_BOOLEAN

#define EINVAL_ASN1_BOOLEAN   __einfo_error ( EINFO_EINVAL_ASN1_BOOLEAN )

Definition at line 57 of file asn1.c.

◆ EINFO_EINVAL_ASN1_BOOLEAN

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

Definition at line 59 of file asn1.c.

◆ EINVAL_ASN1_INTEGER

#define EINVAL_ASN1_INTEGER   __einfo_error ( EINFO_EINVAL_ASN1_INTEGER )

Definition at line 61 of file asn1.c.

◆ EINFO_EINVAL_ASN1_INTEGER

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

Definition at line 63 of file asn1.c.

◆ EINVAL_ASN1_TIME

#define EINVAL_ASN1_TIME   __einfo_error ( EINFO_EINVAL_ASN1_TIME )

Definition at line 65 of file asn1.c.

◆ EINFO_EINVAL_ASN1_TIME

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

Definition at line 67 of file asn1.c.

◆ EINVAL_ASN1_ALGORITHM

#define EINVAL_ASN1_ALGORITHM   __einfo_error ( EINFO_EINVAL_ASN1_ALGORITHM )

Definition at line 69 of file asn1.c.

◆ EINFO_EINVAL_ASN1_ALGORITHM

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

Definition at line 71 of file asn1.c.

◆ EINVAL_BIT_STRING

#define EINVAL_BIT_STRING   __einfo_error ( EINFO_EINVAL_BIT_STRING )

Definition at line 73 of file asn1.c.

◆ EINFO_EINVAL_BIT_STRING

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

Definition at line 75 of file asn1.c.

◆ ENOTSUP_ALGORITHM

#define ENOTSUP_ALGORITHM   __einfo_error ( EINFO_ENOTSUP_ALGORITHM )

Definition at line 77 of file asn1.c.

◆ EINFO_ENOTSUP_ALGORITHM

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

Definition at line 79 of file asn1.c.

◆ ENOTTY_ALGORITHM

#define ENOTTY_ALGORITHM   __einfo_error ( EINFO_ENOTTY_ALGORITHM )

Definition at line 81 of file asn1.c.

◆ EINFO_ENOTTY_ALGORITHM

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

Definition at line 83 of file asn1.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ asn1_start()

static 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 115 of file asn1.c.

115  {
116  unsigned int len_len;
117  unsigned int len;
118 
119  /* Sanity check */
120  if ( cursor->len < 2 /* Tag byte and first length byte */ ) {
121  if ( cursor->len )
122  DBGC ( cursor, "ASN1 %p too short\n", cursor );
123  asn1_invalidate_cursor ( cursor );
124  return -EINVAL_ASN1_EMPTY;
125  }
126 
127  /* Check the tag byte */
128  if ( ( type != ASN1_ANY ) && ( type != asn1_type ( cursor ) ) ) {
129  DBGC ( cursor, "ASN1 %p type mismatch (expected %d, got %d)\n",
130  cursor, type, *( ( uint8_t * ) cursor->data ) );
131  return -ENXIO;
132  }
133  cursor->data++;
134  cursor->len--;
135 
136  /* Extract length of the length field and sanity check */
137  len_len = *( ( uint8_t * ) cursor->data );
138  if ( len_len & 0x80 ) {
139  len_len = ( len_len & 0x7f );
140  cursor->data++;
141  cursor->len--;
142  } else {
143  len_len = 1;
144  }
145  if ( cursor->len < len_len ) {
146  DBGC ( cursor, "ASN1 %p bad length field length %d (max "
147  "%zd)\n", cursor, len_len, cursor->len );
148  asn1_invalidate_cursor ( cursor );
149  return -EINVAL_ASN1_LEN_LEN;
150  }
151 
152  /* Extract the length and sanity check */
153  for ( len = 0 ; len_len ; len_len-- ) {
154  len <<= 8;
155  len |= *( ( uint8_t * ) cursor->data );
156  cursor->data++;
157  cursor->len--;
158  }
159  if ( cursor->len < len ) {
160  DBGC ( cursor, "ASN1 %p bad length %d (max %zd)\n",
161  cursor, len, cursor->len );
162  asn1_invalidate_cursor ( cursor );
163  return -EINVAL_ASN1_LEN;
164  }
165 
166  return len;
167 }
#define EINVAL_ASN1_LEN_LEN
Definition: asn1.c:49
uint32_t type
Operating system type.
Definition: ena.h:12
const void * data
Start of data.
Definition: asn1.h:22
#define DBGC(...)
Definition: compiler.h:505
#define EINVAL_ASN1_LEN
Definition: asn1.c:53
static unsigned int asn1_type(const struct asn1_cursor *cursor)
Extract ASN.1 type.
Definition: asn1.h:454
#define ASN1_ANY
ASN.1 "any tag" magic value.
Definition: asn1.h:101
size_t len
Length of data.
Definition: asn1.h:24
ring len
Length.
Definition: dwmac.h:231
static void asn1_invalidate_cursor(struct asn1_cursor *cursor)
Invalidate ASN.1 object cursor.
Definition: asn1.h:443
unsigned char uint8_t
Definition: stdint.h:10
#define ENXIO
No such device or address.
Definition: errno.h:599
#define EINVAL_ASN1_EMPTY
Definition: asn1.c:45

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 181 of file asn1.c.

181  {
182  int len;
183 
184  /* Parse current object */
185  len = asn1_start ( cursor, type );
186  if ( len < 0 ) {
187  asn1_invalidate_cursor ( cursor );
188  return len;
189  }
190 
191  /* Update cursor */
192  if ( ( ( size_t ) len ) <= cursor->len )
193  cursor->len = len;
194 
195  DBGC ( cursor, "ASN1 %p entered object type %02x (len %x)\n",
196  cursor, type, len );
197  return 0;
198 }
uint32_t type
Operating system type.
Definition: ena.h:12
#define DBGC(...)
Definition: compiler.h:505
static int asn1_start(struct asn1_cursor *cursor, unsigned int type)
Start parsing ASN.1 object.
Definition: asn1.c:115
size_t len
Length of data.
Definition: asn1.h:24
ring len
Length.
Definition: dwmac.h:231
static void asn1_invalidate_cursor(struct asn1_cursor *cursor)
Invalidate ASN.1 object cursor.
Definition: asn1.h:443

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_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(), 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_integer(), 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 214 of file asn1.c.

214  {
215  int len;
216 
217  /* Parse current object */
218  len = asn1_start ( cursor, type );
219  if ( len < 0 )
220  return len;
221 
222  /* Update cursor */
223  cursor->data += len;
224  cursor->len -= len;
225 
226  DBGC ( cursor, "ASN1 %p skipped object type %02x (len %x)\n",
227  cursor, type, len );
228  return 0;
229 }
uint32_t type
Operating system type.
Definition: ena.h:12
const void * data
Start of data.
Definition: asn1.h:22
#define DBGC(...)
Definition: compiler.h:505
static int asn1_start(struct asn1_cursor *cursor, unsigned int type)
Start parsing ASN.1 object.
Definition: asn1.c:115
size_t len
Length of data.
Definition: asn1.h:24
ring len
Length.
Definition: dwmac.h:231

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 243 of file asn1.c.

243  {
244  int rc;
245 
246  if ( ( rc = asn1_skip_if_exists ( cursor, type ) ) != 0 ) {
247  asn1_invalidate_cursor ( cursor );
248  return rc;
249  }
250 
251  return 0;
252 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
uint32_t type
Operating system type.
Definition: ena.h:12
static void asn1_invalidate_cursor(struct asn1_cursor *cursor)
Invalidate ASN.1 object cursor.
Definition: asn1.h:443
int asn1_skip_if_exists(struct asn1_cursor *cursor, unsigned int type)
Skip ASN.1 object if present.
Definition: asn1.c:214

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(), 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 266 of file asn1.c.

266  {
267  struct asn1_cursor temp;
268  const void *end;
269  int len;
270 
271  /* Find end of object */
272  memcpy ( &temp, cursor, sizeof ( temp ) );
273  len = asn1_start ( &temp, type );
274  if ( len < 0 ) {
275  asn1_invalidate_cursor ( cursor );
276  return len;
277  }
278  end = ( temp.data + len );
279 
280  /* Shrink original cursor to contain only its first object */
281  cursor->len = ( end - cursor->data );
282 
283  return 0;
284 }
uint32_t type
Operating system type.
Definition: ena.h:12
const void * data
Start of data.
Definition: asn1.h:22
static int asn1_start(struct asn1_cursor *cursor, unsigned int type)
Start parsing ASN.1 object.
Definition: asn1.c:115
size_t len
Length of data.
Definition: asn1.h:24
void * memcpy(void *dest, const void *src, size_t len) __nonnull
ring len
Length.
Definition: dwmac.h:231
static void asn1_invalidate_cursor(struct asn1_cursor *cursor)
Invalidate ASN.1 object cursor.
Definition: asn1.h:443
uint32_t end
Ending offset.
Definition: netvsc.h:18
An ASN.1 object cursor.
Definition: asn1.h:20

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 292 of file asn1.c.

292  {
293  return asn1_enter ( cursor, ASN1_ANY );
294 }
int asn1_enter(struct asn1_cursor *cursor, unsigned int type)
Enter ASN.1 object.
Definition: asn1.c:181
#define ASN1_ANY
ASN.1 "any tag" magic value.
Definition: asn1.h:101

References ASN1_ANY, and asn1_enter().

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

◆ asn1_skip_any()

int asn1_skip_any ( struct asn1_cursor cursor)

◆ 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 312 of file asn1.c.

312  {
313  return asn1_shrink ( cursor, ASN1_ANY );
314 }
#define ASN1_ANY
ASN.1 "any tag" magic value.
Definition: asn1.h:101
int asn1_shrink(struct asn1_cursor *cursor, unsigned int type)
Shrink ASN.1 cursor to fit object.
Definition: asn1.c:266

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 323 of file asn1.c.

323  {
324  const struct {
325  uint8_t unused;
326  uint8_t data[0];
327  } __attribute__ (( packed )) *bit_string;
328  const uint8_t *last;
329  unsigned int unused_bits;
330  uint8_t unused_mask;
331  int rc;
332 
333  /* Enter bit string */
334  if ( ( rc = asn1_enter ( cursor, ASN1_BIT_STRING ) ) != 0 )
335  return rc;
336 
337  /* Check that bit string header exists */
338  if ( cursor->len < sizeof ( *bit_string ) ) {
339  DBGC ( cursor, "ASN1 %p invalid bit string:\n", cursor );
340  DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
341  asn1_invalidate_cursor ( cursor );
342  return -EINVAL_BIT_STRING;
343  }
344  bit_string = cursor->data;
345  cursor->data = &bit_string->data;
346  cursor->len -= offsetof ( typeof ( *bit_string ), data );
347  unused_bits = bit_string->unused;
348 
349  /* Check validity of unused bits */
350  unused_mask = ( 0xff >> ( 8 - unused_bits ) );
351  last = ( cursor->data + cursor->len - 1 );
352  if ( ( unused_bits >= 8 ) ||
353  ( ( unused_bits > 0 ) && ( cursor->len == 0 ) ) ||
354  ( ( *last & unused_mask ) != 0 ) ) {
355  DBGC ( cursor, "ASN1 %p invalid bit string:\n", cursor );
356  DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
357  asn1_invalidate_cursor ( cursor );
358  return -EINVAL_BIT_STRING;
359  }
360 
361  /* Record or check number of unused bits, as applicable */
362  if ( unused ) {
363  *unused = unused_bits;
364  } else if ( unused_bits ) {
365  DBGC ( cursor, "ASN1 %p invalid integral bit string:\n",
366  cursor );
367  DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
368  asn1_invalidate_cursor ( cursor );
369  return -EINVAL_BIT_STRING;
370  }
371 
372  return 0;
373 }
#define __attribute__(x)
Definition: compiler.h:10
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define EINVAL_BIT_STRING
Definition: asn1.c:73
int asn1_enter(struct asn1_cursor *cursor, unsigned int type)
Enter ASN.1 object.
Definition: asn1.c:181
const void * data
Start of data.
Definition: asn1.h:22
#define DBGC(...)
Definition: compiler.h:505
#define offsetof(type, field)
Get offset of a field within a structure.
Definition: stddef.h:24
size_t len
Length of data.
Definition: asn1.h:24
#define DBGC_HDA(...)
Definition: compiler.h:506
static void asn1_invalidate_cursor(struct asn1_cursor *cursor)
Invalidate ASN.1 object cursor.
Definition: asn1.h:443
unsigned char uint8_t
Definition: stdint.h:10
uint8_t unused
Unused.
Definition: librm.h:140
uint8_t data[48]
Additional event data.
Definition: ena.h:22
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition: acpi.c:47
#define ASN1_BIT_STRING
ASN.1 bit string.
Definition: asn1.h:65

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 ocsp_parse_basic_response(), rsa_parse_mod_exp(), x509_parse(), x509_parse_key_usage(), and x509_parse_public_key().

◆ 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 381 of file asn1.c.

381  {
382  struct asn1_cursor contents;
383  const struct {
384  uint8_t value;
385  } __attribute__ (( packed )) *boolean;
386 
387  /* Enter boolean */
388  memcpy ( &contents, cursor, sizeof ( contents ) );
389  asn1_enter ( &contents, ASN1_BOOLEAN );
390  if ( contents.len != sizeof ( *boolean ) )
391  return -EINVAL_ASN1_BOOLEAN;
392 
393  /* Extract value */
394  boolean = contents.data;
395  return boolean->value;
396 }
#define __attribute__(x)
Definition: compiler.h:10
int asn1_enter(struct asn1_cursor *cursor, unsigned int type)
Enter ASN.1 object.
Definition: asn1.c:181
#define ASN1_BOOLEAN
ASN.1 boolean.
Definition: asn1.h:59
void * memcpy(void *dest, const void *src, size_t len) __nonnull
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
unsigned char uint8_t
Definition: stdint.h:10
#define EINVAL_ASN1_BOOLEAN
Definition: asn1.c:57
An ASN.1 object cursor.
Definition: asn1.h:20

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 405 of file asn1.c.

405  {
406  struct asn1_cursor contents;
407  uint8_t high_byte;
408  int rc;
409 
410  /* Enter integer */
411  memcpy ( &contents, cursor, sizeof ( contents ) );
412  if ( ( rc = asn1_enter ( &contents, ASN1_INTEGER ) ) != 0 )
413  return rc;
414  if ( contents.len < 1 )
415  return -EINVAL_ASN1_INTEGER;
416 
417  /* Initialise value according to sign byte */
418  *value = *( ( int8_t * ) contents.data );
419  contents.data++;
420  contents.len--;
421 
422  /* Process value */
423  while ( contents.len ) {
424  high_byte = ( (*value) >> ( 8 * ( sizeof ( *value ) - 1 ) ) );
425  if ( ( high_byte != 0x00 ) && ( high_byte != 0xff ) ) {
426  DBGC ( cursor, "ASN1 %p integer overflow\n", cursor );
427  return -EINVAL_ASN1_INTEGER;
428  }
429  *value = ( ( *value << 8 ) | *( ( uint8_t * ) contents.data ) );
430  contents.data++;
431  contents.len--;
432  }
433 
434  return 0;
435 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
int asn1_enter(struct asn1_cursor *cursor, unsigned int type)
Enter ASN.1 object.
Definition: asn1.c:181
#define DBGC(...)
Definition: compiler.h:505
void * memcpy(void *dest, const void *src, size_t len) __nonnull
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
#define EINVAL_ASN1_INTEGER
Definition: asn1.c:61
signed char int8_t
Definition: stdint.h:15
unsigned char uint8_t
Definition: stdint.h:10
#define ASN1_INTEGER
ASN.1 integer.
Definition: asn1.h:62
An ASN.1 object cursor.
Definition: asn1.h:20

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 447 of file asn1.c.

448  {
449  int difference;
450 
451  difference = ( cursor2->len - cursor1->len );
452  return ( difference ? difference :
453  memcmp ( cursor1->data, cursor2->data, cursor1->len ) );
454 }
const void * data
Start of data.
Definition: asn1.h:22
size_t len
Length of data.
Definition: asn1.h:24
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:114

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()

static 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 464 of file asn1.c.

464  {
465  struct asn1_algorithm *algorithm;
466 
468  if ( asn1_compare ( &algorithm->oid, cursor ) == 0 )
469  return algorithm;
470  }
471 
472  return NULL;
473 }
An ASN.1 OID-identified algorithm.
Definition: asn1.h:383
int asn1_compare(const struct asn1_cursor *cursor1, const struct asn1_cursor *cursor2)
Compare two ASN.1 objects.
Definition: asn1.c:447
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition: tables.h:385
u16 algorithm
Authentication algorithm (Open System or Shared Key)
Definition: ieee80211.h:1030
#define ASN1_ALGORITHMS
ASN.1 OID-identified algorithms.
Definition: asn1.h:408
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

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 483 of file asn1.c.

485  {
486  struct asn1_cursor contents;
487  int rc;
488 
489  /* Enter algorithm */
490  memcpy ( &contents, cursor, sizeof ( contents ) );
491  asn1_enter ( &contents, ASN1_SEQUENCE );
492 
493  /* Get raw parameters, if applicable */
494  if ( params ) {
495  memcpy ( params, &contents, sizeof ( *params ) );
496  asn1_skip_any ( params );
497  }
498 
499  /* Enter algorithm identifier */
500  if ( ( rc = asn1_enter ( &contents, ASN1_OID ) ) != 0 ) {
501  DBGC ( cursor, "ASN1 %p cannot locate algorithm OID:\n",
502  cursor );
503  DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
504  return -EINVAL_ASN1_ALGORITHM;
505  }
506 
507  /* Identify algorithm */
508  *algorithm = asn1_find_algorithm ( &contents );
509  if ( ! *algorithm ) {
510  DBGC ( cursor, "ASN1 %p unrecognised algorithm:\n", cursor );
511  DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
512  return -ENOTSUP_ALGORITHM;
513  }
514 
515  /* Parse parameters, if applicable */
516  if ( params && (*algorithm)->parse &&
517  ( ( rc = (*algorithm)->parse ( *algorithm, params ) ) != 0 ) ) {
518  DBGC ( cursor, "ASN1 %p cannot parse %s parameters: %s\n",
519  cursor, (*algorithm)->name, strerror ( rc ) );
520  return rc;
521  }
522 
523  return 0;
524 }
#define EINVAL_ASN1_ALGORITHM
Definition: asn1.c:69
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
int asn1_enter(struct asn1_cursor *cursor, unsigned int type)
Enter ASN.1 object.
Definition: asn1.c:181
const void * data
Start of data.
Definition: asn1.h:22
#define DBGC(...)
Definition: compiler.h:505
int asn1_skip_any(struct asn1_cursor *cursor)
Skip ASN.1 object of any type.
Definition: asn1.c:302
size_t len
Length of data.
Definition: asn1.h:24
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define DBGC_HDA(...)
Definition: compiler.h:506
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
#define ASN1_SEQUENCE
ASN.1 sequence.
Definition: asn1.h:89
u16 algorithm
Authentication algorithm (Open System or Shared Key)
Definition: ieee80211.h:1030
static struct asn1_algorithm * asn1_find_algorithm(const struct asn1_cursor *cursor)
Identify ASN.1 algorithm by OID.
Definition: asn1.c:464
#define ASN1_OID
ASN.1 object identifier.
Definition: asn1.h:74
#define ENOTSUP_ALGORITHM
Definition: asn1.c:77
An ASN.1 object cursor.
Definition: asn1.h:20

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 533 of file asn1.c.

534  {
535  int rc;
536 
537  /* Parse algorithm */
538  if ( ( rc = asn1_algorithm ( cursor, algorithm, NULL ) ) != 0 )
539  return rc;
540 
541  /* Check algorithm has a public key */
542  if ( ! (*algorithm)->pubkey ) {
543  DBGC ( cursor, "ASN1 %p algorithm %s is not a public-key "
544  "algorithm:\n", cursor, (*algorithm)->name );
545  DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
546  return -ENOTTY_ALGORITHM;
547  }
548 
549  return 0;
550 }
An ASN.1 OID-identified algorithm.
Definition: asn1.h:383
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define ENOTTY_ALGORITHM
Definition: asn1.c:81
const void * data
Start of data.
Definition: asn1.h:22
#define DBGC(...)
Definition: compiler.h:505
size_t len
Length of data.
Definition: asn1.h:24
#define DBGC_HDA(...)
Definition: compiler.h:506
u16 algorithm
Authentication algorithm (Open System or Shared Key)
Definition: ieee80211.h:1030
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

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 559 of file asn1.c.

560  {
561  int rc;
562 
563  /* Parse algorithm */
564  if ( ( rc = asn1_algorithm ( cursor, algorithm, NULL ) ) != 0 )
565  return rc;
566 
567  /* Check algorithm has a digest */
568  if ( ! (*algorithm)->digest ) {
569  DBGC ( cursor, "ASN1 %p algorithm %s is not a digest "
570  "algorithm:\n", cursor, (*algorithm)->name );
571  DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
572  return -ENOTTY_ALGORITHM;
573  }
574 
575  return 0;
576 }
An ASN.1 OID-identified algorithm.
Definition: asn1.h:383
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define ENOTTY_ALGORITHM
Definition: asn1.c:81
const void * data
Start of data.
Definition: asn1.h:22
#define DBGC(...)
Definition: compiler.h:505
size_t len
Length of data.
Definition: asn1.h:24
#define DBGC_HDA(...)
Definition: compiler.h:506
u16 algorithm
Authentication algorithm (Open System or Shared Key)
Definition: ieee80211.h:1030
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

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 586 of file asn1.c.

588  {
589  int rc;
590 
591  /* Parse algorithm */
592  if ( ( rc = asn1_algorithm ( cursor, algorithm, params ) ) != 0 )
593  return rc;
594 
595  /* Check algorithm has a cipher */
596  if ( ! (*algorithm)->cipher ) {
597  DBGC ( cursor, "ASN1 %p algorithm %s is not a cipher "
598  "algorithm:\n", cursor, (*algorithm)->name );
599  DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
600  return -ENOTTY_ALGORITHM;
601  }
602 
603  return 0;
604 }
An ASN.1 OID-identified algorithm.
Definition: asn1.h:383
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define ENOTTY_ALGORITHM
Definition: asn1.c:81
const void * data
Start of data.
Definition: asn1.h:22
#define DBGC(...)
Definition: compiler.h:505
size_t len
Length of data.
Definition: asn1.h:24
#define DBGC_HDA(...)
Definition: compiler.h:506
u16 algorithm
Authentication algorithm (Open System or Shared Key)
Definition: ieee80211.h:1030

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 613 of file asn1.c.

614  {
615  int rc;
616 
617  /* Parse algorithm */
618  if ( ( rc = asn1_algorithm ( cursor, algorithm, NULL ) ) != 0 )
619  return rc;
620 
621  /* Check algorithm has a public key */
622  if ( ! (*algorithm)->pubkey ) {
623  DBGC ( cursor, "ASN1 %p algorithm %s is not a signature "
624  "algorithm:\n", cursor, (*algorithm)->name );
625  DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
626  return -ENOTTY_ALGORITHM;
627  }
628 
629  /* Check algorithm has a digest */
630  if ( ! (*algorithm)->digest ) {
631  DBGC ( cursor, "ASN1 %p algorithm %s is not a signature "
632  "algorithm:\n", cursor, (*algorithm)->name );
633  DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
634  return -ENOTTY_ALGORITHM;
635  }
636 
637  return 0;
638 }
An ASN.1 OID-identified algorithm.
Definition: asn1.h:383
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define ENOTTY_ALGORITHM
Definition: asn1.c:81
const void * data
Start of data.
Definition: asn1.h:22
#define DBGC(...)
Definition: compiler.h:505
size_t len
Length of data.
Definition: asn1.h:24
#define DBGC_HDA(...)
Definition: compiler.h:506
u16 algorithm
Authentication algorithm (Open System or Shared Key)
Definition: ieee80211.h:1030
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

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 **  algorithm 
)

Parse ASN.1 OID-identified elliptic curve algorithm.

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

Definition at line 647 of file asn1.c.

648  {
649  struct asn1_cursor curve;
650 
651  /* Elliptic curves are identified as either:
652  *
653  * - the algorithm "id-ecPublicKey" with the actual curve
654  * specified in the algorithm parameters, or
655  *
656  * - a standalone object identifier for the curve
657  */
658  if ( asn1_check_algorithm ( cursor, &ecpubkey_algorithm,
659  &curve ) != 0 ) {
660  memcpy ( &curve, cursor, sizeof ( curve ) );
661  }
662 
663  /* Identify curve */
664  asn1_enter ( &curve, ASN1_OID );
665  *algorithm = asn1_find_algorithm ( &curve );
666  if ( ! *algorithm ) {
667  DBGC ( cursor, "ASN1 %p unrecognised EC algorithm:\n",
668  cursor );
669  DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
670  return -ENOTSUP_ALGORITHM;
671  }
672 
673  /* Check algorithm has an elliptic curve */
674  if ( ! (*algorithm)->curve ) {
675  DBGC ( cursor, "ASN1 %p algorithm %s is not an elliptic curve "
676  "algorithm:\n", cursor, (*algorithm)->name );
677  DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
678  return -ENOTTY_ALGORITHM;
679  }
680 
681  return 0;
682 }
#define ENOTTY_ALGORITHM
Definition: asn1.c:81
int asn1_enter(struct asn1_cursor *cursor, unsigned int type)
Enter ASN.1 object.
Definition: asn1.c:181
const void * data
Start of data.
Definition: asn1.h:22
#define DBGC(...)
Definition: compiler.h:505
size_t len
Length of data.
Definition: asn1.h:24
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define DBGC_HDA(...)
Definition: compiler.h:506
u16 algorithm
Authentication algorithm (Open System or Shared Key)
Definition: ieee80211.h:1030
static struct asn1_algorithm * asn1_find_algorithm(const struct asn1_cursor *cursor)
Identify ASN.1 algorithm by OID.
Definition: asn1.c:464
#define ASN1_OID
ASN.1 object identifier.
Definition: asn1.h:74
#define ENOTSUP_ALGORITHM
Definition: asn1.c:77
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:692
An ASN.1 object cursor.
Definition: asn1.h:20

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, and memcpy().

◆ 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 692 of file asn1.c.

694  {
695  struct asn1_algorithm *actual;
696  int rc;
697 
698  /* Parse algorithm */
699  if ( ( rc = asn1_algorithm ( cursor, &actual, params ) ) != 0 )
700  return rc;
701 
702  /* Check algorithm matches */
703  if ( actual != expected ) {
704  DBGC ( cursor, "ASN1 %p algorithm %s does not match %s\n",
705  cursor, actual->name, expected->name );
706  return -ENOTTY_ALGORITHM;
707  }
708 
709  return 0;
710 }
An ASN.1 OID-identified algorithm.
Definition: asn1.h:383
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define ENOTTY_ALGORITHM
Definition: asn1.c:81
#define DBGC(...)
Definition: compiler.h:505
const char * name
Name.
Definition: asn1.h:385

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 719 of file asn1.c.

720  {
721  struct cipher_algorithm *cipher = algorithm->cipher;
722 
723  /* Sanity check */
724  assert ( cipher != NULL );
725 
726  /* Enter parameters */
727  asn1_enter ( params, ASN1_OCTET_STRING );
728 
729  /* Check length */
730  if ( params->len != cipher->blocksize )
731  return -EINVAL;
732 
733  return 0;
734 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
size_t blocksize
Block size.
Definition: crypto.h:60
int asn1_enter(struct asn1_cursor *cursor, unsigned int type)
Enter ASN.1 object.
Definition: asn1.c:181
size_t len
Length of data.
Definition: asn1.h:24
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
u16 algorithm
Authentication algorithm (Open System or Shared Key)
Definition: ieee80211.h:1030
A cipher algorithm.
Definition: crypto.h:50
#define ASN1_OCTET_STRING
ASN.1 octet string.
Definition: asn1.h:68
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

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 743 of file asn1.c.

744  {
745 
746  /* Enter parameters */
747  asn1_enter ( params, ASN1_SEQUENCE );
748 
749  /* Enter nonce */
750  return asn1_enter ( params, ASN1_OCTET_STRING );
751 }
int asn1_enter(struct asn1_cursor *cursor, unsigned int type)
Enter ASN.1 object.
Definition: asn1.c:181
#define ASN1_SEQUENCE
ASN.1 sequence.
Definition: asn1.h:89
#define ASN1_OCTET_STRING
ASN.1 octet string.
Definition: asn1.h:68

References 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 764 of file asn1.c.

764  {
765  struct asn1_cursor contents;
766  unsigned int have_century;
767  unsigned int type;
768  union {
769  struct {
771  uint8_t year;
772  uint8_t month;
773  uint8_t day;
774  uint8_t hour;
775  uint8_t minute;
776  uint8_t second;
777  } __attribute__ (( packed )) named;
778  uint8_t raw[7];
779  } pairs;
780  struct tm tm;
781  const uint8_t *data;
782  size_t remaining;
783  unsigned int tens;
784  unsigned int units;
785  unsigned int i;
786  int rc;
787 
788  /* Determine time format utcTime/generalizedTime */
789  memcpy ( &contents, cursor, sizeof ( contents ) );
790  type = asn1_type ( &contents );
791  switch ( type ) {
792  case ASN1_UTC_TIME:
793  have_century = 0;
794  break;
796  have_century = 1;
797  break;
798  default:
799  DBGC ( cursor, "ASN1 %p invalid time type %02x\n",
800  cursor, type );
801  DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
802  return -EINVAL_ASN1_TIME;
803  }
804 
805  /* Enter utcTime/generalizedTime */
806  if ( ( rc = asn1_enter ( &contents, type ) ) != 0 ) {
807  DBGC ( cursor, "ASN1 %p cannot locate %s time:\n", cursor,
808  ( ( type == ASN1_UTC_TIME ) ? "UTC" : "generalized" ) );
809  DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
810  return rc;
811  }
812 
813  /* Parse digit string a pair at a time */
814  memset ( &pairs, 0, sizeof ( pairs ) );
815  data = contents.data;
816  remaining = contents.len;
817  for ( i = ( have_century ? 0 : 1 ) ; i < sizeof ( pairs.raw ) ; i++ ) {
818  if ( remaining < 2 ) {
819  /* Some certificates violate the X.509 RFC by
820  * omitting the "seconds" value.
821  */
822  if ( i == ( sizeof ( pairs.raw ) - 1 ) )
823  break;
824  DBGC ( cursor, "ASN1 %p invalid time:\n", cursor );
825  DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
826  return -EINVAL_ASN1_TIME;
827  }
828  tens = data[0];
829  units = data[1];
830  if ( ! ( isdigit ( tens ) && isdigit ( units ) ) ) {
831  DBGC ( cursor, "ASN1 %p invalid time:\n", cursor );
832  DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
833  return -EINVAL_ASN1_TIME;
834  }
835  pairs.raw[i] = ( ( 10 * ( tens - '0' ) ) + ( units - '0' ) );
836  data += 2;
837  remaining -= 2;
838  }
839 
840  /* Determine century if applicable */
841  if ( ! have_century )
842  pairs.named.century = ( ( pairs.named.year >= 50 ) ? 19 : 20 );
843 
844  /* Check for trailing "Z" */
845  if ( ( remaining != 1 ) || ( data[0] != 'Z' ) ) {
846  DBGC ( cursor, "ASN1 %p invalid time:\n", cursor );
847  DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
848  return -EINVAL_ASN1_TIME;
849  }
850 
851  /* Fill in time */
852  tm.tm_year = ( ( ( pairs.named.century - 19 ) * 100 ) +
853  pairs.named.year );
854  tm.tm_mon = ( pairs.named.month - 1 );
855  tm.tm_mday = pairs.named.day;
856  tm.tm_hour = pairs.named.hour;
857  tm.tm_min = pairs.named.minute;
858  tm.tm_sec = pairs.named.second;
859 
860  /* Convert to seconds since the Epoch */
861  *time = mktime ( &tm );
862 
863  return 0;
864 }
#define __attribute__(x)
Definition: compiler.h:10
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
int tm_min
Minutes [0,59].
Definition: time.h:19
#define EINVAL_ASN1_TIME
Definition: asn1.c:65
int asn1_enter(struct asn1_cursor *cursor, unsigned int type)
Enter ASN.1 object.
Definition: asn1.c:181
uint32_t type
Operating system type.
Definition: ena.h:12
int tm_mday
Day of month [1,31].
Definition: time.h:23
const void * data
Start of data.
Definition: asn1.h:22
#define DBGC(...)
Definition: compiler.h:505
uint8_t year
Year (BCD)
Definition: ucode.h:12
int tm_year
Years since 1900.
Definition: time.h:27
static unsigned int asn1_type(const struct asn1_cursor *cursor)
Extract ASN.1 type.
Definition: asn1.h:454
size_t len
Length of data.
Definition: asn1.h:24
static int isdigit(int character)
Check if character is a decimal digit.
Definition: ctype.h:29
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define DBGC_HDA(...)
Definition: compiler.h:506
int tm_mon
Month of year [0,11].
Definition: time.h:25
time_t mktime(struct tm *tm)
Calculate seconds since the Epoch.
Definition: time.c:117
#define ASN1_GENERALIZED_TIME
ASN.1 generalized time.
Definition: asn1.h:86
unsigned char uint8_t
Definition: stdint.h:10
Broken-down time.
Definition: time.h:15
uint8_t century
Century (BCD)
Definition: ucode.h:14
uint8_t data[48]
Additional event data.
Definition: ena.h:22
uint8_t day
Day (BCD)
Definition: ucode.h:16
int tm_sec
Seconds [0,60].
Definition: time.h:17
__be32 raw[7]
Definition: CIB_PRM.h:28
#define ASN1_UTC_TIME
ASN.1 UTC time.
Definition: asn1.h:83
int tm_hour
Hour [0,23].
Definition: time.h:21
uint8_t month
Month (BCD)
Definition: ucode.h:18
An ASN.1 object cursor.
Definition: asn1.h:20
void * memset(void *dest, int character, size_t len) __nonnull

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()

static 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 874 of file asn1.c.

875  {
876  unsigned int header_len = 2;
877  unsigned int len_len = 0;
878  size_t temp;
879 
880  /* Construct header */
881  header->type = type;
882  if ( len < 0x80 ) {
883  header->length[0] = len;
884  } else {
885  for ( temp = len ; temp ; temp >>= 8 )
886  len_len++;
887  header->length[0] = ( 0x80 | len_len );
888  header_len += len_len;
889  for ( temp = len ; temp ; temp >>= 8 )
890  header->length[len_len--] = ( temp & 0xff );
891  }
892 
893  return header_len;
894 }
uint32_t type
Operating system type.
Definition: ena.h:12
ring len
Length.
Definition: dwmac.h:231
struct ena_llq_option header
Header locations.
Definition: ena.h:16

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 903 of file asn1.c.

903  {
904  size_t new_len;
905  void *new;
906 
907  /* As with the ASN1 parsing functions, make errors permanent */
908  if ( builder->len && ! builder->data )
909  return -ENOMEM;
910 
911  /* Reallocate data buffer */
912  new_len = ( builder->len + extra );
913  new = realloc ( builder->data, new_len );
914  if ( ! new ) {
915  free ( builder->data );
916  builder->data = NULL;
917  return -ENOMEM;
918  }
919  builder->data = new;
920 
921  /* Move existing data to end of buffer */
922  memmove ( ( builder->data + extra ), builder->data, builder->len );
923  builder->len = new_len;
924 
925  return 0;
926 }
void * data
Data.
Definition: asn1.h:35
uint8_t extra
Signature extra byte.
Definition: smbios.h:17
#define ENOMEM
Not enough space.
Definition: errno.h:534
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
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:606
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
size_t len
Length of data.
Definition: asn1.h:37

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 936 of file asn1.c.

937  {
938  int rc;
939 
940  /* Grow buffer */
941  if ( ( rc = asn1_grow ( builder, len ) ) != 0 )
942  return rc;
943 
944  /* Populate data buffer */
945  memcpy ( builder->data, data, len );
946 
947  return 0;
948 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void * data
Data.
Definition: asn1.h:35
void * memcpy(void *dest, const void *src, size_t len) __nonnull
ring len
Length.
Definition: dwmac.h:231
int asn1_grow(struct asn1_builder *builder, size_t extra)
Grow ASN.1 builder.
Definition: asn1.c:903
uint8_t data[48]
Additional event data.
Definition: ena.h:22

References asn1_grow(), data, asn1_builder::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 959 of file asn1.c.

960  {
962  size_t header_len;
963  int rc;
964 
965  /* Construct header */
966  header_len = asn1_header ( &header, type, len );
967 
968  /* Grow buffer */
969  if ( ( rc = asn1_grow ( builder, header_len + len ) ) != 0 )
970  return rc;
971 
972  /* Populate data buffer */
973  memcpy ( builder->data, &header, header_len );
974  memcpy ( ( builder->data + header_len ), data, len );
975 
976  return 0;
977 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void * data
Data.
Definition: asn1.h:35
uint32_t type
Operating system type.
Definition: ena.h:12
void * memcpy(void *dest, const void *src, size_t len) __nonnull
ring len
Length.
Definition: dwmac.h:231
int asn1_grow(struct asn1_builder *builder, size_t extra)
Grow ASN.1 builder.
Definition: asn1.c:903
static size_t asn1_header(struct asn1_builder_header *header, unsigned int type, size_t len)
Construct ASN.1 header.
Definition: asn1.c:874
An ASN.1 header.
Definition: asn1.h:48
struct ena_llq_option header
Header locations.
Definition: ena.h:16
uint8_t data[48]
Additional event data.
Definition: ena.h:22

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

Referenced by 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 986 of file asn1.c.

986  {
988  size_t header_len;
989  int rc;
990 
991  /* Construct header */
992  header_len = asn1_header ( &header, type, builder->len );
993 
994  /* Grow buffer */
995  if ( ( rc = asn1_grow ( builder, header_len ) ) != 0 )
996  return rc;
997 
998  /* Populate data buffer */
999  memcpy ( builder->data, &header, header_len );
1000 
1001  return 0;
1002 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void * data
Data.
Definition: asn1.h:35
uint32_t type
Operating system type.
Definition: ena.h:12
void * memcpy(void *dest, const void *src, size_t len) __nonnull
int asn1_grow(struct asn1_builder *builder, size_t extra)
Grow ASN.1 builder.
Definition: asn1.c:903
static size_t asn1_header(struct asn1_builder_header *header, unsigned int type, size_t len)
Construct ASN.1 header.
Definition: asn1.c:874
An ASN.1 header.
Definition: asn1.h:48
struct ena_llq_option header
Header locations.
Definition: ena.h:16
size_t len
Length of data.
Definition: asn1.h:37

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

Referenced by 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 1015 of file asn1.c.

1016  {
1017  int next;
1018  int rc;
1019 
1020  /* Sanity check */
1021  assert ( offset <= image->len );
1022 
1023  /* Check that this image can be used to extract an ASN.1 object */
1024  if ( ! ( image->type && image->type->asn1 ) )
1025  return -ENOTSUP;
1026 
1027  /* Try creating ASN.1 cursor */
1028  next = image->type->asn1 ( image, offset, cursor );
1029  if ( next < 0 ) {
1030  rc = next;
1031  DBGC ( image, "IMAGE %s could not extract ASN.1 object: %s\n",
1032  image->name, strerror ( rc ) );
1033  return rc;
1034  }
1035 
1036  return next;
1037 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct image_type * type
Image type, if known.
Definition: image.h:58
#define DBGC(...)
Definition: compiler.h:505
An executable image.
Definition: image.h:23
#define ENOTSUP
Operation not supported.
Definition: errno.h:589
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
ring len
Length.
Definition: dwmac.h:231
int(* asn1)(struct image *image, size_t offset, struct asn1_cursor **cursor)
Extract ASN.1 object from image.
Definition: image.h:132
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
uint32_t next
Next descriptor address.
Definition: dwmac.h:22
uint16_t offset
Offset to command line.
Definition: bzimage.h:8
char * name
Name.
Definition: image.h:37

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

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

◆ REQUIRING_SYMBOL()

REQUIRING_SYMBOL ( image_asn1  )

◆ REQUIRE_OBJECT()

REQUIRE_OBJECT ( config_asn1  )

Variable Documentation

◆ oid_ecpublickey

uint8_t oid_ecpublickey[] = { ASN1_OID_ECPUBLICKEY }
static

"ecPublicKey" object identifier

Definition at line 87 of file asn1.c.

◆ __asn1_algorithm

struct asn1_algorithm ecpubkey_algorithm __asn1_algorithm
Initial value:
= {
.name = "ecPublicKey",
}
#define ASN1_CURSOR(value)
Define an ASN.1 cursor for a static value.
Definition: asn1.h:377
static uint8_t oid_ecpublickey[]
"ecPublicKey" object identifier
Definition: asn1.c:87

Generic elliptic curve container algorithm.

The actual curve to be used is identified via the algorithm parameters, rather than the top-level OID.

Definition at line 94 of file asn1.c.