44 #define EINVAL_ASN1_EMPTY \ 45 __einfo_error ( EINFO_EINVAL_ASN1_EMPTY ) 46 #define EINFO_EINVAL_ASN1_EMPTY \ 47 __einfo_uniqify ( EINFO_EINVAL, 0x01, "Empty or underlength cursor" ) 48 #define EINVAL_ASN1_LEN_LEN \ 49 __einfo_error ( EINFO_EINVAL_ASN1_LEN_LEN ) 50 #define EINFO_EINVAL_ASN1_LEN_LEN \ 51 __einfo_uniqify ( EINFO_EINVAL, 0x02, "Length field overruns cursor" ) 52 #define EINVAL_ASN1_LEN \ 53 __einfo_error ( EINFO_EINVAL_ASN1_LEN ) 54 #define EINFO_EINVAL_ASN1_LEN \ 55 __einfo_uniqify ( EINFO_EINVAL, 0x03, "Field overruns cursor" ) 56 #define EINVAL_ASN1_BOOLEAN \ 57 __einfo_error ( EINFO_EINVAL_ASN1_BOOLEAN ) 58 #define EINFO_EINVAL_ASN1_BOOLEAN \ 59 __einfo_uniqify ( EINFO_EINVAL, 0x04, "Invalid boolean" ) 60 #define EINVAL_ASN1_INTEGER \ 61 __einfo_error ( EINFO_EINVAL_ASN1_INTEGER ) 62 #define EINFO_EINVAL_ASN1_INTEGER \ 63 __einfo_uniqify ( EINFO_EINVAL, 0x04, "Invalid integer" ) 64 #define EINVAL_ASN1_TIME \ 65 __einfo_error ( EINFO_EINVAL_ASN1_TIME ) 66 #define EINFO_EINVAL_ASN1_TIME \ 67 __einfo_uniqify ( EINFO_EINVAL, 0x05, "Invalid time" ) 68 #define EINVAL_ASN1_ALGORITHM \ 69 __einfo_error ( EINFO_EINVAL_ASN1_ALGORITHM ) 70 #define EINFO_EINVAL_ASN1_ALGORITHM \ 71 __einfo_uniqify ( EINFO_EINVAL, 0x06, "Invalid algorithm" ) 72 #define EINVAL_BIT_STRING \ 73 __einfo_error ( EINFO_EINVAL_BIT_STRING ) 74 #define EINFO_EINVAL_BIT_STRING \ 75 __einfo_uniqify ( EINFO_EINVAL, 0x07, "Invalid bit string" ) 76 #define ENOTSUP_ALGORITHM \ 77 __einfo_error ( EINFO_ENOTSUP_ALGORITHM ) 78 #define EINFO_ENOTSUP_ALGORITHM \ 79 __einfo_uniqify ( EINFO_ENOTSUP, 0x01, "Unsupported algorithm" ) 80 #define ENOTTY_ALGORITHM \ 81 __einfo_error ( EINFO_ENOTTY_ALGORITHM ) 82 #define EINFO_ENOTTY_ALGORITHM \ 83 __einfo_uniqify ( EINFO_ENOTTY, 0x01, "Inappropriate algorithm" ) 103 if ( cursor->
len < 2 ) {
105 DBGC ( cursor,
"ASN1 %p too short\n", cursor );
111 DBGC ( cursor,
"ASN1 %p type mismatch (expected %d, got %d)\n",
120 if ( len_len & 0x80 ) {
121 len_len = ( len_len & 0x7f );
127 if ( cursor->
len < len_len ) {
128 DBGC ( cursor,
"ASN1 %p bad length field length %d (max " 129 "%zd)\n", cursor, len_len, cursor->
len );
134 for (
len = 0 ; len_len ; len_len-- ) {
141 DBGC ( cursor,
"ASN1 %p bad length %d (max %zd)\n",
170 DBGC ( cursor,
"ASN1 %p entered object type %02x (len %x)\n",
196 DBGC ( cursor,
"ASN1 %p skipped object type %02x (len %x)\n",
199 if ( ! cursor->
len ) {
200 DBGC ( cursor,
"ASN1 %p reached end of object\n", cursor );
246 memcpy ( &temp, cursor,
sizeof ( temp ) );
303 memcpy ( &contents, cursor,
sizeof ( contents ) );
305 if ( contents.
len != sizeof ( *
boolean ) )
309 boolean = contents.
data;
310 return boolean->value;
326 memcpy ( &contents, cursor,
sizeof ( contents ) );
329 if ( contents.
len < 1 )
338 while ( contents.
len ) {
339 high_byte = ( (*value) >> ( 8 * (
sizeof ( *value ) - 1 ) ) );
340 if ( ( high_byte != 0x00 ) && ( high_byte != 0xff ) ) {
341 DBGC ( cursor,
"ASN1 %p integer overflow\n", cursor );
373 memcpy ( &contents, cursor,
sizeof ( contents ) );
375 DBGC ( cursor,
"ASN1 %p cannot locate bit string:\n", cursor );
381 if ( contents.
len < sizeof ( *bit_string ) ) {
382 DBGC ( cursor,
"ASN1 %p invalid bit string:\n", cursor );
386 bit_string = contents.
data;
388 unused = bit_string->unused;
389 unused_mask = ( 0xff >> ( 8 -
unused ) );
390 last = ( bit_string->data +
len - 1 );
393 ( ( *
last & unused_mask ) != 0 ) ) {
394 DBGC ( cursor,
"ASN1 %p invalid bit string:\n", cursor );
400 bits->data = &bit_string->data;
423 if (
bits->unused ) {
424 DBGC ( cursor,
"ASN1 %p invalid integral bit string:\n",
447 difference = ( cursor2->
len - cursor1->
len );
448 return ( difference ? difference :
484 memcpy ( &contents, cursor,
sizeof ( contents ) );
489 DBGC ( cursor,
"ASN1 %p cannot locate algorithm OID:\n",
498 DBGC ( cursor,
"ASN1 %p unrecognised algorithm:\n", cursor );
522 if ( ! (*algorithm)->pubkey ) {
523 DBGC ( cursor,
"ASN1 %p algorithm %s is not a public-key " 524 "algorithm:\n", cursor, (*algorithm)->name );
548 if ( ! (*algorithm)->digest ) {
549 DBGC ( cursor,
"ASN1 %p algorithm %s is not a digest " 550 "algorithm:\n", cursor, (*algorithm)->name );
574 if ( ! (*algorithm)->pubkey ) {
575 DBGC ( cursor,
"ASN1 %p algorithm %s is not a signature " 576 "algorithm:\n", cursor, (*algorithm)->name );
582 if ( ! (*algorithm)->digest ) {
583 DBGC ( cursor,
"ASN1 %p algorithm %s is not a signature " 584 "algorithm:\n", cursor, (*algorithm)->name );
605 unsigned int have_century;
628 memcpy ( &contents, cursor,
sizeof ( contents ) );
638 DBGC ( cursor,
"ASN1 %p invalid time type %02x\n",
646 DBGC ( cursor,
"ASN1 %p cannot locate %s time:\n", cursor,
653 memset ( &pairs, 0,
sizeof ( pairs ) );
655 remaining = contents.
len;
656 for ( i = ( have_century ? 0 : 1 ) ; i <
sizeof ( pairs.raw ) ; i++ ) {
657 if ( remaining < 2 ) {
661 if ( i == (
sizeof ( pairs.raw ) - 1 ) )
663 DBGC ( cursor,
"ASN1 %p invalid time:\n", cursor );
670 DBGC ( cursor,
"ASN1 %p invalid time:\n", cursor );
674 pairs.raw[i] = ( ( 10 * ( tens -
'0' ) ) + ( units -
'0' ) );
680 if ( ! have_century )
681 pairs.named.century = ( ( pairs.named.year >= 50 ) ? 19 : 20 );
684 if ( ( remaining != 1 ) || (
data[0] !=
'Z' ) ) {
685 DBGC ( cursor,
"ASN1 %p invalid time:\n", cursor );
691 tm.
tm_year = ( ( ( pairs.named.century - 19 ) * 100 ) +
693 tm.
tm_mon = ( pairs.named.month - 1 );
714 unsigned int type,
size_t len ) {
715 unsigned int header_len = 2;
716 unsigned int len_len = 0;
724 for ( temp =
len ; temp ; temp >>= 8 )
726 header->length[0] = ( 0x80 | len_len );
727 header_len += len_len;
728 for ( temp =
len ; temp ; temp >>= 8 )
729 header->length[len_len--] = ( temp & 0xff );
747 if ( builder->
len && ! builder->
data )
762 builder->
len = new_len;
799 const void *
data,
size_t len ) {
834 if ( (
rc =
asn1_grow ( builder, header_len ) ) != 0 )
870 DBGC (
image,
"IMAGE %s could not extract ASN.1 object: %s\n",
#define EINVAL_ASN1_ALGORITHM
An ASN.1 OID-identified algorithm.
struct arbelprm_rc_send_wqe rc
int tm_min
Minutes [0,59].
int asn1_compare(const struct asn1_cursor *cursor1, const struct asn1_cursor *cursor2)
Compare two ASN.1 objects.
#define EINVAL_BIT_STRING
#define EINVAL_ASN1_LEN_LEN
int asn1_enter(struct asn1_cursor *cursor, unsigned int type)
Enter ASN.1 object.
int asn1_generalized_time(const struct asn1_cursor *cursor, time_t *time)
Parse ASN.1 GeneralizedTime.
uint32_t next
Next descriptor address.
#define ASN1_BOOLEAN
ASN.1 boolean.
uint8_t extra
Signature extra byte.
struct image_type * type
Image type, if known.
static __always_inline int off_t userptr_t second
uint32_t type
Operating system type.
int tm_mday
Day of month [1,31].
int asn1_prepend_raw(struct asn1_builder *builder, const void *data, size_t len)
Prepend raw data to ASN.1 builder.
const void * data
Start of data.
int asn1_digest_algorithm(const struct asn1_cursor *cursor, struct asn1_algorithm **algorithm)
Parse ASN.1 OID-identified digest algorithm.
#define ENOENT
No such file or directory.
int image_asn1(struct image *image, size_t offset, struct asn1_cursor **cursor)
Extract ASN.1 object from image.
int tm_year
Years since 1900.
#define offsetof(type, field)
Get offset of a field within a structure.
static unsigned int asn1_type(const struct asn1_cursor *cursor)
Extract ASN.1 type.
int asn1_start(struct asn1_cursor *cursor, unsigned int type, size_t extra)
Start parsing ASN.1 object.
int asn1_skip_any(struct asn1_cursor *cursor)
Skip ASN.1 object of any type.
#define ASN1_ANY
ASN.1 "any tag" magic value.
int asn1_signature_algorithm(const struct asn1_cursor *cursor, struct asn1_algorithm **algorithm)
Parse ASN.1 OID-identified signature algorithm.
#define ENOTSUP
Operation not supported.
size_t len
Length of data.
static int isdigit(int character)
Check if character is a decimal digit.
#define ENOMEM
Not enough space.
int asn1_shrink(struct asn1_cursor *cursor, unsigned int type)
Shrink ASN.1 cursor to fit object.
void * memcpy(void *dest, const void *src, size_t len) __nonnull
int asn1_boolean(const struct asn1_cursor *cursor)
Parse value of ASN.1 boolean.
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
int tm_mon
Month of year [0,11].
#define EINVAL_ASN1_INTEGER
static userptr_t size_t offset
Offset of the first segment within the content.
int(* asn1)(struct image *image, size_t offset, struct asn1_cursor **cursor)
Extract ASN.1 object from image.
int asn1_bit_string(const struct asn1_cursor *cursor, struct asn1_bit_string *bits)
Parse ASN.1 bit string.
time_t mktime(struct tm *tm)
Calculate seconds since the Epoch.
#define ASN1_GENERALIZED_TIME
ASN.1 generalized time.
pseudo_bit_t value[0x00020]
int asn1_grow(struct asn1_builder *builder, size_t extra)
Grow ASN.1 builder.
int asn1_integral_bit_string(const struct asn1_cursor *cursor, struct asn1_bit_string *bits)
Parse ASN.1 bit string that must be an integral number of bytes.
REQUIRE_OBJECT(config_asn1)
char * strerror(int errno)
Retrieve string representation of error number.
static void(* free)(struct refcnt *refcnt))
static void asn1_invalidate_cursor(struct asn1_cursor *cursor)
Invalidate ASN.1 object cursor.
int asn1_pubkey_algorithm(const struct asn1_cursor *cursor, struct asn1_algorithm **algorithm)
Parse ASN.1 OID-identified public-key algorithm.
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
int asn1_enter_any(struct asn1_cursor *cursor)
Enter ASN.1 object of any type.
int asn1_shrink_any(struct asn1_cursor *cursor)
Shrink ASN.1 object of any type.
int asn1_wrap(struct asn1_builder *builder, unsigned int type)
Wrap ASN.1 builder.
uint32_t last
Length to read in last segment, or zero.
static size_t asn1_header(struct asn1_builder_header *header, unsigned int type, size_t len)
Construct ASN.1 header.
#define ASN1_SEQUENCE
ASN.1 sequence.
void * memmove(void *dest, const void *src, size_t len) __nonnull
#define ASN1_INTEGER
ASN.1 integer.
u16 algorithm
Authentication algorithm (Open System or Shared Key)
static struct asn1_algorithm * asn1_find_algorithm(const struct asn1_cursor *cursor)
Identify ASN.1 algorithm by OID.
#define ASN1_OID
ASN.1 object identifier.
#define ENXIO
No such device or address.
#define ASN1_ALGORITHMS
ASN.1 OID-identified algorithms.
REQUIRING_SYMBOL(image_asn1)
static volatile void * bits
int asn1_skip_if_exists(struct asn1_cursor *cursor, unsigned int type)
Skip ASN.1 object if present.
uint8_t unused[32]
Unused.
int asn1_integer(const struct asn1_cursor *cursor, int *value)
Parse value of ASN.1 integer.
int asn1_skip(struct asn1_cursor *cursor, unsigned int type)
Skip ASN.1 object.
#define ENOTSUP_ALGORITHM
int asn1_prepend(struct asn1_builder *builder, unsigned int type, const void *data, size_t len)
Prepend data to ASN.1 builder.
struct ena_aq_header header
Header.
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
uint32_t end
Ending offset.
uint8_t data[48]
Additional event data.
int tm_sec
Seconds [0,60].
void * realloc(void *old_ptr, size_t new_size)
Reallocate memory.
#define ASN1_UTC_TIME
ASN.1 UTC time.
#define EINVAL_ASN1_BOOLEAN
typeof(acpi_finder=acpi_find)
ACPI table finder.
int64_t time_t
Seconds since the Epoch.
uint64_t time
Current time.
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
#define NULL
NULL pointer (VOID *)
size_t len
Length of data.
#define EINVAL_ASN1_EMPTY
#define ASN1_BIT_STRING
ASN.1 bit string.
int asn1_algorithm(const struct asn1_cursor *cursor, struct asn1_algorithm **algorithm)
Parse ASN.1 OID-identified algorithm.
void * memset(void *dest, int character, size_t len) __nonnull