NAME

Crypt::SecretBuffer::PEM - Parse PEM format from a SecretBuffer

SYNOPSIS

use Crypt::SecretBuffer::PEM;
my $secret= secret(load_file => "secrets.pem");
my @pem= Crypt::SecretBuffer::PEM->parse_all($secret->span);

DESCRIPTION

This module parses the PEM format used by OpenSSL and OpenSSH. PEM is a simple text format made of a block of Base64 data with optional headers and begin/end markers. This module parses the begin/end markers, copies that span of bytes into a new SecretBuffer, makes the headers into a hashref, and stores the Span of Base64 as the attribute "content".

To be clear, this only parses the text portions of PEM, not the ASN.1 structure within the base64 data.

The label around the PEM block and its headers (if any) are considered non-secret, and copied out of the SecretBuffer into perl scalars. The Base64 payload remains inside the SecretBuffer, in case this was an unencrypted private key. There is also an option to treat the header values as secrets.

CONSTRUCTORS

parse

my $pem= Crypt::SecretBuffer::PEM->parse($span, %options);

Parse the next PEM block found in the Span. The span is updated to begin on the line following the PEM block. If no PEM block is found, this returns undef and the span object remains unchanged.

Invalid PEM blocks (such as mismatched BEGIN/END markers) are ignored, as well as any text outside of the markers.

Options:

secret_headers

Boolean, whether the values of the PEM headers should be stored in Crypt::SecretBuffer::Span objects. Default is false.

trim_headers

Boolean. The default is to trim leading and trailing whitespace from keys and values of the headers. You can set this to false to preserve that whitespace (but the space following ':' always gets removed)

parse_all

my @pem_blocks= Crypt::SecretBuffer::PEM->parse_all($span, %options);

A file can contain more than one PEM block (such as a SSL certificate chain, and its key) This just calls "parse" in a loop until no more PEM blocks are found.

new

my $pem= Crypt::SecretBuffer::PEM->new(%attributes);

You can construct a PEM object from attributes, in case you want to serialize your own data.

ATTRIBUTES

label

The text from the PEM begin-marker:

-----BEGIN SOME LABEL-----
...
-----END SOME LABEL-----

In this case the attribute would hold 'SOME LABEL'.

buffer

A Crypt::SecretBuffer holding the complete PEM text from BEGIN marker to END marker, inclusive.

header_kv

PEM format has optional header 'NAME: VALUE' pairs that can appear right after the BEGIN marker. When parsed, leading and trailing whitespace are removed from keys and values. When written, keys and values may not contain leading or trailing whitespace, or any control characters. This attribute presents them in their original order as an arrayref of [ $key0, $value0, $key1, $value1, ... ].

Note that the values can be Span objects if you used the secret_headers option.

headers

my $values_arrayref= $pem->headers->get_values('example');
my $value_maybe_arrayref= $pem->headers->{example};
$pem->headers->{example}= $value;
$pem->headers->append('example', $value);

For convenience, you can access the headers by name using this attribute, which masquerades as both a hashref and an object with methods. This object/hashref only provides a view of the header_kv array, and is not particularly efficient at reading or writing it. (but, it's very convenient)

If there are multiple header keys with the same name, the value returned for that name is an arrayref of all the values.

content

A Span or SecretBuffer that contains the bytes of the PEM payload. This span created by "parse" has encoding => BASE64 set, which affects the character-based methods like parse, but has not actually been Base64-decoded, which matters for methods like length or memcmp.

METHODS

serialize

$buffer= $pem->serialize;

This writes a PEM block into a SecretBuffer object. The headers (if any) come from "header_kv", falling back to the "headers" hashref.

VERSION

version 0.019

AUTHOR

Michael Conrad <mike@nrdvana.net>

COPYRIGHT AND LICENSE

This software is copyright (c) 2026 by Michael Conrad.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.