def test_Certificate(self): s = """ -----BEGIN CERTIFICATE----- MIIFSzCCBDOgAwIBAgIHJ6JvWHUrOTANBgkqhkiG9w0BAQUFADCByjELMAkGA1UE BhMCVVMxEDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAY BgNVBAoTEUdvRGFkZHkuY29tLCBJbmMuMTMwMQYDVQQLEypodHRwOi8vY2VydGlm aWNhdGVzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkxMDAuBgNVBAMTJ0dvIERhZGR5 IFNlY3VyZSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTERMA8GA1UEBRMIMDc5Njky ODcwHhcNMTEwNzA4MDAxOTU3WhcNMTIwNzA4MDAxOTU3WjBPMRQwEgYDVQQKFAsq LnRyZXZwLm5ldDEhMB8GA1UECxMYRG9tYWluIENvbnRyb2wgVmFsaWRhdGVkMRQw EgYDVQQDFAsqLnRyZXZwLm5ldDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC ggEBAMgawQKi4zY4TTz1RNL7klt/ibvjG+jGqBYlc6qjUiTQORD3fUrdAF83Alav JiC3rrwfvarL8KpPn7zQQOOk+APwzFxn0sVphDvAN8E7xI/cC7es08EYA9/DDN7r VTe/wvbs77CL5AniRSJyAP5puvSUHgixingTgYmnkIgC+3ZFqyfz2uenxvkPkoUT QEBkm2uEcBOwBMXAih1fdsuhEiJ9qpmejpIEvxLIDoMnCWTPs897zhwr3epQkn5g lKQ9H+FnEo5Jf8YBM4YhAzwG/8pyfc8NtOHafKUb5PhSIC7Vy7N2EBQ4y9kDOZc+ r0Vguq4p+Nncc32JI/i1Cdj/lO0CAwEAAaOCAa4wggGqMA8GA1UdEwEB/wQFMAMB AQAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMA4GA1UdDwEB/wQEAwIF oDAzBgNVHR8ELDAqMCigJqAkhiJodHRwOi8vY3JsLmdvZGFkZHkuY29tL2dkczEt NTIuY3JsME0GA1UdIARGMEQwQgYLYIZIAYb9bQEHFwEwMzAxBggrBgEFBQcCARYl aHR0cHM6Ly9jZXJ0cy5nb2RhZGR5LmNvbS9yZXBvc2l0b3J5LzCBgAYIKwYBBQUH AQEEdDByMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5nb2RhZGR5LmNvbS8wSgYI KwYBBQUHMAKGPmh0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5jb20vcmVwb3Np dG9yeS9nZF9pbnRlcm1lZGlhdGUuY3J0MB8GA1UdIwQYMBaAFP2sYTKTbEXW4u6F X5q653aZaMznMCEGA1UdEQQaMBiCCyoudHJldnAubmV0ggl0cmV2cC5uZXQwHQYD VR0OBBYEFCYv4a9+enZGS27wqAv+TPfJOOb7MA0GCSqGSIb3DQEBBQUAA4IBAQA+ 2OKO77vpwKtoKddDtamBokiVhHrfw0c7ALGysOXtss1CKV2WgH4FdNuh9pFkVZB2 mKZ7keS7EMW11OzgBR3pRRk0AkNYtDsOJEXA2+1NLFgrtdujHrDX4WIoi9MGbqB5 TfK08XufM7OP3yXDLtMxyUtyjprFhdxPE+9p/GJ0IVdZrMmzYTjyCOO8+okY9zAQ RVUKuxd+eEaH3BpPAau4MP2n24gy6WEsJ2auB81ee9fDnx/tfKPqvyuc4r4/Z4aL 5CvQvlPHaG/TTXXNh3pZFl3d/J5/76ZfeQzQtZ+dCrE4a4601Q4hBBXEq5gQfaof H4yTGzfDv+JLIICAIcCs -----END CERTIFICATE-----""" sslc = TlsCertificate.createFromPem(s) assert (sslc.key_sha256 == a2b_hex( "ffd30bcb84dbbc211a510875694354c58863d84fb7fc5853dfe36f4be2eb2e50") ) assert (sslc.cert_sha256 == a2b_hex( "1a50e3de3a153f33b314b67c1aacc2f59fc99c49b8449c33dcc3665663e2bff1") ) assert (Time.posixTimeToStr(sslc.notAfter, True) == "2012-07-08T00:19:57Z") # Write to binary and re-parse it, then check again b = sslc.serialize() sslc2 = TlsCertificate(b) assert (sslc2.key_sha256 == a2b_hex( "ffd30bcb84dbbc211a510875694354c58863d84fb7fc5853dfe36f4be2eb2e50") ) assert (sslc2.cert_sha256 == a2b_hex( "1a50e3de3a153f33b314b67c1aacc2f59fc99c49b8449c33dcc3665663e2bff1") ) assert (Time.posixTimeToStr(sslc2.notAfter, True) == "2012-07-08T00:19:57Z") return 1
def __str__(self): s = """initial_time = %s end_time = %s public_key = %s min_generation = %s""" %\ (Time.posixTimeToStr(self.initial_time), Time.posixTimeToStr(self.end_time), self.public_key, self.min_generation) return s
def test_delta(self): assert(0 == Time.parseDeltaArg("0m")) assert(59 == Time.parseDeltaArg("59m")) assert(60 == Time.parseDeltaArg("1h")) assert(61 == Time.parseDeltaArg("1h1m")) assert(1439 == Time.parseDeltaArg("23h59m")) assert(1440 == Time.parseDeltaArg("1d")) assert(1441 == Time.parseDeltaArg("1d1m")) assert(1500 == Time.parseDeltaArg("1d1h")) assert(1501 == Time.parseDeltaArg("1d1h1m")) assert(1440*37+122 == Time.parseDeltaArg("37d2h2m"))
def printHelp(): s = Time.posixTimeToStr(time.time()) print("""Creates a TACK based on a target certificate. sign KEY CERT KEY : Use this TACK key file ("-" for stdin) CERT : Sign this certificate's public key ("-" for stdin) Optional arguments: -v : Verbose -x : Use python crypto (not OpenSSL) -o FILE : Write the output to this file (instead of stdout) -p PASSWORD : Use this TACK key password instead of prompting -m MIN_GENERATION : Use this min_generation number (0-255) -g GENERATION : Use this generation number (0-255) -e EXPIRATION : Use this UTC time for expiration ("%s", "%sZ", "%sZ", "%sZ" etc.) Or, specify a delta from current time: ("5m", "30d", "1d12h5m", "0m", etc.) If not specified, the certificate's notAfter is used. -n NUM@INTERVAL : Generate NUM TACKs, with expiration times spaced out by INTERVAL (see -e for delta syntax). The -o argument is used as a filename prefix, and the -e argument is used as the first expiration time. """ % (s, s[:13], s[:10], s[:4]))
def printHelp(): s = Time.posixTimeToStr(time.time()) print( """Creates a TACK based on a target certificate. sign -k KEY -c CERT -k KEY : Use this TACK key file ("-" for stdin) -c CERT : Sign this certificate's public key ("-" for stdin) Optional arguments: -v : Verbose -x : Use python crypto (not OpenSSL) -o FILE : Write the output to this file (instead of stdout) -p PASSWORD : Use this TACK key password instead of prompting -m MIN_GENERATION : Use this min_generation number (0-255) -g GENERATION : Use this generation number (0-255) -e EXPIRATION : Use this UTC time for expiration ("%s", "%sZ", "%sZ", "%sZ" etc.) Or, specify a delta from current time: ("5m", "30d", "1d12h5m", "0m", etc.) If not specified, the certificate's notAfter is used. -n NUM@INTERVAL : Generate NUM TACKs, with expiration times spaced out by INTERVAL (see -e for delta syntax). The -o argument is used as a filename prefix, and the -e argument is used as the first expiration time. """ % (s, s[:13], s[:10], s[:4]))
def printHelp(): s = Time.posixTimeToStr(time.time()) print(\ """Creates a TACK based on a target SSL certificate. sign -k KEY -c CERT -k KEY : Use this TACK key file -c CERT : Sign this SSL certificate's public key Optional arguments: -v : Verbose -o FILE : Write the output to this file (instead of stdout) -p PASSWORD : Use this TACK key password instead of prompting -m MIN_GENERATION : Use this min_generation number (0-255) -g GENERATION : Use this generation number (0-255) -e EXPIRATION : Use this UTC time for expiration ("%s", "%sZ", "%sZ", "%sZ" etc.) Or, specify a duration from current time: ("5m", "30d", "1d12h5m", "0m", etc.) - n NUM@INTERVAL : Generate NUM TACKs, with expiration times spaced out by INTERVAL (see -d for INTERVAL syntax). The -o argument is used as a filename prefix, and the -e argument is used as the first expiration time. """ % (s, s[:13], s[:10], s[:4]))
def addPemComments(self, inStr): """Add pre-PEM metadata/comments to PEM strings.""" versionStr = __version__ timeStr = Time.posixTimeToStr(time.time(), True) outStr = "Created by tack.py %s\nCreated at %s\n%s" %\ (versionStr, timeStr, inStr) return outStr
def test_Tack(self): s = """ -----BEGIN TACK----- TAmsAZIpzR+MYwQrsujLhesvpu3dRc5ROhfgySqUVkU1p1hdXo+PwQrmaQo9B9+o hecRrWElh3yThwgYQRgbSwAAAY0cQDHeDLGfKtuw0c17GzHvjuPrWbdEWa75S0gL 7u64XGTJQUtzAwXIWOkQEQ0BRUlbzcGEa9a1PBhjmmWFNF+kGAswhLnXc5qL4y/Z PDUV0rzIIYjXP58T5pphGKRgLlK3Aw== -----END TACK-----""" t = Tack().createFromPem(s) assert (t.public_key.getRawKey() == a2b_hex( "4c09ac019229cd1f8c63042bb2e8" "cb85eb2fa6eddd45ce513a17e0c9" "2a94564535a7585d5e8f8fc10ae6" "690a3d07dfa885e711ad6125877c" "9387081841181b4b")) assert (Time.posixTimeToStr(t.expiration * 60) == "2019-06-25T22:24Z") assert (t.generation == 0) assert (t.target_hash == a2b_hex( "31de0cb19f2adbb0d1cd7b1b31ef8ee3eb59b74459aef94b480beeeeb85c64c9") ) assert (t.signature == a2b_hex("414b730305c858e910110d0145495" "bcdc1846bd6b53c18639a6585345f" "a4180b3084b9d7739a8be32fd93c3" "515d2bcc82188d73f9f13e69a6118" "a4602e52b703"))
def test_Certificate(self): s = """ -----BEGIN CERTIFICATE----- MIIFSzCCBDOgAwIBAgIHJ6JvWHUrOTANBgkqhkiG9w0BAQUFADCByjELMAkGA1UE BhMCVVMxEDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAY BgNVBAoTEUdvRGFkZHkuY29tLCBJbmMuMTMwMQYDVQQLEypodHRwOi8vY2VydGlm aWNhdGVzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkxMDAuBgNVBAMTJ0dvIERhZGR5 IFNlY3VyZSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTERMA8GA1UEBRMIMDc5Njky ODcwHhcNMTEwNzA4MDAxOTU3WhcNMTIwNzA4MDAxOTU3WjBPMRQwEgYDVQQKFAsq LnRyZXZwLm5ldDEhMB8GA1UECxMYRG9tYWluIENvbnRyb2wgVmFsaWRhdGVkMRQw EgYDVQQDFAsqLnRyZXZwLm5ldDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC ggEBAMgawQKi4zY4TTz1RNL7klt/ibvjG+jGqBYlc6qjUiTQORD3fUrdAF83Alav JiC3rrwfvarL8KpPn7zQQOOk+APwzFxn0sVphDvAN8E7xI/cC7es08EYA9/DDN7r VTe/wvbs77CL5AniRSJyAP5puvSUHgixingTgYmnkIgC+3ZFqyfz2uenxvkPkoUT QEBkm2uEcBOwBMXAih1fdsuhEiJ9qpmejpIEvxLIDoMnCWTPs897zhwr3epQkn5g lKQ9H+FnEo5Jf8YBM4YhAzwG/8pyfc8NtOHafKUb5PhSIC7Vy7N2EBQ4y9kDOZc+ r0Vguq4p+Nncc32JI/i1Cdj/lO0CAwEAAaOCAa4wggGqMA8GA1UdEwEB/wQFMAMB AQAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMA4GA1UdDwEB/wQEAwIF oDAzBgNVHR8ELDAqMCigJqAkhiJodHRwOi8vY3JsLmdvZGFkZHkuY29tL2dkczEt NTIuY3JsME0GA1UdIARGMEQwQgYLYIZIAYb9bQEHFwEwMzAxBggrBgEFBQcCARYl aHR0cHM6Ly9jZXJ0cy5nb2RhZGR5LmNvbS9yZXBvc2l0b3J5LzCBgAYIKwYBBQUH AQEEdDByMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5nb2RhZGR5LmNvbS8wSgYI KwYBBQUHMAKGPmh0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5jb20vcmVwb3Np dG9yeS9nZF9pbnRlcm1lZGlhdGUuY3J0MB8GA1UdIwQYMBaAFP2sYTKTbEXW4u6F X5q653aZaMznMCEGA1UdEQQaMBiCCyoudHJldnAubmV0ggl0cmV2cC5uZXQwHQYD VR0OBBYEFCYv4a9+enZGS27wqAv+TPfJOOb7MA0GCSqGSIb3DQEBBQUAA4IBAQA+ 2OKO77vpwKtoKddDtamBokiVhHrfw0c7ALGysOXtss1CKV2WgH4FdNuh9pFkVZB2 mKZ7keS7EMW11OzgBR3pRRk0AkNYtDsOJEXA2+1NLFgrtdujHrDX4WIoi9MGbqB5 TfK08XufM7OP3yXDLtMxyUtyjprFhdxPE+9p/GJ0IVdZrMmzYTjyCOO8+okY9zAQ RVUKuxd+eEaH3BpPAau4MP2n24gy6WEsJ2auB81ee9fDnx/tfKPqvyuc4r4/Z4aL 5CvQvlPHaG/TTXXNh3pZFl3d/J5/76ZfeQzQtZ+dCrE4a4601Q4hBBXEq5gQfaof H4yTGzfDv+JLIICAIcCs -----END CERTIFICATE-----""" sslc = TlsCertificate.createFromPem(s) assert(sslc.key_sha256 == a2b_hex("ffd30bcb84dbbc211a510875694354c58863d84fb7fc5853dfe36f4be2eb2e50")) assert(sslc.cert_sha256 == a2b_hex("1a50e3de3a153f33b314b67c1aacc2f59fc99c49b8449c33dcc3665663e2bff1")) assert(Time.posixTimeToStr(sslc.notAfter, True) == "2012-07-08T00:19:57Z") # Write to binary and re-parse it, then check again b = sslc.serialize() sslc2 = TlsCertificate(b) assert(sslc2.key_sha256 == a2b_hex("ffd30bcb84dbbc211a510875694354c58863d84fb7fc5853dfe36f4be2eb2e50")) assert(sslc2.cert_sha256 == a2b_hex("1a50e3de3a153f33b314b67c1aacc2f59fc99c49b8449c33dcc3665663e2bff1")) assert(Time.posixTimeToStr(sslc2.notAfter, True) == "2012-07-08T00:19:57Z") return 1
def __str__(self): s =\ """key_sha256 = %s notAfter = %s """ % (\ Util.writeBytes(self.key_sha256), Time.posixTimeToStr(self.notAfter, True)) if self.tackExt: s += "\n" + str(self.tackExt) return s
def _getExpiration(self, certificate): expiration = self._getOptionValue("-e") if expiration is None and self._getNumArg() is None: return int(math.ceil(certificate.notAfter / 60.0)) else: try: return Time.parseTimeArg(expiration) except SyntaxError as e: self.printError(e)
def writeText(self): s =\ """key_sha256 = 0x%s notAfter = %s """ % (\ Util.writeBytes(self.key_sha256), Time.posixTimeToStr(self.notAfter, True)) if self.tackExt: s += "\n" + str(self.tackExt) return s
def _getExpiration(self): expiration = self._getOptionValue("-e") if expiration is None and self._getTackCount() is None: return int(math.ceil(self._getCertificate().notAfter / 60.0)) else: try: return Time.parseTimeArg(expiration) except SyntaxError as e: self.printError(e)
def _getExpiration(self, certificate): expiration = self._getOptionValue("-e") if expiration is None and self._getNumArg() is None: # Set expiration based on cert + 30 days (per spec's advice) return int(math.ceil(certificate.notAfter / 60.0)) + (30*24*60) else: try: return Time.parseTimeArg(expiration) except SyntaxError as e: self.printError(e)
def _getExpiration(self, certificate): expiration = self._getOptionValue("-e") if expiration is None and self._getNumArg() is None: # Set expiration based on cert + 30 days (per spec's advice) return int(math.ceil(certificate.notAfter / 60.0)) + (30 * 24 * 60) else: try: return Time.parseTimeArg(expiration) except SyntaxError as e: self.printError(e)
def _getTackCount(self): tackCount = self._getOptionValue("-n") if tackCount is None: return None try: leftArg, rightArg = tackCount.split("@") # could raise ValueError numTacks = int(leftArg) # could raise ValueError interval = Time.parseDurationArg(rightArg) # SyntaxError if numTacks < 1 or numTacks >= 10000: raise ValueError() return numTacks, interval except (ValueError, SyntaxError): self.printError("Bad -n NUMTACKS: %s:" % tackCount)
def _getNumArg(self): numArgRaw = self._getOptionValue("-n") if numArgRaw is None: return None try: leftArg, rightArg = numArgRaw.split("@") # could raise ValueError numTacks = int(leftArg) # could raise ValueError interval = Time.parseDeltaArg(rightArg) # SyntaxError if numTacks < 1 or numTacks >= 10000: raise ValueError() return numTacks, interval except (ValueError, SyntaxError): self.printError("Bad -n NUMTACKS (1 - 10000): %s:" % numArgRaw)
def __str__(self): """Return a readable string describing this TACK. Used by the "TACK view" command to display TACK objects.""" s =\ """TACK ID = %s min_generation = %d generation = %d expiration = %s target_hash = %s\n""" %\ (self.getTackId(), self.min_generation, self.generation, Time.posixTimeToStr(self.expiration*60), Util.writeBytes(self.target_hash)) return s
def __str__(self): """Return a readable string describing this TACK. Used by the "TACK view" command to display TACK objects.""" s =\ """key fingerprint = %s min_generation = %d generation = %d expiration = %s target_hash = %s\n""" %\ (self.getTackId(), self.min_generation, self.generation, Time.posixTimeToStr(self.expiration*60), Util.writeBytes(self.target_hash)) return s
def test_Tack(self): s = """ -----BEGIN TACK----- TAmsAZIpzR+MYwQrsujLhesvpu3dRc5ROhfgySqUVkU1p1hdXo+PwQrmaQo9B9+o hecRrWElh3yThwgYQRgbSwAAAY0cQDHeDLGfKtuw0c17GzHvjuPrWbdEWa75S0gL 7u64XGTJQUtzAwXIWOkQEQ0BRUlbzcGEa9a1PBhjmmWFNF+kGAswhLnXc5qL4y/Z PDUV0rzIIYjXP58T5pphGKRgLlK3Aw== -----END TACK-----""" t = Tack().createFromPem(s) assert(t.public_key.getRawKey() == a2b_hex("4c09ac019229cd1f8c63042bb2e8" "cb85eb2fa6eddd45ce513a17e0c9" "2a94564535a7585d5e8f8fc10ae6" "690a3d07dfa885e711ad6125877c" "9387081841181b4b")) assert(Time.posixTimeToStr(t.expiration*60) == "2019-06-25T22:24Z") assert(t.generation == 0) assert(t.target_hash == a2b_hex("31de0cb19f2adbb0d1cd7b1b31ef8ee3eb59b74459aef94b480beeeeb85c64c9")) assert(t.signature == a2b_hex("414b730305c858e910110d0145495" "bcdc1846bd6b53c18639a6585345f" "a4180b3084b9d7739a8be32fd93c3" "515d2bcc82188d73f9f13e69a6118" "a4602e52b703"))
def test_duration(self): assert(Time.durationToStr(0) == "0m") assert(Time.durationToStr(59) == "59m") assert(Time.durationToStr(60) == "1h") assert(Time.durationToStr(61) == "1h1m") assert(Time.durationToStr(1439) == "23h59m") assert(Time.durationToStr(1440) == "1d") assert(Time.durationToStr(1441) == "1d1m") assert(Time.durationToStr(1500) == "1d1h") assert(Time.durationToStr(1501) == "1d1h1m") assert(Time.durationToStr(1440*37+122) == "37d2h2m") assert(0 == Time.parseDurationArg("0m")) assert(59 == Time.parseDurationArg("59m")) assert(60 == Time.parseDurationArg("1h")) assert(61 == Time.parseDurationArg("1h1m")) assert(1439 == Time.parseDurationArg("23h59m")) assert(1440 == Time.parseDurationArg("1d")) assert(1441 == Time.parseDurationArg("1d1m")) assert(1500 == Time.parseDurationArg("1d1h")) assert(1501 == Time.parseDurationArg("1d1h1m")) assert(1440*37+122 == Time.parseDurationArg("37d2h2m"))
def test_posix(self): assert (Time.posixTimeToStr(1234567890, True) == "2009-02-13T23:31:30Z") assert (Time.posixTimeToStr(1234567890) == "2009-02-13T23:31Z")
def __init__(self, data=None): if data is None: return #self.key_sha256 = bytearray(32) #self.cert_sha256 = bytearray(32) self.notAfter = 0 # Below values are populated for TACK certs self.tackExt = None # Below values hold cert contents excluding TACK stuff self.preExtBytes = None self.extBytes = None self.postExtBytes = None p = ASN1Parser(data) #Get the tbsCertificate tbsCertificateP = p.getChild(0) #Is the optional version field present? #This determines which index the key is at if tbsCertificateP.value[0] == 0xA0: subjectPublicKeyInfoIndex = 6 validityIndex = 4 else: subjectPublicKeyInfoIndex = 5 validityIndex = 3 #Get the subjectPublicKeyInfo spkiP = tbsCertificateP.getChild(subjectPublicKeyInfoIndex) #Parse the notAfter time validityP = tbsCertificateP.getChild(validityIndex) notAfterP = validityP.getChild(1) if notAfterP.type == 0x17: # UTCTime self.notAfter = Time.parseASN1UTCTime(notAfterP.value) elif notAfterP.type == 0x18: # GeneralizedTime self.notAfter = Time.parseASN1GeneralizedTime(notAfterP.value) else: raise SyntaxError() # Get the hash values self.cert_sha256 = Digest.SHA256(data) self.key_sha256 = Digest.SHA256(spkiP.getTotalBytes()) # Check if this is a TACK certificate: #Get the tbsCertificate versionP = tbsCertificateP.getChild(0) if versionP.type != 0xA0: # i.e. tag of [0], version return # X.509 version field not present versionPP = versionP.getTagged() if versionPP.value != bytearray([0x02]): return # X.509 version field does not equal v3 # Find extensions element x = 0 while 1: certFieldP = tbsCertificateP.getChild(x) if not certFieldP: raise SyntaxError("X.509 extensions not present") if certFieldP.type == 0xA3: # i.e. tag of [3], extensions break x += 1 self.preExtBytes = data[versionP.offset:certFieldP.offset] self.extBytes = bytearray() # Iterate through extensions x = 0 certFieldPP = certFieldP.getTagged() while 1: extFieldP = certFieldPP.getChild(x) if not extFieldP: break # Check the extnID and parse out TACK if present extnIDP = extFieldP.getChild(0) if extnIDP.value == TlsCertificate.OID_TACK: if self.tackExt: raise SyntaxError("More than one TACK Extension") # OK! We found a TACK, parse it.. self.tackExt = TackExtension(extFieldP.getChild(1).value) else: # Collect all non-TACK extensions: self.extBytes += data[extFieldP.offset :\ extFieldP.offset + extFieldP.getTotalLength()] x += 1 # Finish copying the tail of the certificate self.postExtBytes = data[certFieldP.offset + certFieldP.getTotalLength():]
def parse(self, b): p = ASN1Parser(b) #Get the tbsCertificate tbsCertificateP = p.getChild(0) #Is the optional version field present? #This determines which index the key is at if tbsCertificateP.value[0]==0xA0: subjectPublicKeyInfoIndex = 6 validityIndex = 4 else: subjectPublicKeyInfoIndex = 5 validityIndex = 3 #Get the subjectPublicKeyInfo spkiP = tbsCertificateP.getChild(subjectPublicKeyInfoIndex) #Parse the notAfter time validityP = tbsCertificateP.getChild(validityIndex) notAfterP = validityP.getChild(1) if notAfterP.type == 0x17: # UTCTime self.notAfter = Time.parseASN1UTCTime(notAfterP.value) elif notAfterP.type == 0x18: # GeneralizedTime self.notAfter = Time.parseASN1GeneralizedTime(notAfterP.value) else: raise SyntaxError() # Get the hash values self.cert_sha256 = Digest.SHA256(b) self.key_sha256 = Digest.SHA256(spkiP.getTotalBytes()) # Check if this is a TACK certificate: #Get the tbsCertificate versionP = tbsCertificateP.getChild(0) if versionP.type != 0xA0: # i.e. tag of [0], version return # X.509 version field not present versionPP = versionP.getTagged() if versionPP.value != bytearray([0x02]): return # X.509 version field does not equal v3 # Find extensions element x = 0 while 1: certFieldP = tbsCertificateP.getChild(x) if not certFieldP: raise SyntaxError("X.509 extensions not present") if certFieldP.type == 0xA3: # i.e. tag of [3], extensions break x += 1 self.preExtBytes = b[versionP.offset : certFieldP.offset] self.extBytes = bytearray() # Iterate through extensions x = 0 certFieldPP = certFieldP.getTagged() while 1: extFieldP = certFieldPP.getChild(x) if not extFieldP: break # Check the extnID and parse out TACK if present extnIDP = extFieldP.getChild(0) if extnIDP.value == TlsCertificate.OID_TACK: if self.tackExt: raise SyntaxError("More than one TACK Extension") # OK! We found a TACK, parse it.. self.tackExt = TackExtension(extFieldP.getChild(1).value) else: # Collect all non-TACK extensions: self.extBytes += b[extFieldP.offset :\ extFieldP.offset + extFieldP.getTotalLength()] x += 1 # Finish copying the tail of the certificate self.postExtBytes = b[certFieldP.offset + certFieldP.getTotalLength():]
def test_posix(self): assert(Time.posixTimeToStr(1234567890, True) == "2009-02-13T23:31:30Z") assert(Time.posixTimeToStr(1234567890) == "2009-02-13T23:31Z")
def test_duration(self): assert (Time.durationToStr(0) == "0m") assert (Time.durationToStr(59) == "59m") assert (Time.durationToStr(60) == "1h") assert (Time.durationToStr(61) == "1h1m") assert (Time.durationToStr(1439) == "23h59m") assert (Time.durationToStr(1440) == "1d") assert (Time.durationToStr(1441) == "1d1m") assert (Time.durationToStr(1500) == "1d1h") assert (Time.durationToStr(1501) == "1d1h1m") assert (Time.durationToStr(1440 * 37 + 122) == "37d2h2m") assert (0 == Time.parseDurationArg("0m")) assert (59 == Time.parseDurationArg("59m")) assert (60 == Time.parseDurationArg("1h")) assert (61 == Time.parseDurationArg("1h1m")) assert (1439 == Time.parseDurationArg("23h59m")) assert (1440 == Time.parseDurationArg("1d")) assert (1441 == Time.parseDurationArg("1d1m")) assert (1500 == Time.parseDurationArg("1d1h")) assert (1501 == Time.parseDurationArg("1d1h1m")) assert (1440 * 37 + 122 == Time.parseDurationArg("37d2h2m"))
def test_string(self): assert(Time.parseTimeArg("2012-07-20T05:40Z")*60 == 1342762800) assert(Time.parseTimeArg("2012-07-20T05Z")*60 == 1342760400) assert(Time.parseTimeArg("2012-07-20Z")*60 == 1342742400) assert(Time.parseTimeArg("2012-07Z")*60 == 1341100800) assert(Time.parseTimeArg("2012Z")*60 == 1325376000)
def test_string(self): assert (Time.parseTimeArg("2012-07-20T05:40Z") * 60 == 1342762800) assert (Time.parseTimeArg("2012-07-20T05Z") * 60 == 1342760400) assert (Time.parseTimeArg("2012-07-20Z") * 60 == 1342742400) assert (Time.parseTimeArg("2012-07Z") * 60 == 1341100800) assert (Time.parseTimeArg("2012Z") * 60 == 1325376000)