Пример #1
0
def read_KAP(kap_file, teambox_email_pkey = None, encrypt_skey = None):
    workdir = Workdir()

    try:
        kap = KAPData()

        # Check if this is an encrypted file.
        is_true_KAP = False
        kap_header_check = None
        try:
            kap_header_check = open(kap_file, "r")
            kap_header = kap_header_check.read(39)
            if kap_header == "--- Encrypted chunk for KPS version 1.0":
                is_true_KAP = True
        finally:
            kap_header_check.close()

        # Decrypt the KAP.
        if is_true_KAP:
            decrypt = Popen(args = ["kpsinstalltool",
                                    "decrypt_verify",
                                    teambox_email_pkey,
                                    encrypt_skey,
                                    kap_file,
                                    os.path.join(workdir.path(), "kap.tar.gz")],
                            shell = False,
                            stdout = PIPE,
                            stderr = PIPE)
            (_, err_text) = decrypt.communicate()
            decrypt.wait()
            if decrypt.returncode != 0:
                raise KAPException("kpsinstalltool error: %s" % err_text)
        else:
            shutil.copyfile(kap_file, os.path.join(workdir.path(), "kap.tar.gz"))

        # Uncompress the KAP.
        if not os.path.exists(os.path.join(workdir.path(), "kap.tar.gz")):
            raise KAPException("Extracted KAP file does not exists.")
        t = tarfile.open(os.path.join(workdir.path(), "kap.tar.gz"))
        t.extractall(workdir.path())

        # Extract the KAP's content.
        fn = os.path.join(workdir.path(), "kap", "keys", "email.sig.pkey")
        if os.path.exists(fn):
            kap.email_sig_pkey = Key.fromBuffer(read_file(fn))
        fn = os.path.join(workdir.path(), "kap", "keys", "email.sig.skey")
        if os.path.exists(fn):
            kap.email_sig_skey = Key.fromBuffer(read_file(fn))
        fn = os.path.join(workdir.path(), "kap", "keys", "email.enc.pkey")
        if os.path.exists(fn):
            kap.email_enc_pkey = Key.fromBuffer(read_file(fn))
        fn = os.path.join(workdir.path(), "kap", "kps.bundle")
        if os.path.exists(fn):
            kap.bundle = read_file(fn)
        fn = os.path.join(workdir.path(), "kap", "kdn")
        if os.path.exists(fn):
            kap.kdn = read_file(fn).strip()
        fn = os.path.join(workdir.path(), "kap", "keyid")
        if os.path.exists(fn):
            kap.key_id = int(read_file(fn).strip())
        fn = os.path.join(workdir.path(), "kap", "lic")
        if os.path.exists(fn):
            kap.license = read_file(fn)

    finally:
        workdir.close()

    return kap
