Data Structures | Macros | Functions
bearssl_pem.h File Reference
Include dependency graph for bearssl_pem.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  br_pem_decoder_context
 PEM decoder context. More...


#define BR_PEM_BEGIN_OBJ   1
 Event: start of object. More...
#define BR_PEM_END_OBJ   2
 Event: end of object. More...
#define BR_PEM_ERROR   3
 Event: decoding error. More...
#define BR_PEM_LINE64   0x0001
 PEM encoding flag: split lines at 64 characters. More...
#define BR_PEM_CRLF   0x0002
 PEM encoding flag: use CR+LF line endings. More...


void br_pem_decoder_init (br_pem_decoder_context *ctx)
 Initialise a PEM decoder structure. More...
size_t br_pem_decoder_push (br_pem_decoder_context *ctx, const void *data, size_t len)
 Push some bytes into the decoder. More...
static void br_pem_decoder_setdest (br_pem_decoder_context *ctx, void(*dest)(void *dest_ctx, const void *src, size_t len), void *dest_ctx)
 Set the receiver for decoded data. More...
int br_pem_decoder_event (br_pem_decoder_context *ctx)
 Get the last event. More...
static const char * br_pem_decoder_name (br_pem_decoder_context *ctx)
 Get the name of the encountered object. More...
size_t br_pem_encode (void *dest, const void *data, size_t len, const char *banner, unsigned flags)
 Encode an object in PEM. More...

Detailed Description

PEM Support

PEM is a traditional encoding layer use to store binary objects (in particular X.509 certificates, and private keys) in text files. While the acronym comes from an old, defunct standard ("Privacy Enhanced Mail"), the format has been reused, with some variations, by many systems, and is a de facto standard, even though it is not, actually, specified in all clarity anywhere.

Format Details

BearSSL contains a generic, streamed PEM decoder, which handles the following format:

PEM Decoder API

The PEM decoder offers a state-machine API. The caller allocates a decoder context, then injects source bytes. Source bytes are pushed with br_pem_decoder_push(). The decoder stops accepting bytes when it reaches an "event", which is either the start of an object, the end of an object, or a decoding error within an object.

The br_pem_decoder_event() function is used to obtain the current event; it also clears it, thus allowing the decoder to accept more bytes. When a object start event is raised, the decoder context offers the found object name (normalised to ASCII uppercase).

When an object is reached, the caller must set an appropriate callback function, which will receive (by chunks) the decoded object data.

Since the decoder context makes no dynamic allocation, it requires no explicit deallocation.

Macro Definition Documentation


#define BR_PEM_BEGIN_OBJ   1

Event: start of object.

This event is raised when the start of a new object has been detected. The object name (normalised to uppercase) can be accessed with br_pem_decoder_name().


#define BR_PEM_CRLF   0x0002

PEM encoding flag: use CR+LF line endings.


#define BR_PEM_END_OBJ   2

Event: end of object.

This event is raised when the end of the current object is reached (normally, i.e. with no decoding error).


#define BR_PEM_ERROR   3

Event: decoding error.

This event is raised when decoding fails within an object. This formally closes the current object and brings the decoder back to the "out of any object" state. The offending line in the source is consumed.


#define BR_PEM_LINE64   0x0001

PEM encoding flag: split lines at 64 characters.

Function Documentation

◆ br_pem_decoder_event()

int br_pem_decoder_event ( br_pem_decoder_context ctx)

Get the last event.

If an event was raised, then this function returns the event value, and also clears it, thereby allowing the decoder to proceed. If no event was raised since the last call to br_pem_decoder_event(), then this function returns 0.

ctxdecoder context.
the raised event, or 0.

◆ br_pem_decoder_init()

void br_pem_decoder_init ( br_pem_decoder_context ctx)

Initialise a PEM decoder structure.

ctxdecoder context to initialise.

◆ br_pem_decoder_name()

static const char* br_pem_decoder_name ( br_pem_decoder_context ctx)

Get the name of the encountered object.

The encountered object name is defined only when the "start of object" event is raised. That name is normalised to uppercase (for ASCII letters only) and does not include trailing dashes.

ctxdecoder context.
the current object name.

◆ br_pem_decoder_push()

size_t br_pem_decoder_push ( br_pem_decoder_context ctx,
const void *  data,
size_t  len 

Push some bytes into the decoder.

Returned value is the number of bytes actually consumed; this may be less than the number of provided bytes if an event is raised. When an event is raised, it must be read (with br_pem_decoder_event()); until the event is read, this function will return 0.

ctxdecoder context.
datanew data bytes.
lennumber of new data bytes.
the number of bytes actually received (may be less than len).

◆ br_pem_decoder_setdest()

static void br_pem_decoder_setdest ( br_pem_decoder_context ctx,
void(*)(void *dest_ctx, const void *src, size_t len)  dest,
void *  dest_ctx 

Set the receiver for decoded data.

When an object is entered, the provided function (with opaque context pointer) will be called repeatedly with successive chunks of decoded data for that object. If dest is set to 0, then decoded data is simply ignored. The receiver can be set at any time, but, in practice, it should be called immediately after receiving a "start of object" event.

ctxdecoder context.
destcallback for receiving decoded data.
dest_ctxopaque context pointer for the dest callback.

◆ br_pem_encode()

size_t br_pem_encode ( void *  dest,
const void *  data,
size_t  len,
const char *  banner,
unsigned  flags 

Encode an object in PEM.

This function encodes the provided binary object (data, of length len bytes) into PEM. The banner text will be included in the header and footer (e.g. use "CERTIFICATE" to get a "BEGIN CERTIFICATE" header).

The length (in characters) of the PEM output is returned; that length does NOT include the terminating zero, that this function nevertheless adds. If using the returned value for allocation purposes, the allocated buffer size MUST be at least one byte larger than the returned size.

If dest is NULL, then the encoding does not happen; however, the length of the encoded object is still computed and returned.

The data pointer may be NULL only if len is zero (when encoding an object of length zero, which is not very useful), or when dest is NULL (in that case, source data bytes are ignored).

Some flags can be specified to alter the encoding behaviour:

  • If BR_PEM_LINE64 is set, then line-breaking will occur after every 64 characters of output, instead of the default of 76.
  • If BR_PEM_CRLF is set, then end-of-line sequence will use CR+LF instead of a single LF.

The data and dest buffers may overlap, in which case the source binary data is destroyed in the process. Note that the PEM-encoded output is always larger than the source binary.

destthe destination buffer (or NULL).
datathe source buffer (can be NULL in some cases).
lenthe source length (in bytes).
bannerthe PEM banner expression.
flagsthe behavioural flags.
the PEM object length (in characters), EXCLUDING the final zero.