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  from .utils.pem import * 
 13   
 14   
15 -class X509(object):
16 """This class represents an X.509 certificate. 17 18 @type bytes: L{bytearray} of unsigned bytes 19 @ivar bytes: The DER-encoded ASN.1 certificate 20 21 @type publicKey: L{tlslite.utils.rsakey.RSAKey} 22 @ivar publicKey: The subject public key from the certificate. 23 24 @type subject: L{bytearray} of unsigned bytes 25 @ivar subject: The DER-encoded ASN.1 subject distinguished name. 26 27 @type certAlg: str 28 @ivar certAlg: algorithm of the public key, "rsa" for RSASSA-PKCS#1 v1.5 29 and "rsa-pss" for RSASSA-PSS 30 """ 31
32 - def __init__(self):
33 self.bytes = bytearray(0) 34 self.publicKey = None 35 self.subject = None 36 self.certAlg = None
37
38 - def parse(self, s):
39 """Parse a PEM-encoded X.509 certificate. 40 41 @type s: str 42 @param s: A PEM-encoded X.509 certificate (i.e. a base64-encoded 43 certificate wrapped with "-----BEGIN CERTIFICATE-----" and 44 "-----END CERTIFICATE-----" tags). 45 """ 46 47 bytes = dePem(s, "CERTIFICATE") 48 self.parseBinary(bytes) 49 return self
50
51 - def parseBinary(self, bytes):
52 """Parse a DER-encoded X.509 certificate. 53 54 @type bytes: str or L{bytearray} of unsigned bytes 55 @param bytes: A DER-encoded X.509 certificate. 56 """ 57 58 self.bytes = bytearray(bytes) 59 p = ASN1Parser(bytes) 60 61 #Get the tbsCertificate 62 tbsCertificateP = p.getChild(0) 63 64 #Is the optional version field present? 65 #This determines which index the key is at. 66 if tbsCertificateP.value[0]==0xA0: 67 subjectPublicKeyInfoIndex = 6 68 else: 69 subjectPublicKeyInfoIndex = 5 70 71 #Get the subject 72 self.subject = tbsCertificateP.getChildBytes(\ 73 subjectPublicKeyInfoIndex - 1) 74 75 #Get the subjectPublicKeyInfo 76 subjectPublicKeyInfoP = tbsCertificateP.getChild(\ 77 subjectPublicKeyInfoIndex) 78 79 # Get the AlgorithmIdentifier 80 algIdentifier = subjectPublicKeyInfoP.getChild(0) 81 algIdentifierLen = algIdentifier.getChildCount() 82 # first item of AlgorithmIdentifier is the algorithm 83 alg = algIdentifier.getChild(0) 84 rsaOID = alg.value 85 if list(rsaOID) == [42, 134, 72, 134, 247, 13, 1, 1, 1]: 86 self.certAlg = "rsa" 87 elif list(rsaOID) == [42, 134, 72, 134, 247, 13, 1, 1, 10]: 88 self.certAlg = "rsa-pss" 89 else: 90 raise SyntaxError("Unrecognized AlgorithmIdentifier") 91 92 # for RSA the parameters of AlgorithmIdentifier should be a NULL 93 if self.certAlg == "rsa": 94 if algIdentifierLen != 2: 95 raise SyntaxError("Missing parameters in AlgorithmIdentifier") 96 params = algIdentifier.getChild(1) 97 if params.value != bytearray(0): 98 raise SyntaxError("Unexpected non-NULL parameters in " 99 "AlgorithmIdentifier") 100 else: # rsa-pss 101 pass # ignore parameters, if any - don't apply key restrictions 102 103 #Get the subjectPublicKey 104 subjectPublicKeyP = subjectPublicKeyInfoP.getChild(1) 105 106 #Adjust for BIT STRING encapsulation 107 if (subjectPublicKeyP.value[0] !=0): 108 raise SyntaxError() 109 subjectPublicKeyP = ASN1Parser(subjectPublicKeyP.value[1:]) 110 111 #Get the modulus and exponent 112 modulusP = subjectPublicKeyP.getChild(0) 113 publicExponentP = subjectPublicKeyP.getChild(1) 114 115 #Decode them into numbers 116 n = bytesToNumber(modulusP.value) 117 e = bytesToNumber(publicExponentP.value) 118 119 #Create a public key instance 120 self.publicKey = _createPublicRSAKey(n, e)
121
122 - def getFingerprint(self):
123 """Get the hex-encoded fingerprint of this certificate. 124 125 @rtype: str 126 @return: A hex-encoded fingerprint. 127 """ 128 return b2a_hex(SHA1(self.bytes))
129
130 - def writeBytes(self):
131 return self.bytes
132