iPXE
Functions
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/uaccess.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)
 
static size_t pem_next (userptr_t data, size_t len, size_t offset)
 Locate next line. More...
 
static int pem_marker (userptr_t data, size_t len, size_t offset, const char *marker)
 Locate boundary marker line. More...
 
int pem_asn1 (userptr_t data, size_t len, size_t offset, struct asn1_cursor **cursor)
 Extract ASN.1 object from PEM data. More...
 
static int pem_image_probe (struct image *image)
 Probe PEM image. More...
 
static int pem_image_asn1 (struct image *image, size_t offset, struct asn1_cursor **cursor)
 Extract ASN.1 object from image. More...
 
struct image_type pem_image_type __image_type (PROBE_NORMAL)
 PEM image type. More...
 

Detailed Description

PEM-encoded ASN.1 data.

Definition in file pem.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ pem_next()

static size_t pem_next ( userptr_t  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  off_t eol;
51 
52  /* Find and skip next newline character, if any */
53  eol = memchr_user ( data, offset, '\n', ( len - offset ) );
54  if ( eol < 0 )
55  return len;
56  return ( eol + 1 );
57 }
off_t memchr_user(userptr_t userptr, off_t offset, int c, size_t len)
Find character in user buffer.
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
signed long off_t
Definition: stdint.h:8
uint32_t len
Length.
Definition: ena.h:14
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12

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

Referenced by pem_asn1(), and pem_marker().

◆ pem_marker()

static int pem_marker ( userptr_t  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  char buf[ 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 ) < sizeof ( buf ) )
80  break;
81  copy_from_user ( buf, data, offset, sizeof ( buf ) );
82  if ( memcmp ( buf, marker, sizeof ( buf ) ) == 0 )
83  return offset;
84 
85  /* Move to next line */
86  offset = pem_next ( data, len, offset );
87  assert ( offset <= len );
88  }
89 
90  return -ENOENT;
91 }
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
#define ENOENT
No such file or directory.
Definition: errno.h:514
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
size_t strlen(const char *src)
Get length of string.
Definition: string.c:213
static size_t pem_next(userptr_t data, size_t len, size_t offset)
Locate next line.
Definition: pem.c:49
uint32_t len
Length.
Definition: ena.h:14
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:98
struct eth_slow_marker_tlv marker
Marker information.
Definition: eth_slow.h:14

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

Referenced by pem_asn1(), and pem_image_probe().

◆ pem_asn1()

int pem_asn1 ( userptr_t  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 105 of file pem.c.

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

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

Referenced by pem_image_asn1().

◆ pem_image_probe()

static int pem_image_probe ( struct image image)
static

Probe PEM image.

Parameters
imagePEM image
Return values
rcReturn status code

Definition at line 193 of file pem.c.

193  {
194  int offset;
195  int rc;
196 
197  /* Check that image contains a BEGIN marker */
198  if ( ( offset = pem_marker ( image->data, image->len, 0,
199  PEM_BEGIN ) ) < 0 ) {
200  rc = offset;
201  DBGC ( image, "PEM %s has no BEGIN marker: %s\n",
202  image->name, strerror ( rc ) );
203  return rc;
204  }
205 
206  return 0;
207 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
userptr_t data
Raw file image.
Definition: image.h:41
#define DBGC(...)
Definition: compiler.h:505
An executable image.
Definition: image.h:24
static int pem_marker(userptr_t data, size_t len, size_t offset, const char *marker)
Locate boundary marker line.
Definition: pem.c:68
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
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
#define PEM_BEGIN
Pre-encapsulation boundary marker.
Definition: pem.h:18
char * name
Name.
Definition: image.h:34

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

◆ pem_image_asn1()

static 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 220 of file pem.c.

221  {
222  int next;
223  int rc;
224 
225  /* Extract ASN.1 object */
226  if ( ( next = pem_asn1 ( image->data, image->len, offset,
227  cursor ) ) < 0 ) {
228  rc = next;
229  DBGC ( image, "PEM %s could not extract ASN.1: %s\n",
230  image->name, strerror ( rc ) );
231  return rc;
232  }
233 
234  return next;
235 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
userptr_t data
Raw file image.
Definition: image.h:41
uint32_t next
Next descriptor address.
Definition: myson.h:18
#define DBGC(...)
Definition: compiler.h:505
An executable image.
Definition: image.h:24
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
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
int pem_asn1(userptr_t data, size_t len, size_t offset, struct asn1_cursor **cursor)
Extract ASN.1 object from PEM data.
Definition: pem.c:105
char * name
Name.
Definition: image.h:34

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

◆ __image_type()

struct image_type pem_image_type __image_type ( PROBE_NORMAL  )

PEM image type.