Beispiel #1
0
def test_run():
    test_session = shared.TLSNClientSession(server='www.mozilla.org')
    sckt = shared.create_sock(test_session.server_name,test_session.ssl_port)
    test_session.start_handshake(sckt)
    test_session.set_auditee_secret()
    test_session.set_auditor_secret()    
    test_session.extract_mod_and_exp()
    test_session.set_enc_first_half_pms()
    test_session.set_enc_second_half_pms()
    test_session.set_encrypted_pms()
    
    test_session.set_master_secret_half()
    test_session.do_key_expansion()
    
    test_session.client_key_exchange = shared.tlsn_ssl.TLSClientKeyExchange(serialized=None,encryptedPMS=test_session.enc_pms)
    test_session.change_cipher_spec = shared.tlsn_ssl.TLSChangeCipherSpec()
    test_session.handshake_messages[4] = test_session.client_key_exchange.serialized
    test_session.handshake_messages[5] = test_session.change_cipher_spec.serialized
    test_session.set_handshake_hashes()    
    
    verify_data = test_session.get_verify_data_for_finished()
    test_session.client_finished = shared.tlsn_ssl.TLSFinished(serialized=None, verify_data=verify_data)
    test_session.handshake_messages[6] = test_session.client_finished.serialized
    print ("We are about to send the final three handshake messages,")
    print ("They are: ")
    print ([binascii.hexlify(x) for x in test_session.handshake_messages[4:7]])
    #Note that the three messages cannot be packed into one record; 
    #change cipher spec is *not* a handshake message
    shared.tlsn_ssl.tls_sender(sckt,test_session.handshake_messages[4],shared.tlsn_ssl.hs)
    shared.tlsn_ssl.tls_sender(sckt,test_session.handshake_messages[5],shared.tlsn_ssl.chcis) 
    #client finished must be sent encrypted
    #print ('We are about to send finished.')
    #print ('The handshake messages are: ', self.handshake_messages[:5])
    shared.tlsn_ssl.tls_sender(sckt,test_session.handshake_messages[6],shared.tlsn_ssl.hs, conn=test_session.client_connection_state)
    records=[]
    while len(records) < 2:
        rspns = shared.recv_socket(sckt,True)
        x, remaining = shared.tlsn_ssl.tls_record_decoder(rspns)
        assert not remaining, "Server sent spurious non-TLS response"
        records.extend(x)
    test_session.server_ccs = [x for x in records if x.content_type == shared.tlsn_ssl.chcis][0]
    print ("We got this server ccs: ", binascii.hexlify(test_session.server_ccs.fragment))
    sf = [x for x in records if x.content_type == shared.tlsn_ssl.hs][0]
    print ("Cipher suite chosen was: ", test_session.chosen_cipher_suite)
    print ("Server finished is: ", binascii.hexlify(sf.fragment))
    print ("We got rspns: ", binascii.hexlify(rspns))
    with open('testharness','wb') as f: f.write(test_session.dump())
    test_session.server_finished = \
        shared.tlsn_ssl.tls_record_fragment_decoder(shared.tlsn_ssl.hs,sf.fragment, \
                                                    conn=test_session.server_connection_state, \
                                                    ignore_bad_mac=True)[0]
    #store the IV immediately after decrypting Finished; this will be needed
    #by auditor in order to replay the decryption
    test_session.IV_after_finished = test_session.server_connection_state.IV
    sha_verify, md5_verify = test_session.set_handshake_hashes(server=True)
    verify_data_check = test_session.get_verify_data_for_finished(sha_verify=sha_verify,\
                                                md5_verify=md5_verify, is_for_client=False)
    print ("Got this from server: ", binascii.hexlify(test_session.server_finished.verify_data))
    print ("Got this from check: ",binascii.hexlify(verify_data_check))
