def buildSignerInfo(self, certificate, pykeyHash, digestValue): """Given a pyasn1 certificate, a pykey hash identifier and a hash value, creates a SignerInfo with the appropriate values.""" signerInfo = rfc2315.SignerInfo() signerInfo['version'] = 1 issuerAndSerialNumber = rfc2315.IssuerAndSerialNumber() issuerAndSerialNumber['issuer'] = self.signer.getIssuer() issuerAndSerialNumber['serialNumber'] = certificate['tbsCertificate'][ 'serialNumber'] signerInfo['issuerAndSerialNumber'] = issuerAndSerialNumber signerInfo['digestAlgorithm'] = self.pykeyHashToDigestAlgorithm( pykeyHash) rsa = rfc2459.AlgorithmIdentifier() rsa['algorithm'] = rfc2459.rsaEncryption rsa['parameters'] = univ.Null() authenticatedAttributes = self.buildAuthenticatedAttributes( digestValue, implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0)) authenticatedAttributesTBS = self.buildAuthenticatedAttributes( digestValue) signerInfo['authenticatedAttributes'] = authenticatedAttributes signerInfo['digestEncryptionAlgorithm'] = rsa authenticatedAttributesEncoded = encoder.encode( authenticatedAttributesTBS) signature = self.signingKey.sign(authenticatedAttributesEncoded, pykeyHash) # signature will be a hexified bit string of the form # "'<hex bytes>'H". For some reason that's what BitString wants, # but since this is an OCTET STRING, we have to strip off the # quotation marks and trailing "H". signerInfo['encryptedDigest'] = univ.OctetString( hexValue=signature[1:-2]) return signerInfo
def getSigningTimeAuthenticode(data): signerInfo, dummy = decode(data, asn1Spec=rfc2315.SignerInfo()) attrs = signerInfo['authenticatedAttributes'] if not attrs: return for attr in attrs: if attr['type'] == univ.ObjectIdentifier('1.2.840.113549.1.9.5'): signingTime, dummy = decode(attr['values'][0], asn1Spec=TimeChoice()) return parseTimeChoice(signingTime)
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)