def _get_certs_from_pkcs7_substrate(substrate): """Extracts DER-encoded X509 certificates from a PKCS7 ASN1 DER substrate :param substrate: The substrate to be processed :returns: A list of DER-encoded X509 certificates """ try: contentInfo, _ = der_decoder.decode(substrate, asn1Spec=rfc2315.ContentInfo()) contentType = contentInfo.getComponentByName('contentType') except Exception: LOG.exception('Unreadable Certificate.') raise exceptions.UnreadableCert if contentType != rfc2315.signedData: LOG.exception('Unreadable Certificate.') raise exceptions.UnreadableCert try: content, _ = der_decoder.decode( contentInfo.getComponentByName('content'), asn1Spec=rfc2315.SignedData()) except Exception: LOG.exception('Unreadable Certificate.') raise exceptions.UnreadableCert for cert in content.getComponentByName('certificates'): yield der_encoder.encode(cert)
def pkcs7_to_certs(data, datatype=PEM): """ Extract certificates from a PKCS #7 object. :returns: a ``list`` of ``IPACertificate`` objects. """ if datatype == PEM: match = re.match(br'-----BEGIN PKCS7-----(.*?)-----END PKCS7-----', data, re.DOTALL) if not match: raise ValueError("not a valid PKCS#7 PEM") data = base64.b64decode(match.group(1)) content_info, tail = decoder.decode(data, rfc2315.ContentInfo()) if tail: raise ValueError("not a valid PKCS#7 message") if content_info['contentType'] != rfc2315.signedData: raise ValueError("not a PKCS#7 signed data message") signed_data, tail = decoder.decode(bytes(content_info['content']), rfc2315.SignedData()) if tail: raise ValueError("not a valid PKCS#7 signed data message") result = [] for certificate in signed_data['certificates']: certificate = encoder.encode(certificate) certificate = load_der_x509_certificate(certificate) result.append(certificate) return result
def apk_signatures(cert_file_object): """ returns a 3-tuple with the hexstring md5, sha1, sha256 hashes of the first certificate of a pkcs7 signature, intended for apk signatures cert_file_object is a file-like object in binary mode """ # TODO zipfile objects don't have the b in the mode even though they are # binary so we can't check mode content_info, _ = der_decoder.decode(cert_file_object.read(), asn1Spec=rfc2315.ContentInfo()) content_type = content_info.getComponentByName("contentType") content_info_map = { (1, 2, 840, 113549, 1, 7, 1): rfc2315.Data(), (1, 2, 840, 113549, 1, 7, 2): rfc2315.SignedData(), (1, 2, 840, 113549, 1, 7, 3): rfc2315.EnvelopedData(), (1, 2, 840, 113549, 1, 7, 4): rfc2315.SignedAndEnvelopedData(), (1, 2, 840, 113549, 1, 7, 5): rfc2315.DigestedData(), (1, 2, 840, 113549, 1, 7, 6): rfc2315.EncryptedData() } content, _ = der_decoder.decode(content_info.getComponentByName("content"), asn1Spec=content_info_map[content_type]) certs = content.getComponentByName("certificates") der = der_encoder.encode(certs[0]) return file_hashes(io.BytesIO(der))
def __split_parse_codefile(self, codefile): """Split the bundle to signadata and signcontent. :codefile: :return: SUCCESS or ERROR list """ try: with open(codefile, 'r') as f: head = f.read(256) sign_node = Asn1Decoder.asn1_node_root(head) sign_length = sign_node[2] f.seek(0, 0) sign_data = f.read(sign_length + 1) self.signedContentOffset = sign_length + 1 decoded, rest = decode(sign_data, asn1Spec=rfc2315.ContentInfo()) signedData_der = decoded['content'] self.__get_codefile_cvc(signedData_der) sign, rest = decode(signedData_der, asn1Spec=rfc2315.SignedData()) self.mfr_signerInfo = sign['signerInfos'][0] if self.mso_cvc != None: # get the co-signer signature self.mso_signerInfo = sign['signerInfos'][1] except Exception, e: self.logger.info("Exception when parsing codefile, reason: " + str(e)) pass
def Signature(pe): try: security = pe.OPTIONAL_HEADER.DATA_DIRECTORY[ pefile.DIRECTORY_ENTRY['IMAGE_DIRECTORY_ENTRY_SECURITY']] except IndexError: print(' No signature') return address = security.VirtualAddress size = security.Size if address == 0: print(' No signature') return signature = pe.write()[address + 8:address + size] if len(signature) != size - 8: print( ' Unable to extract full signature, file is most likely truncated') print(' Extracted: %d bytes' % len(signature)) print(' Expected: %d bytes' % (size - 8)) return try: from pyasn1.codec.der import decoder as der_decoder except ImportError: print(' Signature present but error importing pyasn1 module') return try: from pyasn1_modules import rfc2315 except ImportError: print(' Signature present but error importing pyasn1_modules module') return signatureArg = C2SIP2(signature) contentInfo, _ = der_decoder.decode(signatureArg, asn1Spec=rfc2315.ContentInfo()) contentType = contentInfo.getComponentByName('contentType') contentInfoMap = { (1, 2, 840, 113549, 1, 7, 1): rfc2315.Data(), (1, 2, 840, 113549, 1, 7, 2): rfc2315.SignedData(), (1, 2, 840, 113549, 1, 7, 3): rfc2315.EnvelopedData(), (1, 2, 840, 113549, 1, 7, 4): rfc2315.SignedAndEnvelopedData(), (1, 2, 840, 113549, 1, 7, 5): rfc2315.DigestedData(), (1, 2, 840, 113549, 1, 7, 6): rfc2315.EncryptedData() } content, _ = der_decoder.decode(contentInfo.getComponentByName('content'), asn1Spec=contentInfoMap[contentType]) for line in content.prettyPrint().split('\n'): print(line) oMatch = re.match('( *)value=0x....(.+)', line) if oMatch != None: if sys.version_info[0] > 2: print(oMatch.groups()[0] + ' ' + repr(binascii.a2b_hex(oMatch.groups()[1]).decode())) else: print(oMatch.groups()[0] + ' ' + repr(binascii.a2b_hex(oMatch.groups()[1])))
def print_cert(cert_file): f = open(cert_file, 'r') buf = f.read() buffer_base = base64.b64encode(buf) f.close() f = open(cert_file + '.pem', 'w') f.write('-----BEGIN PKCS7-----\n') f.write(buffer_base) f.write('\n-----END PKCS7-----\n') f.close() f = open(cert_file + '.pem', 'r') _, substrate = pem.readPemBlocksFromFile( f, ('-----BEGIN PKCS7-----', '-----END PKCS7-----')) f.close() os.remove(cert_file + '.pem') assert substrate, 'bad PKCS7 data on input' contentInfo, rest = decoder.decode(substrate, asn1Spec=rfc2315.ContentInfo()) if rest: substrate = substrate[:-len(rest)] buf = contentInfo.getComponentByName('content') contentType = contentInfo.getComponentByName('contentType') content, _ = decoder.decode(contentInfo.getComponentByName('content'), asn1Spec=contentInfoMap[contentType]) print content.prettyPrint()
def get_cert_from_adobe(adobe_cert): f = open(adobe_cert, 'r') buf = f.read() buffer_base = base64.b64encode(buf) f.close() f = open(adobe_cert + '.pem', 'w') f.write('-----BEGIN PKCS7-----\n') f.write(buffer_base) f.write('\n-----END PKCS7-----\n') f.close() f = open(adobe_cert + '.pem', 'r') _, substrate = pem.readPemBlocksFromFile( f, ('-----BEGIN PKCS7-----', '-----END PKCS7-----')) f.close() os.remove(adobe_cert + '.pem') assert substrate, 'bad PKCS7 data on input' contentInfo, rest = decoder.decode(substrate, asn1Spec=rfc2315.ContentInfo()) if rest: substrate = substrate[:-len(rest)] assert encoder.encode(contentInfo, defMode=False) == substrate or \ encoder.encode(contentInfo, defMode=True) == substrate, \ 're-encode fails' contentType = contentInfo.getComponentByName('contentType') content, _ = decoder.decode(contentInfo.getComponentByName('content'), asn1Spec=contentInfoMap[contentType]) return content.getComponentByName('certificates').getComponentByPosition(0)
def process2(self): pe = self._getLibrary(PEFileModule().getName()) if (pe is None): return "" # get the security directory entry address = pe.OPTIONAL_HEADER.DATA_DIRECTORY[pefile.DIRECTORY_ENTRY[ 'IMAGE_DIRECTORY_ENTRY_SECURITY']].VirtualAddress if address > 0: # Always in DER format AFAIK derData = pe.write()[address + 8:] else: logging.debug("address 0") return (contentInfo, rest) = decoder.decode(derData, asn1Spec=rfc2315.ContentInfo()) contentType = contentInfo.getComponentByName('contentType') if contentType == rfc2315.signedData: signedData = decode(contentInfo.getComponentByName('content'), asn1Spec=rfc2315.SignedData()) for sd in signedData: if sd == '': continue signerInfos = sd.getComponentByName('signerInfos') for si in signerInfos: issuerAndSerial = si.getComponentByName( 'issuerAndSerialNumber') issuer = issuerAndSerial.getComponentByName( 'issuer').getComponent() for i in issuer: for r in i: at = r.getComponentByName('type') if rfc2459.id_at_countryName == at: cn = decode(r.getComponentByName('value'), asn1Spec=rfc2459.X520countryName()) print(cn[0]) elif rfc2459.id_at_organizationName == at: on = decode( r.getComponentByName('value'), asn1Spec=rfc2459.X520OrganizationName()) print(on[0].getComponent()) elif rfc2459.id_at_organizationalUnitName == at: ou = decode( r.getComponentByName('value'), asn1Spec=rfc2459.X520OrganizationalUnitName()) print(ou[0].getComponent()) elif rfc2459.id_at_commonName == at: cn = decode(r.getComponentByName('value'), asn1Spec=rfc2459.X520CommonName()) print(cn[0].getComponent()) else: print at
def toDER(self): contentInfo = rfc2315.ContentInfo() contentInfo['contentType'] = rfc2315.signedData signedData = rfc2315.SignedData() signedData['version'] = rfc2315.Version(1) digestAlgorithms = rfc2315.DigestAlgorithmIdentifiers() digestAlgorithms[0] = self.pykeyHashToDigestAlgorithm(pykey.HASH_SHA1) signedData['digestAlgorithms'] = digestAlgorithms dataContentInfo = rfc2315.ContentInfo() dataContentInfo['contentType'] = rfc2315.data signedData['contentInfo'] = dataContentInfo certificates = rfc2315.ExtendedCertificatesAndCertificates().subtype( implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0)) extendedCertificateOrCertificate = rfc2315.ExtendedCertificateOrCertificate( ) certificate = decoder.decode(self.signer.toDER(), asn1Spec=rfc2459.Certificate())[0] extendedCertificateOrCertificate['certificate'] = certificate certificates[0] = extendedCertificateOrCertificate signedData['certificates'] = certificates signerInfos = rfc2315.SignerInfos() if len(self.sha1) > 0: signerInfos[len(signerInfos)] = self.buildSignerInfo( certificate, pykey.HASH_SHA1, self.sha1) if len(self.sha256) > 0: signerInfos[len(signerInfos)] = self.buildSignerInfo( certificate, pykey.HASH_SHA256, self.sha256) signedData['signerInfos'] = signerInfos encoded = encoder.encode(signedData) anyTag = univ.Any(encoded).subtype(explicitTag=tag.Tag( tag.tagClassContext, tag.tagFormatConstructed, 0)) contentInfo['content'] = anyTag return encoder.encode(contentInfo)
def new_rsa(): file_name = raw_input("get an rsa name\n") file = open(file_name,"r") buffer = file.read() buffer_base = base64.b64encode(buffer) file.close() file = open(file_name + ".pem","w") file.write('-----BEGIN PKCS7-----\n') file.write(buffer_base) file.write('\n-----END PKCS7-----\n') file.close() file = open(file_name + ".pem","r") idx, substrate = pem.readPemBlocksFromFile( file, ('-----BEGIN PKCS7-----', '-----END PKCS7-----') ) file.close() assert substrate, 'bad PKCS7 data on input' contentInfo, rest = decoder.decode(substrate, asn1Spec=rfc2315.ContentInfo()) if rest: substrate = substrate[:-len(rest)] #/home/retme/Desktop/xx/SIGN.RSA #print contentInfo #ContentInfo #print(contentInfo.prettyPrint()) buf = contentInfo.getComponentByName('content') f = open("./decode.rsa","w") f.write(str(buf)) f.close() file = open("./encode.rsa","r") buffer = file.read() file.close() contentInfo.setComponentByName('content',buffer) ret = encoder.encode(contentInfo, defMode=True) file = open("./final.rsa","w") file.write(str(ret)); file.close() print_rsa("./final.rsa")
class PFX(univ.Sequence): """RFC7292: PKCS #12: Personal Information Exchange Syntax v1.1 PFX ::= SEQUENCE { version INTEGER {v3(3)}(v3,...), authSafe ContentInfo, macData MacData OPTIONAL } """ componentType = namedtype.NamedTypes( namedtype.NamedType("version", PFXVersion()), namedtype.NamedType("authSafe", rfc2315.ContentInfo()), namedtype.OptionalNamedType("macData", MacData()), )
class SignedData(univ.Sequence): componentType = namedtype.NamedTypes( namedtype.NamedType('version', rfc2315.Version()), namedtype.NamedType('digestAlgorithms', rfc2315.DigestAlgorithmIdentifiers()), namedtype.NamedType('contentInfo', rfc2315.ContentInfo()), namedtype.OptionalNamedType( 'certificates', CertificateSet().subtype(implicitTag=tag.Tag( tag.tagClassContext, tag.tagFormatConstructed, 0))), namedtype.OptionalNamedType( 'crls', rfc2315.CertificateRevocationLists().subtype(implicitTag=tag.Tag( tag.tagClassContext, tag.tagFormatConstructed, 1))), namedtype.NamedType('signerInfos', rfc2315.SignerInfos()))
def Signature(pe): try: security = pe.OPTIONAL_HEADER.DATA_DIRECTORY[ pefile.DIRECTORY_ENTRY['IMAGE_DIRECTORY_ENTRY_SECURITY']] except IndexError: print(' No signature') return address = security.VirtualAddress size = security.Size if address == 0: print(' No signature') return signature = pe.write()[address + 8:address + size] try: from pyasn1.codec.der import decoder as der_decoder except: print(' Signature present but error importing pyasn1 module') return try: from pyasn1_modules import rfc2315 except: print(' Signature present but error importing pyasn1_modules module') return contentInfo, _ = der_decoder.decode(str(signature), asn1Spec=rfc2315.ContentInfo()) contentType = contentInfo.getComponentByName('contentType') contentInfoMap = { (1, 2, 840, 113549, 1, 7, 1): rfc2315.Data(), (1, 2, 840, 113549, 1, 7, 2): rfc2315.SignedData(), (1, 2, 840, 113549, 1, 7, 3): rfc2315.EnvelopedData(), (1, 2, 840, 113549, 1, 7, 4): rfc2315.SignedAndEnvelopedData(), (1, 2, 840, 113549, 1, 7, 5): rfc2315.DigestedData(), (1, 2, 840, 113549, 1, 7, 6): rfc2315.EncryptedData() } content, _ = der_decoder.decode(contentInfo.getComponentByName('content'), asn1Spec=contentInfoMap[contentType]) for line in content.prettyPrint().split('\n'): print(line) oMatch = re.match('( *)value=0x....(.+)', line) if oMatch != None: print(oMatch.groups()[0] + ' ' + repr(binascii.a2b_hex(oMatch.groups()[1])))
def verify_signature(apkfile): from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.asymmetric import padding source_zip = ZipFile(apkfile, 'r') pad = padding.PKCS1v15() data = source_zip.open('META-INF/CERT.SF').read() signed_data = source_zip.open('META-INF/CERT.RSA', 'r').read() obj,rest = der_decoder.decode(signed_data, asn1Spec=rfc2315.ContentInfo(), decodeOpenTypes=True) signature = str(obj['content']['signerInfos'][0]['encryptedDigest']) der_certificate = der_encoder.encode(obj['content']['certificates'][0]['certificate']) print 'Signing Certificate Digest: ' + base64.b64encode(sha256(der_certificate)) cert = x509.load_der_x509_certificate(der_certificate, default_backend()) cert.public_key().verify(signature, data, pad, hashes.SHA256())
def from_envelope(cls, data, *args, **kwargs): """Loads a :class:`SignedData` object from raw data that contains ContentInfo. :param bytes data: The bytes to parse """ # This one is not guarded, which is intentional content, rest = ber_decoder.decode(data, asn1Spec=rfc2315.ContentInfo()) if asn1.oids.get(content['contentType']) is not rfc2315.SignedData: raise ParseError("ContentInfo does not contain SignedData") data = guarded_ber_decode(content['content'], asn1_spec=rfc2315.SignedData()) signed_data = cls(data, *args, **kwargs) signed_data._rest_data = rest return signed_data
def from_stl_file(cls, path=AUTHROOTSTL_PATH): with open(str(path), "rb") as f: content, rest = ber_decoder.decode(f.read(), asn1Spec=rfc2315.ContentInfo()) # # from pyasn1 import debug # debug.setLogger(debug.Debug('all')) if asn1.oids.get(content['contentType']) is not rfc2315.SignedData: raise CertificateTrustListParseError( "ContentInfo does not contain SignedData") data = guarded_ber_decode(content['content'], asn1_spec=rfc2315.SignedData()) signed_data = cls(data) signed_data._rest_data = rest return signed_data
def decode(signature): contentInfo, _ = der_decoder.decode(signature, asn1Spec=rfc2315.ContentInfo()) contentType = contentInfo.getComponentByName('contentType') contentInfoMap = { (1, 2, 840, 113549, 1, 7, 1): rfc2315.Data(), (1, 2, 840, 113549, 1, 7, 2): rfc2315.SignedData(), (1, 2, 840, 113549, 1, 7, 3): rfc2315.EnvelopedData(), (1, 2, 840, 113549, 1, 7, 4): rfc2315.SignedAndEnvelopedData(), (1, 2, 840, 113549, 1, 7, 5): rfc2315.DigestedData(), (1, 2, 840, 113549, 1, 7, 6): rfc2315.EncryptedData() } content, _ = der_decoder.decode(contentInfo.getComponentByName('content'), asn1Spec=contentInfoMap[contentType]) return content
def _process_pkcs7_substrate(substrate): contentInfo, _ = der_decoder.decode(substrate, asn1Spec=rfc2315.ContentInfo()) contentType = contentInfo.getComponentByName('contentType') if contentType != rfc2315.signedData: raise Exception content, _ = der_decoder.decode( contentInfo.getComponentByName('content'), asn1Spec=rfc2315.SignedData()) for blob in content.getComponentByName('certificates'): cert = x509.load_der_x509_certificate(der_encoder.encode(blob), backends.default_backend()) six.print_(cert.public_bytes( encoding=serialization.Encoding.PEM).decode( 'unicode_escape'), end='')
def __init__(self, data): """@todo: to be defined :data: @todo """ decoder.Decoder.supportIndefLength = True self.asn = decoder.decode(data, asn1Spec=rfc2315.ContentInfo())[0] self.contentType = { '1.2.840.113549.1.7.1': rfc2315.Data, '1.2.840.113549.1.7.2': rfc2315.SignedData, '1.2.840.113549.1.7.3': rfc2315.EnvelopedData, '1.2.840.113549.1.7.4': rfc2315.SignedAndEnvelopedData, '1.2.840.113549.1.7.5': rfc2315.DigestedData, '1.2.840.113549.1.7.6': rfc2315.EncryptedData, }.get(str(self.asn[0]), None) assert self.contentType, 'Unsupported message content type' self.content = decoder.decode(self.asn[1], asn1Spec=self.contentType())[0]
def _extract_certs_from_authenticode_blob(buf): contentInfo, _ = der_decoder.decode(buf, asn1Spec=rfc2315.ContentInfo()) contentType = contentInfo.getComponentByName('contentType') contentInfoMap = { (1, 2, 840, 113549, 1, 7, 1): rfc2315.Data(), (1, 2, 840, 113549, 1, 7, 2): rfc2315.SignedData(), (1, 2, 840, 113549, 1, 7, 3): rfc2315.EnvelopedData(), (1, 2, 840, 113549, 1, 7, 4): rfc2315.SignedAndEnvelopedData(), (1, 2, 840, 113549, 1, 7, 5): rfc2315.DigestedData(), (1, 2, 840, 113549, 1, 7, 6): rfc2315.EncryptedData() } content, _ = der_decoder.decode(contentInfo.getComponentByName('content'), asn1Spec=contentInfoMap[contentType]) certs = [] for cert in content['certificates']: tbscert = cert['certificate']['tbsCertificate'] certs.append(_extract_authenticode_tbscerts(tbscert)) for c in content['signerInfos']: tbscert = c['issuerAndSerialNumber'] certs.append(_extract_authenticode_tbscerts(tbscert)) return certs
def getSignatureFromApk(apkPath): signature = '' try: cert = None with zipfile.ZipFile(apkPath, 'r') as apk: certs = [ n for n in apk.namelist() if APKSigner.cert_path_regex.match(n) ] if len(certs) < 1: logging.error( u"[getCertMd5FileFromApk] Found no signing certificates on %s" % apkPath) return '' if len(certs) > 1: logging.error( u"[getCertMd5FileFromApk] Found multiple signing certificates on %s" % apkPath) return '' cert = apk.read(certs[0]) content = decoder.decode(cert, asn1Spec=rfc2315.ContentInfo())[0] if content.getComponentByName('contentType') != rfc2315.signedData: logging.error(u"[genCertMd5FileFromRsa] 不支持的签名格式") return signature content = decoder.decode(content.getComponentByName('content'), asn1Spec=rfc2315.SignedData())[0] try: certificates = content.getComponentByName('certificates') except Exception, e: logging.error( u"[genCertMd5FileFromRsa] Certificates 没有找到,原因:%s", e) return signature cert_encoded = encoder.encode(certificates)[4:] signature = hashlib.md5(cert_encoded).hexdigest()
def getSignatureFromFile(filePath): signature = '' try: fileContent = '' with open(filePath, 'rb') as fp: fileContent = fp.read() content = decoder.decode(fileContent, asn1Spec=rfc2315.ContentInfo())[0] if content.getComponentByName('contentType') != rfc2315.signedData: logging.error(u"[genCertMd5FileFromRsa] 不支持的签名格式") return signature content = decoder.decode(content.getComponentByName('content'), asn1Spec=rfc2315.SignedData())[0] try: certificates = content.getComponentByName('certificates') except Exception, e: logging.error( u"[genCertMd5FileFromRsa] Certificates 没有找到,原因:%s", e) return signature cert_encoded = encoder.encode(certificates)[4:] signature = hashlib.md5(cert_encoded).hexdigest()
def _create_pkcs7(cert, csr, private_key): """Creates the PKCS7 structure and signs it""" content_info = rfc2315.ContentInfo() content_info.setComponentByName('contentType', rfc2315.data) content_info.setComponentByName('content', encoder.encode(rfc2315.Data(csr))) issuer_and_serial = rfc2315.IssuerAndSerialNumber() issuer_and_serial.setComponentByName('issuer', cert[0]['tbsCertificate']['issuer']) issuer_and_serial.setComponentByName( 'serialNumber', cert[0]['tbsCertificate']['serialNumber']) raw_signature, _ = _sign(private_key, csr) signature = rfc2314.univ.OctetString( hexValue=binascii.hexlify(raw_signature).decode('ascii')) # Microsoft adds parameters with ASN.1 NULL encoding here, # but according to rfc5754 they should be absent: # "Implementations MUST generate SHA2 AlgorithmIdentifiers with absent parameters." sha2 = rfc2315.AlgorithmIdentifier() sha2.setComponentByName('algorithm', (2, 16, 840, 1, 101, 3, 4, 2, 1)) alg_from_cert = cert[0]['tbsCertificate']['subjectPublicKeyInfo'][ 'algorithm']['algorithm'] digest_encryption_algorithm = rfc2315.AlgorithmIdentifier() digest_encryption_algorithm.setComponentByName('algorithm', alg_from_cert) digest_encryption_algorithm.setComponentByName('parameters', '\x05\x00') signer_info = rfc2315.SignerInfo() signer_info.setComponentByName('version', 1) signer_info.setComponentByName('issuerAndSerialNumber', issuer_and_serial) signer_info.setComponentByName('digestAlgorithm', sha2) signer_info.setComponentByName('digestEncryptionAlgorithm', digest_encryption_algorithm) signer_info.setComponentByName('encryptedDigest', signature) signer_infos = rfc2315.SignerInfos().setComponents(signer_info) digest_algorithms = rfc2315.DigestAlgorithmIdentifiers().setComponents( sha2) extended_cert_or_cert = rfc2315.ExtendedCertificateOrCertificate() extended_cert_or_cert.setComponentByName('certificate', cert[0]) extended_certs_and_cert = rfc2315.ExtendedCertificatesAndCertificates( ).subtype(implicitTag=rfc2315.tag.Tag(rfc2315.tag.tagClassContext, rfc2315.tag.tagFormatConstructed, 0)) extended_certs_and_cert.setComponents(extended_cert_or_cert) signed_data = rfc2315.SignedData() signed_data.setComponentByName('version', 1) signed_data.setComponentByName('digestAlgorithms', digest_algorithms) signed_data.setComponentByName('contentInfo', content_info) signed_data.setComponentByName('certificates', extended_certs_and_cert) signed_data.setComponentByName('signerInfos', signer_infos) outer_content_info = rfc2315.ContentInfo() outer_content_info.setComponentByName('contentType', rfc2315.signedData) outer_content_info.setComponentByName('content', encoder.encode(signed_data)) return encoder.encode(outer_content_info)
def extractPKCS7(self): pe = pefile.PE(self.filename) pkcs_dict = dict() try: totsize = os.path.getsize(self.filename) self.pe.parse_data_directories(directories=[ pefile.DIRECTORY_ENTRY['IMAGE_DIRECTORY_ENTRY_SECURITY'] ]) sigoff = 0 siglen = 0 for s in self.pe.__structures__: if s.name == 'IMAGE_DIRECTORY_ENTRY_SECURITY': sigoff = s.VirtualAddress siglen = s.Size if sigoff < totsize: f = open(self.filename, 'rb') f.seek(sigoff) thesig = f.read(siglen) f.close() if 'sign' in str(thesig[8:]).lower() or 'root' in str( thesig[8:]).lower() or 'global' in str( thesig[8:]).lower(): pkcs_dict['dwLength'] = struct.unpack('<L', thesig[0:4])[0] pkcs_dict['wRevision'] = find_wRevision( struct.unpack('<h', thesig[4:6])[0]) pkcs_dict['wCertificateType'] = find_wCertificateType( struct.unpack('<h', thesig[6:8])[0]) pkcs_dict['VirtualAddress'] = hex(sigoff) pkcs_dict['totalsize'] = totsize thesig = hashlib.md5(thesig).hexdigest().upper() pkcs_dict['hash'] = thesig address = pe.OPTIONAL_HEADER.DATA_DIRECTORY[ pefile.DIRECTORY_ENTRY[ 'IMAGE_DIRECTORY_ENTRY_SECURITY']].VirtualAddress derData = pe.write()[address + 8:] (contentInfo, rest) = decode(derData, asn1Spec=rfc2315.ContentInfo()) contentType = contentInfo.getComponentByName('contentType') if contentType == rfc2315.signedData: signedData = decode( contentInfo.getComponentByName('content'), asn1Spec=rfc2315.SignedData()) for sd in signedData: if sd == '': continue try: signerInfos = sd.getComponentByName('signerInfos') except: continue for si in signerInfos: issuerAndSerial = si.getComponentByName( 'issuerAndSerialNumber') issuer = issuerAndSerial.getComponentByName( 'issuer').getComponent() for i in issuer: for r in i: at = r.getComponentByName('type') if rfc2459.id_at_countryName == at: cn = decode( r.getComponentByName('value'), asn1Spec=rfc2459.X520countryName()) pkcs_dict['Country'] = str(cn[0]) elif rfc2459.id_at_organizationName == at: on = decode(r.getComponentByName('value'), asn1Spec=rfc2459. X520OrganizationName()) pkcs_dict['Company name'] = str( on[0].getComponent()) elif rfc2459.id_at_organizationalUnitName == at: ou = decode(r.getComponentByName('value'), asn1Spec=rfc2459. X520OrganizationalUnitName()) pkcs_dict['Company Unit name'] = str( ou[0].getComponent()) elif rfc2459.id_at_commonName == at: cn = decode( r.getComponentByName('value'), asn1Spec=rfc2459.X520CommonName()) pkcs_dict['Issuer name'] = str( cn[0].getComponent()) else: print(at) except: return pkcs_dict return pkcs_dict
def getIssuersFromAIA(cert): tbs = cert.getComponentByName('tbsCertificate') extensions = tbs.getComponentByName('extensions') or [] allIssuers = [] for extension in extensions: oid = extension.getComponentByName('extnID') if oid != id_pe_authorityInfoAccess: continue print extension.prettyPrint() value, rest = decoder.decode(extension.getComponentByName('extnValue'), asn1Spec=univ.OctetString()) assert rest == "" aia, rest = decoder.decode(value, asn1Spec=AuthorityInfoAccessSyntax()) assert rest == "" print aia.prettyPrint() for ad in aia: oid = ad.getComponentByName('accessMethod') if oid != id_ad_caIssuers: continue print ad.prettyPrint() loc = ad.getComponentByName('accessLocation').\ getComponentByName('uniformResourceIdentifier') print type(loc), loc certHandle = urlopen(str(loc)) # RFC 5280 says this should either be 'application/pkix-cert' or # 'application/pkcs7-mime' (in which case the result should be a # "certs-only" PCKS#7 response, as specified in RFC 2797). Of # course, we see other values, so just try both formats. print certHandle.info().gettype() issuer = certHandle.read() # Have we got an (incorrect, but let's fix it) PEM encoded cert? if issuer.startswith('-----'): try: (issuer, _) = from_pem(issuer, ['CERTIFICATE']) except PemError as e: print "PEM decode failed:", e print "For cert:", issuer # Is it a certificate? try: cert, rest = decoder.decode(issuer, asn1Spec=certType) assert rest == "" allIssuers.append(cert) continue except PyAsn1Error as e: # On failure, try the next thing print "Cert decode failed:", e pass # If not, it had better be PKCS#7 "certs-only" try: pkcs7, rest = decoder.decode(issuer, asn1Spec=rfc2315.ContentInfo()) assert rest == "" assert pkcs7.getComponentByName( 'contentType') == rfc2315.signedData signedData = decoder.decode( pkcs7.getComponentByName('content'), asn1Spec=rfc2315.SignedData()) except PyAsn1Error as e: # Give up print "PKCS#7 decode also failed:", e print "Skipping issuer URL:", loc continue for signedDatum in signedData: # FIXME: why does this happen? Example is at # http://crt.usertrust.com/AddTrustExternalCARoot.p7c. if signedDatum == '': print "** Skipping strange Any('') in PKCS7 **" continue certs = signedDatum.getComponentByName('certificates') for c in certs: cert = c.getComponentByName('certificate') allIssuers.append(cert) return allIssuers
from pyasn1_modules import rfc2315, pem from pyasn1.codec.der import encoder, decoder import sys if len(sys.argv) != 1: print("""Usage: $ cat pkcs7Certificate.pem | %s""" % sys.argv[0]) sys.exit(-1) idx, substrate = pem.readPemBlocksFromFile( sys.stdin, ('-----BEGIN PKCS7-----', '-----END PKCS7-----') ) assert substrate, 'bad PKCS7 data on input' contentInfo, rest = decoder.decode(substrate, asn1Spec=rfc2315.ContentInfo()) if rest: substrate = substrate[:-len(rest)] print(contentInfo.prettyPrint()) assert encoder.encode(contentInfo) == substrate, 're-encode fails' contentType = contentInfo.getComponentByName('contentType') contentInfoMap = { (1, 2, 840, 113549, 1, 7, 1): rfc2315.Data(), (1, 2, 840, 113549, 1, 7, 2): rfc2315.SignedData(), (1, 2, 840, 113549, 1, 7, 3): rfc2315.EnvelopedData(), (1, 2, 840, 113549, 1, 7, 4): rfc2315.SignedAndEnvelopedData(), (1, 2, 840, 113549, 1, 7, 5): rfc2315.DigestedData(),
def setUp(self): self.asn1Spec = rfc2315.ContentInfo()
def DoSign(candidate_filename, privkey_filename, digest_name, privkey_password=None): sign_type = DetectSignerType(privkey_filename) if sign_type == SIGNER_TYPE_PEM or sign_type == SIGNER_TYPE_PKCS8: format_spec = "DER" if sign_type == SIGNER_TYPE_PKCS8 else "PEM" # openssl pkeyutl does not support passwords for pk8 -- only PEM -- # so convert to PEM in a temp file and use the temp file if format_spec == "DER" and privkey_password is not None: pem_privkey = tempfile.NamedTemporaryFile() p0 = Run([ "openssl", "pkcs8", "-inform", "DER", "-outform", "PEM", "-passin", "stdin", "-in", privkey_filename, "-out", pem_privkey.name ], stdin=subprocess.PIPE) p0.communicate(privkey_password + "\n") assert p0.returncode == 0, ("openssl pkcs8 of %s failed" % privkey_filename) format_spec = "PEM" privkey_filename = pem_privkey.name dgstfile = tempfile.NamedTemporaryFile() p1 = Run([ "openssl", "dgst", "-" + digest_name, "-binary", "-out", dgstfile.name, candidate_filename ]) p1.wait() assert p1.returncode == 0, ("openssl dgst of %s failed" % (candidate_filename, )) pkeyutl_cmd = ["openssl", "pkeyutl", "-sign", "-in", dgstfile.name] if privkey_password is not None: pkeyutl_cmd.extend(["-passin", "stdin"]) pkeyutl_cmd.extend([ "-keyform", format_spec, "-inkey", privkey_filename, "-pkeyopt", "digest:" + digest_name ]) p2 = Run(pkeyutl_cmd, stdin=subprocess.PIPE, stderr=subprocess.PIPE, stdout=subprocess.PIPE) if privkey_password is not None: privkey_password += '\n' (sig, err) = p2.communicate(privkey_password) print(err) assert p2.returncode == 0, ("openssl pkeyutl of %s failed" % (candidate_filename, )) elif sign_type == SIGNER_TYPE_CSS: signfile_path = os.environ[OPTIONS.signfile_path_env] + "SignFile" # Get the CSS key name from the private key file privkey_file = open(privkey_filename) signer_cert_name = privkey_file.readline().strip() privkey_file.close() # Create a temporary file for the signature output signature_file = tempfile.NamedTemporaryFile(delete=False) signature_file_name = signature_file.name signature_file.close() p1 = Run([ signfile_path, "-s", "cl", "-ts", "-vv", "-ha", digest_name.upper(), "-cf", signature_file_name, "-c", signer_cert_name, candidate_filename ], stdout=subprocess.PIPE, stderr=subprocess.PIPE) (out, err) = p1.communicate() if OPTIONS.verbose: print(out) print(err) assert p1.returncode == 0, ("%s signing of %s failed" % (signfile_path, candidate_filename)) # Read the signature result and pull out the signature block signature_file = open(signature_file_name, "rb") sig_content_data = signature_file.read() signature_file.close() os.remove(signature_file_name) (content, remain) = ber_decoder.decode(sig_content_data, asn1Spec=pkcs7.ContentInfo()) assert content.getComponentByName('contentType') == pkcs7.signedData, ( "%s output is not expected PKCS #7 SignedData" % signfile_path) (content, remain) = ber_decoder.decode(content.getComponentByName('content'), asn1Spec=pkcs7.SignedData()) sig = content.getComponentByName('signerInfos')[0].getComponentByName( 'encryptedDigest').asOctets() else: print("Sign type:", sign_type) assert False, "%s does not contain a recognized key." % privkey_filename return sig
def print_rsa(file_name): file = open(file_name,"r") buffer = file.read() buffer_base = base64.b64encode(buffer) file.close() file = open(file_name + ".pem","w") file.write('-----BEGIN PKCS7-----\n') file.write(buffer_base) file.write('\n-----END PKCS7-----\n') file.close() file = open(file_name + ".pem","r") idx, substrate = pem.readPemBlocksFromFile( file, ('-----BEGIN PKCS7-----', '-----END PKCS7-----') ) file.close() assert substrate, 'bad PKCS7 data on input' contentInfo, rest = decoder.decode(substrate, asn1Spec=rfc2315.ContentInfo()) if rest: substrate = substrate[:-len(rest)] #/home/retme/Desktop/xx/SIGN.RSA #print contentInfo #ContentInfo print(contentInfo.prettyPrint()) buf = contentInfo.getComponentByName('content') assert encoder.encode(contentInfo, defMode=False) == substrate or \ encoder.encode(contentInfo, defMode=True) == substrate, \ 're-encode fails' contentType = contentInfo.getComponentByName('contentType') #print contentInfo #certificates = contentInfo.getComponentByName('certificates') #certificates.prettyPrint() #print certificates contentInfoMap = { (1, 2, 840, 113549, 1, 7, 1): rfc2315.Data(), (1, 2, 840, 113549, 1, 7, 2): rfc2315.SignedData(), (1, 2, 840, 113549, 1, 7, 3): rfc2315.EnvelopedData(), (1, 2, 840, 113549, 1, 7, 4): rfc2315.SignedAndEnvelopedData(), (1, 2, 840, 113549, 1, 7, 5): rfc2315.DigestedData(), (1, 2, 840, 113549, 1, 7, 6): rfc2315.EncryptedData() } content, _ = decoder.decode( contentInfo.getComponentByName('content'), asn1Spec=contentInfoMap[contentType] ) #content.getComponentByName('certificates').setComponentByPosition(1) #print content.getComponentByName('certificates').getComponentByPosition(0).getComponentByName('certificate').getComponentByName('tbsCertificate').getComponentByName('serialNumber') #print content print(content.prettyPrint())
def parsePKCS7SignedData(data): container, dummy = decode(data, asn1Spec=rfc2315.ContentInfo()) assert container['contentType'] == rfc2315.signedData content, dummy = decode(container['content'], SignedData()) return content