From 6135fa19b0c19c389e17ff3e260740ec3679db66 Mon Sep 17 00:00:00 2001 From: Magnus Ahltorp Date: Fri, 26 Sep 2014 14:50:10 +0200 Subject: Simplify submitcert --- tools/certtools.py | 48 ++++++++++++++++++++++++++------ tools/submitcert.py | 80 +++++++++++++++++++++-------------------------------- 2 files changed, 71 insertions(+), 57 deletions(-) diff --git a/tools/certtools.py b/tools/certtools.py index 13dad17..fe345cd 100644 --- a/tools/certtools.py +++ b/tools/certtools.py @@ -8,6 +8,20 @@ import sys import hashlib import ecdsa +publickeys = { + "https://ct.googleapis.com/pilot/": + "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEfahLEimAoz2t01p3uMziiLOl/fHTD" + "M0YDOhBRuiBARsV4UvxG2LdNgoIGLrtCzWE0J5APC2em4JlvR8EEEFMoA==", + + "https://127.0.0.1:8080/": + "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE4qWq6afhBUi0OdcWUYhyJLNXTkGqQ9" + "PMS5lqoCgkV2h1ZvpNjBH2u8UbgcOQwqDo66z6BWQJGolozZYmNHE2kQ==", + + "https://flimsy.ct.nordu.net/": + "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE4qWq6afhBUi0OdcWUYhyJLNXTkGqQ9" + "PMS5lqoCgkV2h1ZvpNjBH2u8UbgcOQwqDo66z6BWQJGolozZYmNHE2kQ==", +} + def get_cert_info(s): p = subprocess.Popen( ["openssl", "x509", "-noout", "-subject", "-issuer", "-inform", "der"], @@ -15,7 +29,8 @@ def get_cert_info(s): stderr=subprocess.PIPE) parsed = p.communicate(s) if parsed[1]: - print "error:", parsed[1] + print "ERROR:", parsed[1] + sys.exit(1) result = {} for line in parsed[0].split("\n"): (key, sep, value) = line.partition("=") @@ -34,7 +49,7 @@ def get_certs_from_file(certfile): cert = "" incert = True elif line == "-----END CERTIFICATE-----": - certs.append(cert) + certs.append(base64.decodestring(cert)) incert = False elif incert: cert += line @@ -49,7 +64,6 @@ def get_root_cert(issuer): for accepted_cert in accepted_certs: subject = get_cert_info(base64.decodestring(accepted_cert))["subject"] if subject == issuer: - print "found root cert" root_cert = base64.decodestring(accepted_cert) return root_cert @@ -62,12 +76,11 @@ def get_proof_by_hash(baseurl, hash, tree_size): try: params = urllib.urlencode({"hash":base64.b64encode(hash), "tree_size":tree_size}) - print params result = \ urllib2.urlopen(baseurl + "ct/v1/get-proof-by-hash?" + params).read() return json.loads(result) except urllib2.HTTPError, e: - print e.read() + print "ERROR:", e.read() sys.exit(1) def tls_array(data, length_len): @@ -90,7 +103,7 @@ def add_chain(baseurl, submission): return json.loads(urllib2.urlopen(baseurl + "ct/v1/add-chain", json.dumps(submission)).read()) except urllib2.HTTPError, e: - print e.read() + print "ERROR:", e.read() sys.exit(1) def get_entries(baseurl, start, end): @@ -99,7 +112,7 @@ def get_entries(baseurl, start, end): result = urllib2.urlopen(baseurl + "ct/v1/get-entries?" + params).read() return json.loads(result) except urllib2.HTTPError, e: - print e.read() + print "ERROR:", e.read() sys.exit(1) def decode_certificate_chain(packed_certchain): @@ -118,7 +131,8 @@ def decode_signature(signature): assert rest == "" return (hash_alg, signature_alg, unpacked_signature) -def check_signature(publickey, leafcert, sct): +def check_signature(baseurl, leafcert, sct): + publickey = base64.decodestring(publickeys[baseurl]) calculated_logid = hashlib.sha256(publickey).digest() received_logid = base64.decodestring(sct["id"]) assert calculated_logid == received_logid, \ @@ -146,3 +160,21 @@ def check_signature(publickey, leafcert, sct): vk = ecdsa.VerifyingKey.from_der(publickey) vk.verify(unpacked_signature, signed_struct, hashfunc=hashlib.sha256, sigdecode=ecdsa.util.sigdecode_der) + +def pack_mtl(timestamp, leafcert): + entry_type = struct.pack(">H", 0) + extensions = "" + + timestamped_entry = struct.pack(">Q", timestamp) + entry_type + \ + tls_array(leafcert, 3) + tls_array(extensions, 2) + version = struct.pack(">b", 0) + leaf_type = struct.pack(">b", 0) + merkle_tree_leaf = version + leaf_type + timestamped_entry + return merkle_tree_leaf + +def get_leaf_hash(merkle_tree_leaf): + leaf_hash = hashlib.sha256() + leaf_hash.update(struct.pack(">b", 0)) + leaf_hash.update(merkle_tree_leaf) + + return leaf_hash.digest() diff --git a/tools/submitcert.py b/tools/submitcert.py index 702ffb3..e8d8901 100755 --- a/tools/submitcert.py +++ b/tools/submitcert.py @@ -6,6 +6,7 @@ import base64 import sys import struct import hashlib +import itertools from certtools import * baseurl = sys.argv[1] @@ -13,62 +14,29 @@ certfile = sys.argv[2] lookup_in_log = True -publickeys = { - "https://ct.googleapis.com/pilot/": - "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEfahLEimAoz2t01p3uMziiLOl/fHTD" - "M0YDOhBRuiBARsV4UvxG2LdNgoIGLrtCzWE0J5APC2em4JlvR8EEEFMoA==", - - "https://127.0.0.1:8080/": - "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE4qWq6afhBUi0OdcWUYhyJLNXTkGqQ9" - "PMS5lqoCgkV2h1ZvpNjBH2u8UbgcOQwqDo66z6BWQJGolozZYmNHE2kQ==", - - "https://flimsy.ct.nordu.net/": - "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE4qWq6afhBUi0OdcWUYhyJLNXTkGqQ9" - "PMS5lqoCgkV2h1ZvpNjBH2u8UbgcOQwqDo66z6BWQJGolozZYmNHE2kQ==", -} - - certs = get_certs_from_file(certfile) -result = add_chain(baseurl, {"chain":certs}) - -print result - -publickey = base64.decodestring(publickeys[baseurl]) - -check_signature(publickey, base64.decodestring(certs[0]), result) +result = add_chain(baseurl, {"chain":map(base64.b64encode, certs)}) -for cert in certs: - print get_cert_info(base64.decodestring(cert)) +try: + check_signature(baseurl, certs[0], result) +except AssertionError, e: + print "ERROR:", e + sys.exit(1) +except ecdsa.keys.BadSignatureError, e: + print "ERROR: bad signature" + sys.exit(1) +print "signature check succeeded" if lookup_in_log: - last_issuer = get_cert_info(base64.decodestring(certs[-1]))["issuer"] - last_subject = get_cert_info(base64.decodestring(certs[-1]))["subject"] - entry_type = struct.pack(">H", 0) + merkle_tree_leaf = pack_mtl(result["timestamp"], certs[0]) - extensions = "" - - timestamped_entry = struct.pack(">Q", result["timestamp"]) + entry_type + \ - tls_array(base64.decodestring(certs[0]), 3) + tls_array(extensions, 2) - version = struct.pack(">b", 0) - leaf_type = struct.pack(">b", 0) - merkle_tree_leaf = version + leaf_type + timestamped_entry - - print "merkle_tree_leaf:", base64.b64encode(merkle_tree_leaf) - - leaf_hash = hashlib.sha256() - leaf_hash.update(struct.pack(">b", 0)) - leaf_hash.update(merkle_tree_leaf) - - print base64.b64encode(leaf_hash.digest()) + leaf_hash = get_leaf_hash(merkle_tree_leaf) sth = get_sth(baseurl) - print sth - - proof = get_proof_by_hash(baseurl, leaf_hash.digest(), sth["tree_size"]) - print proof + proof = get_proof_by_hash(baseurl, leaf_hash, sth["tree_size"]) leaf_index = proof["leaf_index"] @@ -76,8 +44,6 @@ if lookup_in_log: fetched_entry = entries["entries"][0] - print fetched_entry - print "does the leaf_input of the fetched entry match what we calculated:", \ base64.decodestring(fetched_entry["leaf_input"]) == merkle_tree_leaf @@ -85,4 +51,20 @@ if lookup_in_log: certchain = decode_certificate_chain(base64.decodestring(extra_data)) - print [base64.b64encode(cert) for cert in certchain] + submittedcertchain = certs[1:] + + for (submittedcert, fetchedcert, i) in zip(submittedcertchain, + certchain, itertools.count(1)): + print "cert", i, "in chain is the same:", submittedcert == fetchedcert + + if len(certchain) == len(submittedcertchain) + 1: + last_issuer = get_cert_info(certs[-1])["issuer"] + root_subject = get_cert_info(certchain[-1])["subject"] + print "issuer of last cert in submitted chain and " \ + "subject of last cert in fetched chain is the same:", \ + last_issuer == root_subject + elif len(certchain) == len(submittedcertchain): + print "cert chains are the same length" + else: + print "ERROR: fetched cert chain has length", len(certchain), + print "and submitted chain has length", len(submittedcertchain) -- cgit v1.1 From 8a40d214037d6a9169a262d14016e8b44d898b04 Mon Sep 17 00:00:00 2001 From: Magnus Ahltorp Date: Fri, 26 Sep 2014 17:14:08 +0200 Subject: Added basic system test --- tools/certtools.py | 49 +++++++++++----- tools/submitcert.py | 2 +- tools/testcase1.py | 133 ++++++++++++++++++++++++++++++++++++++++++++ tools/testcerts/cert1.txt | 86 +++++++++++++++++++++++++++++ tools/testcerts/cert2.txt | 138 ++++++++++++++++++++++++++++++++++++++++++++++ tools/testcerts/cert3.txt | 78 ++++++++++++++++++++++++++ tools/testcerts/cert4.txt | 89 ++++++++++++++++++++++++++++++ tools/testcerts/cert5.txt | 105 +++++++++++++++++++++++++++++++++++ 8 files changed, 666 insertions(+), 14 deletions(-) create mode 100755 tools/testcase1.py create mode 100644 tools/testcerts/cert1.txt create mode 100644 tools/testcerts/cert2.txt create mode 100644 tools/testcerts/cert3.txt create mode 100644 tools/testcerts/cert4.txt create mode 100644 tools/testcerts/cert5.txt diff --git a/tools/certtools.py b/tools/certtools.py index fe345cd..a62d58f 100644 --- a/tools/certtools.py +++ b/tools/certtools.py @@ -100,11 +100,19 @@ def unpack_tls_array(packed_data, length_len): def add_chain(baseurl, submission): try: - return json.loads(urllib2.urlopen(baseurl + "ct/v1/add-chain", - json.dumps(submission)).read()) + result = urllib2.urlopen(baseurl + "ct/v1/add-chain", + json.dumps(submission)).read() + return json.loads(result) except urllib2.HTTPError, e: print "ERROR:", e.read() sys.exit(1) + except ValueError, e: + print "==== FAILED REQUEST ====" + print submission + print "======= RESPONSE =======" + print result + print "========================" + raise e def get_entries(baseurl, start, end): try: @@ -131,7 +139,31 @@ def decode_signature(signature): assert rest == "" return (hash_alg, signature_alg, unpacked_signature) -def check_signature(baseurl, leafcert, sct): +def check_signature(baseurl, signature, data): + publickey = base64.decodestring(publickeys[baseurl]) + (hash_alg, signature_alg, unpacked_signature) = decode_signature(signature) + assert hash_alg == 4, \ + "hash_alg is %d, expected 4" % (hash_alg,) # sha256 + assert signature_alg == 3, \ + "signature_alg is %d, expected 3" % (signature_alg,) # ecdsa + + vk = ecdsa.VerifyingKey.from_der(publickey) + vk.verify(unpacked_signature, data, hashfunc=hashlib.sha256, + sigdecode=ecdsa.util.sigdecode_der) + +def check_sth_signature(baseurl, sth): + signature = base64.decodestring(sth["tree_head_signature"]) + + version = struct.pack(">b", 0) + signature_type = struct.pack(">b", 1) + timestamp = struct.pack(">Q", sth["timestamp"]) + tree_size = struct.pack(">Q", sth["tree_size"]) + hash = base64.decodestring(sth["sha256_root_hash"]) + tree_head = version + signature_type + timestamp + tree_size + hash + + check_signature(baseurl, signature, tree_head) + +def check_sct_signature(baseurl, leafcert, sct): publickey = base64.decodestring(publickeys[baseurl]) calculated_logid = hashlib.sha256(publickey).digest() received_logid = base64.decodestring(sct["id"]) @@ -150,16 +182,7 @@ def check_signature(baseurl, leafcert, sct): entry_type + tls_array(leafcert, 3) + \ tls_array(base64.decodestring(sct["extensions"]), 2) - (hash_alg, signature_alg, unpacked_signature) = decode_signature(signature) - assert hash_alg == 4 # sha256 - assert signature_alg == 3 # ecdsa - - hash = hashlib.sha256() - hash.update(signed_struct) - - vk = ecdsa.VerifyingKey.from_der(publickey) - vk.verify(unpacked_signature, signed_struct, hashfunc=hashlib.sha256, - sigdecode=ecdsa.util.sigdecode_der) + check_signature(baseurl, signature, signed_struct) def pack_mtl(timestamp, leafcert): entry_type = struct.pack(">H", 0) diff --git a/tools/submitcert.py b/tools/submitcert.py index e8d8901..1fa6982 100755 --- a/tools/submitcert.py +++ b/tools/submitcert.py @@ -19,7 +19,7 @@ certs = get_certs_from_file(certfile) result = add_chain(baseurl, {"chain":map(base64.b64encode, certs)}) try: - check_signature(baseurl, certs[0], result) + check_sct_signature(baseurl, certs[0], result) except AssertionError, e: print "ERROR:", e sys.exit(1) diff --git a/tools/testcase1.py b/tools/testcase1.py new file mode 100755 index 0000000..63dddc7 --- /dev/null +++ b/tools/testcase1.py @@ -0,0 +1,133 @@ +#!/usr/bin/env python +import urllib2 +import urllib +import json +import base64 +import sys +import struct +import hashlib +import itertools +from certtools import * + +baseurl = "https://127.0.0.1:8080/" +certfiles = ["testcerts/cert1.txt", "testcerts/cert2.txt", + "testcerts/cert3.txt", "testcerts/cert4.txt", + "testcerts/cert5.txt"] + +cc1 = get_certs_from_file(certfiles[0]) +cc2 = get_certs_from_file(certfiles[1]) +cc3 = get_certs_from_file(certfiles[2]) +cc4 = get_certs_from_file(certfiles[3]) +cc5 = get_certs_from_file(certfiles[4]) + +failures = 0 + +def assert_equal(actual, expected, name): + global failures + if actual != expected: + print "ERROR:", name, "expected", expected, "got", actual + failures += 1 + else: + print name, "was correct" + +def print_and_check_tree_size(expected): + global failures + sth = get_sth(baseurl) + try: + check_sth_signature(baseurl, sth) + except AssertionError, e: + print "ERROR:", e + failures += 1 + except ecdsa.keys.BadSignatureError, e: + print "ERROR: bad STH signature" + failures += 1 + tree_size = sth["tree_size"] + if tree_size == expected: + print "tree size", tree_size + else: + print "ERROR: tree size", tree_size, "expected", expected + failures += 1 + +def do_add_chain(chain): + global failures + try: + result = add_chain(baseurl, {"chain":map(base64.b64encode, chain)}) + except ValueError, e: + print "ERROR:", e + failures += 1 + try: + check_sct_signature(baseurl, chain[0], result) + except AssertionError, e: + print "ERROR:", e + failures += 1 + except ecdsa.keys.BadSignatureError, e: + print "ERROR: bad SCT signature" + failures += 1 + print "signature check succeeded" + return result + +def get_and_validate_proof(timestamp, cert, leaf_index, nentries): + merkle_tree_leaf = pack_mtl(timestamp, cert) + leaf_hash = get_leaf_hash(merkle_tree_leaf) + sth = get_sth(baseurl) + proof = get_proof_by_hash(baseurl, leaf_hash, sth["tree_size"]) + assert_equal(proof["leaf_index"], leaf_index, "leaf_index") + assert_equal(len(proof["audit_path"]), nentries, "audit_path length") + +print_and_check_tree_size(0) + +result1 = do_add_chain(cc1) + +print_and_check_tree_size(1) + +result2 = do_add_chain(cc1) + +assert_equal(result2["timestamp"], result1["timestamp"], "timestamp") + +print_and_check_tree_size(1) + +# TODO: add invalid cert and check that it generates an error +# and that treesize still is 1 + +get_and_validate_proof(result1["timestamp"], cc1[0], 0, 0) + +result3 = do_add_chain(cc2) + +print_and_check_tree_size(2) + +get_and_validate_proof(result1["timestamp"], cc1[0], 0, 1) +get_and_validate_proof(result3["timestamp"], cc2[0], 1, 1) + +result4 = do_add_chain(cc3) + +print_and_check_tree_size(3) + +get_and_validate_proof(result1["timestamp"], cc1[0], 0, 2) +get_and_validate_proof(result3["timestamp"], cc2[0], 1, 2) +get_and_validate_proof(result4["timestamp"], cc3[0], 2, 1) + +result5 = do_add_chain(cc4) + +print_and_check_tree_size(4) + +get_and_validate_proof(result1["timestamp"], cc1[0], 0, 2) +get_and_validate_proof(result3["timestamp"], cc2[0], 1, 2) +get_and_validate_proof(result4["timestamp"], cc3[0], 2, 2) +get_and_validate_proof(result5["timestamp"], cc4[0], 3, 2) + +result6 = do_add_chain(cc5) + +print_and_check_tree_size(5) + +get_and_validate_proof(result1["timestamp"], cc1[0], 0, 3) +get_and_validate_proof(result3["timestamp"], cc2[0], 1, 3) +get_and_validate_proof(result4["timestamp"], cc3[0], 2, 3) +get_and_validate_proof(result5["timestamp"], cc4[0], 3, 3) +get_and_validate_proof(result6["timestamp"], cc5[0], 4, 1) + +print "-------" +if failures: + print failures, "failed tests" if failures != 1 else "failed test" + sys.exit(1) +else: + print "all tests succeeded" diff --git a/tools/testcerts/cert1.txt b/tools/testcerts/cert1.txt new file mode 100644 index 0000000..4871b22 --- /dev/null +++ b/tools/testcerts/cert1.txt @@ -0,0 +1,86 @@ +CONNECTED(00000003) +--- +Certificate chain + 0 s:/C=SE/2.5.4.17=114 27/ST=Stockholms l\xC3\xA4n/L=Stockholm/2.5.4.9=Valhallav\xC3\xA4gen 79/O=Kungliga Tekniska H\xC3\xB6gskolan/OU=ITA/CN=ns-vip-01.sys.kth.se + i:/C=NL/O=TERENA/CN=TERENA SSL CA +-----BEGIN CERTIFICATE----- +MIIFBTCCA+2gAwIBAgIRAN/MrgvfgxMmWUPdGv/VYEgwDQYJKoZIhvcNAQEFBQAw +NjELMAkGA1UEBhMCTkwxDzANBgNVBAoTBlRFUkVOQTEWMBQGA1UEAxMNVEVSRU5B +IFNTTCBDQTAeFw0xNDA3MDMwMDAwMDBaFw0xNzA3MDIyMzU5NTlaMIG8MQswCQYD +VQQGEwJTRTEPMA0GA1UEERMGMTE0IDI3MRgwFgYDVQQIDA9TdG9ja2hvbG1zIGzD +pG4xEjAQBgNVBAcTCVN0b2NraG9sbTEaMBgGA1UECQwRVmFsaGFsbGF2w6RnZW4g +NzkxJTAjBgNVBAoMHEt1bmdsaWdhIFRla25pc2thIEjDtmdza29sYW4xDDAKBgNV +BAsTA0lUQTEdMBsGA1UEAxMUbnMtdmlwLTAxLnN5cy5rdGguc2UwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCmIUMi8T6Mf+ku/h7d0bYsi8/oKySKTpkS +rzeAbuUNhmnT+VTMvb2w538KcPKnOhFGFRF3Lzfa1j70vKuLWbfLqQHOXa0Yq0zb +mvVNFH9Uthtpmv7uj5o8uK7kTSNF2FzaWnm3gg6QckxYAAS1eG9wjRvfSSSwzbw0 +e/y3tvhN+vxerzZX8oiY4dFWmtmPRf9xE18LkQus41AJPLH+4SCXbpuJn4Vo3kTk +rZp2MZo4bZ6PB/y257FowNOokkQG/Qg6wOX+9WW/zHCj8RqofaEhmpgtVyOklgJk +DTLN8Z8869Zo+Nt2TeDyPWRr+IxFSVZCXAnEL0qCMYDrHAzZKJkDAgMBAAGjggGF +MIIBgTAfBgNVHSMEGDAWgBQMvZNoDPPeq6NJays3V0fqkOO57TAdBgNVHQ4EFgQU +3BVAdQu5ifzshxwoM7LxZfO3KnEwDgYDVR0PAQH/BAQDAgWgMAwGA1UdEwEB/wQC +MAAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMCIGA1UdIAQbMBkwDQYL +KwYBBAGyMQECAh0wCAYGZ4EMAQICMDoGA1UdHwQzMDEwL6AtoCuGKWh0dHA6Ly9j +cmwudGNzLnRlcmVuYS5vcmcvVEVSRU5BU1NMQ0EuY3JsMG0GCCsGAQUFBwEBBGEw +XzA1BggrBgEFBQcwAoYpaHR0cDovL2NydC50Y3MudGVyZW5hLm9yZy9URVJFTkFT +U0xDQS5jcnQwJgYIKwYBBQUHMAGGGmh0dHA6Ly9vY3NwLnRjcy50ZXJlbmEub3Jn +MDMGA1UdEQQsMCqCFG5zLXZpcC0wMS5zeXMua3RoLnNlggZrdGguc2WCCnd3dy5r +dGguc2UwDQYJKoZIhvcNAQEFBQADggEBAK7O5ycJffAYElE0wXYDyRIakFWHbouO +0l9D+npPMz8pKzIeLEZ46/sCK9E+Nd3AkCIpL0hZftlSKsDg3mppAgMhMLn2/Tux +HelMlEqdwN7/7fiNPGzsBYu4fBqpGddbI69RWf/1JzR2Xeo76kQ6UCwg3EirYfw7 +zpeV81ct9fxYcFEyabiG18l7hmYEm/3SeKeRDcYWauk+hB/kg7lzCJ2qZFIk/sQM +EEmI7JvoNuAfrWYwfr9hG39CawNQ0beGnlAAKxJeU2IC1Sbl9ccBu1JFRcsMRTr+ +Y8IfG+gNlh5a/vDJ98MnSJZp8QZo1TXDinEk+2tSHVR5iin1oOH1D60= +-----END CERTIFICATE----- + 1 s:/C=NL/O=TERENA/CN=TERENA SSL CA + i:/C=US/ST=UT/L=Salt Lake City/O=The USERTRUST Network/OU=http://www.usertrust.com/CN=UTN-USERFirst-Hardware +-----BEGIN CERTIFICATE----- +MIIEmDCCA4CgAwIBAgIQS8gUAy8H+mqk8Nop32F5ujANBgkqhkiG9w0BAQUFADCB +lzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug +Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho +dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3Qt +SGFyZHdhcmUwHhcNMDkwNTE4MDAwMDAwWhcNMjAwNTMwMTA0ODM4WjA2MQswCQYD +VQQGEwJOTDEPMA0GA1UEChMGVEVSRU5BMRYwFAYDVQQDEw1URVJFTkEgU1NMIENB +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw+NIxC9cwcupmf0booNd +ij2tOtDipEMfTQ7+NSUwpWkbxOjlwY9UfuFqoppcXN49/ALOlrhfj4NbzGBAkPjk +tjolnF8UUeyx56+eUKExVccCvaxSin81joL6hK0V/qJ/gxA6VVOULAEWdJRUYyij +8lspPZSIgCDiFFkhGbSkmOFg5vLrooCDQ+CtaPN5GYtoQ1E/iptBhQw1jF218bbl +p8ODtWsjb9Sl61DllPFKX+4nSxQSFSRMDc9ijbcAIa06Mg9YC18em9HfnY6pGTVQ +L0GprTvG4EWyUzl/Ib8iGodcNK5Sbwd9ogtOnyt5pn0T3fV/g3wvWl13eHiRoBS/ +fQIDAQABo4IBPjCCATowHwYDVR0jBBgwFoAUoXJfJhsomEOVXQc31YWWnUvSw0Uw +HQYDVR0OBBYEFAy9k2gM896ro0lrKzdXR+qQ47ntMA4GA1UdDwEB/wQEAwIBBjAS +BgNVHRMBAf8ECDAGAQH/AgEAMBgGA1UdIAQRMA8wDQYLKwYBBAGyMQECAh0wRAYD +VR0fBD0wOzA5oDegNYYzaHR0cDovL2NybC51c2VydHJ1c3QuY29tL1VUTi1VU0VS +Rmlyc3QtSGFyZHdhcmUuY3JsMHQGCCsGAQUFBwEBBGgwZjA9BggrBgEFBQcwAoYx +aHR0cDovL2NydC51c2VydHJ1c3QuY29tL1VUTkFkZFRydXN0U2VydmVyX0NBLmNy +dDAlBggrBgEFBQcwAYYZaHR0cDovL29jc3AudXNlcnRydXN0LmNvbTANBgkqhkiG +9w0BAQUFAAOCAQEATiPuSJz2hYtxxApuc5NywDqOgIrZs8qy1AGcKM/yXA4hRJML +thoh45gBlA5nSYEevj0NTmDa76AxTpXv8916WoIgQ7ahY0OzUGlDYktWYrA0irkT +Q1mT7BR5iPNIk+idyfqHcgxrVqDDFY1opYcfcS3mWm08aXFABFXcoEOUIEU4eNe9 +itg5xt8Jt1qaqQO4KBB4zb8BG1oRPjj02Bs0ec8z0gH9rJjNbUcRkEy7uVvYcOfV +r7bMxIbmdcCeKbYrDyqlaQIN4+mitF3A884saoU4dmHGSYKrUbOCprlBmCiY+2v+ +ihb/MX5UR6g83EMmqZsFt57ANEORMNQywxFa4Q== +-----END CERTIFICATE----- +--- +Server certificate +subject=/C=SE/2.5.4.17=114 27/ST=Stockholms l\xC3\xA4n/L=Stockholm/2.5.4.9=Valhallav\xC3\xA4gen 79/O=Kungliga Tekniska H\xC3\xB6gskolan/OU=ITA/CN=ns-vip-01.sys.kth.se +issuer=/C=NL/O=TERENA/CN=TERENA SSL CA +--- +No client certificate CA names sent +--- +SSL handshake has read 2608 bytes and written 452 bytes +--- +New, TLSv1/SSLv3, Cipher is RC4-MD5 +Server public key is 2048 bit +SSL-Session: + Protocol : TLSv1 + Cipher : RC4-MD5 + Session-ID: 1CB6F52D821C229181597FA36C61A4DAB2AB0330A5157E1C8094AA73D475C123 + Session-ID-ctx: + Master-Key: E01E6B7F470205A7BAE7CCB5290A57E59DE52D822E5AFC5BFFC1DD28C5CA9D4D55CD2308CCB7E302641BF5B352E6AB11 + Key-Arg : None + Krb5 Principal: None + Start Time: 1406768584 + Timeout : 300 (sec) + Verify return code: 20 (unable to get local issuer certificate) +--- diff --git a/tools/testcerts/cert2.txt b/tools/testcerts/cert2.txt new file mode 100644 index 0000000..011caf5 --- /dev/null +++ b/tools/testcerts/cert2.txt @@ -0,0 +1,138 @@ +CONNECTED(00000003) +--- +Certificate chain + 0 s:/C=SE/O=Kungliga Tekniska H\xC3\xB6gskolan/OU=ITA/CN=www.lan.kth.se + i:/C=NL/O=TERENA/CN=TERENA SSL CA +-----BEGIN CERTIFICATE----- +MIIEfzCCA2egAwIBAgIRALtnWx1jbyJqNiquRFaHsxwwDQYJKoZIhvcNAQEFBQAw +NjELMAkGA1UEBhMCTkwxDzANBgNVBAoTBlRFUkVOQTEWMBQGA1UEAxMNVEVSRU5B +IFNTTCBDQTAeFw0xMzAxMTYwMDAwMDBaFw0xNjAxMTYyMzU5NTlaMFsxCzAJBgNV +BAYTAlNFMSUwIwYDVQQKDBxLdW5nbGlnYSBUZWtuaXNrYSBIw7Znc2tvbGFuMQww +CgYDVQQLEwNJVEExFzAVBgNVBAMTDnd3dy5sYW4ua3RoLnNlMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2fC9NwlmMN9ja8S9sMRdPXTY9XMutGDbVStq +VQbflK1A4Ap3ODAEIsTFz1xn5OvrxSPFyphbDwNDlfvnB9lWQQvG6EZ003zExbiY +g2WrUk74IsGEgvjw3u+1DIRJCO/mKXlg1a/8wkzINXvnra+yTMDO8VLmiLmUrvn+ +yYi8gr7ekUgFr+3rm9J25tfHyan9p15RMcI//WQTfjq3X/EnyImOiZpMyh0OjSif +LnwHrE0M3grivYP6PZN3mJjKJNFGL9zh5S/Wt4Q65t9wXhO5oAkDA9XS6bk1yOv2 +V81qRANaBdP/ieHghko2UV/mGeHeJhHYB02XFg5mpxxIndBcxwIDAQABo4IBYTCC +AV0wHwYDVR0jBBgwFoAUDL2TaAzz3qujSWsrN1dH6pDjue0wHQYDVR0OBBYEFDAA +juxftrwLBCSto5PE6PBYMX1RMA4GA1UdDwEB/wQEAwIFoDAMBgNVHRMBAf8EAjAA +MB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAYBgNVHSAEETAPMA0GCysG +AQQBsjEBAgIdMDoGA1UdHwQzMDEwL6AtoCuGKWh0dHA6Ly9jcmwudGNzLnRlcmVu +YS5vcmcvVEVSRU5BU1NMQ0EuY3JsMG0GCCsGAQUFBwEBBGEwXzA1BggrBgEFBQcw +AoYpaHR0cDovL2NydC50Y3MudGVyZW5hLm9yZy9URVJFTkFTU0xDQS5jcnQwJgYI +KwYBBQUHMAGGGmh0dHA6Ly9vY3NwLnRjcy50ZXJlbmEub3JnMBkGA1UdEQQSMBCC +Dnd3dy5sYW4ua3RoLnNlMA0GCSqGSIb3DQEBBQUAA4IBAQCrfiHdIwVEVO1HwZXb +Hi5KsOFDcHS+MH5tvo2Cj6uXzDOMFWSoLm31MR4TK55Hzz7oMkpO+rxchqpvoUtl +m2ma9phntzvCppeOcob2dZt6lyqzg4uIxlgV6ucULQ27KlwGZPAp46ZdK1M3qVMR +gQ2kOXc0wMAKFXu4qvrj2JsWFnZKn233Cg2iS6ixDjqZvSxzC23buhN48dzCdYI/ +mWaisULtkd95O+WhtQPp5tP5QqGmwGoM6+Q1StOo4068CG1TRDoQWnjVHHt5yU2O +gG3YSEwpMe/FJS4UcojdAkWewbv4ArP72/LEBkqubicFib6ALkQ7WfuUf8XN4Ky3 +vVwW +-----END CERTIFICATE----- + 1 s:/C=NL/O=TERENA/CN=TERENA SSL CA + i:/C=US/ST=UT/L=Salt Lake City/O=The USERTRUST Network/OU=http://www.usertrust.com/CN=UTN-USERFirst-Hardware +-----BEGIN CERTIFICATE----- +MIIEmDCCA4CgAwIBAgIQS8gUAy8H+mqk8Nop32F5ujANBgkqhkiG9w0BAQUFADCB +lzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug +Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho +dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3Qt +SGFyZHdhcmUwHhcNMDkwNTE4MDAwMDAwWhcNMjAwNTMwMTA0ODM4WjA2MQswCQYD +VQQGEwJOTDEPMA0GA1UEChMGVEVSRU5BMRYwFAYDVQQDEw1URVJFTkEgU1NMIENB +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw+NIxC9cwcupmf0booNd +ij2tOtDipEMfTQ7+NSUwpWkbxOjlwY9UfuFqoppcXN49/ALOlrhfj4NbzGBAkPjk +tjolnF8UUeyx56+eUKExVccCvaxSin81joL6hK0V/qJ/gxA6VVOULAEWdJRUYyij +8lspPZSIgCDiFFkhGbSkmOFg5vLrooCDQ+CtaPN5GYtoQ1E/iptBhQw1jF218bbl +p8ODtWsjb9Sl61DllPFKX+4nSxQSFSRMDc9ijbcAIa06Mg9YC18em9HfnY6pGTVQ +L0GprTvG4EWyUzl/Ib8iGodcNK5Sbwd9ogtOnyt5pn0T3fV/g3wvWl13eHiRoBS/ +fQIDAQABo4IBPjCCATowHwYDVR0jBBgwFoAUoXJfJhsomEOVXQc31YWWnUvSw0Uw +HQYDVR0OBBYEFAy9k2gM896ro0lrKzdXR+qQ47ntMA4GA1UdDwEB/wQEAwIBBjAS +BgNVHRMBAf8ECDAGAQH/AgEAMBgGA1UdIAQRMA8wDQYLKwYBBAGyMQECAh0wRAYD +VR0fBD0wOzA5oDegNYYzaHR0cDovL2NybC51c2VydHJ1c3QuY29tL1VUTi1VU0VS +Rmlyc3QtSGFyZHdhcmUuY3JsMHQGCCsGAQUFBwEBBGgwZjA9BggrBgEFBQcwAoYx +aHR0cDovL2NydC51c2VydHJ1c3QuY29tL1VUTkFkZFRydXN0U2VydmVyX0NBLmNy +dDAlBggrBgEFBQcwAYYZaHR0cDovL29jc3AudXNlcnRydXN0LmNvbTANBgkqhkiG +9w0BAQUFAAOCAQEATiPuSJz2hYtxxApuc5NywDqOgIrZs8qy1AGcKM/yXA4hRJML +thoh45gBlA5nSYEevj0NTmDa76AxTpXv8916WoIgQ7ahY0OzUGlDYktWYrA0irkT +Q1mT7BR5iPNIk+idyfqHcgxrVqDDFY1opYcfcS3mWm08aXFABFXcoEOUIEU4eNe9 +itg5xt8Jt1qaqQO4KBB4zb8BG1oRPjj02Bs0ec8z0gH9rJjNbUcRkEy7uVvYcOfV +r7bMxIbmdcCeKbYrDyqlaQIN4+mitF3A884saoU4dmHGSYKrUbOCprlBmCiY+2v+ +ihb/MX5UR6g83EMmqZsFt57ANEORMNQywxFa4Q== +-----END CERTIFICATE----- + 2 s:/C=US/ST=UT/L=Salt Lake City/O=The USERTRUST Network/OU=http://www.usertrust.com/CN=UTN-USERFirst-Hardware + i:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root +-----BEGIN CERTIFICATE----- +MIIEPDCCAySgAwIBAgIQSEus8arH1xND0aJ0NUmXJTANBgkqhkiG9w0BAQUFADBv +MQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFk +ZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBF +eHRlcm5hbCBDQSBSb290MB4XDTA1MDYwNzA4MDkxMFoXDTIwMDUzMDEwNDgzOFow +gZcxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJVVDEXMBUGA1UEBxMOU2FsdCBMYWtl +IENpdHkxHjAcBgNVBAoTFVRoZSBVU0VSVFJVU1QgTmV0d29yazEhMB8GA1UECxMY +aHR0cDovL3d3dy51c2VydHJ1c3QuY29tMR8wHQYDVQQDExZVVE4tVVNFUkZpcnN0 +LUhhcmR3YXJlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsffDOD+0 +qH/POYJRZ9Btn9L/WPPnnyvsDYlUmbk4mRb34CF5SMK7YXQSlh08anLVPBBnOjnt +KxPNZuuVCTOkbJex6MbswXV5nEZejavQav25KlUXEFSzGfCa9vGxXbanbfvgcRdr +ooj7AN/+GjF3DJoBerEy4ysBBzhuw6VeI7xFm3tQwckwj9vlK3rTW/szQB6g1ZgX +vIuHw4nTXaCOsqqq9o5piAbF+okh8widaS4JM5spDUYPjMxJNLBpUb35Bs1orWZM +vD6sYb0KiA7I3z3ufARMnQpea5HW7sftKI2rTYeJc9BupNAeFosU4XZEA39jrOTN +SZzFkvSrMqFIWwIDAQABo4GqMIGnMB8GA1UdIwQYMBaAFK29mHo0tCb3+sQmVO8D +veAky1QaMB0GA1UdDgQWBBShcl8mGyiYQ5VdBzfVhZadS9LDRTAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBEBgNVHR8EPTA7MDmgN6A1hjNodHRwOi8v +Y3JsLnVzZXJ0cnVzdC5jb20vQWRkVHJ1c3RFeHRlcm5hbENBUm9vdC5jcmwwDQYJ +KoZIhvcNAQEFBQADggEBADzse+Cuow6WbTDXhcbSaFtFWoKmNA+wyZIjXhFtCBGy +dAkjOjUlc1heyrl8KPpH7PmgA1hQtlPvjNs55Gfp2MooRtSn4PU4dfjny1y/HRE8 +akCbLURW0/f/BSgyDBXIZEWT6CEkjy3aeoR7T8/NsiV8dxDTlNEEkaglHAkiD31E +NREU768A/l7qX46w2ZJZuvwTlqAYAVbO2vYoC7Gv3VxPXLLzj1pxz+0YrWOIHY6V +9+qV5x+tkLiECEeFfyIvGh1IMNZMCNg3GWcyK+tc0LL8blefBDVekAB+EcfeEyrN +pG1FJseIVqDwavfY5/wnfmcI0L36tsNhAgFlubgvz1o= +-----END CERTIFICATE----- + 3 s:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root + i:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root +-----BEGIN CERTIFICATE----- +MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU +MBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs +IFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290 +MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1UEBhMCU0Ux +FDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5h +bCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9v +dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvt +H7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9 +uMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzX +mk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LX +a0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzN +E0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0 +WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD +VR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0 +Jvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU +cnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsx +IjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJKoZIhvcN +AQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxH +YINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5 +6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvC +Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX +c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a +mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ= +-----END CERTIFICATE----- +--- +Server certificate +subject=/C=SE/O=Kungliga Tekniska H\xC3\xB6gskolan/OU=ITA/CN=www.lan.kth.se +issuer=/C=NL/O=TERENA/CN=TERENA SSL CA +--- +No client certificate CA names sent +--- +SSL handshake has read 5205 bytes and written 340 bytes +--- +New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA +Server public key is 2048 bit +SSL-Session: + Protocol : TLSv1 + Cipher : DHE-RSA-AES256-SHA + Session-ID: 6389C01938F30B55DE1970773DAF16F5F0577712DCC25140FC5B09E60712DF4C + Session-ID-ctx: + Master-Key: 0ABCD607E10E921BDF9D0D5439972F8789517C18318AF2FA5CEFF7F45A74F246C27D25ED9E6CE97500156803DA037BDA + Key-Arg : None + Krb5 Principal: None + Start Time: 1411388821 + Timeout : 300 (sec) + Verify return code: 19 (self signed certificate in certificate chain) +--- diff --git a/tools/testcerts/cert3.txt b/tools/testcerts/cert3.txt new file mode 100644 index 0000000..d12e485 --- /dev/null +++ b/tools/testcerts/cert3.txt @@ -0,0 +1,78 @@ +CONNECTED(00000003) +--- +Certificate chain + 0 s:/OU=Domain Control Validated/CN=*.nordu.net + i:/C=NL/O=TERENA/CN=TERENA SSL CA + 1 s:/C=NL/O=TERENA/CN=TERENA SSL CA + i:/C=US/ST=UT/L=Salt Lake City/O=The USERTRUST Network/OU=http://www.usertrust.com/CN=UTN-USERFirst-Hardware + 2 s:/C=US/ST=UT/L=Salt Lake City/O=The USERTRUST Network/OU=http://www.usertrust.com/CN=UTN-USERFirst-Hardware + i:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root +--- +Server certificate +-----BEGIN CERTIFICATE----- +MIIEZDCCA0ygAwIBAgIRALmfsKN7LvrBTlo9bsrluT0wDQYJKoZIhvcNAQEFBQAw +NjELMAkGA1UEBhMCTkwxDzANBgNVBAoTBlRFUkVOQTEWMBQGA1UEAxMNVEVSRU5B +IFNTTCBDQTAeFw0xMzAzMjEwMDAwMDBaFw0xNjA0MDIyMzU5NTlaMDkxITAfBgNV +BAsTGERvbWFpbiBDb250cm9sIFZhbGlkYXRlZDEUMBIGA1UEAxQLKi5ub3JkdS5u +ZXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQClir/sHXJpaMQ8SpK1 +giyizJhK9GSuZkoTaIKiK2hXkHUbxJ09w6pspWXPbUwLK8ZFn32vHMabshKxe4fL +d0kR/AEr9okwfnABK7+u4CBEs10D2oVrRFS2GFAUtri8v+5+n/mWDoqGc2XybQNs +CoYyVdSYs6YO/+b8dEGfOrRD2XFoTtP32T35YIlejwpg72f9lUnvOi6Jh+s6jV8P +hIJV6w3exVQojDiEPSQ3fV/KF6FAaQK4XyEspHL4TH0mtaJhEjnAvHDmN1Bw4WhV +0Bm86alryZxYNTmpPXDD5AFNBIuL+5FfQgZm+s7QzZriguRGDv8L+YKePFvhiaPV +AagTAgMBAAGjggFoMIIBZDAfBgNVHSMEGDAWgBQMvZNoDPPeq6NJays3V0fqkOO5 +7TAdBgNVHQ4EFgQU6YkL0qj0tSK5bsZfjDUNLwXUlFgwDgYDVR0PAQH/BAQDAgWg +MAwGA1UdEwEB/wQCMAAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMCIG +A1UdIAQbMBkwDQYLKwYBBAGyMQECAh0wCAYGZ4EMAQIBMDoGA1UdHwQzMDEwL6At +oCuGKWh0dHA6Ly9jcmwudGNzLnRlcmVuYS5vcmcvVEVSRU5BU1NMQ0EuY3JsMG0G +CCsGAQUFBwEBBGEwXzA1BggrBgEFBQcwAoYpaHR0cDovL2NydC50Y3MudGVyZW5h +Lm9yZy9URVJFTkFTU0xDQS5jcnQwJgYIKwYBBQUHMAGGGmh0dHA6Ly9vY3NwLnRj +cy50ZXJlbmEub3JnMBYGA1UdEQQPMA2CCyoubm9yZHUubmV0MA0GCSqGSIb3DQEB +BQUAA4IBAQAdj2R0qT47oLIMnYw69qU58VZB/rnejwhNVdzLtLZ+vQ1YwcXoabOi +9LmSOZ019ESWxZ415/FjvoLXYKpkq8w96bDw/jqPhUWwK2U6EpD/MlYUKWyAH9XP +ZLBaYewZEBjkwxYIlroUboPWXUYJIDwotvNgSE9N8Xy1XZ4oi0UVfxxyo3XRpS49 +Ch1az16jKS5rF5R1Q/t6UxYrnfx4XMZHFx56ks6kpucxch37JJ/2i1O84/T9lX17 +7qwk+SO93EmtgxE40wtvL1i2cTZaNHcybyClV6N3Bm8Hu2L4e35SF761CMc4rzlu +SbDmRK4Rxa5UmgfZnezD0snHVUCrzKzP +-----END CERTIFICATE----- +subject=/OU=Domain Control Validated/CN=*.nordu.net +issuer=/C=NL/O=TERENA/CN=TERENA SSL CA +--- +No client certificate CA names sent +--- +SSL handshake has read 4093 bytes and written 434 bytes +--- +New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384 +Server public key is 2048 bit +Secure Renegotiation IS supported +Compression: NONE +Expansion: NONE +SSL-Session: + Protocol : TLSv1.2 + Cipher : ECDHE-RSA-AES256-GCM-SHA384 + Session-ID: 1A247C94557A7847AA13E2EFD64ECE3C2DD142B15ABB7BF78BFE43F28BB2C144 + Session-ID-ctx: + Master-Key: D714373C285767FD040C497DFA59C81AA43BCF62AB9199F5FAB2C34211F7FB767922047DD758441C5493B238E716B477 + Key-Arg : None + PSK identity: None + PSK identity hint: None + SRP username: None + TLS session ticket lifetime hint: 300 (seconds) + TLS session ticket: + 0000 - 7d 26 51 e1 11 16 18 15-b2 1c 21 51 10 10 f0 0d }&Q.......!Q.... + 0010 - 29 f5 24 13 c8 a5 dd 34-87 c1 36 6a 97 12 cc f3 ).$....4..6j.... + 0020 - e4 bb 50 db 39 94 3b b3-8e 52 df 73 89 a2 30 91 ..P.9.;..R.s..0. + 0030 - 4e a5 8c 80 97 49 79 0f-ce a9 1a eb a8 a0 2d fa N....Iy.......-. + 0040 - 53 90 fe f1 29 1b 43 5d-09 cc 6c 81 de f8 41 e7 S...).C]..l...A. + 0050 - dc c3 57 b5 66 e0 03 2b-fd e7 82 5b b6 c4 6a fe ..W.f..+...[..j. + 0060 - 15 55 55 cd ea af a6 b8-c5 80 2f c8 2d dd bf a0 .UU......./.-... + 0070 - 1b 23 4c 60 67 70 1c 39-2c 9a 39 1d e0 a4 f7 c0 .#L`gp.9,.9..... + 0080 - 6e c9 8b 59 c2 cc 2b 12-ee 5d 8f 8c 4a 8e ab 07 n..Y..+..]..J... + 0090 - 9e be d3 89 9d c1 1e 17-a5 65 19 41 14 63 32 62 .........e.A.c2b + 00a0 - ce 51 ce ee c0 0c 01 49-b0 0b da 41 29 67 21 e0 .Q.....I...A)g!. + 00b0 - 2f 77 e2 35 44 35 ba 78-47 fc 3c 11 24 57 8d e3 /w.5D5.xG.<.$W.. + + Start Time: 1411743389 + Timeout : 300 (sec) + Verify return code: 20 (unable to get local issuer certificate) +--- diff --git a/tools/testcerts/cert4.txt b/tools/testcerts/cert4.txt new file mode 100644 index 0000000..1762e35 --- /dev/null +++ b/tools/testcerts/cert4.txt @@ -0,0 +1,89 @@ +CONNECTED(00000003) +--- +Certificate chain + 0 s:/businessCategory=Private Organization/1.3.6.1.4.1.311.60.2.1.3=US/1.3.6.1.4.1.311.60.2.1.2=Delaware/serialNumber=3359300/street=16 Allen Rd/postalCode=03894-4801/C=US/ST=NH/L=Wolfeboro,/O=Python Software Foundation/CN=www.python.org + i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 Extended Validation Server CA + 1 s:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 Extended Validation Server CA + i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance EV Root CA +--- +Server certificate +-----BEGIN CERTIFICATE----- +MIIG2jCCBcKgAwIBAgIQAbtvABIrF382yrSc6otrJjANBgkqhkiG9w0BAQsFADB1 +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMTQwMgYDVQQDEytEaWdpQ2VydCBTSEEyIEV4dGVuZGVk +IFZhbGlkYXRpb24gU2VydmVyIENBMB4XDTE0MDkwNTAwMDAwMFoXDTE2MDkwOTEy +MDAwMFowgfkxHTAbBgNVBA8TFFByaXZhdGUgT3JnYW5pemF0aW9uMRMwEQYLKwYB +BAGCNzwCAQMTAlVTMRkwFwYLKwYBBAGCNzwCAQITCERlbGF3YXJlMRAwDgYDVQQF +EwczMzU5MzAwMRQwEgYDVQQJEwsxNiBBbGxlbiBSZDETMBEGA1UEERMKMDM4OTQt +NDgwMTELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAk5IMRMwEQYDVQQHEwpXb2xmZWJv +cm8sMSMwIQYDVQQKExpQeXRob24gU29mdHdhcmUgRm91bmRhdGlvbjEXMBUGA1UE +AxMOd3d3LnB5dGhvbi5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQCtUnfHpOteoIqZxGsaR/2tIenj0+pBtNBiWT6PlYLLXC6MNRjFwtnhRzEVanAm +GEEOEQwUokYZHw8kCL2SIZ1DFI5IIFyhTFql1dqiKtoQse0LAZlUHscVxn9OZyWM +DA4JZ6A4c3/j5SA9hGO3+KyTc95GfiEXqkSkmjH3aBtY2flr+H1fvatQA8AIAD5k +weQLFbbqi33Uvf4sJ3OhY63Kf1ZWteXSeCT+FRMlFTaYbauo86AmU9X2/b85wold +naUO3VjcGjTSoSuaxtWuHFRxpOTBG7bqPbtWk+X5l+rjsIoGJ6ZrRFbAtHqG+S3v +luEG9FtgGAo+3hKm99U8UKKVAgMBAAGjggLfMIIC2zAfBgNVHSMEGDAWgBQ901Cl +1qCt7vNKYApl0yHU+PjWDzAdBgNVHQ4EFgQUTWfmKThuIBhkZX4B3yNf+DpBqokw +ggEUBgNVHREEggELMIIBB4IOd3d3LnB5dGhvbi5vcmeCCnB5dGhvbi5vcmeCD3B5 +cGkucHl0aG9uLm9yZ4IPZG9jcy5weXRob24ub3JnghN0ZXN0cHlwaS5weXRob24u +b3Jngg9idWdzLnB5dGhvbi5vcmeCD3dpa2kucHl0aG9uLm9yZ4INaGcucHl0aG9u +Lm9yZ4IPbWFpbC5weXRob24ub3JnghRwYWNrYWdpbmcucHl0aG9uLm9yZ4IQcHl0 +aG9uaG9zdGVkLm9yZ4IUd3d3LnB5dGhvbmhvc3RlZC5vcmeCFXRlc3QucHl0aG9u +aG9zdGVkLm9yZ4IMdXMucHljb24ub3Jngg1pZC5weXRob24ub3JnMA4GA1UdDwEB +/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwdQYDVR0fBG4w +bDA0oDKgMIYuaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL3NoYTItZXYtc2VydmVy +LWcxLmNybDA0oDKgMIYuaHR0cDovL2NybDQuZGlnaWNlcnQuY29tL3NoYTItZXYt +c2VydmVyLWcxLmNybDBCBgNVHSAEOzA5MDcGCWCGSAGG/WwCATAqMCgGCCsGAQUF +BwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5jb20vQ1BTMIGIBggrBgEFBQcBAQR8 +MHowJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBSBggrBgEF +BQcwAoZGaHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkV4 +dGVuZGVkVmFsaWRhdGlvblNlcnZlckNBLmNydDAMBgNVHRMBAf8EAjAAMA0GCSqG +SIb3DQEBCwUAA4IBAQBsTgMOFUP8wHVpgCzm/fQTrKp4nxcb9m9gkTW1aRKuhlAY +g/CUQ8DC0Ii1XqOolTmGi6NIyX2Xf+RWqh7UzK+Q30Y2RGGb/47uZaif9WaIlKGn +40D1mzzyGjrfTMSSFlrtwyg/3yM8KN800Cz5HgXnHD2qIuYcYqXRRS6E7PEHB1Dm +h72iCAHYwUTgfcfqUWVEZ26EQhP4Lk4+hs2UJsAUnMWj7/bnk8LR/KZumLuuv3RK +lmR1Qg+9AChafiCCFra1UxfgznvF5ocJzr6nNmYc6k1ImaipRq7c/OuwUTTqNqR2 +FceHmpqlkA2AvjdvSvwnODux3QPbMucIaJXrUUwf +-----END CERTIFICATE----- +subject=/businessCategory=Private Organization/1.3.6.1.4.1.311.60.2.1.3=US/1.3.6.1.4.1.311.60.2.1.2=Delaware/serialNumber=3359300/street=16 Allen Rd/postalCode=03894-4801/C=US/ST=NH/L=Wolfeboro,/O=Python Software Foundation/CN=www.python.org +issuer=/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 Extended Validation Server CA +--- +No client certificate CA names sent +--- +SSL handshake has read 3662 bytes and written 434 bytes +--- +New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256 +Server public key is 2048 bit +Secure Renegotiation IS supported +Compression: NONE +Expansion: NONE +SSL-Session: + Protocol : TLSv1.2 + Cipher : ECDHE-RSA-AES128-GCM-SHA256 + Session-ID: 1DE0E69544F8883ADCF023857A02135C5332AB1D514A30DAB522FCF6F23E1DB6 + Session-ID-ctx: + Master-Key: 5959095AB05ED21709F503091DFCEAFDBD8C3ED809DA5BC8886A6E25A7D66D78F8528A20C900F288E77852C311E881EF + Key-Arg : None + PSK identity: None + PSK identity hint: None + SRP username: None + TLS session ticket lifetime hint: 14400 (seconds) + TLS session ticket: + 0000 - 63 cc 77 4a 00 db 2c 42-2e 8f 76 23 dd a9 ae 53 c.wJ..,B..v#...S + 0010 - f0 ac 9f 96 82 bb 06 da-a2 8b 3a 44 cb 66 77 d2 ..........:D.fw. + 0020 - 01 7d 5a b4 0e bd 63 d0-38 f4 86 b4 05 76 68 9f .}Z...c.8....vh. + 0030 - 6f 76 1a 2e 06 93 3d d2-05 7e 0e 57 1a 0d a0 22 ov....=..~.W..." + 0040 - f5 17 e5 1b a7 9d b9 02-95 d8 08 cb 10 31 fb e9 .............1.. + 0050 - 63 26 8c 6e 52 76 cb 7f-64 cc bc c6 43 52 cf 0f c&.nRv..d...CR.. + 0060 - 8e ba 6a 6d b2 30 43 c5-0c 6b 5c 7d 86 90 ad 02 ..jm.0C..k\}.... + 0070 - 8a 71 3b 17 22 ae 4f a6-0e 1b d8 5a fa 86 f1 3c .q;.".O....Z...< + 0080 - c4 bd 56 7d 6d 40 ed 06-f5 12 56 ff 15 ab 39 69 ..V}m@....V...9i + 0090 - 20 21 84 e5 15 ac 52 58-8b 13 d0 f3 db 89 a7 c6 !....RX........ + 00a0 - fd 35 6b ec 94 19 99 e1-cb 28 89 3d aa bb ba 52 .5k......(.=...R + 00b0 - 13 1a 7b c8 39 04 7d cc-49 34 99 52 88 ce ac 8d ..{.9.}.I4.R.... + + Start Time: 1411736151 + Timeout : 300 (sec) + Verify return code: 20 (unable to get local issuer certificate) +--- diff --git a/tools/testcerts/cert5.txt b/tools/testcerts/cert5.txt new file mode 100644 index 0000000..0f3f8f1 --- /dev/null +++ b/tools/testcerts/cert5.txt @@ -0,0 +1,105 @@ +CONNECTED(00000003) +--- +Certificate chain + 0 s:/C=US/ST=California/L=San Francisco/O=Wikimedia Foundation, Inc./CN=*.wikipedia.org + i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance CA-3 + 1 s:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance CA-3 + i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance EV Root CA +--- +Server certificate +-----BEGIN CERTIFICATE----- +MIIKMzCCCRugAwIBAgIQDfxZHyWomiN2WUOBQIituTANBgkqhkiG9w0BAQUFADBm +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSUwIwYDVQQDExxEaWdpQ2VydCBIaWdoIEFzc3VyYW5j +ZSBDQS0zMB4XDTEyMTAyMjAwMDAwMFoXDTE2MDEyMDEyMDAwMFoweTELMAkGA1UE +BhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBGcmFuY2lz +Y28xIzAhBgNVBAoTGldpa2ltZWRpYSBGb3VuZGF0aW9uLCBJbmMuMRgwFgYDVQQD +DA8qLndpa2lwZWRpYS5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQDCuToIC6iqulFKeu4DD5l336SonDpCEiVPqSyopch4fm+Zz2Da0KsCROq1AX5K +9kb7WXbSSpnVbXaaDDF/dxD65kD+keNJONqEAVdylW/G16Sa89agTVdgLTjZK2dI +99Q7ws9ijH2psHOUHRJLaJdySLO97OkGwcttd8UGDlCS98A7mN9icvpF4XMl6Oqw +q1/mj624a1BmAzhQaBLPNKsZcJmadACRL7LJ6sNr/SZV1SENlRLHnkmW/c4T2lSp +ikvIyJaOFLlt9J0aqCB+Tb0LwO4gNtrMaJ+fjBBJrMVRtLojrukc/yOdGBlTCx7x +JK5ER9VTf/sb1RViqSKMtSojAgMBAAGjggbIMIIGxDAfBgNVHSMEGDAWgBRQ6nOJ +2yn7EI+e5QEg1N55mUiD9zAdBgNVHQ4EFgQUAouBfESp0dUaQhWaXSogknV7Q3cw +ggObBgNVHREEggOSMIIDjoIPKi53aWtpcGVkaWEub3Jngg13aWtpcGVkaWEub3Jn +gg9tLndpa2lwZWRpYS5vcmeCEnplcm8ud2lraXBlZGlhLm9yZ4IRKi5tLndpa2lw +ZWRpYS5vcmeCDXdpa2lib29rcy5vcmeCD20ud2lraWJvb2tzLm9yZ4IPKi53aWtp +Ym9va3Mub3JnghEqLm0ud2lraWJvb2tzLm9yZ4IMd2lraWRhdGEub3Jngg5tLndp +a2lkYXRhLm9yZ4IOKi53aWtpZGF0YS5vcmeCECoubS53aWtpZGF0YS5vcmeCDXdp +a2ltZWRpYS5vcmeCD20ud2lraW1lZGlhLm9yZ4IPKi53aWtpbWVkaWEub3JnghEq +Lm0ud2lraW1lZGlhLm9yZ4IXd2lraW1lZGlhZm91bmRhdGlvbi5vcmeCGW0ud2lr +aW1lZGlhZm91bmRhdGlvbi5vcmeCGSoud2lraW1lZGlhZm91bmRhdGlvbi5vcmeC +GyoubS53aWtpbWVkaWFmb3VuZGF0aW9uLm9yZ4IMd2lraW5ld3Mub3Jngg5tLndp +a2luZXdzLm9yZ4IOKi53aWtpbmV3cy5vcmeCECoubS53aWtpbmV3cy5vcmeCDXdp +a2lxdW90ZS5vcmeCD20ud2lraXF1b3RlLm9yZ4IPKi53aWtpcXVvdGUub3JnghEq +Lm0ud2lraXF1b3RlLm9yZ4IOd2lraXNvdXJjZS5vcmeCEG0ud2lraXNvdXJjZS5v +cmeCECoud2lraXNvdXJjZS5vcmeCEioubS53aWtpc291cmNlLm9yZ4IPd2lraXZl +cnNpdHkub3JnghFtLndpa2l2ZXJzaXR5Lm9yZ4IRKi53aWtpdmVyc2l0eS5vcmeC +EyoubS53aWtpdmVyc2l0eS5vcmeCDndpa2l2b3lhZ2Uub3JnghBtLndpa2l2b3lh +Z2Uub3JnghAqLndpa2l2b3lhZ2Uub3JnghIqLm0ud2lraXZveWFnZS5vcmeCDndp +a3Rpb25hcnkub3JnghBtLndpa3Rpb25hcnkub3JnghAqLndpa3Rpb25hcnkub3Jn +ghIqLm0ud2lrdGlvbmFyeS5vcmeCDW1lZGlhd2lraS5vcmeCDyoubWVkaWF3aWtp +Lm9yZ4IPbS5tZWRpYXdpa2kub3JnghEqLm0ubWVkaWF3aWtpLm9yZ4IUKi56ZXJv +Lndpa2lwZWRpYS5vcmcwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUF +BwMBBggrBgEFBQcDAjBhBgNVHR8EWjBYMCqgKKAmhiRodHRwOi8vY3JsMy5kaWdp +Y2VydC5jb20vY2EzLWcyOC5jcmwwKqAooCaGJGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0 +LmNvbS9jYTMtZzI4LmNybDCCAcQGA1UdIASCAbswggG3MIIBswYJYIZIAYb9bAEB +MIIBpDA6BggrBgEFBQcCARYuaHR0cDovL3d3dy5kaWdpY2VydC5jb20vc3NsLWNw +cy1yZXBvc2l0b3J5Lmh0bTCCAWQGCCsGAQUFBwICMIIBVh6CAVIAQQBuAHkAIAB1 +AHMAZQAgAG8AZgAgAHQAaABpAHMAIABDAGUAcgB0AGkAZgBpAGMAYQB0AGUAIABj +AG8AbgBzAHQAaQB0AHUAdABlAHMAIABhAGMAYwBlAHAAdABhAG4AYwBlACAAbwBm +ACAAdABoAGUAIABEAGkAZwBpAEMAZQByAHQAIABDAFAALwBDAFAAUwAgAGEAbgBk +ACAAdABoAGUAIABSAGUAbAB5AGkAbgBnACAAUABhAHIAdAB5ACAAQQBnAHIAZQBl +AG0AZQBuAHQAIAB3AGgAaQBjAGgAIABsAGkAbQBpAHQAIABsAGkAYQBiAGkAbABp +AHQAeQAgAGEAbgBkACAAYQByAGUAIABpAG4AYwBvAHIAcABvAHIAYQB0AGUAZAAg +AGgAZQByAGUAaQBuACAAYgB5ACAAcgBlAGYAZQByAGUAbgBjAGUALjB7BggrBgEF +BQcBAQRvMG0wJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBF +BggrBgEFBQcwAoY5aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0 +SGlnaEFzc3VyYW5jZUNBLTMuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQEF +BQADggEBAFBllO9JfipPjol+w1hrrwbJ2ZdT1l09ZkjdmvcIhyv54XxaW8NDsjjp +5IIMc28q3JvuERxBnbKiwcrco/JGqwsywTSkYam9pS5ALhP4EXB773cfpYXEeyOC +LyXQgp79CZXe1q5l3DDKtWXRWyuZ8WZw3dd4y8qPJ9JvkIw4ZFgZgo7NV+Fa0HtY +vTe7D68o+EbYdmOLRkxKTEldv7A8f6WAWf5KRFE9dIsQvDD96zTYzdfzOCnonDuz +wJwsJ4BJB8uIs3jFNg05e+6ZrENL/QBEDFe8H09auNHSBuwy4gxEVdfZwgxgrKlf +uMko54p5i2QMvXtvIr/a3Nzlx6CiavI= +-----END CERTIFICATE----- +subject=/C=US/ST=California/L=San Francisco/O=Wikimedia Foundation, Inc./CN=*.wikipedia.org +issuer=/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance CA-3 +--- +No client certificate CA names sent +--- +SSL handshake has read 4905 bytes and written 434 bytes +--- +New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256 +Server public key is 2048 bit +Secure Renegotiation IS supported +Compression: NONE +Expansion: NONE +SSL-Session: + Protocol : TLSv1.2 + Cipher : ECDHE-RSA-AES128-GCM-SHA256 + Session-ID: 2022CC0AC2A1FCAB925F6511FCC28ACB27DDA644586ED6502753A3AA9FD70109 + Session-ID-ctx: + Master-Key: 81B1182E9E133115CE67AD77ED3429F907601B7C5B30A9D5EE66F08652264B06F8576B6943369C92F6734DA8C146B4E8 + Key-Arg : None + PSK identity: None + PSK identity hint: None + SRP username: None + TLS session ticket lifetime hint: 300 (seconds) + TLS session ticket: + 0000 - 4f bd 82 9c 08 63 6f 2c-6f a1 09 b9 33 a3 66 b0 O....co,o...3.f. + 0010 - 5f 4f 74 38 3a fc 89 a5-e6 88 42 ab 58 7f d6 ba _Ot8:.....B.X... + 0020 - 30 1f 13 da 7e 7d 31 a3-0d 87 85 67 1b 86 5d 66 0...~}1....g..]f + 0030 - e0 8e 14 03 c9 89 73 60-38 60 87 a0 0d 48 dd dd ......s`8`...H.. + 0040 - 1d b9 c3 8f 91 ed 92 2d-48 02 fb f0 79 25 4f 56 .......-H...y%OV + 0050 - 5a ce 68 23 08 78 bc 86-1b ad 7a b7 58 41 04 19 Z.h#.x....z.XA.. + 0060 - 29 0c b6 66 72 f1 27 36-83 18 4b b4 9c 41 64 bb )..fr.'6..K..Ad. + 0070 - 6f 52 0b df 03 f6 cc c2-b2 37 c2 c9 0e f9 df 9f oR.......7...... + 0080 - 13 af d6 d0 35 e8 e9 ac-f3 a6 02 07 9b 2f a2 e6 ....5......../.. + 0090 - 48 c6 1c c0 12 b2 ec 55-36 ad a0 c0 3c f5 cc db H......U6...<... + + Start Time: 1411743946 + Timeout : 300 (sec) + Verify return code: 20 (unable to get local issuer certificate) +--- -- cgit v1.1 From 3847607ce64a715993df3eaa42d9c4ea42064678 Mon Sep 17 00:00:00 2001 From: Magnus Ahltorp Date: Sat, 27 Sep 2014 15:22:42 +0200 Subject: testcase1: Added certificate fetching --- tools/testcase1.py | 125 +++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 88 insertions(+), 37 deletions(-) diff --git a/tools/testcase1.py b/tools/testcase1.py index 63dddc7..f78faa3 100755 --- a/tools/testcase1.py +++ b/tools/testcase1.py @@ -21,14 +21,30 @@ cc4 = get_certs_from_file(certfiles[3]) cc5 = get_certs_from_file(certfiles[4]) failures = 0 +indentation = "" -def assert_equal(actual, expected, name): +def testgroup(name): + global indentation + print name + ":" + indentation = " " + +def print_error(message, *args): + global failures, indentation + print indentation + "ERROR:", message % args + failures += 1 + +def print_success(message, *args): + print indentation + message % args + +def assert_equal(actual, expected, name, quiet=False, nodata=False): global failures if actual != expected: - print "ERROR:", name, "expected", expected, "got", actual - failures += 1 - else: - print name, "was correct" + if nodata: + print_error("%s differs", name) + else: + print_error("%s expected %s got %s", name, expected, actual) + elif not quiet: + print_success("%s was correct", name) def print_and_check_tree_size(expected): global failures @@ -36,46 +52,73 @@ def print_and_check_tree_size(expected): try: check_sth_signature(baseurl, sth) except AssertionError, e: - print "ERROR:", e - failures += 1 + print_error("%s", e) except ecdsa.keys.BadSignatureError, e: - print "ERROR: bad STH signature" - failures += 1 + print_error("bad STH signature") tree_size = sth["tree_size"] - if tree_size == expected: - print "tree size", tree_size - else: - print "ERROR: tree size", tree_size, "expected", expected - failures += 1 + assert_equal(tree_size, expected, "tree size") def do_add_chain(chain): global failures try: result = add_chain(baseurl, {"chain":map(base64.b64encode, chain)}) except ValueError, e: - print "ERROR:", e - failures += 1 + print_error("%s", e) try: check_sct_signature(baseurl, chain[0], result) except AssertionError, e: - print "ERROR:", e - failures += 1 + print_error("%s", e) except ecdsa.keys.BadSignatureError, e: - print "ERROR: bad SCT signature" - failures += 1 - print "signature check succeeded" + print_error("bad SCT signature") + print_success("signature check succeeded") return result -def get_and_validate_proof(timestamp, cert, leaf_index, nentries): +def get_and_validate_proof(timestamp, chain, leaf_index, nentries): + cert = chain[0] merkle_tree_leaf = pack_mtl(timestamp, cert) leaf_hash = get_leaf_hash(merkle_tree_leaf) sth = get_sth(baseurl) proof = get_proof_by_hash(baseurl, leaf_hash, sth["tree_size"]) assert_equal(proof["leaf_index"], leaf_index, "leaf_index") assert_equal(len(proof["audit_path"]), nentries, "audit_path length") + get_and_check_entry(timestamp, chain, leaf_index) + +def get_and_check_entry(timestamp, chain, leaf_index): + entries = get_entries(baseurl, leaf_index, leaf_index) + assert_equal(len(entries), 1, "get_entries", quiet=True) + fetched_entry = entries["entries"][0] + merkle_tree_leaf = pack_mtl(timestamp, chain[0]) + leaf_input = base64.decodestring(fetched_entry["leaf_input"]) + assert_equal(leaf_input, merkle_tree_leaf, "entry", nodata=True) + extra_data = base64.decodestring(fetched_entry["extra_data"]) + certchain = decode_certificate_chain(extra_data) + + submittedcertchain = chain[1:] + + for (submittedcert, fetchedcert, i) in zip(submittedcertchain, + certchain, itertools.count(1)): + assert_equal(fetchedcert, submittedcert, "cert %d in chain" % (i,)) + + if len(certchain) == len(submittedcertchain) + 1: + last_issuer = get_cert_info(certs[-1])["issuer"] + root_subject = get_cert_info(certchain[-1])["subject"] + if last_issuer == root_subject: + print_success("fetched chain has an appended root cert") + else: + print_error("fetched chain has an extra entry") + failures += 1 + elif len(certchain) == len(submittedcertchain): + print_success("cert chains are the same length") + else: + print_error("cert chain length %d expected %d or %d", + len(certchain), + len(submittedcertchain), + len(submittedcertchain)) print_and_check_tree_size(0) +testgroup("cert1") + result1 = do_add_chain(cc1) print_and_check_tree_size(1) @@ -89,41 +132,49 @@ print_and_check_tree_size(1) # TODO: add invalid cert and check that it generates an error # and that treesize still is 1 -get_and_validate_proof(result1["timestamp"], cc1[0], 0, 0) +get_and_validate_proof(result1["timestamp"], cc1, 0, 0) + +testgroup("cert2") result3 = do_add_chain(cc2) print_and_check_tree_size(2) -get_and_validate_proof(result1["timestamp"], cc1[0], 0, 1) -get_and_validate_proof(result3["timestamp"], cc2[0], 1, 1) +get_and_validate_proof(result1["timestamp"], cc1, 0, 1) +get_and_validate_proof(result3["timestamp"], cc2, 1, 1) + +testgroup("cert3") result4 = do_add_chain(cc3) print_and_check_tree_size(3) -get_and_validate_proof(result1["timestamp"], cc1[0], 0, 2) -get_and_validate_proof(result3["timestamp"], cc2[0], 1, 2) -get_and_validate_proof(result4["timestamp"], cc3[0], 2, 1) +get_and_validate_proof(result1["timestamp"], cc1, 0, 2) +get_and_validate_proof(result3["timestamp"], cc2, 1, 2) +get_and_validate_proof(result4["timestamp"], cc3, 2, 1) + +testgroup("cert4") result5 = do_add_chain(cc4) print_and_check_tree_size(4) -get_and_validate_proof(result1["timestamp"], cc1[0], 0, 2) -get_and_validate_proof(result3["timestamp"], cc2[0], 1, 2) -get_and_validate_proof(result4["timestamp"], cc3[0], 2, 2) -get_and_validate_proof(result5["timestamp"], cc4[0], 3, 2) +get_and_validate_proof(result1["timestamp"], cc1, 0, 2) +get_and_validate_proof(result3["timestamp"], cc2, 1, 2) +get_and_validate_proof(result4["timestamp"], cc3, 2, 2) +get_and_validate_proof(result5["timestamp"], cc4, 3, 2) + +testgroup("cert5") result6 = do_add_chain(cc5) print_and_check_tree_size(5) -get_and_validate_proof(result1["timestamp"], cc1[0], 0, 3) -get_and_validate_proof(result3["timestamp"], cc2[0], 1, 3) -get_and_validate_proof(result4["timestamp"], cc3[0], 2, 3) -get_and_validate_proof(result5["timestamp"], cc4[0], 3, 3) -get_and_validate_proof(result6["timestamp"], cc5[0], 4, 1) +get_and_validate_proof(result1["timestamp"], cc1, 0, 3) +get_and_validate_proof(result3["timestamp"], cc2, 1, 3) +get_and_validate_proof(result4["timestamp"], cc3, 2, 3) +get_and_validate_proof(result5["timestamp"], cc4, 3, 3) +get_and_validate_proof(result6["timestamp"], cc5, 4, 1) print "-------" if failures: -- cgit v1.1 From 6195b000f6a5dd6e9a07ab61ac64f66b6304bf78 Mon Sep 17 00:00:00 2001 From: Linus Nordberg Date: Wed, 8 Oct 2014 12:35:38 +0200 Subject: Create webroot/log if it doesn't exist. mod_log (httpd) gets really sad when trying to create log/error. --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index 5a13905..1170f31 100644 --- a/Makefile +++ b/Makefile @@ -13,3 +13,4 @@ release: cp catlfish.config rel mkdir rel/catlfish cp -r webroot rel/catlfish + test -d rel/catlfish/webroot/log || mkdir rel/catlfish/webroot/log -- cgit v1.1 From a758fa14bf8ae02c9dc9c3501e90344e25b82918 Mon Sep 17 00:00:00 2001 From: Linus Nordberg Date: Sat, 27 Sep 2014 15:44:07 +0200 Subject: Clean up the plop interface, in preparation for a new db implementation. --- src/catlfish.erl | 151 ++++++++++++++++++++++++++++++++++++++++++++----------- src/v1.erl | 2 +- 2 files changed, 123 insertions(+), 30 deletions(-) diff --git a/src/catlfish.erl b/src/catlfish.erl index 2ba9d58..b6856b8 100644 --- a/src/catlfish.erl +++ b/src/catlfish.erl @@ -7,32 +7,119 @@ -define(PROTOCOL_VERSION, 0). --spec add_chain(binary(), list()) -> list(). +%%-type signature_type() :: certificate_timestamp | tree_hash | test. % uint8 +-type entry_type() :: x509_entry | precert_entry | test. % uint16 +-type leaf_type() :: timestamped_entry | test. % uint8 +-type leaf_version() :: v1 | v2. % uint8 + +-record(mtl, {leaf_version :: leaf_version(), + leaf_type :: leaf_type(), + entry :: timestamped_entry()}). +-type mtl() :: #mtl{}. + +-record(timestamped_entry, {timestamp :: integer(), + entry_type :: entry_type(), + signed_entry :: binary(), + extensions = <<>> :: binary()}). +-type timestamped_entry() :: #timestamped_entry{}. + +-spec serialise(mtl() | timestamped_entry()) -> binary(). +serialise(#timestamped_entry{timestamp = Timestamp} = E) -> + list_to_binary( + [<>, + serialise_entry_type(E#timestamped_entry.entry_type), + encode_tls_vector(E#timestamped_entry.signed_entry, 3), + encode_tls_vector(E#timestamped_entry.extensions, 2)]); +serialise(#mtl{leaf_version = LeafVersion, + leaf_type = LeafType, + entry = TimestampedEntry}) -> + list_to_binary( + [serialise_leaf_version(LeafVersion), + serialise_leaf_type(LeafType), + serialise(TimestampedEntry)]). + +serialise_leaf_version(v1) -> + <<0:8>>; +serialise_leaf_version(v2) -> + <<1:8>>. + +serialise_leaf_type(timestamped_entry) -> + <<0:8>>. +%% serialise_leaf_type(_) -> +%% <<>>. + +serialise_entry_type(x509_entry) -> + <<0:16>>; +serialise_entry_type(precert_entry) -> + <<1:16>>. + +serialise_signature_type(certificate_timestamp) -> + <<0:8>>; +serialise_signature_type(tree_hash) -> + <<1:8>>. + +-spec add_chain(binary(), [binary()]) -> nonempty_string(). add_chain(LeafCert, CertChain) -> - Entry = #plop_entry{type = x509, data = LeafCert}, - EDVectors = [serialise_tls_vector(X, 3) || X <- CertChain], - ExtraData = serialise_tls_vector(list_to_binary(EDVectors), 3), - SPT = plop:add(#timestamped_entry{entry = Entry}, ExtraData), - R = [{sct_version, ?PROTOCOL_VERSION}, - {id, base64:encode(SPT#spt.logid)}, - {timestamp, SPT#spt.timestamp}, - {extensions, base64:encode("")}, - {signature, base64:encode(plop:serialise(SPT#spt.signature))}], - binary_to_list(jiffy:encode({R})). + EntryHash = crypto:hash(sha256, LeafCert), + TimestampedEntry = + case plop:get(EntryHash) of + notfound -> + Timestamp = plop:generate_timestamp(), + TSE = #timestamped_entry{timestamp = Timestamp, + entry_type = x509_entry, + signed_entry = LeafCert}, + MTL = #mtl{leaf_version = v1, + leaf_type = timestamped_entry, + entry = TSE}, + ok = plop:add( + serialise_logentry(Timestamp, LeafCert, CertChain), + ht:leaf_hash(serialise(MTL)), + crypto:hash(sha256, LeafCert)), + TSE; + {_Index, Entry} -> + <> = Entry, + %% TODO: Perform a costly db consistency check against + %% unpacked LogEntry (w/ LeafCert and CertChain) + #timestamped_entry{timestamp = Timestamp, + entry_type = x509_entry, + signed_entry = LeafCert} + end, + SCT_sig = + plop:spt(list_to_binary([<>, + serialise_signature_type(certificate_timestamp), + serialise(TimestampedEntry)])), + binary_to_list( + jiffy:encode( + {[{sct_version, ?PROTOCOL_VERSION}, + {id, base64:encode(plop:logid())}, + {timestamp, TimestampedEntry#timestamped_entry.timestamp}, + {extensions, base64:encode(<<>>)}, + {signature, base64:encode(plop:serialise(SCT_sig))}]})). + +-spec serialise_logentry(integer(), binary(), [binary()]) -> binary(). +serialise_logentry(Timestamp, LeafCert, CertChain) -> + list_to_binary( + [<>, + list_to_binary( + [encode_tls_vector(LeafCert, 3), + encode_tls_vector( + list_to_binary( + [encode_tls_vector(X, 3) || X <- CertChain]), 3)])]). -spec entries(non_neg_integer(), non_neg_integer()) -> list(). entries(Start, End) -> - encode_entries(plop:get(Start, End)). + binary_to_list( + jiffy:encode({[{entries, x_entries(plop:get(Start, End))}]})). -spec entry_and_proof(non_neg_integer(), non_neg_integer()) -> list(). entry_and_proof(Index, TreeSize) -> binary_to_list( jiffy:encode( case plop:inclusion_and_entry(Index, TreeSize) of - {ok, MTL, Extra, Path} -> - {[{leaf_input, base64:encode(plop:serialise(MTL))}, - %% Extra data is already in TLS vector format. - {extra_data, base64:encode(Extra)}, + {ok, {Entry, Path}} -> + {LeafCertVector, CertChainVector} = unpack_entry(Entry), + {[{leaf_input, base64:encode(LeafCertVector)}, + {extra_data, base64:encode(CertChainVector)}, {audit_path, [base64:encode(X) || X <- Path]}]}; {notfound, Msg} -> {[{success, false}, @@ -40,20 +127,26 @@ entry_and_proof(Index, TreeSize) -> end)). %% Private functions. --spec encode_entries([{mtl(), binary()}]) -> list(). -encode_entries(Entries) -> - binary_to_list(jiffy:encode({[{entries, unpack_entries(Entries)}]})). +unpack_entry(Entry) -> + %% FIXME: Do this with some beatiful binary matching. + LeafCertVectorLen = binary:decode_unsigned(binary_part(Entry, 0, 3)), + LeafCertVector = binary_part(Entry, 3, LeafCertVectorLen), + CertChainVectorPos = 3 + LeafCertVectorLen, + CertChainVector = binary_part( + Entry, CertChainVectorPos, + byte_size(Entry) - CertChainVectorPos), + {LeafCertVector, CertChainVector}. --spec unpack_entries([{mtl(), binary()}]) -> list(). -unpack_entries([]) -> +-spec x_entries([{non_neg_integer(), binary(), binary()}]) -> list(). +x_entries([]) -> []; -unpack_entries([H|T]) -> - {MTL, Extra} = H, - LeafInput = base64:encode(plop:serialise(MTL)), - ExtraData = base64:encode(Extra), - [{[{leaf_input, LeafInput}, {extra_data, ExtraData}]} | unpack_entries(T)]. - --spec serialise_tls_vector(binary(), non_neg_integer()) -> binary(). -serialise_tls_vector(Binary, LengthLen) -> +x_entries([H|T]) -> + {_Index, _Hash, Entry} = H, + {LeafCertVector, CertChainVector} = unpack_entry(Entry), + [{[{leaf_input, LeafCertVector}, {extra_data, CertChainVector}]} | + x_entries(T)]. + +-spec encode_tls_vector(binary(), non_neg_integer()) -> binary(). +encode_tls_vector(Binary, LengthLen) -> Length = byte_size(Binary), <>. diff --git a/src/v1.erl b/src/v1.erl index 304b0a8..b58516d 100644 --- a/src/v1.erl +++ b/src/v1.erl @@ -82,7 +82,7 @@ binary_to_list( jiffy:encode( case plop:inclusion(Hash, TreeSize) of - {ok, Index, Path} -> + {ok, {Index, Path}} -> {[{leaf_index, Index}, {audit_path, [base64:encode(X) || X <- Path]}]}; -- cgit v1.1 From 02cf1b6d6c217b12157dc7ae662046e2319f316c Mon Sep 17 00:00:00 2001 From: Magnus Ahltorp Date: Sat, 27 Sep 2014 18:34:49 +0200 Subject: Fix api problems --- src/catlfish.erl | 44 ++++++++++++++++++++++++++++---------------- src/v1.erl | 2 +- 2 files changed, 29 insertions(+), 17 deletions(-) diff --git a/src/catlfish.erl b/src/catlfish.erl index b6856b8..bd3c106 100644 --- a/src/catlfish.erl +++ b/src/catlfish.erl @@ -58,6 +58,15 @@ serialise_signature_type(certificate_timestamp) -> serialise_signature_type(tree_hash) -> <<1:8>>. +build_mtl(Timestamp, LeafCert) -> + TSE = #timestamped_entry{timestamp = Timestamp, + entry_type = x509_entry, + signed_entry = LeafCert}, + MTL = #mtl{leaf_version = v1, + leaf_type = timestamped_entry, + entry = TSE}, + serialise(MTL). + -spec add_chain(binary(), [binary()]) -> nonempty_string(). add_chain(LeafCert, CertChain) -> EntryHash = crypto:hash(sha256, LeafCert), @@ -76,8 +85,8 @@ add_chain(LeafCert, CertChain) -> ht:leaf_hash(serialise(MTL)), crypto:hash(sha256, LeafCert)), TSE; - {_Index, Entry} -> - <> = Entry, + {_Index, _MTLHash, Entry} -> + <> = Entry, %% TODO: Perform a costly db consistency check against %% unpacked LogEntry (w/ LeafCert and CertChain) #timestamped_entry{timestamp = Timestamp, @@ -91,7 +100,7 @@ add_chain(LeafCert, CertChain) -> binary_to_list( jiffy:encode( {[{sct_version, ?PROTOCOL_VERSION}, - {id, base64:encode(plop:logid())}, + {id, base64:encode(plop:get_logid())}, {timestamp, TimestampedEntry#timestamped_entry.timestamp}, {extensions, base64:encode(<<>>)}, {signature, base64:encode(plop:serialise(SCT_sig))}]})). @@ -117,8 +126,9 @@ entry_and_proof(Index, TreeSize) -> jiffy:encode( case plop:inclusion_and_entry(Index, TreeSize) of {ok, {Entry, Path}} -> - {LeafCertVector, CertChainVector} = unpack_entry(Entry), - {[{leaf_input, base64:encode(LeafCertVector)}, + {Timestamp, LeafCertVector, CertChainVector} = unpack_entry(Entry), + MTL = build_mtl(Timestamp, LeafCertVector), + {[{leaf_input, base64:encode(MTL)}, {extra_data, base64:encode(CertChainVector)}, {audit_path, [base64:encode(X) || X <- Path]}]}; {notfound, Msg} -> @@ -128,25 +138,27 @@ entry_and_proof(Index, TreeSize) -> %% Private functions. unpack_entry(Entry) -> - %% FIXME: Do this with some beatiful binary matching. - LeafCertVectorLen = binary:decode_unsigned(binary_part(Entry, 0, 3)), - LeafCertVector = binary_part(Entry, 3, LeafCertVectorLen), - CertChainVectorPos = 3 + LeafCertVectorLen, - CertChainVector = binary_part( - Entry, CertChainVectorPos, - byte_size(Entry) - CertChainVectorPos), - {LeafCertVector, CertChainVector}. + <> = Entry, + {LeafCertVector, CertChainVector} = decode_tls_vector(LogEntry, 3), + {Timestamp, LeafCertVector, CertChainVector}. -spec x_entries([{non_neg_integer(), binary(), binary()}]) -> list(). x_entries([]) -> []; x_entries([H|T]) -> - {_Index, _Hash, Entry} = H, - {LeafCertVector, CertChainVector} = unpack_entry(Entry), - [{[{leaf_input, LeafCertVector}, {extra_data, CertChainVector}]} | + [_Index, _Hash, Entry] = H, + {Timestamp, LeafCertVector, CertChainVector} = unpack_entry(Entry), + MTL = build_mtl(Timestamp, LeafCertVector), + [{[{leaf_input, base64:encode(MTL)}, {extra_data, base64:encode(CertChainVector)}]} | x_entries(T)]. -spec encode_tls_vector(binary(), non_neg_integer()) -> binary(). encode_tls_vector(Binary, LengthLen) -> Length = byte_size(Binary), <>. + +-spec decode_tls_vector(binary(), non_neg_integer()) -> {binary(), binary()}. +decode_tls_vector(Binary, LengthLen) -> + <> = Binary, + <> = Rest, + {ExtractedBinary, Rest2}. diff --git a/src/v1.erl b/src/v1.erl index b58516d..304b0a8 100644 --- a/src/v1.erl +++ b/src/v1.erl @@ -82,7 +82,7 @@ binary_to_list( jiffy:encode( case plop:inclusion(Hash, TreeSize) of - {ok, {Index, Path}} -> + {ok, Index, Path} -> {[{leaf_index, Index}, {audit_path, [base64:encode(X) || X <- Path]}]}; -- cgit v1.1 From b0766332d2be4272a8d8065de684c61f1ad15c4d Mon Sep 17 00:00:00 2001 From: Magnus Ahltorp Date: Sat, 27 Sep 2014 18:35:48 +0200 Subject: Make each included application in the release explicit --- reltool.config | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/reltool.config b/reltool.config index 434345c..80b374d 100644 --- a/reltool.config +++ b/reltool.config @@ -1,6 +1,5 @@ %% -*- mode: erlang -*- {sys, [ - {lib_dirs, [".."]}, {erts, [{mod_cond, derived}, {app_file, strip}]}, {app_file, strip}, {rel, "catlfish", "0.2.0-dev", @@ -12,6 +11,7 @@ ]}, {boot_rel, "catlfish"}, {excl_archive_filters, ["^include$","^priv$","^\\.git$"]}, - {app, catlfish, [{app_file, all}]} -%% {app, plop, [{mod_cond, app}, {incl_cond, include}, {lib_dir, "../plop"}]} + {app, catlfish, [{app_file, all}, {lib_dir, "."}]}, + {app, plop, [{app_file, all}, {lib_dir, "../plop"}]}, + {app, jiffy, [{app_file, all}, {lib_dir, "../jiffy"}]} ]}. -- cgit v1.1