OLD | NEW |
| 1 # Authors: |
| 2 # Trevor Perrin |
| 3 # Google - parsing subject field |
| 4 # |
| 5 # See the LICENSE file for legal information regarding use of this file. |
| 6 |
1 """Class representing an X.509 certificate.""" | 7 """Class representing an X.509 certificate.""" |
2 | 8 |
3 from utils.asn1parser import ASN1Parser | 9 from .utils.asn1parser import ASN1Parser |
4 from utils.cryptomath import * | 10 from .utils.cryptomath import * |
5 from utils.keyfactory import _createPublicRSAKey | 11 from .utils.keyfactory import _createPublicRSAKey |
| 12 from .utils.pem import * |
6 | 13 |
7 | 14 |
8 class X509: | 15 class X509(object): |
9 """This class represents an X.509 certificate. | 16 """This class represents an X.509 certificate. |
10 | 17 |
11 @type bytes: L{array.array} of unsigned bytes | 18 @type bytes: L{bytearray} of unsigned bytes |
12 @ivar bytes: The DER-encoded ASN.1 certificate | 19 @ivar bytes: The DER-encoded ASN.1 certificate |
13 | 20 |
14 @type publicKey: L{tlslite.utils.RSAKey.RSAKey} | 21 @type publicKey: L{tlslite.utils.rsakey.RSAKey} |
15 @ivar publicKey: The subject public key from the certificate. | 22 @ivar publicKey: The subject public key from the certificate. |
16 | 23 |
17 @type subject: L{array.array} of unsigned bytes | 24 @type subject: L{bytearray} of unsigned bytes |
18 @ivar subject: The DER-encoded ASN.1 subject distinguished name. | 25 @ivar subject: The DER-encoded ASN.1 subject distinguished name. |
19 """ | 26 """ |
20 | 27 |
21 def __init__(self): | 28 def __init__(self): |
22 self.bytes = createByteArraySequence([]) | 29 self.bytes = bytearray(0) |
23 self.publicKey = None | 30 self.publicKey = None |
24 self.subject = None | 31 self.subject = None |
25 | 32 |
26 def parse(self, s): | 33 def parse(self, s): |
27 """Parse a PEM-encoded X.509 certificate. | 34 """Parse a PEM-encoded X.509 certificate. |
28 | 35 |
29 @type s: str | 36 @type s: str |
30 @param s: A PEM-encoded X.509 certificate (i.e. a base64-encoded | 37 @param s: A PEM-encoded X.509 certificate (i.e. a base64-encoded |
31 certificate wrapped with "-----BEGIN CERTIFICATE-----" and | 38 certificate wrapped with "-----BEGIN CERTIFICATE-----" and |
32 "-----END CERTIFICATE-----" tags). | 39 "-----END CERTIFICATE-----" tags). |
33 """ | 40 """ |
34 | 41 |
35 start = s.find("-----BEGIN CERTIFICATE-----") | 42 bytes = dePem(s, "CERTIFICATE") |
36 end = s.find("-----END CERTIFICATE-----") | |
37 if start == -1: | |
38 raise SyntaxError("Missing PEM prefix") | |
39 if end == -1: | |
40 raise SyntaxError("Missing PEM postfix") | |
41 s = s[start+len("-----BEGIN CERTIFICATE-----") : end] | |
42 | |
43 bytes = base64ToBytes(s) | |
44 self.parseBinary(bytes) | 43 self.parseBinary(bytes) |
45 return self | 44 return self |
46 | 45 |
47 def parseBinary(self, bytes): | 46 def parseBinary(self, bytes): |
48 """Parse a DER-encoded X.509 certificate. | 47 """Parse a DER-encoded X.509 certificate. |
49 | 48 |
50 @type bytes: str or L{array.array} of unsigned bytes | 49 @type bytes: str or L{bytearray} of unsigned bytes |
51 @param bytes: A DER-encoded X.509 certificate. | 50 @param bytes: A DER-encoded X.509 certificate. |
52 """ | 51 """ |
53 | 52 |
54 if isinstance(bytes, type("")): | 53 self.bytes = bytearray(bytes) |
55 bytes = stringToBytes(bytes) | |
56 | |
57 self.bytes = bytes | |
58 p = ASN1Parser(bytes) | 54 p = ASN1Parser(bytes) |
59 | 55 |
60 #Get the tbsCertificate | 56 #Get the tbsCertificate |
61 tbsCertificateP = p.getChild(0) | 57 tbsCertificateP = p.getChild(0) |
62 | 58 |
63 #Is the optional version field present? | 59 #Is the optional version field present? |
64 #This determines which index the key is at. | 60 #This determines which index the key is at. |
65 if tbsCertificateP.value[0]==0xA0: | 61 if tbsCertificateP.value[0]==0xA0: |
66 subjectPublicKeyInfoIndex = 6 | 62 subjectPublicKeyInfoIndex = 6 |
67 else: | 63 else: |
(...skipping 24 matching lines...) Expand all Loading... |
92 #Get the modulus and exponent | 88 #Get the modulus and exponent |
93 modulusP = subjectPublicKeyP.getChild(0) | 89 modulusP = subjectPublicKeyP.getChild(0) |
94 publicExponentP = subjectPublicKeyP.getChild(1) | 90 publicExponentP = subjectPublicKeyP.getChild(1) |
95 | 91 |
96 #Decode them into numbers | 92 #Decode them into numbers |
97 n = bytesToNumber(modulusP.value) | 93 n = bytesToNumber(modulusP.value) |
98 e = bytesToNumber(publicExponentP.value) | 94 e = bytesToNumber(publicExponentP.value) |
99 | 95 |
100 #Create a public key instance | 96 #Create a public key instance |
101 self.publicKey = _createPublicRSAKey(n, e) | 97 self.publicKey = _createPublicRSAKey(n, e) |
102 return self | |
103 | 98 |
104 def getFingerprint(self): | 99 def getFingerprint(self): |
105 """Get the hex-encoded fingerprint of this certificate. | 100 """Get the hex-encoded fingerprint of this certificate. |
106 | 101 |
107 @rtype: str | 102 @rtype: str |
108 @return: A hex-encoded fingerprint. | 103 @return: A hex-encoded fingerprint. |
109 """ | 104 """ |
110 return sha.sha(self.bytes).hexdigest() | 105 return b2a_hex(SHA1(self.bytes)) |
111 | |
112 def getCommonName(self): | |
113 """Get the Subject's Common Name from the certificate. | |
114 | |
115 The cryptlib_py module must be installed in order to use this | |
116 function. | |
117 | |
118 @rtype: str or None | |
119 @return: The CN component of the certificate's subject DN, if | |
120 present. | |
121 """ | |
122 import cryptlib_py | |
123 import array | |
124 c = cryptlib_py.cryptImportCert(self.bytes, cryptlib_py.CRYPT_UNUSED) | |
125 name = cryptlib_py.CRYPT_CERTINFO_COMMONNAME | |
126 try: | |
127 try: | |
128 length = cryptlib_py.cryptGetAttributeString(c, name, None) | |
129 returnVal = array.array('B', [0] * length) | |
130 cryptlib_py.cryptGetAttributeString(c, name, returnVal) | |
131 returnVal = returnVal.tostring() | |
132 except cryptlib_py.CryptException, e: | |
133 if e[0] == cryptlib_py.CRYPT_ERROR_NOTFOUND: | |
134 returnVal = None | |
135 return returnVal | |
136 finally: | |
137 cryptlib_py.cryptDestroyCert(c) | |
138 | 106 |
139 def writeBytes(self): | 107 def writeBytes(self): |
140 return self.bytes | 108 return self.bytes |
141 | 109 |
142 | 110 |
OLD | NEW |