#PEM Parser
#define FIO_PEM
#include "fio-stl.h"PEM wraps DER bytes in Base64 armor:
-----BEGIN <label>-----
<base64 DER>
-----END <label>-----This module extracts PEM blocks, decodes certificates, and parses private keys used by the TLS/X.509 helpers.
Limit: encrypted private keys are not supported. If the key asks for a password, this parser politely leaves the room.
#Supported Labels
CERTIFICATEPRIVATE KEY(PKCS#8)RSA PRIVATE KEY(legacy PKCS#1)EC PRIVATE KEY(legacy SEC1)
Private-key parsing supports RSA, P-256, and Ed25519 where the required crypto modules are available.
#Types
#fio_pem_key_type_e
typedef enum {
FIO_PEM_KEY_UNKNOWN = 0,
FIO_PEM_KEY_RSA = 1,
FIO_PEM_KEY_ECDSA_P256 = 2,
FIO_PEM_KEY_ED25519 = 3,
} fio_pem_key_type_e;#fio_pem_s
typedef struct {
const uint8_t *der;
size_t der_len;
const char *label;
size_t label_len;
} fio_pem_s;A decoded PEM block. der points into the caller-provided DER output buffer. label points into the original PEM input.
#fio_pem_private_key_s
typedef struct fio_pem_private_key_s fio_pem_private_key_s;Parsed private-key material. The active union member depends on type:
- RSA: fixed-size byte arrays for
n,e,d, optionalp,q,dP,dQ, andqInv, each with a length. - P-256: 32-byte private scalar, optional 65-byte uncompressed public key.
- Ed25519: 32-byte seed, optional 32-byte public key.
Call fio_pem_private_key_clear when done.
#API
#fio_pem_parse
SFUNC size_t fio_pem_parse(fio_pem_s *out,
uint8_t *der_buf,
size_t der_buf_len,
const char *pem_data,
size_t pem_len);Finds the next PEM block, decodes its Base64 body into der_buf, and fills out.
Returns the number of bytes consumed from pem_data, or 0 on error. To parse a file with multiple PEM blocks, advance by the returned count and call again.
#fio_pem_parse_certificate
SFUNC int fio_pem_parse_certificate(fio_x509_cert_s *cert,
const char *pem_data,
size_t pem_len);Finds a CERTIFICATE block, decodes it, and parses the DER certificate with the X.509 parser. Returns 0 on success, -1 on error.
Requires the X.509 module for the certificate parse.
#fio_pem_parse_private_key
SFUNC int fio_pem_parse_private_key(fio_pem_private_key_s *key,
const char *pem_data,
size_t pem_len);Parses a PEM private key into key.
Supported forms:
| PEM label | Format | Supported keys |
|---|---|---|
PRIVATE KEY |
PKCS#8 | RSA, P-256, Ed25519 |
RSA PRIVATE KEY |
PKCS#1 | RSA |
EC PRIVATE KEY |
SEC1 | P-256 |
Returns 0 on success, -1 on unsupported format, missing dependency, encrypted key, or malformed input.
#fio_pem_get_certificate_der
SFUNC size_t fio_pem_get_certificate_der(uint8_t *der_out,
size_t der_out_len,
const char *pem_data,
size_t pem_len);Extracts a CERTIFICATE block as raw DER without parsing the X.509 structure. Returns the DER length written, or 0 on error.
#fio_pem_private_key_clear
FIO_IFUNC void fio_pem_private_key_clear(fio_pem_private_key_s *key);Securely zeros a parsed private-key structure.
#Example: Extract Certificate DER
#define FIO_PEM
#include "fio-stl.h"
size_t load_der(uint8_t *der, size_t der_cap, const char *pem, size_t pem_len) {
return fio_pem_get_certificate_der(der, der_cap, pem, pem_len);
}#Example: Parse Multiple Blocks
#define FIO_PEM
#include "fio-stl.h"
void scan_pem(const char *pem, size_t len) {
uint8_t der[8192];
while (len) {
fio_pem_s block;
size_t used = fio_pem_parse(&block, der, sizeof(der), pem, len);
if (!used)
break;
/* block.label / block.label_len name the PEM type. */
/* block.der / block.der_len hold the decoded DER bytes. */
pem += used;
len -= used;
}
}#Dependency Notes
- Generic
fio_pem_parseneeds only the PEM/base64 helpers. - Certificate parsing needs X.509 support.
- Private key parsing uses ASN.1, and RSA/P-256/Ed25519 support depends on the matching crypto headers.