Пример #2
0
def read_KAR(teambox_ssl_key, teambox_ssl_cert, kar_file):
    workdir = Workdir()

    try:
        # Decrypt the file.
        s = SMIME.SMIME()
        s.set_cipher(SMIME.Cipher('aes_256_cbc'))
        s.load_key(teambox_ssl_key.as_path(), teambox_ssl_cert.as_path())
        pkcs7 = SMIME.load_pkcs7(kar_file)
        data = s.decrypt(pkcs7)
        data = write_file(os.path.join(workdir.path(), "signed_kar.tar"), data)

        kar_tar_file = tarfile.TarFile(os.path.join(workdir.path(), "signed_kar.tar"), "r")

        # Verify the sanity of KAR level 2 file members.
        m_tar = tar_getfirstmember(kar_tar_file, ["kar.tar.gz", "./kar.tar.gz"])
        if not m_tar: raise KARException("KAR is missing 'kar.tar.gz'.")
        if not m_tar.isfile() and not m_tar.isdir():
            raise KARException("%s is not a regular file or a directory." % (m.name))
        m_sig = tar_getfirstmember(kar_tar_file, ["kar_sig", "./kar_sig"])
        if not m_sig: raise KARException("KAR is missing 'kar_sig'.")
        if not m_sig.isfile() and not m_sig.isdir():
            raise KARException("%s is not a regular file or a directory." % (m.name))

        # Extract the KAR level 2 file members.
        tar_list = kar_tar_file.getmembers()
        for i in tar_list:
            if not i.isfile() and not i.isdir():
                raise KARException("%s is not a regular file or directory." % (m.name))
            kar_tar_file.extract(i, workdir.path())

        # Calculate the hash of the data file to validate the KAR
        # signature.
        kar_hasher = hashlib.sha256()
        kar_hasher.update(kar_tar_file.extractfile(m_tar).read())
        write_file(os.path.join(workdir.path(), "kar_hash"), kar_hasher.hexdigest() + "\n")

        # Extract the KAR data file.
        tf = tarfile.TarFile(mode = "r", fileobj = gzip.GzipFile(os.path.join(workdir.path(), "kar.tar.gz"), "r"))
        tf.extractall(path = os.path.join(workdir.path()))

        # Verify the KAR signature.
        signverify = Popen(args = ["sslsigntool", "verify", "kar/cert.pem", "kar_hash", "kar_sig"],
                           stdout = PIPE,
                           stderr = PIPE,
                           cwd = workdir.path())
        (out_text, err_text) = signverify.communicate()
        if signverify.returncode != 0:
            raise KARException("sslsigntool exception: %s" % err_text.strip());

        # Extract some informations from the signing certificate.
        kar = KARData()
        fn = os.path.join(workdir.path(), "kar", "cert.pem")
        if os.path.exists(fn):
            kar.cert = ssl.Cert(cert_data = read_file(fn))

        # Read level 1 KAR data
        fn = os.path.join(workdir.path(), "kar", "product_name")
        if os.path.exists(fn):
            kar.product_name = read_file(fn).strip()
        fn = os.path.join(workdir.path(), "kar", "product_version")
        if os.path.exists(fn):
            kar.product_version = read_file(fn).strip()
        fn = os.path.join(workdir.path(), "kar", "info")
        if os.path.exists(fn):
            kar.info = read_file(fn)
        fn = os.path.join(workdir.path(), "kar", "parent_kdn")
        if os.path.exists(fn):
            kar.parent_kdn = read_file(fn).strip()
        fn = os.path.join(workdir.path(), "kar", "admin")
        if os.path.exists(fn):
            kar.admin = read_file(fn).strip()
        fn = os.path.join(workdir.path(), "kar", "kar.enc.pkey")
        if os.path.exists(fn):
            kar.enc_pkey = Key.fromFile(fn)
        fn = os.path.join(workdir.path(), "kar", "info")
        if os.path.exists(fn):
            kar.info = read_file(fn)

    finally:
        # Remove the temporaries
        workdir.close()

    # Return the KAR data.
    return kar
Пример #3
0
def write_KAP(kap, kap_file, do_encrypt = True, teambox_email_skey = None, encrypt_pkey = None):
    workdir = Workdir()
    workdir_sig = Workdir()

    if do_encrypt and (not teambox_email_skey or not encrypt_pkey):
        raise KAPException("Encryption demanded but no key used.")

    try:
        # Copy the generated key files in $workdir/kap
        os.mkdir(os.path.join(workdir.path(), "kap"))
        os.mkdir(os.path.join(workdir.path(), "kap", "keys"))

        # Build the KAP.
        if kap.email_sig_pkey:
            kap.email_sig_pkey.save(os.path.join(workdir.path(), "kap", "keys", "email.sig.pkey"))
        if kap.email_sig_skey:
            kap.email_sig_skey.save(os.path.join(workdir.path(), "kap", "keys", "email.sig.skey"))
        if kap.email_enc_pkey:
            kap.email_enc_pkey.save(os.path.join(workdir.path(), "kap", "keys", "email.enc.pkey"))
        if kap.bundle:
            bundle_path = os.path.join(workdir.path(), "kap", "kps.bundle")
            write_file(bundle_path, kap.bundle)
        if kap.kdn:
            kdn_path = os.path.join(workdir.path(), "kap", "kdn")
            write_file(kdn_path, kap.kdn)
        if kap.key_id:
            key_id_path = os.path.join(workdir.path(), "kap", "keyid")
            write_file(key_id_path, str(kap.key_id))
        if kap.license:
            license_file_path = os.path.join(workdir.path(), "kap", "lic")
            write_file(license_file_path, kap.license)

        workdir.tar(os.path.join(workdir_sig.path(), "kap.tar.gz"), compressed = True)

        # Encrypt the KAP.
        kap_zip = os.path.join(workdir_sig.path(), "kap.tar.gz")
        if do_encrypt:
            encrypt = Popen(args = ["kpsinstalltool",
                                    "sign_encrypt",
                                    teambox_email_skey,
                                    encrypt_pkey,
                                    kap_zip,
                                    kap_file],
                            shell = False,
                            stdout = PIPE,
                            stderr = PIPE)
            (_, err_text) = encrypt.communicate()
            encrypt.wait()
            if encrypt.returncode != 0:
                raise KAPException("kpsinstalltool error: %s" % err_text)
        else:
            shutil.copyfile(kap_zip, kap_file)

    finally:
        workdir_sig.close()
        workdir.close()
