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