def from_pdf_object(cls, pdf_dict): """ Read a PDF dictionary into a :class:`.SigCertConstraints` object. :param pdf_dict: A :class:`~.generic.DictionaryObject`. :return: A :class:`.SigCertConstraints` object. """ if isinstance(pdf_dict, generic.IndirectObject): pdf_dict = pdf_dict.get_object() try: if pdf_dict['/Type'] != '/SVCert': # pragma: nocover raise ValueError('Object /Type entry is not /SVCert') except KeyError: # pragma: nocover pass flags = SigCertConstraintFlags(pdf_dict.get('/Ff', 0)) subjects = [ oskeys.parse_certificate(cert.original_bytes) for cert in pdf_dict.get('/Subject', ()) ] issuers = [ oskeys.parse_certificate(cert.original_bytes) for cert in pdf_dict.get('/Issuer', ()) ] def format_attr(attr): # strip initial / attr = attr[1:] # attempt to convert abbreviated attrs to OIDs, since build() # takes OIDs return name_type_abbrevs_rev.get(attr.upper(), attr) subject_dns = x509.Name.build({ format_attr(attr): value for dn_dir in pdf_dict.get('/SubjectDN', ()) for attr, value in dn_dir.items() }) def parse_key_usage(val): return [SigCertKeyUsage.read_from_sv_string(ku) for ku in val] key_usage = get_and_apply(pdf_dict, '/KeyUsage', parse_key_usage) url = pdf_dict.get('/URL') url_type = pdf_dict.get('/URLType') kwargs = { 'flags': flags, 'subjects': subjects or None, 'subject_dn': subject_dns or None, 'issuers': issuers or None, 'info_url': url, 'key_usage': key_usage } if url is not None and url_type is not None: kwargs['url_type'] = url_type return cls(**kwargs)
def is_type(cls, container_bytes, password=None): try: cert = k.parse_certificate(container_bytes) cert.native return True except Exception: return False
def create_degenerate_pkcs7(*certificates: List[x509.Certificate]) -> ContentInfo: """Produce a PKCS#7 Degenerate case. The degenerate case is a SignedData content type in which there are no signers. Certificates are disseminated via the ``certificates`` attribute. Args: *certificates (List[x509.Certificate]): The certificates to attach to the degenerate pkcs#7 payload. The first must always be the issued certificate. Returns: ContentInfo: The ContentInfo containing a SignedData structure. """ certificates_der = [c.public_bytes(serialization.Encoding.DER) for c in certificates] certificates_asn1 = [parse_certificate(der_bytes) for der_bytes in certificates_der] # draft-gutmann-scep 3.4. content type must be omitted empty = ContentInfo({ 'content_type': ContentType('data') }) sd_certificates = CertificateSet([CertificateChoices('certificate', asn1) for asn1 in certificates_asn1]) sd = SignedData({ 'version': CMSVersion(1), 'encap_content_info': empty, 'digest_algorithms': DigestAlgorithms([]), 'certificates': sd_certificates, 'signer_infos': SignerInfos([]), 'crls': RevocationInfoChoices([]), }) return ContentInfo({ 'content_type': ContentType('signed_data'), 'content': sd, })
def create_degenerate_certificate(certificate: x509.Certificate) -> ContentInfo: """Produce a PKCS#7 Degenerate case with a single certificate. Args: certificate (x509.Certificate): The certificate to attach to the degenerate pkcs#7 payload. Returns: ContentInfo: The ContentInfo containing a SignedData structure. """ der_bytes = certificate.public_bytes( serialization.Encoding.DER ) asn1cert = parse_certificate(der_bytes) empty = ContentInfo({ 'content_type': ContentType('data') }) sd = SignedData({ 'version': CMSVersion(1), 'encap_content_info': empty, 'digest_algorithms': DigestAlgorithms([]), 'certificates': CertificateSet([CertificateChoices('certificate', asn1cert)]), 'signer_infos': SignerInfos([]), 'crls': RevocationInfoChoices([]), }) return ContentInfo({ 'content_type': ContentType('signed_data'), 'content': sd, })
def _load_objects(self): if self._loaded: return q = self.pkcs11_session.get_objects({ Attribute.LABEL: self.cert_label, Attribute.CLASS: ObjectClass.CERTIFICATE }) # need to run through the full iterator to make sure the operation # terminates cert_obj, = list(q) self._signing_cert = oskeys.parse_certificate( cert_obj[Attribute.VALUE]) self._load_ca_chain() q = self.pkcs11_session.get_objects({ Attribute.LABEL: self.key_label, Attribute.CLASS: ObjectClass.PRIVATE_KEY }) self._key_handle, = list(q) self._loaded = True
def _load_ca_chain(self) -> Set[x509.Certificate]: q = self.pkcs11_session.get_objects({ Attribute.LABEL: 'CA', Attribute.CLASS: ObjectClass.CERTIFICATE }) cert_obj, = list(q) intermediate_ca = keys.parse_certificate(cert_obj[Attribute.VALUE]) q = self.pkcs11_session.get_objects({ Attribute.LABEL: 'Root', Attribute.CLASS: ObjectClass.CERTIFICATE }) cert_obj, = list(q) root_ca = keys.parse_certificate(cert_obj[Attribute.VALUE]) return {intermediate_ca, root_ca}
def parse_certificate(self, input_filename, algo): with open(os.path.join(fixtures_dir, input_filename), 'rb') as f: parsed = keys.parse_certificate(f.read()) self.assertEqual(algo, parsed['tbs_certificate']['subject_public_key_info']['algorithm']['algorithm'].native) self.assertEqual('Codex Non Sufficit LC', parsed['tbs_certificate']['subject'].native['organization_name']) # Make sure we can parse the whole structure parsed.native
def sid(self) -> SignerIdentifier: """Get a SignerIdentifier for IssuerAndSerialNumber""" derp = self.certificate.public_bytes(serialization.Encoding.DER) asn1cert = parse_certificate(derp) # Signer Identifier ias = IssuerAndSerialNumber({'issuer': asn1cert.issuer, 'serial_number': asn1cert.serial_number}) sid = SignerIdentifier('issuer_and_serial_number', ias) return sid
def _pull_cert(pkcs11_session: Session, label: str): q = pkcs11_session.get_objects({ Attribute.LABEL: label, Attribute.CLASS: ObjectClass.CERTIFICATE }) # need to run through the full iterator to make sure the operation # terminates try: cert_obj, = list(q) except ValueError: raise PKCS11Error( f"Could not find (unique) cert with label '{label}'." ) return oskeys.parse_certificate(cert_obj[Attribute.VALUE])
def add_signer(self, signer: Signer): """Add a signer to SignerInfos. Args: signer (Signer): Signer instance Returns: PKIMessageBuilder: This instance See Also: - `pkcs#7 RFC2315 Section 9.2 <https://tools.ietf.org/html/rfc2315#section-9.2>`_. """ self._signers.append(signer) der_certificate = signer.certificate.public_bytes(serialization.Encoding.DER) asn1_certificate = parse_certificate(der_certificate) self._certificates.append(CertificateChoices('certificate', asn1_certificate)) return self
def __pull(self): other_certs = self.other_certs if other_certs is None or self.bulk_fetch: # first, query all certs q = self.pkcs11_session.get_objects({ Attribute.CLASS: ObjectClass.CERTIFICATE }) for cert_obj in q: label = cert_obj[Attribute.LABEL] if other_certs is None or label in other_certs: yield oskeys.parse_certificate(cert_obj[Attribute.VALUE]) else: # fetch certs one by one for label in other_certs: yield _pull_cert(self.pkcs11_session, label)
def certificates(self, *certificates: List[x509.Certificate]): """Add x.509 certificates to be attached to the certificates field. Args: certificates: variadic argument of x509.Certificate Returns: PKIMessageBuilder: This instance See Also: - `pkcs#7 RFC 2315 Section 9.1 <https://tools.ietf.org/html/rfc2315#section-9.1>`_. """ for cert in certificates: # Serialize and load to avoid constructing asn1crypto.Certificate ourselves (yuck) derp = cert.public_bytes(serialization.Encoding.DER) asn1cert = parse_certificate(derp) choice = CertificateChoices('certificate', asn1cert) self._certificates.append(choice) return self
def test_pubkey_wrong_cert(): r = PdfFileReader(BytesIO(VECTOR_IMAGE_PDF)) w = writer.PdfFileWriter() from oscrypto import keys recpt_cert = keys.parse_certificate( read_all(TESTING_CA_DIR + '/intermediate/newcerts/signer.cert.pem')) test_data = b'This is test data!' dummy_stream = generic.StreamObject(stream_data=test_data) ref = w.add_object(dummy_stream) w.encrypt_pubkey([recpt_cert]) out = BytesIO() w.write(out) r = PdfFileReader(out) result = r.decrypt_pubkey(PUBKEY_TEST_DECRYPTER) assert result == AuthResult.FAILED with pytest.raises(misc.PdfError): r.get_object(ref.reference)
def _build_recipient_info(self, symmetric_key: bytes, recipient: x509.Certificate) -> RecipientInfo: """Build an ASN.1 data structure containing the encrypted symmetric key for the encrypted_content. NOTE: The recipient is always identified by issuerAndSerialNumber NOTE: Args: symmetric_key (bytes): Typically the randomly generated 3DES key for the encrypted_content. recipient (x509.Certificate): The certificate which will be used to encrypt the symmetric key. Returns: RecipientInfo: Instance of ASN.1 data structure with required attributes and encrypted key. """ encrypted_symkey = recipient.public_key().encrypt( symmetric_key, asympad.PKCS1v15()) asn1cert = parse_certificate( recipient.public_bytes(serialization.Encoding.DER)) ias = IssuerAndSerialNumber({ 'issuer': asn1cert.issuer, 'serial_number': asn1cert.serial_number }) ri = RecipientInfo( 'ktri', KeyTransRecipientInfo({ 'version': 0, 'rid': RecipientIdentifier('issuer_and_serial_number', ias), 'key_encryption_algorithm': KeyEncryptionAlgorithm( {'algorithm': KeyEncryptionAlgorithmId('rsa')}), 'encrypted_key': encrypted_symkey, })) return ri
def from_pem_data(certdata: str | bytes, keydata: str | bytes, dhparams: DirtyDH = None, username: str = None, domain: str = None) -> KerberosCredential: if isinstance(certdata, str): certdata = base64.b64decode( certdata.replace(' ', '').replace('\r', '').replace('\n', '').replace('\t', '')) if isinstance(keydata, str): keydata = base64.b64decode( keydata.replace(' ', '').replace('\r', '').replace('\n', '').replace('\t', '')) k = KerberosCredential() k.certificate = parse_certificate(certdata) k.private_key = parse_private(keydata) k.set_user_and_domain_from_cert(username=username, domain=domain) k.set_dhparams(dhparams) return k
def __init__(self, pem_data: str): # OpenSSL have an option to write readable text into the same file with PEM data start = self._find_start(pem_data) pem_data = pem_data[start:] self._cert: asn1x509.Certificate = parse_certificate(pem_data.encode()) self._pem_data = pem_data
def on_get(self, req, resp): operation = req.get_param("operation", required=True) if operation.lower() == "getcacert": resp.body = keys.parse_certificate( self.authority.certificate_buf).dump() resp.append_header("Content-Type", "application/x-x509-ca-cert") return # If we bump into exceptions later encrypted_container = b"" attr_list = [ cms.CMSAttribute({ 'type': "message_type", 'values': ["3"] }), cms.CMSAttribute({ 'type': "pki_status", 'values': ["2"] # rejected }) ] try: info = cms.ContentInfo.load( b64decode(req.get_param("message", required=True))) ############################################### ### Verify signature of the outer container ### ############################################### signed_envelope = info['content'] encap_content_info = signed_envelope['encap_content_info'] encap_content = encap_content_info['content'] # TODO: try except current_certificate, = signed_envelope["certificates"] signer, = signed_envelope["signer_infos"] # TODO: compare cert to current one if we are renewing assert signer["digest_algorithm"]["algorithm"].native == "md5" assert signer["signature_algorithm"][ "algorithm"].native == "rsassa_pkcs1v15" message_digest = None transaction_id = None sender_nonce = None for attr in signer["signed_attrs"]: if attr["type"].native == "sender_nonce": sender_nonce, = attr["values"] elif attr["type"].native == "trans_id": transaction_id, = attr["values"] elif attr["type"].native == "message_digest": message_digest, = attr["values"] if hashlib.md5(encap_content.native).digest( ) != message_digest.native: raise SCEPBadMessageCheck() assert message_digest msg = signer["signed_attrs"].dump(force=True) assert msg[0] == 160 # Verify signature try: asymmetric.rsa_pkcs1v15_verify( asymmetric.load_certificate(current_certificate.dump()), signer["signature"].native, b"\x31" + msg[1:], # wtf?! "md5") except SignatureError: raise SCEPBadMessageCheck() ############################### ### Decrypt inner container ### ############################### info = cms.ContentInfo.load(encap_content.native) encrypted_envelope = info['content'] encrypted_content_info = encrypted_envelope[ 'encrypted_content_info'] iv = encrypted_content_info['content_encryption_algorithm'][ 'parameters'].native if encrypted_content_info['content_encryption_algorithm'][ "algorithm"].native != "des": raise SCEPBadAlgo() encrypted_content = encrypted_content_info[ 'encrypted_content'].native recipient, = encrypted_envelope['recipient_infos'] if recipient.native["rid"][ "serial_number"] != self.authority.certificate.serial_number: raise SCEPBadCertId() # Since CA private key is not directly readable here, we'll redirect it to signer socket key = asymmetric.rsa_pkcs1v15_decrypt( self.authority.private_key, recipient.native["encrypted_key"]) if len(key) == 8: key = key * 3 # Convert DES to 3DES buf = symmetric.tripledes_cbc_pkcs5_decrypt( key, encrypted_content, iv) _, _, common_name = self.authority.store_request(buf, overwrite=True) cert, buf = self.authority.sign(common_name, overwrite=True) signed_certificate = asymmetric.load_certificate(buf) content = signed_certificate.asn1.dump() except SCEPError as e: attr_list.append( cms.CMSAttribute({ 'type': "fail_info", 'values': ["%d" % e.code] })) else: ################################## ### Degenerate inner container ### ################################## degenerate = cms.ContentInfo({ 'content_type': "signed_data", 'content': cms.SignedData({ 'version': "v1", 'certificates': [signed_certificate.asn1], 'digest_algorithms': [cms.DigestAlgorithm({'algorithm': "md5"})], 'encap_content_info': { 'content_type': "data", 'content': cms.ContentInfo({ 'content_type': "signed_data", 'content': None }).dump() }, 'signer_infos': [] }) }) ################################ ### Encrypt middle container ### ################################ key = os.urandom(8) iv, encrypted_content = symmetric.des_cbc_pkcs5_encrypt( key, degenerate.dump(), os.urandom(8)) assert degenerate.dump() == symmetric.tripledes_cbc_pkcs5_decrypt( key * 3, encrypted_content, iv) ri = cms.RecipientInfo({ 'ktri': cms.KeyTransRecipientInfo({ 'version': "v0", 'rid': cms.RecipientIdentifier({ 'issuer_and_serial_number': cms.IssuerAndSerialNumber({ 'issuer': current_certificate.chosen["tbs_certificate"] ["issuer"], 'serial_number': current_certificate.chosen["tbs_certificate"] ["serial_number"], }), }), 'key_encryption_algorithm': { 'algorithm': "rsa" }, 'encrypted_key': asymmetric.rsa_pkcs1v15_encrypt( asymmetric.load_certificate( current_certificate.chosen.dump()), key) }) }) encrypted_container = cms.ContentInfo({ 'content_type': "enveloped_data", 'content': cms.EnvelopedData({ 'version': "v1", 'recipient_infos': [ri], 'encrypted_content_info': { 'content_type': "data", 'content_encryption_algorithm': { 'algorithm': "des", 'parameters': iv }, 'encrypted_content': encrypted_content } }) }).dump() attr_list = [ cms.CMSAttribute({ 'type': "message_digest", 'values': [hashlib.sha1(encrypted_container).digest()] }), cms.CMSAttribute({ 'type': "message_type", 'values': ["3"] }), cms.CMSAttribute({ 'type': "pki_status", 'values': ["0"] # ok }) ] finally: ############################## ### Signed outer container ### ############################## attrs = cms.CMSAttributes(attr_list + [ cms.CMSAttribute({ 'type': "recipient_nonce", 'values': [sender_nonce] }), cms.CMSAttribute({ 'type': "trans_id", 'values': [transaction_id] }) ]) signer = cms.SignerInfo({ "signed_attrs": attrs, 'version': "v1", 'sid': cms.SignerIdentifier({ 'issuer_and_serial_number': cms.IssuerAndSerialNumber({ 'issuer': self.authority.certificate.issuer, 'serial_number': self.authority.certificate.serial_number, }), }), 'digest_algorithm': algos.DigestAlgorithm({'algorithm': "sha1"}), 'signature_algorithm': algos.SignedDigestAlgorithm({'algorithm': "rsassa_pkcs1v15"}), 'signature': asymmetric.rsa_pkcs1v15_sign(self.authority.private_key, b"\x31" + attrs.dump()[1:], "sha1") }) resp.append_header("Content-Type", "application/x-pki-message") resp.body = cms.ContentInfo({ 'content_type': "signed_data", 'content': cms.SignedData({ 'version': "v1", 'certificates': [self.authority.certificate], 'digest_algorithms': [cms.DigestAlgorithm({'algorithm': "sha1"})], 'encap_content_info': { 'content_type': "data", 'content': encrypted_container }, 'signer_infos': [signer] }) }).dump()
def parse(self): assert self.type == ContainerTypes.X509 self.asn1 = k.parse_certificate(self.bytes) self.asn1.native self._raise_if_wrong_algorithm() self._is_parsed = True
def parse_der_cert(der_cert): cert = asymmetric.load_certificate(keys.parse_certificate(der_cert)) return cert
def on_get(self, req, resp): operation = req.get_param("operation", required=True) if operation == "GetCACert": resp.body = keys.parse_certificate( self.authority.certificate_buf).dump() resp.append_header("Content-Type", "application/x-x509-ca-cert") return elif operation == "GetCACaps": # TODO: return renewal flag based on renewal subnets config option resp.body = "Renewal\nMD5\nSHA-1\nSHA-256\nSHA-512\nDES3\n" return elif operation == "PKIOperation": pass else: raise falcon.HTTPBadRequest("Bad request", "Unknown operation %s" % operation) # If we bump into exceptions later encrypted_container = b"" attr_list = [ cms.CMSAttribute({ 'type': "message_type", 'values': ["3"] }), cms.CMSAttribute({ 'type': "pki_status", 'values': ["2"] # rejected }) ] try: info = cms.ContentInfo.load( b64decode(req.get_param("message", required=True))) ############################################### ### Verify signature of the outer container ### ############################################### signed_envelope = info['content'] encap_content_info = signed_envelope['encap_content_info'] encap_content = encap_content_info['content'] # TODO: try except current_certificate, = signed_envelope["certificates"] signer, = signed_envelope["signer_infos"] # TODO: compare cert to current one if we are renewing digest_algorithm = signer["digest_algorithm"]["algorithm"].native signature_algorithm = signer["signature_algorithm"][ "algorithm"].native if digest_algorithm not in ("md5", "sha1", "sha256", "sha512"): raise SCEPBadAlgo() if signature_algorithm != "rsassa_pkcs1v15": raise SCEPBadAlgo() message_digest = None transaction_id = None sender_nonce = None for attr in signer["signed_attrs"]: if attr["type"].native == "sender_nonce": sender_nonce, = attr["values"] elif attr["type"].native == "trans_id": transaction_id, = attr["values"] elif attr["type"].native == "message_digest": message_digest, = attr["values"] if getattr(hashlib, digest_algorithm)(encap_content.native).digest( ) != message_digest.native: raise SCEPDigestMismatch() if not sender_nonce: raise SCEPBadRequest() if not transaction_id: raise SCEPBadRequest() assert message_digest msg = signer["signed_attrs"].dump(force=True) assert msg[0] == 160 # Verify signature try: asymmetric.rsa_pkcs1v15_verify( asymmetric.load_certificate(current_certificate.dump()), signer["signature"].native, b"\x31" + msg[1:], # wtf?! "md5") except SignatureError: raise SCEPSignatureMismatch() ############################### ### Decrypt inner container ### ############################### info = cms.ContentInfo.load(encap_content.native) encrypted_envelope = info['content'] encrypted_content_info = encrypted_envelope[ 'encrypted_content_info'] iv = encrypted_content_info['content_encryption_algorithm'][ 'parameters'].native if encrypted_content_info['content_encryption_algorithm'][ "algorithm"].native != "des": raise SCEPBadAlgo() encrypted_content = encrypted_content_info[ 'encrypted_content'].native recipient, = encrypted_envelope['recipient_infos'] if recipient.native["rid"][ "serial_number"] != self.authority.certificate.serial_number: raise SCEPBadCertId() key = asymmetric.rsa_pkcs1v15_decrypt( self.authority.private_key, recipient.native["encrypted_key"]) if len(key) == 8: key = key * 3 # Convert DES to 3DES buf = symmetric.tripledes_cbc_pkcs5_decrypt( key, encrypted_content, iv) _, _, common_name = self.authority.store_request(buf, overwrite=True) logger.info( "SCEP client from %s requested with %s digest algorithm, %s signature", req.context["remote_addr"], digest_algorithm, signature_algorithm) cert, buf = self.authority.sign(common_name, profile=config.PROFILES["gw"], overwrite=True) signed_certificate = asymmetric.load_certificate(buf) content = signed_certificate.asn1.dump() except SCEPError as e: attr_list.append( cms.CMSAttribute({ 'type': "fail_info", 'values': ["%d" % e.code] })) logger.info("Failed to sign SCEP request due to: %s" % e.explaination) else: ################################## ### Degenerate inner container ### ################################## degenerate = cms.ContentInfo({ 'content_type': "signed_data", 'content': cms.SignedData({ 'version': "v1", 'certificates': [signed_certificate.asn1], 'digest_algorithms': [cms.DigestAlgorithm({'algorithm': digest_algorithm})], 'encap_content_info': { 'content_type': "data", 'content': cms.ContentInfo({ 'content_type': "signed_data", 'content': None }).dump() }, 'signer_infos': [] }) }) ################################ ### Encrypt middle container ### ################################ key = os.urandom(8) iv, encrypted_content = symmetric.des_cbc_pkcs5_encrypt( key, degenerate.dump(), os.urandom(8)) assert degenerate.dump() == symmetric.tripledes_cbc_pkcs5_decrypt( key * 3, encrypted_content, iv) ri = cms.RecipientInfo({ 'ktri': cms.KeyTransRecipientInfo({ 'version': "v0", 'rid': cms.RecipientIdentifier({ 'issuer_and_serial_number': cms.IssuerAndSerialNumber({ 'issuer': current_certificate.chosen["tbs_certificate"] ["issuer"], 'serial_number': current_certificate.chosen["tbs_certificate"] ["serial_number"], }), }), 'key_encryption_algorithm': { 'algorithm': "rsa" }, 'encrypted_key': asymmetric.rsa_pkcs1v15_encrypt( asymmetric.load_certificate( current_certificate.chosen.dump()), key) }) }) encrypted_container = cms.ContentInfo({ 'content_type': "enveloped_data", 'content': cms.EnvelopedData({ 'version': "v1", 'recipient_infos': [ri], 'encrypted_content_info': { 'content_type': "data", 'content_encryption_algorithm': { 'algorithm': "des", 'parameters': iv }, 'encrypted_content': encrypted_content } }) }).dump() attr_list = [ cms.CMSAttribute({ 'type': "message_digest", 'values': [ getattr( hashlib, digest_algorithm)(encrypted_container).digest() ] }), cms.CMSAttribute({ 'type': "message_type", 'values': ["3"] }), cms.CMSAttribute({ 'type': "pki_status", 'values': ["0"] # ok }) ] finally: ############################## ### Signed outer container ### ############################## attrs = cms.CMSAttributes(attr_list + [ cms.CMSAttribute({ 'type': "recipient_nonce", 'values': [sender_nonce] }), cms.CMSAttribute({ 'type': "trans_id", 'values': [transaction_id] }) ]) signer = cms.SignerInfo({ "signed_attrs": attrs, 'version': "v1", 'sid': cms.SignerIdentifier({ 'issuer_and_serial_number': cms.IssuerAndSerialNumber({ 'issuer': self.authority.certificate.issuer, 'serial_number': self.authority.certificate.serial_number, }), }), 'digest_algorithm': algos.DigestAlgorithm({'algorithm': digest_algorithm}), 'signature_algorithm': algos.SignedDigestAlgorithm({'algorithm': "rsassa_pkcs1v15"}), 'signature': asymmetric.rsa_pkcs1v15_sign(self.authority.private_key, b"\x31" + attrs.dump()[1:], digest_algorithm) }) resp.append_header("Content-Type", "application/x-pki-message") resp.body = cms.ContentInfo({ 'content_type': "signed_data", 'content': cms.SignedData({ 'version': "v1", 'certificates': [self.authority.certificate], 'digest_algorithms': [cms.DigestAlgorithm({'algorithm': digest_algorithm})], 'encap_content_info': { 'content_type': "data", 'content': encrypted_container }, 'signer_infos': [signer] }) }).dump()
def test_parse_certificate_pem_leading_whitespace(self): with open(os.path.join(fixtures_dir, 'keys/test.crt'), 'rb') as f: parsed = keys.parse_certificate(b'\n' + f.read()) # Make sure we can parse the whole structure parsed.native