Beispiel #2
0
def prepare_pms(tlsn_session, session_id):
    n = shared.bi2ba(tlsn_session.server_modulus)
    rs_choice = random.choice(shared.reliable_sites.keys())
    print("ramdom choice:", rs_choice)
    for i in range(10):  #keep trying until reliable site check succeeds
        try:
            pms_session = shared.TLSNClientSession(
                rs_choice,
                shared.reliable_sites[rs_choice][0],
                ccs=53,
                tlsver=global_tlsver)
            if not pms_session:
                raise Exception(
                    "Client session construction failed in prepare_pms")
            tls_sock = shared.create_sock(pms_session.server_name,
                                          pms_session.ssl_port)
            pms_session.start_handshake(tls_sock)
            # 1# message exchange with auditor
            reply = send_and_recv(
                'rcr_rsr_rsname_n', pms_session.client_random +
                pms_session.server_random + rs_choice[:5] + n, session_id)
            if reply[0] != 'success':
                raise Exception(
                    'Failed to receive a reply for rcr_rsr_rsname_n:')
            if not reply[1] == 'rrsapms_rhmac_rsapms':
                raise Exception('bad reply. Expected rrsapms_rhmac_rsapms:')
            reply_data = reply[2]
            rrsapms2 = reply_data[:256]
            pms_session.p_auditor = reply_data[256:304]
            rsapms2 = reply_data[304:]
            response = pms_session.complete_handshake(tls_sock, rrsapms2)
            tls_sock.close()
            if not response:
                print("PMS trial failed")
                continue
            #judge success/fail based on whether a properly encoded
            #Change Cipher Spec record is returned by the server (we could
            #also check the server finished, but it isn't necessary)
            if not response.count(
                    shared.TLSRecord(shared.chcis,
                                     f='\x01',
                                     tlsver=global_tlsver).serialized):
                print("PMS trial failed, retrying. (",
                      binascii.hexlify(response), ")")
                continue
            tlsn_session.auditee_secret = pms_session.auditee_secret
            tlsn_session.auditee_padding_secret = pms_session.auditee_padding_secret
            tlsn_session.enc_second_half_pms = shared.ba2int(rsapms2)
            tlsn_session.set_enc_first_half_pms()
            tlsn_session.set_encrypted_pms()
            return
        except shared.TLSNSSLError:
            shared.ssl_dump(pms_session, fn='preparepms_ssldump')
            shared.ssl_dump(tlsn_session)
            raise
    raise Exception ('Could not prepare PMS with ', rs_choice, ' after 10 tries. Please '+\
                     'double check that you are using a valid public key modulus for this site; '+\
                     'it may have expired.')
Beispiel #3
0
def probe_server_modulus(server):
    probe_session = shared.TLSNClientSession(server, tlsver=global_tlsver)
    print('ssl port is: ', probe_session.ssl_port)
    tls_sock = shared.create_sock(probe_session.server_name,
                                  probe_session.ssl_port)
    try:
        probe_session.start_handshake(tls_sock)
    except Exception as e:
        print("tls 1.1 not support")
        old_tlsver = bytearray('\x03\x01')
        probe_session = shared.TLSNClientSession(server, tlsver=old_tlsver)
        tls_sock = shared.create_sock(probe_session.server_name,
                                      probe_session.ssl_port)
        probe_session.start_handshake(tls_sock)

    server_mod, server_exp = probe_session.extract_mod_and_exp()
    tls_sock.close()
    return shared.bi2ba(server_mod)
