iPXE
der.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2016 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  * You can also choose to distribute this program under the terms of
20  * the Unmodified Binary Distribution Licence (as given in the file
21  * COPYING.UBDL), provided that you have satisfied its requirements.
22  */
23 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 
26 #include <stdlib.h>
27 #include <errno.h>
28 #include <assert.h>
29 #include <ipxe/asn1.h>
30 #include <ipxe/der.h>
31 #include <ipxe/uaccess.h>
32 #include <ipxe/image.h>
33 
34 /** @file
35  *
36  * DER-encoded ASN.1 data
37  *
38  */
39 
40 /**
41  * Extract ASN.1 object from image
42  *
43  * @v image DER image
44  * @v offset Offset within image
45  * @v cursor ASN.1 cursor to fill in
46  * @ret next Offset to next image, or negative error
47  *
48  * The caller is responsible for eventually calling free() on the
49  * allocated ASN.1 cursor.
50  */
51 static int der_asn1 ( struct image *image, size_t offset __unused,
52  struct asn1_cursor **cursor ) {
53  void *data;
54 
55  /* Allocate cursor and data buffer */
56  *cursor = malloc ( sizeof ( **cursor ) + image->len );
57  if ( ! *cursor )
58  return -ENOMEM;
59  data = ( ( ( void * ) *cursor ) + sizeof ( **cursor ) );
60 
61  /* Populate cursor and data buffer */
62  (*cursor)->data = data;
63  (*cursor)->len = image->len;
65 
66  return image->len;
67 }
68 
69 /**
70  * Probe DER image
71  *
72  * @v image DER image
73  * @ret rc Return status code
74  */
75 static int der_probe ( struct image *image ) {
76  struct asn1_cursor cursor;
77  uint8_t buf[8];
78  size_t extra;
79  size_t total;
80  int len;
81  int rc;
82 
83  /* Sanity check: no realistic DER image can be smaller than this */
84  if ( image->len < sizeof ( buf ) )
85  return -ENOEXEC;
86 
87  /* Prepare partial cursor */
88  cursor.data = buf;
89  cursor.len = sizeof ( buf );
90  copy_from_user ( buf, image->data, 0, sizeof ( buf ) );
91  extra = ( image->len - sizeof ( buf ) );
92 
93  /* Get length of ASN.1 sequence */
94  len = asn1_start ( &cursor, ASN1_SEQUENCE, extra );
95  if ( len < 0 ) {
96  rc = len;
97  DBGC ( image, "DER %s is not valid ASN.1: %s\n",
98  image->name, strerror ( rc ) );
99  return rc;
100  }
101 
102  /* Add length of tag and length bytes consumed by asn1_start() */
103  total = ( len + ( cursor.data - ( ( void * ) buf ) ) );
104  assert ( total <= image->len );
105 
106  /* Check that image comprises a single well-formed ASN.1 object */
107  if ( total != image->len ) {
108  DBGC ( image, "DER %s is not single ASN.1\n", image->name );
109  return -ENOEXEC;
110  }
111 
112  return 0;
113 }
114 
115 /** DER image type */
116 struct image_type der_image_type __image_type ( PROBE_NORMAL ) = {
117  .name = "DER",
118  .probe = der_probe,
119  .asn1 = der_asn1,
120 };
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
userptr_t data
Raw file image.
Definition: image.h:41
static int der_asn1(struct image *image, size_t offset __unused, struct asn1_cursor **cursor)
Extract ASN.1 object from image.
Definition: der.c:51
Error codes.
#define ENOEXEC
Exec format error.
Definition: errno.h:519
static __always_inline void copy_from_user(void *dest, userptr_t src, off_t src_off, size_t len)
Copy data from user buffer.
Definition: uaccess.h:337
const void * data
Start of data.
Definition: asn1.h:21
#define DBGC(...)
Definition: compiler.h:505
An executable image type.
Definition: image.h:76
#define PROBE_NORMAL
Normal image probe priority.
Definition: image.h:129
An executable image.
Definition: image.h:24
struct image_type der_image_type __image_type(PROBE_NORMAL)
DER image type.
int asn1_start(struct asn1_cursor *cursor, unsigned int type, size_t extra)
Start parsing ASN.1 object.
Definition: asn1.c:98
Access to external ("user") memory.
char * name
Name of this image type.
Definition: image.h:78
size_t len
Length of data.
Definition: asn1.h:23
#define ENOMEM
Not enough space.
Definition: errno.h:534
Assertions.
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
Executable images.
ASN.1 encoding.
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
size_t len
Length of raw file image.
Definition: image.h:43
unsigned char uint8_t
Definition: stdint.h:10
DER image format.
#define ASN1_SEQUENCE
ASN.1 sequence.
Definition: asn1.h:85
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:583
static int der_probe(struct image *image)
Probe DER image.
Definition: der.c:75
#define __unused
Declare a variable or data structure as unused.
Definition: compiler.h:573
uint32_t len
Length.
Definition: ena.h:14
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
char * name
Name.
Definition: image.h:34
An ASN.1 object cursor.
Definition: asn1.h:19