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()
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()