Package tlslite :: Module x509
[hide private]
[frames] | no frames]

Source Code for Module tlslite.x509

  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   
  7  """Class representing an X.509 certificate.""" 
  8   
  9  from .utils.asn1parser import ASN1Parser 
 10  from .utils.cryptomath import * 
 11  from .utils.keyfactory import _createPublicRSAKey 
 12   
 13   
14 -class X509:
15 """This class represents an X.509 certificate. 16 17 @type bytes: L{bytearray} of unsigned bytes 18 @ivar bytes: The DER-encoded ASN.1 certificate 19 20 @type publicKey: L{tlslite.utils.rsakey.RSAKey} 21 @ivar publicKey: The subject public key from the certificate. 22 23 @type subject: L{array.array} of unsigned bytes 24 @ivar subject: The DER-encoded ASN.1 subject distinguished name. 25 """ 26
27 - def __init__(self):
28 self.bytes = createByteArraySequence([]) 29 self.publicKey = None 30 self.subject = None
31
32 - def parse(self, s):
33 """Parse a PEM-encoded X.509 certificate. 34 35 @type s: str 36 @param s: A PEM-encoded X.509 certificate (i.e. a base64-encoded 37 certificate wrapped with "-----BEGIN CERTIFICATE-----" and 38 "-----END CERTIFICATE-----" tags). 39 """ 40 41 start = s.find("-----BEGIN CERTIFICATE-----") 42 end = s.find("-----END CERTIFICATE-----") 43 if start == -1: 44 raise SyntaxError("Missing PEM prefix") 45 if end == -1: 46 raise SyntaxError("Missing PEM postfix") 47 s = s[start+len("-----BEGIN CERTIFICATE-----") : end] 48 49 bytes = base64ToBytes(s) 50 self.parseBinary(bytes) 51 return self
52
53 - def parseBinary(self, bytes):
54 """Parse a DER-encoded X.509 certificate. 55 56 @type bytes: str or L{bytearray} of unsigned bytes 57 @param bytes: A DER-encoded X.509 certificate. 58 """ 59 60 if isinstance(bytes, type("")): 61 bytes = stringToBytes(bytes) 62 63 self.bytes = bytes 64 p = ASN1Parser(bytes) 65 66 #Get the tbsCertificate 67 tbsCertificateP = p.getChild(0) 68 69 #Is the optional version field present? 70 #This determines which index the key is at. 71 if tbsCertificateP.value[0]==0xA0: 72 subjectPublicKeyInfoIndex = 6 73 else: 74 subjectPublicKeyInfoIndex = 5 75 76 #Get the subject 77 self.subject = tbsCertificateP.getChildBytes(\ 78 subjectPublicKeyInfoIndex - 1) 79 80 #Get the subjectPublicKeyInfo 81 subjectPublicKeyInfoP = tbsCertificateP.getChild(\ 82 subjectPublicKeyInfoIndex) 83 84 #Get the algorithm 85 algorithmP = subjectPublicKeyInfoP.getChild(0) 86 rsaOID = algorithmP.value 87 if list(rsaOID) != [6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0]: 88 raise SyntaxError("Unrecognized AlgorithmIdentifier") 89 90 #Get the subjectPublicKey 91 subjectPublicKeyP = subjectPublicKeyInfoP.getChild(1) 92 93 #Adjust for BIT STRING encapsulation 94 if (subjectPublicKeyP.value[0] !=0): 95 raise SyntaxError() 96 subjectPublicKeyP = ASN1Parser(subjectPublicKeyP.value[1:]) 97 98 #Get the modulus and exponent 99 modulusP = subjectPublicKeyP.getChild(0) 100 publicExponentP = subjectPublicKeyP.getChild(1) 101 102 #Decode them into numbers 103 n = bytesToNumber(modulusP.value) 104 e = bytesToNumber(publicExponentP.value) 105 106 #Create a public key instance 107 self.publicKey = _createPublicRSAKey(n, e)
108
109 - def getFingerprint(self):
110 """Get the hex-encoded fingerprint of this certificate. 111 112 @rtype: str 113 @return: A hex-encoded fingerprint. 114 """ 115 return sha1(bytesToString(self.bytes)).hexdigest()
116
117 - def writeBytes(self):
118 return self.bytes
119