def split_pkcs12(app: Flask): """Split up .p12 containers if necessary.""" with app.app_context(): push_certificate_path = app.config['PUSH_CERTIFICATE'] if not os.path.exists(push_certificate_path): raise RuntimeError('You specified a push certificate at: {}, but it does not exist.'.format(push_certificate_path)) # We can handle loading PKCS#12 but APNS2Client specifically requests PEM encoded certificates push_certificate_basename, ext = os.path.splitext(push_certificate_path) if ext.lower() == '.p12': pem_key_path = push_certificate_basename + '.key' pem_certificate_path = push_certificate_basename + '.crt' if not os.path.exists(pem_key_path) or not os.path.exists(pem_certificate_path): app.logger.info('You provided a PKCS#12 push certificate, we will have to encode it as PEM to continue...') app.logger.info('.key and .crt files will be saved in the same location') with open(push_certificate_path, 'rb') as fd: if 'PUSH_CERTIFICATE_PASSWORD' in app.config: key, certificate, intermediates = parse_pkcs12(fd.read(), bytes(app.config['PUSH_CERTIFICATE_PASSWORD'], 'utf8')) else: key, certificate, intermediates = parse_pkcs12(fd.read()) crypto_key = serialization.load_der_private_key(key.dump(), None, default_backend()) with open(pem_key_path, 'wb') as fd: fd.write(crypto_key.private_bytes( encoding=serialization.Encoding.PEM, format=serialization.PrivateFormat.PKCS8, encryption_algorithm=serialization.NoEncryption())) crypto_cert = x509.load_der_x509_certificate(certificate.dump(), default_backend()) with open(pem_certificate_path, 'wb') as fd: fd.write(crypto_cert.public_bytes(serialization.Encoding.PEM))
def parse(self): assert self.type == ContainerTypes.PKCS12 if self.password is None: (self.privatekey, self.cert, self.certs) = k.parse_pkcs12(self.bytes) else: (self.privatekey, self.cert, self.certs) = k.parse_pkcs12(self.bytes, password=self.password) self._raise_if_wrong_algorithm() self._is_parsed = True
def is_type(cls, container_bytes, password=None): try: if password is None: k.parse_pkcs12(container_bytes) else: k.parse_pkcs12(container_bytes, password=password) return True except Exception: return False
def main(): date = datetime.datetime.utcnow() - datetime.timedelta(hours=12) date = date.strftime('%Y%m%d%H%M%S+00\'00\'') dct = { b'sigflags': 3, # b'sigpage': 0, b'sigbutton': True, b'signature_img': b'signature_test.png', b'contact': b'*****@*****.**', b'location': b'Szczecin', b'signingdate': date.encode(), b'reason': b'Dokument podpisany cyfrowo', b'signature': b'Dokument podpisany cyfrowo', b'signaturebox': (470, 0, 570, 100), } with open('demo2_user1.p12', 'rb') as f: key, cert, certe = keys.parse_pkcs12(f.read(), b'1234') fname = 'pdf.pdf' if len(sys.argv) > 1: fname = sys.argv[1] datau = open(fname, 'rb').read() datas = pdf.cms.sign(datau, dct, key, cert, certe, 'sha256') fname = fname.replace('.pdf', '-signed-cms-oscrypto.pdf') with open(fname, 'wb') as fp: fp.write(datau) fp.write(datas)
def test_parse_pkcs12_chain(self): with open(os.path.join(fixtures_dir, 'keys/test-third.p12'), 'rb') as f: key_info, cert_info, extra_cert_infos = keys.parse_pkcs12( f.read(), b'password123') with open(os.path.join(fixtures_dir, 'keys/test-third-der.key'), 'rb') as f: private_key = asn1crypto.keys.RSAPrivateKey.load(f.read()) key_der = asn1crypto.keys.PrivateKeyInfo.wrap(private_key, 'rsa').dump() with open(os.path.join(fixtures_dir, 'keys/test-third-der.crt'), 'rb') as f: cert_der = f.read() with open(os.path.join(fixtures_dir, 'keys/test-inter-der.crt'), 'rb') as f: intermediate_cert_der = f.read() with open(os.path.join(fixtures_dir, 'keys/test-der.crt'), 'rb') as f: root_cert_der = f.read() self.assertEqual(key_der, key_info.dump()) self.assertEqual(cert_der, cert_info.dump()) self.assertEqual(sorted([intermediate_cert_der, root_cert_der]), sorted([info.dump() for info in extra_cert_infos])) # Make sure we can parse the DER key_info.native cert_info.native for info in extra_cert_infos: info.native
def sign_mach_o( filename: str, p12_path: str, passphrase: Optional[str] = None, force: bool = False, file_list: Optional[str] = None, detach_target: Optional[str] = None, ): """ Code sign a Mach-O binary in place """ bundle, filepath = get_bundle_exec(filename) if passphrase is None: passphrase = getpass.getpass(f"Enter the passphrase for {p12_path}: ") pass_bytes = passphrase.encode() # Load cert and privkey with open(p12_path, "rb") as f: privkey, cert, _ = parse_pkcs12(f.read(), pass_bytes) # Include the bundle name in the detached target if detach_target: detach_target = os.path.join(detach_target, os.path.basename(bundle)) # Sign cs = CodeSigner(filepath, cert, privkey, force=force, detach_target=detach_target) cs.make_signature() if file_list is not None: cs.write_file_list(file_list)
def from_pfx_string(data: str | bytes, password: str, dhparams: DirtyDH = None, username: str = None, domain: str = None) -> KerberosCredential: k = KerberosCredential() if password is None: password = b'' if isinstance(password, str): password = password.encode() if isinstance(data, str): data = base64.b64decode( data.replace(' ', '').replace('\r', '').replace('\n', '').encode()) # private_key is not actually the private key object but the privkey data because oscrypto privkey # cant be serialized so we cant make copy of it. k.private_key, k.certificate, extra_certs = parse_pkcs12( data, password=password) #k.private_key = load_private_key(privkeyinfo) k.set_user_and_domain_from_cert(username=username, domain=domain) k.set_dhparams(dhparams) return k
def test_parse_pkcs12_chain(self): with open(os.path.join(fixtures_dir, 'keys/test-third.p12'), 'rb') as f: key_info, cert_info, extra_cert_infos = keys.parse_pkcs12(f.read(), b'password123') with open(os.path.join(fixtures_dir, 'keys/test-third-der.key'), 'rb') as f: private_key = asn1crypto.keys.RSAPrivateKey.load(f.read()) key_der = asn1crypto.keys.PrivateKeyInfo.wrap(private_key, 'rsa').dump() with open(os.path.join(fixtures_dir, 'keys/test-third-der.crt'), 'rb') as f: cert_der = f.read() with open(os.path.join(fixtures_dir, 'keys/test-inter-der.crt'), 'rb') as f: intermediate_cert_der = f.read() with open(os.path.join(fixtures_dir, 'keys/test-der.crt'), 'rb') as f: root_cert_der = f.read() self.assertEqual(key_der, key_info.dump()) self.assertEqual(cert_der, cert_info.dump()) self.assertEqual( sorted([intermediate_cert_der, root_cert_der]), sorted([info.dump() for info in extra_cert_infos]) ) # Make sure we can parse the DER key_info.native cert_info.native for info in extra_cert_infos: info.native
def from_p12_file(cls, p12_file, password=None): with open(p12_file, 'rb') as file_handle: private_key_info, certificate, chain = keys.parse_pkcs12( file_handle.read(), password=password) cert = cls(certificate=certificate) private_key = PrivateKey(private_key=private_key_info) return cert, private_key
def get_apns() -> apns2.APNSClient: apns = getattr(g, '_apns', None) if apns is None: push_certificate_path = current_app.config['PUSH_CERTIFICATE'] if not os.path.exists(push_certificate_path): raise RuntimeError('You specified a push certificate at: {}, but it does not exist.'.format(push_certificate_path)) client_cert = push_certificate_path # can be a single path or tuple of 2 # We can handle loading PKCS#12 but APNS2Client specifically requests PEM encoded certificates push_certificate_basename, ext = os.path.splitext(push_certificate_path) if ext.lower() == '.p12': pem_key_path = push_certificate_basename + '.key' pem_certificate_path = push_certificate_basename + '.crt' if not os.path.exists(pem_key_path) or not os.path.exists(pem_certificate_path): current_app.logger.info('You provided a PKCS#12 push certificate, we will have to encode it as PEM to continue...') current_app.logger.info('.key and .crt files will be saved in the same location') with open(push_certificate_path, 'rb') as fd: if 'PUSH_CERTIFICATE_PASSWORD' in current_app.config: key, certificate, intermediates = parse_pkcs12(fd.read(), bytes(current_app.config['PUSH_CERTIFICATE_PASSWORD'], 'utf8')) else: key, certificate, intermediates = parse_pkcs12(fd.read()) crypto_key = serialization.load_der_private_key(key.dump(), None, default_backend()) with open(pem_key_path, 'wb') as fd: fd.write(crypto_key.private_bytes( encoding=serialization.Encoding.PEM, format=serialization.PrivateFormat.PKCS8, encryption_algorithm=serialization.NoEncryption())) crypto_cert = x509.load_der_x509_certificate(certificate.dump(), default_backend()) with open(pem_certificate_path, 'wb') as fd: fd.write(crypto_cert.public_bytes(serialization.Encoding.PEM)) client_cert = pem_certificate_path, pem_key_path try: apns = g._apns = apns2.APNSClient(mode='prod', client_cert=client_cert) except: raise RuntimeError('Your push certificate is expired or invalid') return apns
def from_pfx(pfxfile, pfxpass, dh_params=None): pkinit = PKINIT() #print('Loading pfx12') if isinstance(pfxpass, str): pfxpass = pfxpass.encode() with open(pfxfile, 'rb') as f: pkinit.privkeyinfo, pkinit.certificate, pkinit.extra_certs = parse_pkcs12( f.read(), password=pfxpass) pkinit.privkey = load_private_key(pkinit.privkeyinfo) #print('pfx12 loaded!') pkinit.setup(dh_params=dh_params) return pkinit
def test_pkcs12(pw): arch = CONFIG.get_pki_arch(ArchLabel('testing-ca')) package = arch.package_pkcs12(CertLabel('signer1'), password=pw) if pw: # there's something about passwordless PKCS#12 files that doesn't quite # jive between oscrypto and pyca/cryptography key, cert, chain = oskeys.parse_pkcs12(package, password=pw) assert cert.dump() == arch.get_cert(CertLabel('signer1')).dump() assert len(chain) == 2 assert key is not None from cryptography.hazmat.primitives.serialization import pkcs12 key, cert, chain = pkcs12.load_key_and_certificates(package, password=pw) assert key is not None assert len(chain) == 2
def test_parse_pkcs12_dsa(self): with open(os.path.join(fixtures_dir, 'keys/test-dsa.p12'), 'rb') as f: key_info, cert_info, extra_cert_infos = keys.parse_pkcs12(f.read(), b'password123') with open(os.path.join(fixtures_dir, 'keys/test-pkcs8-dsa-der.key'), 'rb') as f: key_der = f.read() with open(os.path.join(fixtures_dir, 'keys/test-dsa-der.crt'), 'rb') as f: cert_der = f.read() self.assertEqual(key_der, key_info.dump()) self.assertEqual(cert_der, cert_info.dump()) self.assertEqual([], extra_cert_infos) # Make sure we can parse the DER key_info.native cert_info.native
def parse_pkcs12(self, input_filename, password): with open(os.path.join(fixtures_dir, input_filename), 'rb') as f: key_info, cert_info, extra_cert_infos = keys.parse_pkcs12(f.read(), password) with open(os.path.join(fixtures_dir, 'keys/test-pkcs8-der.key'), 'rb') as f: key_der = f.read() with open(os.path.join(fixtures_dir, 'keys/test-der.crt'), 'rb') as f: cert_der = f.read() self.assertEqual(key_der, key_info.dump()) self.assertEqual(cert_der, cert_info.dump()) self.assertEqual([], extra_cert_infos) # Make sure we can parse the DER key_info.native cert_info.native
def test_pkcs12(pw): data = {'cert': 'signer1'} if pw is not None: data['passphrase'] = pw.decode('ascii') response = CLIENT.post('/_certomancer/pfx-download/testing-ca', data=data) package = response.data if pw: # there's something about passwordless PKCS#12 files that doesn't quite # jive between oscrypto and pyca/cryptography key, cert, chain = oskeys.parse_pkcs12(package, password=pw) assert 'Alice' in cert.subject.human_friendly assert len(chain) == 2 assert key is not None from cryptography.hazmat.primitives.serialization import pkcs12 key, cert, chain = pkcs12.load_key_and_certificates(package, password=pw) assert key is not None assert len(chain) == 2
def build_as_req_negoEx(user_cert, cert_pass, remoteComputer, diffieHellmanExchange): pfx = open(user_cert, 'rb').read() privkeyinfo, certificate, extra_certs = parse_pkcs12( pfx, password=cert_pass.encode()) privkey = load_private_key(privkeyinfo) issuer = certificate.issuer.native['common_name'] cname = "AzureAD\\" + issuer + "\\" + [ i for i in certificate.subject.native['common_name'] if i.startswith('S-1') ][0] now = datetime.datetime.now(datetime.timezone.utc) req_body = build_req_body_NegoEx(remoteComputer, cname, now) padata = BuildPkinit_pa(req_body, now, diffieHellmanExchange, privkey, certificate) payload = PA_PK_AS_REQ() payload['signedAuthPack'] = padata pa_data = { 'padata-type': PaDataType.PK_AS_REQ.value, 'padata-value': payload.dump() } asreq = { 'pvno': 5, 'msg-type': 10, 'padata': [pa_data], 'req-body': req_body } req = { 'kerberos-v5': algos.DigestAlgorithmId('1.3.6.1.5.2.7'), 'null': core.Null(), 'Kerberos': AS_REQ(asreq) } req = SPNEGO_PKINIT_REP(req) return issuer, req.dump().hex()
def split_pkcs12(app: Flask): """Split up .p12 containers if necessary.""" with app.app_context(): if 'PUSH_CERTIFICATE' not in app.config: app.logger.warn( 'No push certificate specified, you will not be able to manage devices until this is configured' ) return push_certificate_path = app.config['PUSH_CERTIFICATE'] if not os.path.exists(push_certificate_path): raise RuntimeError( 'You specified a push certificate at: {}, but it does not exist.' .format(push_certificate_path)) # We can handle loading PKCS#12 but APNS2Client specifically requests PEM encoded certificates push_certificate_basename, ext = os.path.splitext( push_certificate_path) if ext.lower() == '.p12': pem_key_path = push_certificate_basename + '.key' pem_certificate_path = push_certificate_basename + '.crt' if not os.path.exists(pem_key_path) or not os.path.exists( pem_certificate_path): app.logger.info( 'You provided a PKCS#12 push certificate, we will have to encode it as PEM to continue...' ) app.logger.info( '.key and .crt files will be saved in the same location: %s, %s', pem_key_path, pem_certificate_path) with open(push_certificate_path, 'rb') as fd: if 'PUSH_CERTIFICATE_PASSWORD' in app.config: key, certificate, intermediates = parse_pkcs12( fd.read(), bytes(app.config['PUSH_CERTIFICATE_PASSWORD'], 'utf8')) else: key, certificate, intermediates = parse_pkcs12( fd.read()) try: crypto_key = serialization.load_der_private_key( key.dump(), None, default_backend()) with open(pem_key_path, 'wb') as fd: fd.write( crypto_key.private_bytes( encoding=serialization.Encoding.PEM, format=serialization.PrivateFormat.PKCS8, encryption_algorithm=serialization. NoEncryption())) crypto_cert = x509.load_der_x509_certificate( certificate.dump(), default_backend()) with open(pem_certificate_path, 'wb') as fd: fd.write( crypto_cert.public_bytes( serialization.Encoding.PEM)) except PermissionError: app.logger.error( 'Could not write out .key or .crt file. You will not be able to push APNS messages' ) app.logger.error( 'This means your MDM is BROKEN until you fix permissions' ) else: app.logger.info('.p12 already split into PEM/KEY components')