This file is indexed.

/usr/lib/python2.7/dist-packages/flashproxy/keys.py is in flashproxy-common 1.7-4.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
import base64
import errno
import os
import sys
import tempfile

from hashlib import sha1

try:
    import M2Crypto
    from M2Crypto import BIO, RSA
except ImportError:
    # Defer the error so that the main program gets a chance to print help text
    M2Crypto = None

class options(object):
    disable_pin = True

def add_module_opts(parser):
    parser.add_argument("--disable-pin", help="disable all certificate pinning "
        "checks", action="store_true",)

    old_parse = parser.parse_args
    def parse_args(namespace):
        options.disable_pin = namespace.disable_pin
        return namespace
    parser.parse_args = lambda *a, **kw: parse_args(old_parse(*a, **kw))


# We trust no other CA certificate than this.
#
# To find the certificate to copy here,
# $ strace openssl s_client -connect FRONT_DOMAIN:443 -verify 10 -CApath /etc/ssl/certs 2>&1 | grep /etc/ssl/certs
# stat("/etc/ssl/certs/XXXXXXXX.0", {st_mode=S_IFREG|0644, st_size=YYYY, ...}) = 0
PIN_GOOGLE_CA_CERT = """\
subject=/C=US/O=Equifax/OU=Equifax Secure Certificate Authority
issuer=/C=US/O=Equifax/OU=Equifax Secure Certificate Authority
-----BEGIN CERTIFICATE-----
MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJV
UzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2Vy
dGlmaWNhdGUgQXV0aG9yaXR5MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1
MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VxdWlmYXgxLTArBgNVBAsTJEVx
dWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCBnzANBgkqhkiG9w0B
AQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPRfM6f
BeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+A
cJkVV5MW8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kC
AwEAAaOCAQkwggEFMHAGA1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQ
MA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlm
aWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoGA1UdEAQTMBGBDzIwMTgw
ODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvSspXXR9gj
IBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQF
MAMBAf8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUA
A4GBAFjOKer89961zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y
7qj/WsjTVbJmcVfewCHrPSqnI0kBBIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh
1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee9570+sB3c4
-----END CERTIFICATE-----
"""
# SHA-1 digest of expected public keys. Any of these is valid. See
# http://www.imperialviolet.org/2011/05/04/pinning.html for the reason behind
# hashing the public key, not the entire certificate.
PIN_GOOGLE_PUBKEY_SHA1 = (
    # https://src.chromium.org/viewvc/chrome/trunk/src/net/http/transport_security_state_static.h?revision=209003&view=markup
    # kSPKIHash_Google1024
    "\x40\xc5\x40\x1d\x6f\x8c\xba\xf0\x8b\x00\xed\xef\xb1\xee\x87\xd0\x05\xb3\xb9\xcd",
    # kSPKIHash_GoogleG2
    "\x43\xda\xd6\x30\xee\x53\xf8\xa9\x80\xca\x6e\xfd\x85\xf4\x6a\xa3\x79\x90\xe0\xea",
)

def check_certificate_pin(sock, cert_pubkey):
    if options.disable_pin: return
    found = []
    for cert in sock.get_peer_cert_chain():
        pubkey_der = cert.get_pubkey().as_der()
        pubkey_digest = sha1(pubkey_der).digest()
        if pubkey_digest in cert_pubkey:
            break
        found.append(pubkey_digest)
    else:
        found = "(" + ", ".join(x.encode("hex") for x in found) + ")"
        expected = "(" + ", ".join(x.encode("hex") for x in cert_pubkey) + ")"
        raise ValueError("Public key does not match pin: got %s but expected any of %s" % (found, expected))

def get_state_dir():
    """Get a directory where we can put temporary files. Returns None if any
    suitable temporary directory will do."""
    pt_dir = os.environ.get("TOR_PT_STATE_LOCATION")
    if pt_dir is None:
        return None
    try:
        os.makedirs(pt_dir)
    except OSError, e:
        if e.errno != errno.EEXIST:
            raise
    return pt_dir

class temp_cert(object):
    """Implements a with-statement over raw certificate data."""

    def __init__(self, certdata):
        fd, self.path = tempfile.mkstemp(prefix="fp-cert-temp-", dir=get_state_dir(), suffix=".crt")
        os.write(fd, certdata)
        os.close(fd)

    def __enter__(self):
        return self.path

    def __exit__(self, type, value, traceback):
        os.unlink(self.path)

def get_pubkey(defaultkeybytes, overridefn=None):
    if overridefn is not None:
        return RSA.load_pub_key(overridefn)
    else:
        return RSA.load_pub_key_bio(BIO.MemoryBuffer(defaultkeybytes))

def pubkey_b64enc(plaintext, pubkey, urlsafe=False):
    ciphertext = pubkey.public_encrypt(plaintext, RSA.pkcs1_oaep_padding)
    if urlsafe:
        return base64.urlsafe_b64encode(ciphertext)
    else:
        return ciphertext.encode("base64")

def ensure_M2Crypto():
    if M2Crypto is None:
        print >> sys.stderr, """\
This program requires the M2Crypto library, which is not installed.

You can install it using one of the packages at
http://chandlerproject.org/Projects/MeTooCrypto#Downloads.

On Debian-like systems, use the command "apt-get install python-m2crypto".\
"""
        sys.exit(1)