1# Author: Trevor Perrin 2# See the LICENSE file for legal information regarding use of this file. 3 4from .compat import * 5import binascii 6 7#This code is shared with tackpy (somewhat), so I'd rather make minimal 8#changes, and preserve the use of a2b_base64 throughout. 9 10def dePem(s, name): 11 """Decode a PEM string into a bytearray of its payload. 12 13 The input must contain an appropriate PEM prefix and postfix 14 based on the input name string, e.g. for name="CERTIFICATE":: 15 16 -----BEGIN CERTIFICATE----- 17 MIIBXDCCAUSgAwIBAgIBADANBgkqhkiG9w0BAQUFADAPMQ0wCwYDVQQDEwRUQUNL 18 ... 19 KoZIhvcNAQEFBQADAwA5kw== 20 -----END CERTIFICATE----- 21 22 The first such PEM block in the input will be found, and its 23 payload will be base64 decoded and returned. 24 """ 25 prefix = "-----BEGIN %s-----" % name 26 postfix = "-----END %s-----" % name 27 start = s.find(prefix) 28 if start == -1: 29 raise SyntaxError("Missing PEM prefix") 30 end = s.find(postfix, start+len(prefix)) 31 if end == -1: 32 raise SyntaxError("Missing PEM postfix") 33 s = s[start+len("-----BEGIN %s-----" % name) : end] 34 retBytes = a2b_base64(s) # May raise SyntaxError 35 return retBytes 36 37def dePemList(s, name): 38 """Decode a sequence of PEM blocks into a list of bytearrays. 39 40 The input must contain any number of PEM blocks, each with the appropriate 41 PEM prefix and postfix based on the input name string, e.g. for 42 name="TACK BREAK SIG". Arbitrary text can appear between and before and 43 after the PEM blocks. For example:: 44 45 Created by TACK.py 0.9.3 Created at 2012-02-01T00:30:10Z 46 -----BEGIN TACK BREAK SIG----- 47 ATKhrz5C6JHJW8BF5fLVrnQss6JnWVyEaC0p89LNhKPswvcC9/s6+vWLd9snYTUv 48 YMEBdw69PUP8JB4AdqA3K6Ap0Fgd9SSTOECeAKOUAym8zcYaXUwpk0+WuPYa7Zmm 49 SkbOlK4ywqt+amhWbg9txSGUwFO5tWUHT3QrnRlE/e3PeNFXLx5Bckg= 50 -----END TACK BREAK SIG----- 51 Created by TACK.py 0.9.3 Created at 2012-02-01T00:30:11Z 52 -----BEGIN TACK BREAK SIG----- 53 ATKhrz5C6JHJW8BF5fLVrnQss6JnWVyEaC0p89LNhKPswvcC9/s6+vWLd9snYTUv 54 YMEBdw69PUP8JB4AdqA3K6BVCWfcjN36lx6JwxmZQncS6sww7DecFO/qjSePCxwM 55 +kdDqX/9/183nmjx6bf0ewhPXkA0nVXsDYZaydN8rJU1GaMlnjcIYxY= 56 -----END TACK BREAK SIG----- 57 58 All such PEM blocks will be found, decoded, and return in an ordered list 59 of bytearrays, which may have zero elements if not PEM blocks are found. 60 """ 61 bList = [] 62 prefix = "-----BEGIN %s-----" % name 63 postfix = "-----END %s-----" % name 64 while 1: 65 start = s.find(prefix) 66 if start == -1: 67 return bList 68 end = s.find(postfix, start+len(prefix)) 69 if end == -1: 70 raise SyntaxError("Missing PEM postfix") 71 s2 = s[start+len(prefix) : end] 72 retBytes = a2b_base64(s2) # May raise SyntaxError 73 bList.append(retBytes) 74 s = s[end+len(postfix) : ] 75 76def pem(b, name): 77 """Encode a payload bytearray into a PEM string. 78 79 The input will be base64 encoded, then wrapped in a PEM prefix/postfix 80 based on the name string, e.g. for name="CERTIFICATE":: 81 82 -----BEGIN CERTIFICATE----- 83 MIIBXDCCAUSgAwIBAgIBADANBgkqhkiG9w0BAQUFADAPMQ0wCwYDVQQDEwRUQUNL 84 ... 85 KoZIhvcNAQEFBQADAwA5kw== 86 -----END CERTIFICATE----- 87 """ 88 s1 = b2a_base64(b)[:-1] # remove terminating \n 89 s2 = "" 90 while s1: 91 s2 += s1[:64] + "\n" 92 s1 = s1[64:] 93 s = ("-----BEGIN %s-----\n" % name) + s2 + \ 94 ("-----END %s-----\n" % name) 95 return s 96 97def pemSniff(inStr, name): 98 searchStr = "-----BEGIN %s-----" % name 99 return searchStr in inStr 100