• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# PEM Decoder and Encoder
2
3Often times DER-encoded data is wrapped in PEM encoding. This allows the binary
4DER data to be identified and reliably sent over various communication channels.
5
6The `asn1crypto.pem` module includes three functions:
7
8 - `detect(byte_string)`
9 - `unarmor(pem_bytes, multiple=False)`
10 - `armor(type_name, der_bytes, headers=None)`
11
12## detect()
13
14The `detect()` function accepts a byte string and looks for a `BEGIN` block
15line. This is useful to determine in a byte string needs to be PEM-decoded
16before parsing.
17
18```python
19from asn1crypto import pem, x509
20
21with open('/path/to/cert', 'rb') as f:
22    der_bytes = f.read()
23    if pem.detect(der_bytes):
24        _, _, der_bytes = pem.unarmor(der_bytes)
25```
26
27## unarmor()
28
29The `unarmor()` function accepts a byte string and the flag to indicates if
30more than one PEM block may be contained in the byte string. The result is
31a three-element tuple.
32
33 - The first element is a unicode string of the type of PEM block. Examples
34   include: `CERTIFICATE`, `PRIVATE KEY`, `PUBLIC KEY`.
35 - The second element is a `dict` of PEM block headers. Headers are typically
36   only used by encrypted OpenSSL private keys, and are in the format
37   `Name: Value`.
38 - The third element is a byte string of the decoded block contents.
39
40```python
41from asn1crypto import pem, x509
42
43with open('/path/to/cert', 'rb') as f:
44    der_bytes = f.read()
45    if pem.detect(der_bytes):
46        type_name, headers, der_bytes = pem.unarmor(der_bytes)
47
48cert = x509.Certificate.load(der_bytes)
49```
50
51If the `multiple` keyword argument is set to `True`, a generator will be
52returned.
53
54```python
55from asn1crypto import pem, x509
56
57certs = []
58with open('/path/to/ca_certs', 'rb') as f:
59    for type_name, headers, der_bytes in pem.unarmor(f.read(), multiple=True):
60        certs.append(x509.Certificate.load(der_bytes))
61```
62
63## armor()
64
65The `armor()` function accepts three parameters: a unicode string of the block
66type name, a byte string to encode and an optional keyword argument `headers`,
67that should be a `dict` of headers to add after the `BEGIN` line. Headers are
68typically only used by encrypted OpenSSL private keys.
69
70```python
71from asn1crypto import pem, x509
72
73# cert is an instance of x509.Certificate
74
75with open('/path/to/cert', 'wb') as f:
76    der_bytes = cert.dump()
77    pem_bytes = pem.armor('CERTIFICATE', der_bytes)
78    f.write(pem_bytes)
79```
80