Beispiel #4
0
def review(audit_filename):
    review_result = ""
    try:
        ok, result = extract_audit_data(audit_filename)
        if not ok:
            #        print(result)
            review_result += "Valid proof file format: False\n"
            return False, review_result, None
        else:
            review_result += "Valid Proof File Format: True\n"
            audit_data = result
    except Exception as e:
        review_result += "Valid proof file format: False\n"
        return False, review_result, None

    #1. Verify TLS Server's pubkey
    # to-do: verify cert signed by trusted root CA
    # to-do: extrct pubkey from ca certificate, compare with pubkey in pgsg
    try:
        audit_session = shared.TLSNClientSession(
            ccs=audit_data['cipher_suite'], tlsver=audit_data['tlsver'])
        first_cert_len = shared.ba2int(audit_data['certs'][:3])
        cert_bi = audit_data['certs'][3:3 + first_cert_len]
        cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_ASN1,
                                               cert_bi)
        cert_cn = cert.get_subject().CN
        print(cert.get_subject().get_components())
        print("cert CN:", cert.get_subject().commonName)
        #    server_name = cert.get_subject().CN
        print("audit_data server:", audit_data['host'])
        server_name = audit_data['host']
        #    print("is rsapublickey:",isinstance(cert.get_pubkey().to_cryptography_key(), cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey))
        server_mod = cert.get_pubkey().to_cryptography_key().public_numbers().n
        #    print("extrct public_key mod:", server_mod)

        if cert_cn.startswith("*."):
            cert_cn = cert_cn[2:]
        if cert_cn.endswith(".cn"):
            cert_cn = cert_cn[:-3]
        if cert_cn.startswith("www."):
            cert_cn = cert_cn[4:]

        print("cert CN:", cert_cn)
        if "." in cert_cn:
            cert_cn_arrays = cert_cn.split(".")
            cert_cn = cert_cn_arrays[-2]
        print("cert CN:", cert_cn)

        #    if not server_name.endswith(cert_cn):
        #    if cert_cn not in server_name:
        #        review_result += "Valid Host name: False\n"
        #        return False, review_result, None
        #    else:
        #        review_result += "Valid Host name: True\n"
        print('Processing data for server:', server_name)
        #    if server_name.strip() != audit_data['host'].strip():
        #        return False, "host name not match"
        public_hex = binascii.hexlify(shared.bi2ba(server_mod))
        #    if  server_name.startswith("*."):
        #        short = server_name[2:]
        #        url_openssl = "free-api."+short
        #        print ('Processing data for server:', server_name)
        cipher_key = audit_data['cipher_suite']
        cipher_suites = shared.tlsn_cipher_suites
        chosen_cipher = cipher_suites[cipher_key][0]
        print("chosen cipher suite:", chosen_cipher)
        tls_ver = "-tls1_1"
        if audit_data['tlsver'] == bytearray('\x03\x01'):
            tls_ver = "-tls1"

        print("tls ver:", tls_ver)
        cmd = "echo |openssl s_client " + tls_ver + " -cipher " + chosen_cipher + " -connect " + server_name + ":443 2>&1 | openssl x509 -pubkey -modulus -noout 2>&1 | grep 'Modulus' | sed 's/Modulus=//g' "
        print("cmd:", cmd)
        import subprocess
        public_openssl = subprocess.check_output(cmd, shell=True).strip('\n')

        print("hex:" + public_hex.upper().lower())
        print("openssl:" + public_openssl.upper().lower())
        if public_hex.upper().lower() == public_openssl.upper().lower():
            review_result += "Valid server pub key: True\n"

        else:
            review_result += "Valid server pub key: False\n"
            return False, review_result, None

    except Exception as e:
        review_result += "Valid server pub key: False\n"
        return False, review_result, None

    try:
        check_cert = os.system("echo |openssl s_client " + tls_ver +
                               " -cipher " + chosen_cipher + " -connect " +
                               server_name + ":443")
        print("check_cert result:", check_cert)
        if check_cert == 0:
            review_result += "Valid server certificate chain: True\n"
        else:
            review_result += "Valid server certificate chain: False\n"
            return False, review_result, None
    except Exception as e:
        review_result += "Valid server certificate chain: False\n"
        return False, review_result, None

    # to-do check if openssl cmd return 0
    #2. Verify Proof from the Auditor Side
    # the partial proof from auditor is signed by auditor
    #First, extract the cert in DER form from the notarization file
    #Then, extract from the cert the modulus and server name (common name field)
    #To do this, we need to initialise the TLSNClientSession
    try:
        audit_session = shared.TLSNClientSession(
            ccs=audit_data['cipher_suite'], tlsver=audit_data['tlsver'])
        first_cert_len = shared.ba2int(audit_data['certs'][:3])
        #    server_mod, server_exp = audit_session.extract_mod_and_exp(certDER=audit_data['certs'][3:3+first_cert_len], sn=True)
        data_to_be_verified = audit_data['commit_hash'] + audit_data[
            'pms2'] + shared.bi2ba(server_mod) + audit_data['audit_time']
        data_to_be_verified = sha256(data_to_be_verified).digest()
        if not shared.verify_signature(data_to_be_verified,
                                       audit_data['signature'],
                                       oracle_int_modulus):
            review_result += "Valid Auditor Signature: False\n"
            return False, review_result, None
        else:
            review_result += "Valid Auditor Signature: True\n"
        #3. Verify commitment hash.
        if not sha256(audit_data['response'] + audit_data['certs']).digest(
        ) == audit_data['commit_hash']:
            review_result += "Valid server response: False\n"
            return False, review_result, None
        else:
            review_result += "Valid encrypted server response: True\n"
    except Exception as e:
        review_result += "Valid server response: False\n"
        print(e)
        return False, review_result, None

    #4 Decrypt html and check for mac errors. Response data and MAC code from auditee will be checked by the MAC key from Auditor
    try:
        audit_session.unexpected_server_app_data_count = shared.ba2int(
            audit_data['response'][0])
        audit_session.tlsver = audit_data['tlsver']
        audit_session.client_random = audit_data['client_random']
        audit_session.server_random = audit_data['server_random']
        audit_session.pms1 = audit_data['pms1']
        audit_session.pms2 = audit_data['pms2']
        audit_session.p_auditee = shared.tls_10_prf(
            'master secret' + audit_session.client_random +
            audit_session.server_random,
            first_half=audit_session.pms1)[0]
        audit_session.p_auditor = shared.tls_10_prf(
            'master secret' + audit_session.client_random +
            audit_session.server_random,
            second_half=audit_session.pms2)[1]

        audit_session.set_master_secret_half()
        audit_session.do_key_expansion()
        audit_session.store_server_app_data_records(audit_data['response'][1:])
        audit_session.IV_after_finished = (map(ord,audit_data['IV'][:256]),ord(audit_data['IV'][256]), \
                ord(audit_data['IV'][257])) if audit_data['cipher_suite'] in [4,5] else audit_data['IV']

        print("start to decrypt")
        plaintext, bad_mac = audit_session.process_server_app_data_records(
            is_for_auditor=True)
        print("decrypt done")
        if bad_mac:
            review_result += "Valid decrypted response content: False\n"
            return False, review_result, None

        plaintext = shared.dechunk_http(plaintext)
        plaintext = shared.gunzip_http(plaintext)
        if plaintext == audit_data['html']:
            review_result += "Valid decrypted response content: True\n"
        else:
            review_result += "Valid decrypted response content: False\n"
            return False, review_result, None
    except Exception as e:
        review_result += "Valid decrypted response content: False\n"
        return False, review_result, None
    #5 Display html + success.


