Esempio n. 1
0
def decrypt_html(pms2, tlsn_session):
    '''Receive correct server mac key and then decrypt server response (html),
    (includes authentication of response). Submit resulting html for browser
    for display (optionally render by stripping http headers).'''
    print("\nStarting decryption of content, may take a few seconds...")
    try:
        tlsn_session.auditor_secret = pms2[:tlsn_session.n_auditor_entropy]
        tlsn_session.set_auditor_secret()
        tlsn_session.set_master_secret_half(
        )  #without arguments sets the whole MS
        tlsn_session.do_key_expansion(
        )  #also resets encryption connection state
    except shared.TLSNSSLError:
        shared.ssl_dump(tlsn_session)
        raise
        #either using slowAES or a RC4 ciphersuite
    try:
        plaintext, bad_mac = tlsn_session.process_server_app_data_records()


#        print(plaintext)
    except shared.TLSNSSLError:
        shared.ssl_dump(tlsn_session)
        raise
    if bad_mac:
        return False, "ERROR! Audit not valid! Plaintext is not authenticated."

    # if http data chunked, dechunk
    plaintext = shared.dechunk_http(plaintext)
    if global_use_gzip:
        plaintext = shared.gunzip_http(plaintext)
    return True, plaintext
Esempio n. 2
0
def decrypt_html_stage2(plaintext, tlsn_session, sf):
    plaintext = shared.dechunk_http(plaintext)
    if global_use_gzip:
        plaintext = shared.gunzip_http(plaintext)
    #write a session dump for checking even in case of success
    with open(join(current_session_dir, 'session_dump' + sf), 'wb') as f:
        f.write(tlsn_session.dump())
    commit_dir = join(current_session_dir, 'commit')
    html_path = join(commit_dir, 'html-' + sf)
    with open(html_path, 'wb') as f:
        f.write('\xef\xbb\xbf' + plaintext)  #see "Byte order mark"
    if not int(shared.config.get("General", "prevent_render")):
        htm = l_path = join(commit_dir, 'forbrowser-' + sf + '.html')
        with open(html_path, 'wb') as f:
            f.write('\r\n\r\n'.join(plaintext.split('\r\n\r\n')[1:]))
    print("Decryption complete.")
    return ('success', html_path)
Esempio n. 3
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
    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'] 
    plaintext, bad_mac = audit_session.process_server_app_data_records(is_for_auditor=True)
    if bad_mac:
        print ('Audit FAILED. Decrypted data has bad HMACs.')
    print ('HTML decryption with correct HMACs OK.')
    plaintext = shared.dechunk_http(plaintext)
    plaintext = shared.gunzip_http(plaintext)
    #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))
    #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')    

    print ("Audit passed! You can read the html at: ",
           join(current_session_dir,'audited.html'), 
           'and check the server certificate with the data provided in ',
           join(current_session_dir,'domain_data.txt'))
    
Esempio n. 5
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']
    plaintext, bad_mac = audit_session.process_server_app_data_records(
        is_for_auditor=True)
    if bad_mac:
        print('Audit FAILED. Decrypted data has bad HMACs.')
    print('HTML decryption with correct HMACs OK.')
    plaintext = shared.dechunk_http(plaintext)
    plaintext = shared.gunzip_http(plaintext)
    #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))
    #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')

    print("Audit passed! You can read the html at: ",
          join(current_session_dir, 'audited.html'),
          'and check the server certificate with the data provided in ',