iPXE
pem.c File Reference

PEM-encoded ASN.1 data. More...

#include <stdlib.h>
#include <errno.h>
#include <assert.h>
#include <ipxe/asn1.h>
#include <ipxe/base64.h>
#include <ipxe/image.h>
#include <ipxe/pem.h>

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 FILE_SECBOOT (PERMITTED)
static size_t pem_next (const void *data, size_t len, size_t offset)
 Locate next line.
static int pem_marker (const void *data, size_t len, size_t offset, const char *marker)
 Locate boundary marker line.
int pem_asn1 (const void *data, size_t len, size_t offset, struct asn1_cursor **cursor)
 Extract ASN.1 object from PEM data.
static int pem_image_probe (struct image *image)
 Probe PEM image.
static int pem_image_asn1 (struct image *image, size_t offset, struct asn1_cursor **cursor)
 Extract ASN.1 object from image.
struct image_type pem_image_type __image_type (PROBE_NORMAL)
 PEM image type.

Detailed Description

PEM-encoded ASN.1 data.

Definition in file pem.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED )

◆ pem_next()

size_t pem_next ( const void * data,
size_t len,
size_t offset )
static

Locate next line.

Parameters
dataPEM data
lenLength of PEM data
offsetStarting offset
Return values
nextOffset to next line

Definition at line 49 of file pem.c.

49 {
50 const void *sep;
51
52 /* Find and skip next newline character, if any */
53 sep = memchr ( ( data + offset ), '\n', ( len - offset ) );
54 if ( ! sep )
55 return len;
56 return ( ( sep - data ) + 1 );
57}
uint16_t offset
Offset to command line.
Definition bzimage.h:3
ring len
Length.
Definition dwmac.h:226
uint8_t data[48]
Additional event data.
Definition ena.h:11
void * memchr(const void *src, int character, size_t len)
Find character within a memory region.
Definition string.c:136

References data, len, memchr(), and offset.

Referenced by pem_asn1(), and pem_marker().

◆ pem_marker()

int pem_marker ( const void * data,
size_t len,
size_t offset,
const char * marker )
static

Locate boundary marker line.

Parameters
dataPEM data
lenLength of PEM data
offsetStarting offset
markerBoundary marker
Return values
offsetOffset to boundary marker line, or negative error

Definition at line 68 of file pem.c.

69 {
70 size_t marker_len = strlen ( marker );
71
72 /* Sanity check */
73 assert ( offset <= len );
74
75 /* Scan for marker at start of line */
76 while ( offset < len ) {
77
78 /* Check for marker */
79 if ( ( len - offset ) < marker_len )
80 break;
81 if ( memcmp ( ( data + offset ), marker, marker_len ) == 0 )
82 return offset;
83
84 /* Move to next line */
86 assert ( offset <= len );
87 }
88
89 return -ENOENT;
90}
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
struct eth_slow_marker_tlv marker
Marker information.
Definition eth_slow.h:3
#define ENOENT
No such file or directory.
Definition errno.h:515
static size_t pem_next(const void *data, size_t len, size_t offset)
Locate next line.
Definition pem.c:49
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition string.c:115
size_t strlen(const char *src)
Get length of string.
Definition string.c:244

References assert, data, ENOENT, len, marker, memcmp(), offset, pem_next(), and strlen().

Referenced by pem_asn1(), and pem_image_probe().

◆ pem_asn1()

int pem_asn1 ( const void * data,
size_t len,
size_t offset,
struct asn1_cursor ** cursor )

Extract ASN.1 object from PEM data.

Parameters
dataPEM data
lenLength of PEM data
offsetOffset within data
cursorASN.1 cursor to fill in
Return values
nextOffset to next object, or negative error

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

Definition at line 104 of file pem.c.