Пример #4
0
def write_KAR(kar, kar_file, teambox_ssl_cert, client_ssl_cert, client_ssl_key):
    workdir = Workdir()
    workdir_sig = Workdir()

    try:
        # Make sure we have everything that is mandatory in the KAR.
        for i in ['cert', 'enc_pkey', 'product_name', 'product_version', 'info', 'admin']:
            if not kar.__dict__.has_key(i):
                raise KARException("Value for %s field missing from KAR." % i)

        # Add the level 1 KAR data.
        os.mkdir(os.path.join(workdir.path(), "kar"))
        fn = os.path.join(workdir.path(), "kar", "cert.pem")
        kar.cert.save(fn)
        fn = os.path.join(workdir.path(), "kar", "kar.enc.pkey")
        kar.enc_pkey.save(fn)
        fn = os.path.join(workdir.path(), "kar", "product_name")
        write_file(fn, kar.product_name)
        fn = os.path.join(workdir.path(), "kar", "product_version")
        write_file(fn, kar.product_version)
        fn = os.path.join(workdir.path(), "kar", "info")
        write_file(fn, kar.info)
        fn = os.path.join(workdir.path(), "kar", "admin")
        write_file(fn, kar.admin)
        if kar.parent_kdn:
            fn = os.path.join(workdir.path(), "kar", "parent_kdn")
            write_file(fn, kar.parent_kdn)

        # Zip the level 1 KAR.
        workdir.tar(os.path.join(workdir.path(), "kar.tar.gz"), compressed = True)

        # Create the KAR file level 2 files.
        shutil.copy(os.path.join(workdir.path(), "kar.tar.gz"), workdir_sig.path())

        # Sign the KAR level 2.
        kar_hasher = hashlib.sha256()
        kar_hasher.update(read_file(os.path.join(workdir_sig.path(), "kar.tar.gz")))
        hash_path = os.path.join(workdir_sig.path(), "kar_hash")
        sig_path = os.path.join(workdir_sig.path(), "kar_sig")
        write_file(hash_path, kar_hasher.hexdigest() + "\n")
        sslsign = Popen(args = ["sslsigntool",
                                "sign",
                                client_ssl_cert.as_path(),
                                client_ssl_key.as_path(),
                                hash_path,
                                sig_path],
                        stdout = PIPE,
                        stderr = PIPE,
                        cwd = workdir_sig.path())
        (out_text, err_text) = sslsign.communicate()
        if sslsign.returncode != 0:
            raise KARException("sslsigntool exception: %s" % err_text.strip())
        os.unlink(hash_path)
        workdir_sig.tar(os.path.join(workdir_sig.path(), "signed_kar.tar"))

        # Encrypt the KAR level 2.
        inf = BIO.openfile(os.path.join(workdir_sig.path(), "signed_kar.tar"), "r")
        outf = BIO.openfile(kar_file, "w")

        xs = X509.X509_Stack()
        xs.push(teambox_ssl_cert.as_cert())

        s = SMIME.SMIME()
        s.set_cipher(SMIME.Cipher('aes_256_cbc'))
        s.set_x509_stack(xs)
        s.load_key(client_ssl_key.as_path(), certfile = teambox_ssl_cert.as_path())
        pkcs7 = s.encrypt(inf, flags = SMIME.PKCS7_BINARY)
        pkcs7.write(outf)
    finally:
        # Remove the temporaries.
        workdir.close()
        workdir_sig.close()