iPXE
Defines | Functions
pem.h File Reference

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

#include <stdint.h>
#include <ipxe/uaccess.h>
#include <ipxe/asn1.h>
#include <ipxe/image.h>

Go to the source code of this file.

Defines

#define PEM_BEGIN   "-----BEGIN"
 Pre-encapsulation boundary marker.
#define PEM_END   "-----END"
 Post-encapsulation boundary marker.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
int pem_asn1 (userptr_t data, size_t len, size_t offset, struct asn1_cursor **cursor)
 Extract ASN.1 object from PEM data.
struct image_type pem_image_type __image_type (PROBE_NORMAL)

Detailed Description

PEM-encoded ASN.1 data.

Definition in file pem.h.


Define Documentation

#define PEM_BEGIN   "-----BEGIN"

Pre-encapsulation boundary marker.

Definition at line 18 of file pem.h.

Referenced by pem_asn1(), and pem_image_probe().

#define PEM_END   "-----END"

Post-encapsulation boundary marker.

Definition at line 21 of file pem.h.

Referenced by pem_asn1().


Function Documentation

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )
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.

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

Referenced by pem_image_asn1().

                                             {
        size_t encoded_len;
        size_t decoded_max_len;
        char *encoded;
        void *decoded;
        int decoded_len;
        int begin;
        int end;
        int rc;

        /* Locate and skip BEGIN marker */
        begin = pem_marker ( data, len, offset, PEM_BEGIN );
        if ( begin < 0 ) {
                rc = begin;
                DBGC ( data, "PEM [%#zx,%#zx) missing BEGIN marker: %s\n",
                       offset, len, strerror ( rc ) );
                goto err_begin;
        }
        begin = pem_next ( data, len, begin );

        /* Locate and skip END marker */
        end = pem_marker ( data, len, begin, PEM_END );
        if ( end < 0 ) {
                rc = end;
                DBGC ( data, "PEM [%#zx,%#zx) missing END marker: %s\n",
                       offset, len, strerror ( rc ) );
                goto err_end;
        }
        encoded_len = ( end - begin );
        end = pem_next ( data, len, end );

        /* Extract Base64-encoded data */
        encoded = malloc ( encoded_len + 1 /* NUL */ );
        if ( ! encoded ) {
                rc = -ENOMEM;
                goto err_alloc_encoded;
        }
        copy_from_user ( encoded, data, begin, encoded_len );
        encoded[encoded_len] = '\0';

        /* Allocate cursor and data buffer */
        decoded_max_len = base64_decoded_max_len ( encoded );
        *cursor = malloc ( sizeof ( **cursor ) + decoded_max_len );
        if ( ! *cursor ) {
                rc = -ENOMEM;
                goto err_alloc_cursor;
        }
        decoded = ( ( ( void * ) *cursor ) + sizeof ( **cursor ) );

        /* Decode Base64-encoded data */
        decoded_len = base64_decode ( encoded, decoded, decoded_max_len );
        if ( decoded_len < 0 ) {
                rc = decoded_len;
                DBGC ( data, "PEM could not decode: %s\n", strerror ( rc ) );
                goto err_decode;
        }
        (*cursor)->data = decoded;
        (*cursor)->len = decoded_len;
        assert ( (*cursor)->len <= decoded_max_len );

        /* Free Base64-encoded data */
        free ( encoded );

        /* Update offset and skip any unencapsulated trailer */
        offset = end;
        if ( pem_marker ( data, len, offset, PEM_BEGIN ) < 0 )
                offset = len;

        return offset;

 err_decode:
        free ( *cursor );
        *cursor = NULL;
 err_alloc_cursor:
        free ( encoded );
 err_alloc_encoded:
 err_end:
 err_begin:
        return rc;
}
struct image_type pem_image_type __image_type ( PROBE_NORMAL  ) [read]