105 {
106 size_t encoded_len;
107 size_t decoded_max_len;
108 char *encoded;
109 void *decoded;
110 int decoded_len;
111 int begin;
112 int end;
113 int rc;
114
115 /* Locate and skip BEGIN marker */
116 begin = pem_marker ( data, len, offset, PEM_BEGIN );
117 if ( begin < 0 ) {
118 rc = begin;
119 DBGC ( data, "PEM [%#zx,%#zx) missing BEGIN marker: %s\n",
120 offset, len, strerror ( rc ) );
121 goto err_begin;
122 }
123 begin = pem_next ( data, len, begin );
124
125 /* Locate and skip END marker */
126 end = pem_marker ( data, len, begin, PEM_END );
127 if ( end < 0 ) {
128 rc = end;
129 DBGC ( data, "PEM [%#zx,%#zx) missing END marker: %s\n",
130 offset, len, strerror ( rc ) );
131 goto err_end;
132 }
133 encoded_len = ( end - begin );
134 end = pem_next ( data, len, end );
135
136 /* Extract Base64-encoded data */
137 encoded = malloc ( encoded_len + 1 /* NUL */ );
138 if ( ! encoded ) {
139 rc = -ENOMEM;
140 goto err_alloc_encoded;
141 }
142 memcpy ( encoded, ( data + begin ), encoded_len );
143 encoded[encoded_len] = '\0';
144
145 /* Allocate cursor and data buffer */
146 decoded_max_len = base64_decoded_max_len ( encoded );
147 *cursor = malloc ( sizeof ( **cursor ) + decoded_max_len );
148 if ( ! *cursor ) {
149 rc = -ENOMEM;
150 goto err_alloc_cursor;
151 }
152 decoded = ( ( ( void * ) *cursor ) + sizeof ( **cursor ) );
153
154 /* Decode Base64-encoded data */
155 decoded_len = base64_decode ( encoded, decoded, decoded_max_len );
156 if ( decoded_len < 0 ) {
157 rc = decoded_len;
158 DBGC ( data, "PEM could not decode: %s\n", strerror ( rc ) );
159 goto err_decode;
160 }
161 (*cursor)->data = decoded;
162 (*cursor)->len = decoded_len;
163 assert ( (*cursor)->len <= decoded_max_len );
164
165 /* Free Base64-encoded data */
166 free ( encoded );
167
168 /* Update offset and skip any unencapsulated trailer */
169 offset = end;
170 if ( pem_marker ( data, len, offset, PEM_BEGIN ) < 0 )
171 offset = len;
172
173 return offset;
174
175 err_decode:
176 free ( *cursor );
177 *cursor = NULL;
178 err_alloc_cursor:
179 free ( encoded );
180 err_alloc_encoded:
181 err_end:
182 err_begin:
183 return rc;
184}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
int base64_decode(const char *encoded, void *data, size_t len)
Base64-decode string.
Definition base64.c:92
static size_t base64_decoded_max_len(const char *encoded)
Calculate maximum length of base64-decoded string.
Definition base64.h:35
#define DBGC(...)
Definition compiler.h:505
#define ENOMEM
Not enough space.
Definition errno.h:535
void * memcpy(void *dest, const void *src, size_t len) __nonnull
void * malloc(size_t size)
Allocate memory.
Definition malloc.c:621
uint32_t end
Ending offset.
Definition netvsc.h:7
static int pem_marker(const void *data, size_t len, size_t offset, const char *marker)
Locate boundary marker line.
Definition pem.c:68
#define PEM_BEGIN
Pre-encapsulation boundary marker.
Definition pem.h:18
#define PEM_END
Post-encapsulation boundary marker.
Definition pem.h:21
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79

References assert, base64_decode(), base64_decoded_max_len(), data, DBGC, end, ENOMEM, free, len, malloc(), memcpy(), NULL, offset, PEM_BEGIN, PEM_END, pem_marker(), pem_next(), rc, and strerror().

Referenced by efisig_asn1(), ipair_rx_pubkey(), and pem_image_asn1().

◆ pem_image_probe()

int pem_image_probe ( struct image * image)
static

Probe PEM image.

Parameters
imagePEM image
Return values
rcReturn status code

Definition at line 192 of file pem.c.

192 {
193 int offset;
194 int rc;
195
196 /* Check that image contains a BEGIN marker */
197 if ( ( offset = pem_marker ( image->data, image->len, 0,
198 PEM_BEGIN ) ) < 0 ) {
199 rc = offset;
200 DBGC ( image, "PEM %s has no BEGIN marker: %s\n",
201 image->name, strerror ( rc ) );
202 return rc;
203 }
204
205 return 0;
206}
An executable image.
Definition image.h:24
const void * data
Read-only data.
Definition image.h:51
char * name
Name.
Definition image.h:38
size_t len
Length of raw file image.
Definition image.h:56

References image::data, DBGC, image::len, image::name, offset, PEM_BEGIN, pem_marker(), rc, and strerror().

Referenced by __image_type().

◆ pem_image_asn1()

int pem_image_asn1 ( struct image * image,
size_t offset,
struct asn1_cursor ** cursor )
static

Extract ASN.1 object from image.

Parameters
imagePEM image
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 219 of file pem.c.

220 {
221 int next;
222 int rc;
223
224 /* Extract ASN.1 object */
225 if ( ( next = pem_asn1 ( image->data, image->len, offset,
226 cursor ) ) < 0 ) {
227 rc = next;
228 DBGC ( image, "PEM %s could not extract ASN.1: %s\n",
229 image->name, strerror ( rc ) );
230 return rc;
231 }
232
233 return next;
234}
uint32_t next
Next descriptor address.
Definition dwmac.h:11
int pem_asn1(const void *data, size_t len, size_t offset, struct asn1_cursor **cursor)
Extract ASN.1 object from PEM data.
Definition pem.c:104

References image::data, DBGC, image::len, image::name, next, offset, pem_asn1(), rc, and strerror().

Referenced by __image_type().

◆ __image_type()

struct image_type pem_image_type __image_type ( PROBE_NORMAL )

PEM image type.

References __image_type, pem_image_asn1(), pem_image_probe(), and PROBE_NORMAL.