#    with open(join(current_session_dir,'audited.html'),'wb') as f:
#        f.write(plaintext)
#print out the info about the domain
#    n_hexlified = binascii.hexlify(shared.bi2ba(server_mod))
#    print("pubkey string:"+n_hexlified)
#    #pubkey in the format 09 56 23 ....
#    n_write = " ".join(n_hexlified[i:i+2] for i in range(0, len(n_hexlified), 2))
#    with open(join(current_session_dir,'domain_data.txt'), 'wb') as f:
#        f.write('Server name: '+audit_session.server_name + '\n\n'+'Server pubkey:' + '\n\n' + n_write+'\n')
    return True, review_result, plaintext
Beispiel #5
0
def start_generate(server_name, headers, server_modulus):
    global global_tlsver
    global global_use_gzip
    global global_use_slowaes

    print("server_name:", server_name)
    session_id = ''.join(
        random.choice(string.ascii_lowercase + string.digits)
        for x in range(10))
    tlsn_session = shared.TLSNClientSession(server_name, tlsver=global_tlsver)
    tlsn_session.server_modulus = shared.ba2int(server_modulus)
    tlsn_session.server_mod_length = shared.bi2ba(len(server_modulus))

    print('Preparing encrypted pre-master secret')
    prepare_pms(tlsn_session, session_id)

    for i in range(10):
        try:
            print('Performing handshake with server')
            tls_sock = shared.create_sock(tlsn_session.server_name,
                                          tlsn_session.ssl_port)
            tlsn_session.start_handshake(tls_sock)
            retval = negotiate_crippled_secrets(tlsn_session, tls_sock,
                                                session_id)
            if not retval == 'success':
                raise shared.TLSNSSLError('Failed to negotiate secrets: ' +
                                          retval)
            print('Getting data from server')
            #
            response = make_tlsn_request(headers, tlsn_session, tls_sock)
            #prefix response with number of to-be-ignored records,
            #note: more than 256 unexpected records will cause a failure of audit. Just as well!
            response = shared.bi2ba(
                tlsn_session.unexpected_server_app_data_count,
                fixed=1) + response
            break
        except shared.TLSNSSLError:
            shared.ssl_dump(tlsn_session)
            raise
        except Exception as e:
            print(
                'Exception caught while getting data from server, retrying...',
                e)
            if i == 9:
                raise Exception('Notarization failed')
            continue

    # commit its own hash, get auditor's secrets
    ok, commit_hash, pms2, signature, audit_time = commit_session(
        tlsn_session, response, session_id)
    if not ok:
        return ok, "commit hash to auditor failed"
# no need to verify signatures
    msg = sha256(commit_hash + pms2 +
                 shared.bi2ba(tlsn_session.server_modulus) +
                 audit_time).digest()
    oracle_ba_modulus = binascii.unhexlify(oracle_modulus)
    oracle_int_modulus = shared.ba2int(oracle_ba_modulus)
    print(msg)
    print(signature)
    if not shared.verify_signature(msg, signature, oracle_int_modulus):
        raise Exception("Notarization FAILED, notary signature invalid.")

    ok, result = decrypt_html(pms2, tlsn_session)
    if not ok:
        return ok, result
    html = result

    print('Verified OK')

    host_line = "host: " + server_name + "\r\n"
    readable = host_line
    b = """""" ""

    b = """<meta[ ]+http-equiv=["']?content-type["']?[ ]+content=["']?text/html;[ ]*charset=([0-9-a-zA-Z]+)["']?"""
    B = re.compile(b, re.IGNORECASE)
    encodings = B.search(html)
    #    print("encoding:")
    if encodings != None:
        encoding = encodings.group(1)
        if encoding.lower() == 'gb231' or encoding.lower() == 'gb2312':
            html = html.decode('gb18030')
            #        print(html)
        else:
            html = html.decode(encoding)
    else:
        html.decode('utf-8')

    print("html len:", len(html))
    html = "response:\r\n" + html + '\r\n-----PROOF BINARY DATA-----\r\n'
    #    print(html)
    #    readable += html.decode().encode('utf-8')
    readable += html
    # chosen_cipher_suite
    audit_data = shared.bi2ba(tlsn_session.chosen_cipher_suite,
                              fixed=2)  # 2 bytes
    # client_random, server_random
    audit_data += tlsn_session.client_random + tlsn_session.server_random  # 64 bytes
    # pre_master_key, two parts, each generated by auditee or auditor
    audit_data += tlsn_session.pms1 + pms2  #48 bytes
    # length of server_cert, sent by TLS Server, why fix 3 ?
    audit_data += shared.bi2ba(len(tlsn_session.server_certificate.certs),
                               fixed=3)
    # server_certs, it's very hard to verify these babies on-chain.
    audit_data += tlsn_session.server_certificate.certs
    # tls version
    audit_data += tlsn_session.tlsver  #2 bytes
    # proposed tls version in ClientHello?
    #    audit_data += tlsn_session.initial_tlsver #2 bytes
    # length of response
    audit_data += shared.bi2ba(len(response), fixed=8)  #8 bytes
    # response data
    audit_data += response  #note that it includes unexpected pre-request app data, 10s of kB
    # IV_after_finished used by RC4, necessory to authenticate response
    IV = tlsn_session.IV_after_finished if tlsn_session.chosen_cipher_suite in [47,53] \
                else shared.rc4_state_to_bytearray(tlsn_session.IV_after_finished)
    # length of IV, should be before IV ?
    audit_data += shared.bi2ba(len(IV), fixed=2)  #2 bytes
    # IV
    audit_data += IV  #16 bytes or 258 bytes for RC4.
    # length of auditor's public key, in modulus formate
    audit_data += shared.bi2ba(len(oracle_ba_modulus), fixed=2)
    # auditor's signature
    audit_data += signature  #512 bytes RSA PKCS 1 v1.5 padding
    # hash that auditee commits to auditor
    audit_data += commit_hash  #32 bytes sha256 hash
    # auditor's public key
    audit_data += oracle_ba_modulus
    # timestamp used to make signature unique
    audit_data += audit_time
    #    audit_data = bytearray(readable.encode('utf-8')) + audit_data

    date = time_str = time.strftime('%d-%b-%Y-%H-%M-%S-', time.gmtime())
    filename = date + session_id + ".pgsg"
    #    print("proof file name:",filename)
    proofpath = join(PROOF_DIR, filename)
    with open(proofpath, "w") as f:
        f.write(readable)
        f.write(audit_data)

    return True, filename
Beispiel #6
0
    oracle_ba_modulus = bytearray('').join(map(chr, oracle_modulus))
    oracle_int_modulus = shared.ba2int(oracle_ba_modulus)

    shared.load_program_config()

    if int(shared.config.get("General", "gzip_disabled")) == 1:
        global_use_gzip = False

    audit_data = extract_audit_data(audit_filename)
    #1. Verify notary pubkey - done in extract_audit_data
    print('Notary pubkey OK')
    #2. Verify signature
    #First, extract the cert in DER form from the notarization file
    #Then, extract from the cert the modulus and server name (common name field)
    #To do this, we need to initialise the TLSNClientSession
    audit_session = shared.TLSNClientSession(
        ccs=audit_data['cipher_suite'], tlsver=audit_data['initial_tlsver'])
    first_cert_len = shared.ba2int(audit_data['certs'][:3])
    server_mod, server_exp = audit_session.extract_mod_and_exp(
        certDER=audit_data['certs'][3:3 + first_cert_len], sn=True)
    print('Processing data for server: ', audit_session.server_name)
    data_to_be_verified = audit_data['commit_hash'] + audit_data[
        'pms2'] + shared.bi2ba(server_mod) + audit_data['audit_time']
    data_to_be_verified = sha256(data_to_be_verified).digest()
    if not shared.verify_signature(
            data_to_be_verified, audit_data['signature'], oracle_int_modulus):
        print('Audit FAILED. Signature is not verified.')
        exit()
    print('Notary signature OK')
    #3. Verify commitment hash.
    if not sha256(
            audit_data['response']).digest() == audit_data['commit_hash']: