Example #1
1
    def validatecertificatesignature(self, signed_cert, signing_cert):
        """Given a cert signed by another cert, validates the signature."""
        # First the naive way -- note this does not check expiry / use etc.

        cert_signing = x509.load_pem_x509_certificate(ssl.DER_cert_to_PEM_cert(der_encoder.encode(signing_cert)).encode(), default_backend())

        public_key = cert_signing.public_key()

        der_cert = der_encoder.encode(signed_cert)
        cert_signed = x509.load_pem_x509_certificate(ssl.DER_cert_to_PEM_cert(der_cert).encode(), default_backend())

        data = cert_signed.tbs_certificate_bytes
        signature = cert_signed.signature

        new_api = hasattr(public_key, "verify")
        if not new_api:
            verifier = public_key.verifier(signature, padding.PKCS1v15(), cert_signed.signature_hash_algorithm)
            try:
                verifier.update(data)
                verifier.verify()
            except:
                raise Asn1Error('1: Validation of cert signature failed.')
        else:
            try:
                verifier = public_key.verify(signature, data, padding.PKCS1v15(), cert_signed.signature_hash_algorithm)
                # verifier.update(data)
                # verifier.verify()
            except:
                raise Asn1Error('1: Validation of cert signature failed.')
Example #2
0
File: ccache.py Project: kcr/pykrb5
    def _write(self, file, header, principal, sessions):
        self._pack_write(file, '!H', self._FVNO_4)
        self._write_header_tags(file, header)
        self._write_principal(file, principal)

        for s in sessions:
            self._write_principal(file, s.client)
            self._write_principal(file, s.service)
            self._write_key(file, s.key)
            self._write_time(file, s.auth_time)
            self._write_time(file, s.start_time)
            self._write_time(file, s.end_time)
            self._write_time(file, s.renew_until)
            self._pack_write(file, 'B', 0 if s.u2u_ticket is None else 1)
            self._write_ticket_flags(file, s.ticket_flags or 0)
            self._write_addresses(file, s.addresses or [])
            self._write_authdata(file, [])
            ticket = asn1.Ticket()
            s.ticket.to_asn1(ticket)
            self._write_data(file, encoder.encode(ticket))
            if s.u2u_ticket is not None:
                u2u_ticket = asn1.Ticket()
                s.u2u_ticket.to_asn1(u2u_ticket)
                self._write_data(file, encoder.encode(u2u_ticket))
            else:
                self._write_data(file, "")
Example #3
0
    def testDerCodec(self):

        substrate = pem.readBase64fromText(self.pem_text_unordered)

        asn1Object, rest = der_decoder.decode(substrate, asn1Spec=self.asn1Spec)

        assert not rest
        assert asn1Object.prettyPrint()
        assert der_encoder.encode(asn1Object) == substrate

        contentType = asn1Object['contentType']
        substrate = asn1Object['content']

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

        innerAsn1Object, rest = der_decoder.decode(
            substrate, asn1Spec=contentInfoMap[contentType]
        )

        asn1Object['content'] = der_encoder.encode(innerAsn1Object)

        substrate = pem.readBase64fromText(self.pem_text_reordered)

        assert not rest
        assert asn1Object.prettyPrint()
        assert der_encoder.encode(asn1Object) == substrate
Example #4
0
def _encode_extension(oid, critical, value):
    ext = rfc2459.Extension()
    ext['extnID'] = univ.ObjectIdentifier(oid)
    ext['critical'] = univ.Boolean(critical)
    ext['extnValue'] = univ.Any(encoder.encode(univ.OctetString(value)))
    ext = encoder.encode(ext)
    return ext
Example #5
0
def getRevokedSerials(crl):
    serials = []
    if None != crl[0]['tbsCertList'] and None != crl[0]['tbsCertList']['revokedCertificates']:
        print b64encode(encoder.encode(crl[0]['tbsCertList']['issuer']))
        for cert in crl[0]['tbsCertList']['revokedCertificates']:
            serials.append(b64encode(encoder.encode(cert['userCertificate'])))
    return serials
Example #6
0
def _build_signature(key, certreqinfo, network):
    secret_exponent = encoding.to_long(256, encoding.byte_to_int, key[0][1].asOctets())[0]
    coin  = Key(secret_exponent=secret_exponent, netcode=network)
    print "building signature for %s address: %s" % (network, coin.address())
    pubkeybitstring = (key[0].getComponentByPosition(2), key[0].getComponentByPosition(3))
    certreqinfoder = encoder.encode(certreqinfo)
    hashvalue = SHA256.new(certreqinfoder)
    dgst = hashvalue.digest()
    dgstaslong = encoding.to_long(256, encoding.byte_to_int, dgst)[0]
    order2 = pycoin.ecdsa.generator_secp256k1.order()
    ## random sign
    generator = pycoin.ecdsa.generator_secp256k1
    rawsig2 = randomsign(generator, secret_exponent, dgstaslong)
    ## deterministic sign
    ##rawsig2 = pycoin.ecdsa.sign(pycoin.ecdsa.generator_secp256k1, secret_exponent, dgstaslong)
    r2, s2 = rawsig2
    print "signature: r: %x s: %x" % (r2, s2)
    if not pycoin.ecdsa.verify(generator, coin.public_pair(), dgstaslong, rawsig2):
        raise SignatureVerifyException("Generated signature r: %x s: %x does not verify against public key %s" % (r2, s2, public_pair))
    signature = ECDSASigValue()
    signature.setComponentByName('r', r2)
    signature.setComponentByName('s', s2)
    dersig = encoder.encode(signature)
    signaturevalue = "'{0}'H".format(binascii.hexlify(dersig))
    bitstring = univ.BitString( value=signaturevalue )
    return rfc2314.Signature( bitstring )
Example #7
0
  def getRSAPublicKey(self):
    """ Gets an ASN.1-encoded form of this RSA key's public key. """
    # Get a RSAPublicKey structure
    pkinfo = univ.Sequence()
    rsakey = self.getRSAKey()
    pkinfo.setComponentByPosition(0, univ.Integer(rsakey.n))
    pkinfo.setComponentByPosition(1, univ.Integer(rsakey.e))
    
    # Encode the public key info as a bit string
    pklong = long(encoder.encode(pkinfo).encode('hex'), 16)
    pkbitstring = univ.BitString("'00%s'B" % self.toBitString_(pklong))

    # Get the rsaEncryption identifier:
    idrsaencryption = univ.ObjectIdentifier('1.2.840.113549.1.1.1')

    # Get the AlgorithmIdentifier for rsaEncryption
    idinfo = univ.Sequence()
    idinfo.setComponentByPosition(0, idrsaencryption)
    idinfo.setComponentByPosition(1, univ.Null(''))

    # Get the SubjectPublicKeyInfo structure
    publickeyinfo = univ.Sequence()
    publickeyinfo.setComponentByPosition(0, idinfo)
    publickeyinfo.setComponentByPosition(1, pkbitstring)

    # Encode the public key structure
    publickey = encoder.encode(publickeyinfo)
    return publickey
Example #8
0
def api_sign_certificate():
    if request.headers['Content-Type'] == 'application/json':
        certificate = b64decode(str(request.json.get("certificate")))
        bitcoin_address = str(request.json.get("bitcoin_address"))

        # Get the ACA secret key
        f = open(ACA_KEY, "r")
        sk_string = f.read()
        f.close()
        sk = RSA.importKey(sk_string)

        # Get the certificate hash and the asn1 representation of the certificate
        certificate_hash = certificate_hashing(certificate)
        signature = sk.sign(certificate_hash, 1)[0]
        asn1_cert = decoder.decode(certificate, asn1Spec=Certificate())[0]

        # Attach the signature to the certificate
        bin_signature = Signature("'%s'H" % ''.join("%02X" % ord(c) for c in long_to_bytes(signature)))
        asn1_cert.setComponentByName("signatureValue", bin_signature)

        # Store the certificate
        der_cert = encoder.encode(asn1_cert)
        store_certificate(encoder.encode(asn1_cert), bitcoin_address)

        return b64encode(der_cert)
Example #9
0
    def getTGT(self, userName, requestPAC=True):

        clientName = Principal(userName, type=constants.PrincipalNameType.NT_PRINCIPAL.value)

        asReq = AS_REQ()

        domain = self.__domain.upper()
        serverName = Principal('krbtgt/%s' % domain, type=constants.PrincipalNameType.NT_PRINCIPAL.value)

        pacRequest = KERB_PA_PAC_REQUEST()
        pacRequest['include-pac'] = requestPAC
        encodedPacRequest = encoder.encode(pacRequest)

        asReq['pvno'] = 5
        asReq['msg-type'] = int(constants.ApplicationTagNumbers.AS_REQ.value)

        asReq['padata'] = noValue
        asReq['padata'][0] = noValue
        asReq['padata'][0]['padata-type'] = int(constants.PreAuthenticationDataTypes.PA_PAC_REQUEST.value)
        asReq['padata'][0]['padata-value'] = encodedPacRequest

        reqBody = seq_set(asReq, 'req-body')

        opts = list()
        opts.append(constants.KDCOptions.forwardable.value)
        opts.append(constants.KDCOptions.renewable.value)
        opts.append(constants.KDCOptions.proxiable.value)
        reqBody['kdc-options'] = constants.encodeFlags(opts)

        seq_set(reqBody, 'sname', serverName.components_to_asn1)
        seq_set(reqBody, 'cname', clientName.components_to_asn1)

        if domain == '':
            raise Exception('Empty Domain not allowed in Kerberos')

        reqBody['realm'] = domain

        now = datetime.datetime.utcnow() + datetime.timedelta(days=1)
        reqBody['till'] = KerberosTime.to_asn1(now)
        reqBody['rtime'] = KerberosTime.to_asn1(now)
        reqBody['nonce'] = random.getrandbits(31)

        supportedCiphers = (int(constants.EncryptionTypes.rc4_hmac.value),)

        seq_set_iter(reqBody, 'etype', supportedCiphers)

        message = encoder.encode(asReq)

        try:
            r = sendReceive(message, domain, self.__kdcHost)
        except KerberosError, e:
            if e.getErrorCode() == constants.ErrorCodes.KDC_ERR_ETYPE_NOSUPP.value:
                # RC4 not available, OK, let's ask for newer types
                supportedCiphers = (int(constants.EncryptionTypes.aes256_cts_hmac_sha1_96.value),
                                    int(constants.EncryptionTypes.aes128_cts_hmac_sha1_96.value),)
                seq_set_iter(reqBody, 'etype', supportedCiphers)
                message = encoder.encode(asReq)
                r = sendReceive(message, domain, self.__kdcHost)
            else:
                raise e
Example #10
0
    def to_pem(self, pem_format='PKCS8'):

        if isinstance(self._prepared_key, pyrsa.PrivateKey):
            der = self._prepared_key.save_pkcs1(format='DER')
            if pem_format == 'PKCS8':
                pem = pyrsa_pem.save_pem(PKCS8_RSA_HEADER + der, pem_marker='PRIVATE KEY')
            elif pem_format == 'PKCS1':
                pem = pyrsa_pem.save_pem(der, pem_marker='RSA PRIVATE KEY')
            else:
                raise ValueError("Invalid pem format specified: %r" % (pem_format,))
        else:
            if pem_format == 'PKCS8':
                asn_key = AsnPubKey()
                asn_key.setComponentByName('modulus', self._prepared_key.n)
                asn_key.setComponentByName('publicExponent', self._prepared_key.e)
                der = encoder.encode(asn_key)

                header = PubKeyHeader()
                header['oid'] = univ.ObjectIdentifier('1.2.840.113549.1.1.1')
                pub_key = OpenSSLPubKey()
                pub_key['header'] = header
                pub_key['key'] = univ.BitString.fromOctetString(der)

                der = encoder.encode(pub_key)
                pem = pyrsa_pem.save_pem(der, pem_marker='PUBLIC KEY')
            elif pem_format == 'PKCS1':
                der = self._prepared_key.save_pkcs1(format='DER')
                pem = pyrsa_pem.save_pem(der, pem_marker='RSA PUBLIC KEY')
            else:
                raise ValueError("Invalid pem format specified: %r" % (pem_format,))
        return pem
Example #11
0
    def testDerCodec(self):

        substrate = pem.readBase64fromText(self.pem_text)

        asn1Object, rest = der_decoder.decode(substrate, asn1Spec=self.asn1Spec)

        assert not rest
        assert asn1Object.prettyPrint()
        assert der_encoder.encode(asn1Object) == substrate

        for extn in asn1Object['tbsCertificate']['extensions']:

            if extn['extnID'] == rfc3779.id_pe_ipAddrBlocks:
                s = extn['extnValue']
                addr_blocks, rest = der_decoder.decode(s, rfc3779.IPAddrBlocks())
                assert not rest
                assert addr_blocks.prettyPrint()
                assert der_encoder.encode(addr_blocks) == s

            if extn['extnID'] == rfc3779.id_pe_autonomousSysIds:
                s = extn['extnValue']
                as_ids, rest = der_decoder.decode(s, rfc3779.ASIdentifiers())
                assert not rest
                assert as_ids.prettyPrint()
                assert der_encoder.encode(as_ids) == s
Example #12
0
 def toDER(self):
     tbsCertificate = rfc2459.TBSCertificate()
     tbsCertificate.setComponentByName('version', self.getVersion())
     tbsCertificate.setComponentByName('serialNumber', self.getSerialNumber())
     tbsCertificate.setComponentByName('signature', self.getSignature())
     tbsCertificate.setComponentByName('issuer', self.getIssuer())
     tbsCertificate.setComponentByName('validity', self.getValidity())
     tbsCertificate.setComponentByName('subject', self.getSubject())
     tbsCertificate.setComponentByName('subjectPublicKeyInfo', self.getSubjectPublicKeyInfo())
     if self.extensions:
         extensions = rfc2459.Extensions().subtype(
             explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3))
         count = 0
         for extension in self.extensions:
             extensions.setComponentByPosition(count, extension)
             count += 1
         tbsCertificate.setComponentByName('extensions', extensions)
     tbsDER = encoder.encode(tbsCertificate)
     rsaPrivateKey = rsa.PrivateKey(self.issuerRSA_N, self.issuerRSA_E, self.issuerRSA_D,
                                    self.issuerRSA_P, self.issuerRSA_Q)
     signature = rsa.sign(tbsDER, rsaPrivateKey, 'SHA-256')
     certificate = rfc2459.Certificate()
     certificate.setComponentByName('tbsCertificate', tbsCertificate)
     certificate.setComponentByName('signatureAlgorithm', self.getSignatureAlgorithm())
     certificate.setComponentByName('signatureValue', byteStringToHexifiedBitString(signature))
     return encoder.encode(certificate)
Example #13
0
def ExportRsaX509(params):
  oid = ASN1Sequence(RSA_OID, univ.Null())
  key = ASN1Sequence(univ.Integer(params['n']), univ.Integer(params['e']))
  binkey = BytesToBin(encoder.encode(key))
  pubkey = univ.BitString("'%s'B" % binkey)  # needs to be a BIT STRING
  seq = ASN1Sequence(oid, pubkey)
  return Base64WSEncode(encoder.encode(seq))
Example #14
0
    def _parseauthattrs(auth_attrs, required):
        results = dict.fromkeys(required)
        for attr in auth_attrs:
            if (attr['type'] in oids.OID_TO_CLASS and
                        oids.OID_TO_CLASS.get(attr['type']) in required):
                # There are more than those I require, but I don't know what they are,
                # and what to do with them. The spec does not talk about them.
                # One example:
                # 1.3.6.1.4.1.311.2.1.11 contains as value 1.3.6.1.4.1.311.2.1.21
                # SPC_STATEMENT_TYPE_OBJID    SPC_INDIVIDUAL_SP_KEY_PURPOSE_OBJID
                results[oids.OID_TO_CLASS.get(attr['type'])] = attr['values']
        if None in iter(results.values()):
            raise Asn1Error('Missing mandatory field(s) in auth_attrs.')

        # making sure that the auth_attrs were processed in correct order
        # they need to be sorted in ascending order in the SET, when DER encoded
        # This also makes sure that the tag on Attributes is correct.
        a = [der_encoder.encode(i) for i in auth_attrs]
        a.sort()
        attrs_for_hash = pkcs7.Attributes()
        for i in range(len(auth_attrs)):
            d, _ = decoder.decode(a[i], asn1Spec=pkcs7.Attribute())
            attrs_for_hash.setComponentByPosition(i, d)
        encoded_attrs = der_encoder.encode(attrs_for_hash)

        return results, encoded_attrs
Example #15
0
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)
Example #16
0
    def make_ap_req_bytes(self, auth_key_usage,
                          subkey=None, checksum=None):
        now = datetime.datetime.utcnow()

        authenticator = asn1.Authenticator()
        authenticator.setComponentByName('authenticator-vno', 5)
        authenticator.setComponentByName('crealm', self.client.realm)
        asn1.seq_set(authenticator, 'cname',
                     self.client.components_to_asn1)
        if checksum is not None:
            asn1.seq_set_dict(authenticator, 'cksum', checksum)
        authenticator.setComponentByName('cusec', now.microsecond)
        authenticator.setComponentByName('ctime',
                                         types.KerberosTime.to_asn1(now))
        if subkey is not None:
            asn1.seq_set_dict(authenticator, 'subkey', subkey.to_asn1())

        encoder.encode(authenticator)

        ap_req = asn1.APReq()
        ap_req.setComponentByName('pvno', 5)
        ap_req.setComponentByName('msg-type', int(constants.Asn1Tags.ap_req))
        asn1.seq_set_flags(ap_req, 'ap-options', constants.APOptions())
        asn1.seq_set(ap_req, 'ticket', self.ticket.to_asn1)
        asn1.seq_set_dict(ap_req, 'authenticator', 
                          self.key.encrypted_data(
                              auth_key_usage, encoder.encode(authenticator)))

        return encoder.encode(ap_req)
Example #17
0
def convertPKCS1toPKCS8pubKey(bitsdata):
    pubkey_pkcs1_b64 = b''.join(bitsdata.split(b'\n')[1:-2])
    pubkey_pkcs1, restOfInput = der_decoder.decode(
        base64.b64decode(pubkey_pkcs1_b64))
    bitstring = univ.Sequence()
    bitstring.setComponentByPosition(0, univ.Integer(pubkey_pkcs1[0]))
    bitstring.setComponentByPosition(1, univ.Integer(pubkey_pkcs1[1]))
    bitstring = der_encoder.encode(bitstring)
    try:
        bitstring = ''.join(
            [('00000000' + bin(ord(x))[2:])[-8:] for x in list(bitstring)])
    except:
        bitstring = ''.join(
            [('00000000' + bin(x)[2:])[-8:] for x in list(bitstring)])
    bitstring = univ.BitString("'%s'B" % bitstring)
    pubkeyid = univ.Sequence()
    pubkeyid.setComponentByPosition(
        0, univ.ObjectIdentifier('1.2.840.113549.1.1.1'))  # OID rsaEncryption
    pubkeyid.setComponentByPosition(1, univ.Null(''))
    pubkey_seq = univ.Sequence()
    pubkey_seq.setComponentByPosition(0, pubkeyid)
    pubkey_seq.setComponentByPosition(1, bitstring)
    base64.MAXBINSIZE = (64 // 4) * 3
    res = b"-----BEGIN PUBLIC KEY-----\n"
    res += base64.encodestring(der_encoder.encode(pubkey_seq))
    res += b"-----END PUBLIC KEY-----\n"
    return res
Example #18
0
 def toDER(self):
     (signatureOID, hashName) = stringToAlgorithmIdentifiers(self.signature)
     tbsCertificate = rfc2459.TBSCertificate()
     tbsCertificate.setComponentByName('version', self.getVersion())
     tbsCertificate.setComponentByName('serialNumber', self.getSerialNumber())
     tbsCertificate.setComponentByName('signature', signatureOID)
     tbsCertificate.setComponentByName('issuer', self.getIssuer())
     tbsCertificate.setComponentByName('validity', self.getValidity())
     tbsCertificate.setComponentByName('subject', self.getSubject())
     tbsCertificate.setComponentByName('subjectPublicKeyInfo',
                                       self.subjectKey.asSubjectPublicKeyInfo())
     if self.extensions:
         extensions = rfc2459.Extensions().subtype(
             explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3))
         count = 0
         for extension in self.extensions:
             extensions.setComponentByPosition(count, extension)
             count += 1
         tbsCertificate.setComponentByName('extensions', extensions)
     certificate = rfc2459.Certificate()
     certificate.setComponentByName('tbsCertificate', tbsCertificate)
     certificate.setComponentByName('signatureAlgorithm', signatureOID)
     tbsDER = encoder.encode(tbsCertificate)
     certificate.setComponentByName('signatureValue', self.issuerKey.sign(tbsDER, hashName))
     return encoder.encode(certificate)
Example #19
0
def getChainFingerprint(certChain):
    fingerprint = hashlib.sha1()
    secret = hashlib.sha1()
    for cert in certChain:
        fingerprint.update(der_encoder.encode(cert))
        secret.update(der_encoder.encode(cert[0][0]['serialNumber']))
    return fingerprint.hexdigest(), base64.b64encode(secret.digest())
Example #20
0
 def testDerCodec(self):
     substrate = pem.readBase64fromText(self.pss_sha512_pem_text)
     asn1Object, rest = der_decoder.decode(substrate, asn1Spec=self.asn1Spec)
     assert not rest
     assert asn1Object.prettyPrint()
     assert asn1Object[0] == rfc4055.id_RSASSA_PSS
     assert der_encoder.encode(asn1Object) == substrate
     assert substrate == der_encoder.encode(asn1Object)
Example #21
0
def export_rsa_to_pkcs8(params):
    oid = ASN1Sequence(RSA_OID, univ.Null())
    key = univ.Sequence().setComponentByPosition(0, univ.Integer(0))  # version
    for i in range(len(RSA_PARAMS)):
        key.setComponentByPosition(i + 1, univ.Integer(params[RSA_PARAMS[i]]))
    octkey = encoder.encode(key)
    seq = ASN1Sequence(univ.Integer(0), oid, univ.OctetString(octkey))
    return encoder.encode(seq)
Example #22
0
 def testDerCodec(self):
     substrate = pem.readBase64fromText(self.oaep_full_pem_text)
     asn1Object, rest = der_decoder.decode(substrate, asn1Spec=self.asn1Spec)
     assert not rest
     assert asn1Object.prettyPrint()
     assert asn1Object[0] == rfc3560.id_RSAES_OAEP
     assert der_encoder.encode(asn1Object) == substrate
     assert substrate == der_encoder.encode(asn1Object)
Example #23
0
def ExportDsaPkcs8(params):
  alg_params = univ.Sequence()
  for i in range(len(DSA_PARAMS)):
    alg_params.setComponentByPosition(i, univ.Integer(params[DSA_PARAMS[i]]))
  oid = ASN1Sequence(DSA_OID, alg_params)
  octkey = encoder.encode(univ.Integer(params['x']))
  seq = ASN1Sequence(univ.Integer(0), oid, univ.OctetString(octkey))
  return Base64WSEncode(encoder.encode(seq))
Example #24
0
    def toDER(self):
        contentInfo = rfc2315.ContentInfo()
        contentInfo['contentType'] = rfc2315.signedData

        signedData = rfc2315.SignedData()
        signedData['version'] = rfc2315.Version(1)

        digestAlgorithms = rfc2315.DigestAlgorithmIdentifiers()
        sha1 = rfc2459.AlgorithmIdentifier()
        sha1['algorithm'] = univ.ObjectIdentifier('1.3.14.3.2.26')
        sha1['parameters'] = univ.Null()
        digestAlgorithms[0] = 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()
        signerInfo = rfc2315.SignerInfo()
        signerInfo['version'] = 1
        issuerAndSerialNumber = rfc2315.IssuerAndSerialNumber()
        issuerAndSerialNumber['issuer'] = self.signer.getIssuer()
        issuerAndSerialNumber['serialNumber'] = certificate['tbsCertificate']['serialNumber']
        signerInfo['issuerAndSerialNumber'] = issuerAndSerialNumber
        signerInfo['digestAlgorithm'] = sha1
        rsa = rfc2459.AlgorithmIdentifier()
        rsa['algorithm'] = rfc2459.rsaEncryption
        rsa['parameters'] = univ.Null()
        authenticatedAttributes = rfc2315.Attributes().subtype(
            implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))
        hashAttribute = rfc2315.Attribute()
        # PKCS#9 messageDigest
        hashAttribute['type'] = univ.ObjectIdentifier('1.2.840.113549.1.9.4')
        hashAttribute['values'] = univ.SetOf(rfc2459.AttributeValue())
        hashAttribute['values'][0] = univ.OctetString(self.hash)
        authenticatedAttributes[0] = hashAttribute
        signerInfo['authenticatedAttributes'] = authenticatedAttributes
        signerInfo['digestEncryptionAlgorithm'] = rsa
        signerInfo['encryptedDigest'] = univ.OctetString('signature goes here')
        signerInfos[0] = signerInfo
        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)
Example #25
0
    def new(cls, alias, certs, key, key_format='pkcs8'):
        """
        Helper function to create a new PrivateKeyEntry.

        :param str alias: The alias for the Private Key Entry
        :param list certs: An list of certificates, as byte strings.
          The first one should be the one belonging to the private key,
          the others the chain (in correct order).
        :param str key: A byte string containing the private key in the
          format specified in the key_format parameter (default pkcs8).
        :param str key_format: The format of the provided private key.
          Valid options are pkcs8 or rsa_raw. Defaults to pkcs8.

        :returns: A loaded :class:`PrivateKeyEntry` instance, ready
          to be placed in a keystore.

        :raises UnsupportedKeyFormatException: If the key format is
          unsupported.
        """
        timestamp = int(time.time()) * 1000

        cert_chain = []
        for cert in certs:
            cert_chain.append(('X.509', cert))

        pke = cls(timestamp = timestamp,
                  alias = alias,
                  cert_chain = cert_chain)

        if key_format == 'pkcs8':
            try:
                private_key_info = asn1_checked_decode(key, asn1Spec=rfc5208.PrivateKeyInfo())

                pke._algorithm_oid = private_key_info['privateKeyAlgorithm']['algorithm'].asTuple()
                pke.pkey = private_key_info['privateKey'].asOctets()
                pke.pkey_pkcs8 = key
            except PyAsn1Error as e:
                raise BadKeyEncodingException("Failed to parse provided key as a PKCS#8 PrivateKeyInfo structure", e)

        elif key_format == 'rsa_raw':
            pke._algorithm_oid = RSA_ENCRYPTION_OID

            # We must encode it to pkcs8
            private_key_info = rfc5208.PrivateKeyInfo()
            private_key_info.setComponentByName('version','v1')
            a = rfc2459.AlgorithmIdentifier()
            a.setComponentByName('algorithm', pke._algorithm_oid)
            a.setComponentByName('parameters', univ.Any(encoder.encode(univ.Null())))
            private_key_info.setComponentByName('privateKeyAlgorithm', a)
            private_key_info.setComponentByName('privateKey', key)

            pke.pkey_pkcs8 = encoder.encode(private_key_info)
            pke.pkey = key

        else:
            raise UnsupportedKeyFormatException("Key Format '%s' is not supported" % key_format)

        return pke
Example #26
0
def ExportDsaX509(params):
  alg_params = ASN1Sequence(univ.Integer(params['p']),
                            univ.Integer(params['q']),
                            univ.Integer(params['g']))
  oid = ASN1Sequence(DSA_OID, alg_params)
  binkey = BytesToBin(encoder.encode(univ.Integer(params['y'])))
  pubkey = univ.BitString("'%s'B" % binkey)  # needs to be a BIT STRING
  seq = ASN1Sequence(oid, pubkey)
  return Base64WSEncode(encoder.encode(seq))
Example #27
0
 def toDER(self):
     (signatureOID, hashAlgorithm) = stringToAlgorithmIdentifiers(self.signature)
     certificate = rfc2459.Certificate()
     tbsCertificate = self.getTBSCertificate()
     certificate.setComponentByName('tbsCertificate', tbsCertificate)
     certificate.setComponentByName('signatureAlgorithm', signatureOID)
     tbsDER = encoder.encode(tbsCertificate)
     certificate.setComponentByName('signatureValue', self.issuerKey.sign(tbsDER, hashAlgorithm))
     return encoder.encode(certificate)
def getPubkey(self, privkey):
  k =  gdata.tlslite.utils.keyfactory.parsePEMKey(privkey, private=True)
  oid = ASN1Sequence(univ.ObjectIdentifier('1.2.840.113549.1.1.1'), univ.Null())
  key = ASN1Sequence(univ.Integer(k.n), univ.Integer(k.e))
  binkey = BytesToBin(encoder.encode(key))
  pubkey = univ.BitString("'%s'B" % binkey)
  seq = ASN1Sequence(oid, pubkey)
  pubkeydata = encoder.encode(seq)
  return pubkeydata
 def ValidateCertificateSignature(self, signed_cert, signing_cert):
   """Given a cert signed by another cert, validates the signature."""
   # First the naive way -- note this does not check expiry / use etc.
   signed_m2 = M2_X509.load_cert_der_string(der_encoder.encode(signed_cert))
   signing_m2 = M2_X509.load_cert_der_string(der_encoder.encode(signing_cert))
   pubkey = signing_m2.get_pubkey()
   v = signed_m2.verify(pubkey)
   if v != 1:
     self.openssl_error = M2_Err.get_error()
     raise Asn1Error('1: Validation of cert signature failed.')
Example #30
0
 def __encode_extension(self, oid, critical, value):
     # TODO: have another proxy for crypto_x509.Extension which would
     # provide public_bytes on the top of what python-cryptography has
     ext = rfc2459.Extension()
     # TODO: this does not have to be so weird, pyasn1 now has codecs
     # which are capable of providing python-native types
     ext['extnID'] = univ.ObjectIdentifier(oid)
     ext['critical'] = univ.Boolean(critical)
     ext['extnValue'] = univ.Any(encoder.encode(univ.OctetString(value)))
     ext = encoder.encode(ext)
     return ext
 def encode_cert_id_base64(self, hkey):
     return b64encode(der_encoder.encode(
         self.encode_cert_id_key(hkey))).decode('ascii')
Example #32
0
def main():
    data_file = sys.argv[1]

    with file(data_file, 'rb') as objf:
        fingerprinter = fingerprint.Fingerprinter(objf)
        is_pecoff = fingerprinter.EvalPecoff()
        fingerprinter.EvalGeneric()
        results = fingerprinter.HashIt()

    print('Generic hashes:')
    hashes = [x for x in results if x['name'] == 'generic']
    if len(hashes) > 1:
        print('More than one generic finger? Only printing first one.')
    for hname in sorted(hashes[0].keys()):
        if hname != 'name':
            print('%s: %s' % (hname, hashes[0][hname].encode('hex')))
    print

    if not is_pecoff:
        print('This is not a PE/COFF binary. Exiting.')
        return

    print('PE/COFF hashes:')
    hashes = [x for x in results if x['name'] == 'pecoff']
    if len(hashes) > 1:
        print('More than one PE/COFF finger? Only printing first one.')
    for hname in sorted(hashes[0].keys()):
        if hname != 'name' and hname != 'SignedData':
            print('%s: %s' % (hname, hashes[0][hname].encode('hex')))
    print

    signed_pecoffs = [
        x for x in results if x['name'] == 'pecoff' and 'SignedData' in x
    ]

    if not signed_pecoffs:
        print('This PE/COFF binary has no signature. Exiting.')
        return

    signed_pecoff = signed_pecoffs[0]

    signed_datas = signed_pecoff['SignedData']
    # There may be multiple of these, if the windows binary was signed multiple
    # times, e.g. by different entities. Each of them adds a complete SignedData
    # blob to the binary.
    # TODO(user): Process all instances
    signed_data = signed_datas[0]

    blob = pecoff_blob.PecoffBlob(signed_data)

    auth = auth_data.AuthData(blob.getCertificateBlob())
    content_hasher_name = auth.digest_algorithm().name
    computed_content_hash = signed_pecoff[content_hasher_name]

    try:
        auth.ValidateAsn1()
        auth.ValidateHashes(computed_content_hash)
        auth.ValidateSignatures()
        auth.ValidateCertChains(time.gmtime())
    except auth_data.Asn1Error:
        if auth.openssl_error:
            print('OpenSSL Errors:\n%s' % auth.openssl_error)
        raise

    print('Program: %s, URL: %s' % (auth.program_name, auth.program_url))
    if auth.has_countersignature:
        print('Countersignature is present. Timestamp: %s UTC' %
              time.asctime(time.gmtime(auth.counter_timestamp)))
    else:
        print('Countersignature is not present.')

    print('Binary is signed with cert issued by:')
    pprint.pprint(auth.signing_cert_id)
    print

    print('Cert chain head issued by:')
    pprint.pprint(auth.cert_chain_head[2])
    print('  Chain not before: %s UTC' %
          (time.asctime(time.gmtime(auth.cert_chain_head[0]))))
    print('  Chain not after: %s UTC' %
          (time.asctime(time.gmtime(auth.cert_chain_head[1]))))
    print

    if auth.has_countersignature:
        print('Countersig chain head issued by:')
        pprint.pprint(auth.counter_chain_head[2])
        print('  Countersig not before: %s UTC' %
              (time.asctime(time.gmtime(auth.counter_chain_head[0]))))
        print('  Countersig not after: %s UTC' %
              (time.asctime(time.gmtime(auth.counter_chain_head[1]))))
        print

    print('Certificates')
    for (issuer, serial), cert in auth.certificates.items():
        print('  Issuer: %s' % issuer)
        print('  Serial: %s' % serial)
        subject = cert[0][0]['subject']
        subject_dn = str(dn.DistinguishedName.TraverseRdn(subject[0]))
        print('  Subject: %s' % subject_dn)
        not_before = cert[0][0]['validity']['notBefore']
        not_after = cert[0][0]['validity']['notAfter']
        not_before_time = not_before.ToPythonEpochTime()
        not_after_time = not_after.ToPythonEpochTime()
        print('  Not Before: %s UTC (%s)' %
              (time.asctime(time.gmtime(not_before_time)), not_before[0]))
        print('  Not After: %s UTC (%s)' %
              (time.asctime(time.gmtime(not_after_time)), not_after[0]))
        bin_cert = der_encoder.encode(cert)
        print('  MD5: %s' % hashlib.md5(bin_cert).hexdigest())
        print('  SHA1: %s' % hashlib.sha1(bin_cert).hexdigest())
        print

    if auth.trailing_data:
        print('Signature Blob had trailing (unvalidated) data (%d bytes): %s' %
              (len(auth.trailing_data), auth.trailing_data.encode('hex')))
 def _convert_pyasn1_to_openssl_certificate(self, cert):
     cert_der = der_encoder.encode(cert)
     cert_openssl = load_certificate(FILETYPE_ASN1, cert_der)
     return cert_openssl
 def _get_name_hash(self, cert):
     sha1_hash = hashlib.sha1()
     sha1_hash.update(der_encoder.encode(self._get_subject(cert)))
     return sha1_hash.hexdigest()
Example #35
0
def check_timestamp(tst, certificate, data=None, digest=None, hashname=None, nonce=None):
    hashname = hashname or 'sha1'
    hashobj = hashlib.new(hashname)
    if digest is None:
        if not data:
            raise ValueError("check_timestamp requires data or digest argument")
        hashobj.update(data)
        digest = hashobj.digest()

    if not isinstance(tst, rfc3161.TimeStampToken):
        tst, substrate = decoder.decode(tst, asn1Spec=rfc3161.TimeStampToken())
        if substrate:
            return False, "extra data after tst"
    signed_data = tst.content
    if certificate != "":
        try:
            certificate = X509.load_cert_string(certificate, X509.FORMAT_PEM)
        except:
            certificate = X509.load_cert_string(certificate, X509.FORMAT_DER)
    else:
        return False, "missing certificate"
    if nonce is not None and int(tst.tst_info['nonce']) != int(nonce):
        return False, 'nonce is different or missing'
    # check message imprint with respect to locally computed digest
    message_imprint = tst.tst_info.message_imprint
    if message_imprint.hash_algorithm[0] != get_hash_oid(hashname) or \
        str(message_imprint.hashed_message) != digest:
            return False, 'Message imprint mismatch'
    #
    if not len(signed_data['signerInfos']):
        return False, 'No signature'
    # We validate only one signature
    signer_info = signed_data['signerInfos'][0]
    # check content type
    if tst.content['contentInfo']['contentType'] != rfc3161.id_ct_TSTInfo:
        return False, "Signed content type is wrong: %s != %s" % (
            tst.content['contentInfo']['contentType'], rfc3161.id_ct_TSTInfo)

    # check signed data digest
    content = str(decoder.decode(str(tst.content['contentInfo']['content']),
        asn1Spec=univ.OctetString())[0])
    # if there is authenticated attributes, they must contain the message
    # digest and they are the signed data otherwise the content is the
    # signed data
    if len(signer_info['authenticatedAttributes']):
        authenticated_attributes = signer_info['authenticatedAttributes']
        signer_digest_algorithm = signer_info['digestAlgorithm']['algorithm']
        signer_hash_class = get_hash_class_from_oid(signer_digest_algorithm)
        signer_hash_name = get_hash_from_oid(signer_digest_algorithm)
        content_digest = signer_hash_class(content).digest()
        for authenticated_attribute in authenticated_attributes:
            if authenticated_attribute[0] == id_attribute_messageDigest:
                try:
                    signed_digest = str(decoder.decode(str(authenticated_attribute[1][0]),
                            asn1Spec=univ.OctetString())[0])
                    if signed_digest != content_digest:
                        return False, 'Content digest != signed digest'
                    s = univ.SetOf()
                    for i, x in enumerate(authenticated_attributes):
                        s.setComponentByPosition(i, x)
                    signed_data = encoder.encode(s)
                    break
                except PyAsn1Error:
                    raise
                    pass
        else:
            return False, 'No signed digest'
    else:
        signed_data = content
    # check signature
    signature = signer_info['encryptedDigest']
    pub_key = certificate.get_pubkey()
    pub_key.reset_context(signer_hash_name)
    pub_key.verify_init()
    pub_key.verify_update(signed_data)
    if pub_key.verify_final(str(signature)) != 1:
        return False, 'Bad signature'
    return True, ''
Example #36
0
    def signEncryptTicket(self, kdcRep, encASRepPart, encTicketPart, pacInfos):
        logging.info('Signing/Encrypting final ticket')

        # We changed everything we needed to make us special. Now let's repack and calculate checksums
        validationInfoBlob = pacInfos[PAC_LOGON_INFO]
        validationInfoAlignment = '\x00' * (((len(validationInfoBlob) + 7) / 8 * 8) - len(validationInfoBlob))

        pacClientInfoBlob = pacInfos[PAC_CLIENT_INFO_TYPE]
        pacClientInfoAlignment = '\x00' * (((len(pacClientInfoBlob) + 7) / 8 * 8) - len(pacClientInfoBlob))

        serverChecksum = PAC_SIGNATURE_DATA(pacInfos[PAC_SERVER_CHECKSUM])
        serverChecksumBlob = str(pacInfos[PAC_SERVER_CHECKSUM])
        serverChecksumAlignment = '\x00' * (((len(serverChecksumBlob) + 7) / 8 * 8) - len(serverChecksumBlob))

        privSvrChecksum = PAC_SIGNATURE_DATA(pacInfos[PAC_PRIVSVR_CHECKSUM])
        privSvrChecksumBlob = str(pacInfos[PAC_PRIVSVR_CHECKSUM])
        privSvrChecksumAlignment = '\x00' * (((len(privSvrChecksumBlob) + 7) / 8 * 8) - len(privSvrChecksumBlob))

        # The offset are set from the beginning of the PAC_TYPE
        # [MS-PAC] 2.4 PAC_INFO_BUFFER
        offsetData = 8 + len(str(PAC_INFO_BUFFER())) * 4

        # Let's build the PAC_INFO_BUFFER for each one of the elements
        validationInfoIB = PAC_INFO_BUFFER()
        validationInfoIB['ulType'] = PAC_LOGON_INFO
        validationInfoIB['cbBufferSize'] = len(validationInfoBlob)
        validationInfoIB['Offset'] = offsetData
        offsetData = (offsetData + validationInfoIB['cbBufferSize'] + 7) / 8 * 8

        pacClientInfoIB = PAC_INFO_BUFFER()
        pacClientInfoIB['ulType'] = PAC_CLIENT_INFO_TYPE
        pacClientInfoIB['cbBufferSize'] = len(pacClientInfoBlob)
        pacClientInfoIB['Offset'] = offsetData
        offsetData = (offsetData + pacClientInfoIB['cbBufferSize'] + 7) / 8 * 8

        serverChecksumIB = PAC_INFO_BUFFER()
        serverChecksumIB['ulType'] = PAC_SERVER_CHECKSUM
        serverChecksumIB['cbBufferSize'] = len(serverChecksumBlob)
        serverChecksumIB['Offset'] = offsetData
        offsetData = (offsetData + serverChecksumIB['cbBufferSize'] + 7) / 8 * 8

        privSvrChecksumIB = PAC_INFO_BUFFER()
        privSvrChecksumIB['ulType'] = PAC_PRIVSVR_CHECKSUM
        privSvrChecksumIB['cbBufferSize'] = len(privSvrChecksumBlob)
        privSvrChecksumIB['Offset'] = offsetData
        # offsetData = (offsetData+privSvrChecksumIB['cbBufferSize'] + 7) /8 *8

        # Building the PAC_TYPE as specified in [MS-PAC]
        buffers = str(validationInfoIB) + str(pacClientInfoIB) + str(serverChecksumIB) + str(
            privSvrChecksumIB) + validationInfoBlob + validationInfoAlignment + str(
            pacInfos[PAC_CLIENT_INFO_TYPE]) + pacClientInfoAlignment
        buffersTail = str(serverChecksumBlob) + serverChecksumAlignment + str(privSvrChecksum) + privSvrChecksumAlignment

        pacType = PACTYPE()
        pacType['cBuffers'] = 4
        pacType['Version'] = 0
        pacType['Buffers'] = buffers + buffersTail

        blobToChecksum = str(pacType)

        checkSumFunctionServer = _checksum_table[serverChecksum['SignatureType']]
        if serverChecksum['SignatureType'] == ChecksumTypes.hmac_sha1_96_aes256.value:
            keyServer = Key(Enctype.AES256, unhexlify(self.__options.aesKey))
        elif serverChecksum['SignatureType'] == ChecksumTypes.hmac_sha1_96_aes128.value:
            keyServer = Key(Enctype.AES128, unhexlify(self.__options.aesKey))
        elif serverChecksum['SignatureType'] == ChecksumTypes.hmac_md5.value:
            keyServer = Key(Enctype.RC4, unhexlify(self.__options.nthash))
        else:
            raise Exception('Invalid Server checksum type 0x%x' % serverChecksum['SignatureType'])

        checkSumFunctionPriv = _checksum_table[privSvrChecksum['SignatureType']]
        if privSvrChecksum['SignatureType'] == ChecksumTypes.hmac_sha1_96_aes256.value:
            keyPriv = Key(Enctype.AES256, unhexlify(self.__options.aesKey))
        elif privSvrChecksum['SignatureType'] == ChecksumTypes.hmac_sha1_96_aes128.value:
            keyPriv = Key(Enctype.AES128, unhexlify(self.__options.aesKey))
        elif privSvrChecksum['SignatureType'] == ChecksumTypes.hmac_md5.value:
            keyPriv = Key(Enctype.RC4, unhexlify(self.__options.nthash))
        else:
            raise Exception('Invalid Priv checksum type 0x%x' % serverChecksum['SignatureType'])

        serverChecksum['Signature'] = checkSumFunctionServer.checksum(keyServer, KERB_NON_KERB_CKSUM_SALT, blobToChecksum)
        logging.info('\tPAC_SERVER_CHECKSUM')
        privSvrChecksum['Signature'] = checkSumFunctionPriv.checksum(keyPriv, KERB_NON_KERB_CKSUM_SALT, serverChecksum['Signature'])
        logging.info('\tPAC_PRIVSVR_CHECKSUM')

        buffersTail = str(serverChecksum) + serverChecksumAlignment + str(privSvrChecksum) + privSvrChecksumAlignment
        pacType['Buffers'] = buffers + buffersTail

        authorizationData = AuthorizationData()
        authorizationData[0] = None
        authorizationData[0]['ad-type'] = AuthorizationDataType.AD_WIN2K_PAC.value
        authorizationData[0]['ad-data'] = str(pacType)
        authorizationData = encoder.encode(authorizationData)

        encTicketPart['authorization-data'][0]['ad-data'] = authorizationData

        if logging.getLogger().level == logging.DEBUG:
            logging.debug('Customized EncTicketPart')
            print encTicketPart.prettyPrint()
            print ('\n')

        encodedEncTicketPart = encoder.encode(encTicketPart)

        cipher = _enctype_table[kdcRep['ticket']['enc-part']['etype']]
        if cipher.enctype == EncryptionTypes.aes256_cts_hmac_sha1_96.value:
            key = Key(cipher.enctype, unhexlify(self.__options.aesKey))
        elif cipher.enctype == EncryptionTypes.aes128_cts_hmac_sha1_96.value:
            key = Key(cipher.enctype, unhexlify(self.__options.aesKey))
        elif cipher.enctype == EncryptionTypes.rc4_hmac.value:
            key = Key(cipher.enctype, unhexlify(self.__options.nthash))
        else:
            raise Exception('Unsupported enctype 0x%x' % cipher.enctype)

        # Key Usage 2
        # AS-REP Ticket and TGS-REP Ticket (includes TGS session
        # key or application session key), encrypted with the
        # service key (Section 5.3)
        logging.info('\tEncTicketPart')
        cipherText = cipher.encrypt(key, 2, str(encodedEncTicketPart), None)

        kdcRep['ticket']['enc-part']['cipher'] = cipherText
        kdcRep['ticket']['enc-part']['kvno'] = 2

        # Lastly.. we have to encrypt the kdcRep['enc-part'] part
        # with a key we chose. It actually doesn't really matter since nobody uses it (could it be trash?)
        encodedEncASRepPart = encoder.encode(encASRepPart)

        # Key Usage 3
        # AS-REP encrypted part (includes TGS session key or
        # application session key), encrypted with the client key
        # (Section 5.4.2)
        sessionKey = Key(cipher.enctype, str(encASRepPart['key']['keyvalue']))
        logging.info('\tEncASRepPart')
        cipherText = cipher.encrypt(sessionKey, 3, str(encodedEncASRepPart), None)

        kdcRep['enc-part']['cipher'] = cipherText
        kdcRep['enc-part']['etype'] = cipher.enctype
        kdcRep['enc-part']['kvno'] = 1

        if logging.getLogger().level == logging.DEBUG:
            logging.debug('Final Golden Ticket')
            print kdcRep.prettyPrint()
            print ('\n')

        return encoder.encode(kdcRep), cipher, sessionKey
Example #37
0
issuerCert, _ = decoder.decode(pem.readPemBlocksFromFile(
    sys.stdin,
    ('-----BEGIN CERTIFICATE-----', '-----END CERTIFICATE-----'))[1],
                               asn1Spec=rfc2459.Certificate())
userCert, _ = decoder.decode(pem.readPemBlocksFromFile(
    sys.stdin,
    ('-----BEGIN CERTIFICATE-----', '-----END CERTIFICATE-----'))[1],
                             asn1Spec=rfc2459.Certificate())

# Build OCSP request

ocspReq = mkOcspRequest(issuerCert, userCert)

# Use HTTP POST to get response (see Appendix A of RFC 2560)
# In case you need proxies, set the http_proxy env variable

httpReq = urllib2.Request(ocspUrl, encoder.encode(ocspReq),
                          {'Content-Type': 'application/ocsp-request'})
httpRsp = urllib2.urlopen(httpReq).read()

# Process OCSP response

ocspRsp, _ = decoder.decode(httpRsp, asn1Spec=rfc2560.OCSPResponse())

producedAt, certId, certStatus, thisUpdate = parseOcspResponse(ocspRsp)

print('Certificate ID %s is %s at %s till %s\n' %
      (certId.getComponentByName('serialNumber'), certStatus, producedAt,
       thisUpdate))
    def process_ocsp_response(self, issuer, cert_id, ocsp_response):
        try:
            res = der_decoder.decode(ocsp_response, OCSPResponse())[0]
            if self.test_mode is not None:
                ocsp_load_failure = getenv(
                    "SF_TEST_OCSP_FORCE_BAD_OCSP_RESPONSE")
                if ocsp_load_failure is not None:
                    raise RevocationCheckError("Force fail")
        except Exception:
            raise RevocationCheckError(msg='Invalid OCSP Response',
                                       errno=ER_INVALID_OCSP_RESPONSE)

        if res.getComponentByName('responseStatus') != OCSPResponseStatus(
                'successful'):
            raise RevocationCheckError(msg="Invalid Status: {0}".format(
                res.getComponentByName('response_status')),
                                       errno=ER_INVALID_OCSP_RESPONSE)

        response_bytes = res.getComponentByName('responseBytes')
        basic_ocsp_response = der_decoder.decode(
            response_bytes.getComponentByName('response'),
            BasicOCSPResponse())[0]

        attached_certs = basic_ocsp_response.getComponentByName('certs')
        if self._has_certs_in_ocsp_response(attached_certs):
            logger.debug("Certificate is attached in Basic OCSP Response")
            cert_der = der_encoder.encode(attached_certs[0])
            cert_openssl = load_certificate(FILETYPE_ASN1, cert_der)
            ocsp_cert = self._convert_openssl_to_pyasn1_certificate(
                cert_openssl)

            cur_time = datetime.utcnow().replace(tzinfo=pytz.utc)
            tbs_certificate = ocsp_cert.getComponentByName('tbsCertificate')
            """
            Signature verification should happen before any kind of
            validation
            """

            self.verify_signature(
                ocsp_cert.getComponentByName('signatureAlgorithm'),
                ocsp_cert.getComponentByName('signatureValue'), issuer,
                ocsp_cert.getComponentByName('tbsCertificate'))

            cert_valid, debug_msg = self.check_cert_time_validity(
                cur_time, tbs_certificate)
            if not cert_valid:
                raise RevocationCheckError(msg=debug_msg,
                                           errno=ER_INVALID_OCSP_RESPONSE_CODE)
        else:
            logger.debug("Certificate is NOT attached in Basic OCSP Response. "
                         "Using issuer's certificate")
            ocsp_cert = issuer

        tbs_response_data = basic_ocsp_response.getComponentByName(
            'tbsResponseData')

        logger.debug("Verifying the OCSP response is signed by the issuer.")
        self.verify_signature(
            basic_ocsp_response.getComponentByName('signatureAlgorithm'),
            basic_ocsp_response.getComponentByName('signature'), ocsp_cert,
            tbs_response_data)

        single_response = tbs_response_data.getComponentByName('responses')[0]
        cert_status = single_response.getComponentByName('certStatus')

        if self.test_mode is not None:
            test_cert_status = getenv("SF_TEST_OCSP_CERT_STATUS")
            if test_cert_status == 'revoked':
                cert_status = 'revoked'
            elif test_cert_status == 'unknown':
                cert_status = 'unknown'
            elif test_cert_status == 'good':
                cert_status = 'good'

        try:
            if cert_status.getName() == 'good':
                self._process_good_status(single_response, cert_id,
                                          ocsp_response)
                SnowflakeOCSP.OCSP_CACHE.update_cache(self, cert_id,
                                                      ocsp_response)
            elif cert_status.getName() == 'revoked':
                self._process_revoked_status(single_response, cert_id)
            elif cert_status.getName() == 'unknown':
                self._process_unknown_status(cert_id)
            else:
                debug_msg = "Unknown revocation status was returned. " \
                            "OCSP response may be malformed: {0}. ".format(cert_status)
                raise RevocationCheckError(msg=debug_msg,
                                           errno=ER_INVALID_OCSP_RESPONSE_CODE)
        except RevocationCheckError as op_er:
            if not self.debug_ocsp_failure_url:
                debug_msg = op_er.msg
            else:
                debug_msg = "{0} Consider running curl -o ocsp.der {1}".\
                    format(op_er.msg,
                           self.debug_ocsp_failure_url)
            raise RevocationCheckError(msg=debug_msg, errno=op_er.errno)
 def get_signed_data(self) -> bytes:
     return der_encoder.encode(self.dom)
Example #40
0
def getKerberosTGT(clientName,
                   password,
                   domain,
                   lmhash,
                   nthash,
                   aesKey='',
                   kdcHost=None,
                   requestPAC=True):

    asReq = AS_REQ()

    domain = domain.upper()
    serverName = Principal('krbtgt/%s' % domain,
                           type=constants.PrincipalNameType.NT_PRINCIPAL.value)

    pacRequest = KERB_PA_PAC_REQUEST()
    pacRequest['include-pac'] = requestPAC
    encodedPacRequest = encoder.encode(pacRequest)

    asReq['pvno'] = 5
    asReq['msg-type'] = int(constants.ApplicationTagNumbers.AS_REQ.value)
    asReq['padata'] = None
    asReq['padata'][0] = None
    asReq['padata'][0]['padata-type'] = int(
        constants.PreAuthenticationDataTypes.PA_PAC_REQUEST.value)
    asReq['padata'][0]['padata-value'] = encodedPacRequest

    reqBody = seq_set(asReq, 'req-body')

    opts = list()
    opts.append(constants.KDCOptions.forwardable.value)
    opts.append(constants.KDCOptions.renewable.value)
    opts.append(constants.KDCOptions.proxiable.value)
    reqBody['kdc-options'] = constants.encodeFlags(opts)

    seq_set(reqBody, 'sname', serverName.components_to_asn1)
    seq_set(reqBody, 'cname', clientName.components_to_asn1)

    if domain == '':
        raise Exception('Empty Domain not allowed in Kerberos')

    reqBody['realm'] = domain

    now = datetime.datetime.utcnow() + datetime.timedelta(days=1)
    reqBody['till'] = KerberosTime.to_asn1(now)
    reqBody['rtime'] = KerberosTime.to_asn1(now)
    reqBody['nonce'] = random.getrandbits(31)

    # Yes.. this shouldn't happend but it's inherited from the past
    if aesKey is None:
        aesKey = ''

    if nthash == '':
        # This is still confusing. I thought KDC_ERR_ETYPE_NOSUPP was enough,
        # but I found some systems that accepts all ciphers, and trigger an error
        # when requesting subsequent TGS :(. More research needed.
        # So, in order to support more than one cypher, I'm setting aes first
        # since most of the systems would accept it. If we're lucky and
        # KDC_ERR_ETYPE_NOSUPP is returned, we will later try rc4.
        if aesKey != '':
            if len(aesKey) == 64:
                supportedCiphers = (int(
                    constants.EncryptionTypes.aes256_cts_hmac_sha1_96.value), )
            else:
                supportedCiphers = (int(
                    constants.EncryptionTypes.aes128_cts_hmac_sha1_96.value), )
        else:
            supportedCiphers = (int(
                constants.EncryptionTypes.aes256_cts_hmac_sha1_96.value), )
    else:
        # We have hashes to try, only way is to request RC4 only
        supportedCiphers = (int(constants.EncryptionTypes.rc4_hmac.value), )

    seq_set_iter(reqBody, 'etype', supportedCiphers)

    message = encoder.encode(asReq)

    try:
        r = sendReceive(message, domain, kdcHost)
    except KerberosError as e:
        if e.getErrorCode() == constants.ErrorCodes.KDC_ERR_ETYPE_NOSUPP.value:
            if supportedCiphers[0] in (
                    constants.EncryptionTypes.aes128_cts_hmac_sha1_96.value,
                    constants.EncryptionTypes.aes256_cts_hmac_sha1_96.value
            ) and aesKey is '':
                supportedCiphers = (int(
                    constants.EncryptionTypes.rc4_hmac.value), )
                seq_set_iter(reqBody, 'etype', supportedCiphers)
                message = encoder.encode(asReq)
                r = sendReceive(message, domain, kdcHost)
            else:
                raise
        else:
            raise

    # This should be the PREAUTH_FAILED packet

    asRep = decoder.decode(r, asn1Spec=KRB_ERROR())[0]
    methods = decoder.decode(asRep['e-data'], asn1Spec=METHOD_DATA())[0]
    salt = b''
    encryptionTypesData = dict()
    for method in methods:
        if method[
                'padata-type'] == constants.PreAuthenticationDataTypes.PA_ETYPE_INFO2.value:
            etypes2 = decoder.decode(method['padata-value'],
                                     asn1Spec=ETYPE_INFO2())[0]
            for etype2 in etypes2:
                if etype2['salt'] is None:
                    salt = ''
                else:
                    salt = str(etype2['salt'])
                encryptionTypesData[etype2['etype']] = salt
        elif method[
                'padata-type'] == constants.PreAuthenticationDataTypes.PA_ETYPE_INFO.value:
            etypes = decoder.decode(str(method['padata-value']),
                                    asn1Spec=ETYPE_INFO())[0]
            for etype in etypes:
                if etype['salt'] is None:
                    salt = ''
                else:
                    salt = str(etype['salt'])
                encryptionTypesData[etype['etype']] = salt

    enctype = supportedCiphers[0]

    if enctype not in encryptionTypesData:
        raise Exception('No Encryption Data Available!')

    # Let's build the timestamp
    timeStamp = PA_ENC_TS_ENC()

    now = datetime.datetime.utcnow()
    timeStamp['patimestamp'] = KerberosTime.to_asn1(now)
    timeStamp['pausec'] = now.microsecond

    # Encrypt the shyte
    cipher = _enctype_table[enctype]

    # Pass the hash/aes key :P
    if nthash != '':
        print('here1')
        key = Key(cipher.enctype, nthash)
    elif aesKey != '':
        print('here2')
        key = Key(cipher.enctype, unhexlify(aesKey))
    else:
        print('here3')
        key = cipher.string_to_key(password, encryptionTypesData[enctype],
                                   None)
    encodedTimeStamp = encoder.encode(timeStamp)

    # Key Usage 1
    # AS-REQ PA-ENC-TIMESTAMP padata timestamp, encrypted with the
    # client key (Section 5.2.7.2)
    encriptedTimeStamp = cipher.encrypt(key, 1, encodedTimeStamp, None)

    encryptedData = EncryptedData()
    encryptedData['etype'] = cipher.enctype
    encryptedData['cipher'] = encriptedTimeStamp
    encodedEncryptedData = encoder.encode(encryptedData)

    # Now prepare the new AS_REQ again with the PADATA
    # ToDo: cannot we reuse the previous one?
    asReq = AS_REQ()

    asReq['pvno'] = 5
    asReq['msg-type'] = int(constants.ApplicationTagNumbers.AS_REQ.value)
    asReq['padata'] = None
    asReq['padata'][0] = None
    asReq['padata'][0]['padata-type'] = int(
        constants.PreAuthenticationDataTypes.PA_ENC_TIMESTAMP.value)
    asReq['padata'][0]['padata-value'] = encodedEncryptedData

    asReq['padata'][1] = None
    asReq['padata'][1]['padata-type'] = int(
        constants.PreAuthenticationDataTypes.PA_PAC_REQUEST.value)
    asReq['padata'][1]['padata-value'] = encodedPacRequest

    reqBody = seq_set(asReq, 'req-body')

    opts = list()
    opts.append(constants.KDCOptions.forwardable.value)
    opts.append(constants.KDCOptions.renewable.value)
    opts.append(constants.KDCOptions.proxiable.value)
    reqBody['kdc-options'] = constants.encodeFlags(opts)

    seq_set(reqBody, 'sname', serverName.components_to_asn1)
    seq_set(reqBody, 'cname', clientName.components_to_asn1)

    reqBody['realm'] = domain

    now = datetime.datetime.utcnow() + datetime.timedelta(days=1)
    reqBody['till'] = KerberosTime.to_asn1(now)
    reqBody['rtime'] = KerberosTime.to_asn1(now)
    reqBody['nonce'] = random.getrandbits(31)

    seq_set_iter(reqBody, 'etype', ((int(cipher.enctype), )))

    try:
        tgt = sendReceive(encoder.encode(asReq), domain, kdcHost)
    except Exception as e:
        if str(e).find('KDC_ERR_ETYPE_NOSUPP') >= 0:
            if lmhash is '' and nthash is '' and (aesKey is ''
                                                  or aesKey is None):
                from impacket.ntlm import compute_lmhash, compute_nthash
                lmhash = compute_lmhash(password)
                nthash = compute_nthash(password)
                return getKerberosTGT(clientName, password, domain, lmhash,
                                      nthash, aesKey, kdcHost, requestPAC)
        raise

    # So, we have the TGT, now extract the new session key and finish

    asRep = decoder.decode(tgt, asn1Spec=AS_REP())[0]
    cipherText = asRep['enc-part']['cipher']

    # Key Usage 3
    # AS-REP encrypted part (includes TGS session key or
    # application session key), encrypted with the client key
    # (Section 5.4.2)
    from .crypto import bytify
    print('cypherText: {}'.format(repr(str(cipherText))))
    plainText = cipher.decrypt(key, 3, bytes(cipherText))
    encASRepPart = decoder.decode(plainText, asn1Spec=EncASRepPart())[0]

    # Get the session key and the ticket
    # We're assuming the cipher for this session key is the same
    # as the one we used before.
    # ToDo: change this
    sessionKey = Key(cipher.enctype, bytes(encASRepPart['key']['keyvalue']))

    # ToDo: Check Nonces!

    return tgt, cipher, key, sessionKey
    def fromTGT(self, tgt, oldSessionKey, sessionKey):
        self.headers = []
        header = Header()
        header['tag'] = 1
        header['taglen'] = 8
        header['tagdata'] = '\xff\xff\xff\xff\x00\x00\x00\x00'
        self.headers.append(header)

        decodedTGT = decoder.decode(tgt, asn1Spec=AS_REP())[0]

        tmpPrincipal = types.Principal()
        tmpPrincipal.from_asn1(decodedTGT, 'crealm', 'cname')
        self.principal = Principal()
        self.principal.fromPrincipal(tmpPrincipal)

        # Now let's add the credential
        cipherText = decodedTGT['enc-part']['cipher']

        cipher = crypto._enctype_table[decodedTGT['enc-part']['etype']]

        # Key Usage 3
        # AS-REP encrypted part (includes TGS session key or
        # application session key), encrypted with the client key
        # (Section 5.4.2)
        plainText = cipher.decrypt(oldSessionKey, 3, str(cipherText))

        encASRepPart = decoder.decode(plainText, asn1Spec=EncASRepPart())[0]

        credential = Credential()
        server = types.Principal()
        server.from_asn1(encASRepPart, 'srealm', 'sname')
        tmpServer = Principal()
        tmpServer.fromPrincipal(server)

        credential['client'] = self.principal
        credential['server'] = tmpServer
        credential['is_skey'] = 0

        credential['key'] = KeyBlock()
        credential['key']['keytype'] = int(encASRepPart['key']['keytype'])
        credential['key']['keyvalue'] = str(encASRepPart['key']['keyvalue'])
        credential['key']['keylen'] = len(credential['key']['keyvalue'])

        credential['time'] = Times()
        credential['time']['authtime'] = self.toTimeStamp(
            types.KerberosTime.from_asn1(encASRepPart['authtime']))
        credential['time']['starttime'] = self.toTimeStamp(
            types.KerberosTime.from_asn1(encASRepPart['starttime']))
        credential['time']['endtime'] = self.toTimeStamp(
            types.KerberosTime.from_asn1(encASRepPart['endtime']))
        credential['time']['renew_till'] = self.toTimeStamp(
            types.KerberosTime.from_asn1(encASRepPart['renew-till']))

        flags = self.reverseFlags(encASRepPart['flags'])
        credential['tktflags'] = flags

        credential['num_address'] = 0
        credential.ticket = CountedOctetString()
        credential.ticket['data'] = encoder.encode(decodedTGT['ticket'].clone(
            tagSet=Ticket.tagSet, cloneValueFlag=True))
        credential.ticket['length'] = len(credential.ticket['data'])
        credential.secondTicket = CountedOctetString()
        credential.secondTicket['data'] = ''
        credential.secondTicket['length'] = 0
        self.credentials.append(credential)
Example #42
0
def getKerberosType1(username,
                     password,
                     domain,
                     lmhash,
                     nthash,
                     aesKey='',
                     TGT=None,
                     TGS=None,
                     targetName='',
                     kdcHost=None,
                     useCache=True):
    if TGT is None and TGS is None:
        if useCache is True:
            try:
                ccache = CCache.loadFile(os.getenv('KRB5CCNAME'))
            except Exception as e:
                # No cache present
                pass
            else:
                # retrieve user and domain information from CCache file if needed
                if username == '' and len(ccache.principal.components) > 0:
                    username = ccache.principal.components[0]['data']
                if domain == '':
                    domain = ccache.principal.realm['data']
                LOG.debug("Using Kerberos Cache: %s" % os.getenv('KRB5CCNAME'))
                principal = 'host/%s@%s' % (targetName.upper(), domain.upper())
                creds = ccache.getCredential(principal)
                if creds is None:
                    # Let's try for the TGT and go from there
                    principal = 'krbtgt/%s@%s' % (domain.upper(),
                                                  domain.upper())
                    creds = ccache.getCredential(principal)
                    if creds is not None:
                        TGT = creds.toTGT()
                        LOG.debug('Using TGT from cache')
                    else:
                        LOG.debug("No valid credentials found in cache. ")
                else:
                    TGS = creds.toTGS()

    # First of all, we need to get a TGT for the user
    userName = Principal(username,
                         type=constants.PrincipalNameType.NT_PRINCIPAL.value)
    while True:
        if TGT is None:
            if TGS is None:
                try:
                    tgt, cipher, oldSessionKey, sessionKey = getKerberosTGT(
                        userName, password, domain, lmhash, nthash, aesKey,
                        kdcHost)
                except KerberosError as e:
                    if e.getErrorCode(
                    ) == constants.ErrorCodes.KDC_ERR_ETYPE_NOSUPP.value:
                        # We might face this if the target does not support AES
                        # So, if that's the case we'll force using RC4 by converting
                        # the password to lm/nt hashes and hope for the best. If that's already
                        # done, byebye.
                        if lmhash is '' and nthash is '' and (
                                aesKey is '' or aesKey is None
                        ) and TGT is None and TGS is None:
                            from impacket.ntlm import compute_lmhash, compute_nthash
                            LOG.debug(
                                'Got KDC_ERR_ETYPE_NOSUPP, fallback to RC4')
                            lmhash = compute_lmhash(password)
                            nthash = compute_nthash(password)
                            continue
                        else:
                            raise
                    else:
                        raise

        else:
            tgt = TGT['KDC_REP']
            cipher = TGT['cipher']
            sessionKey = TGT['sessionKey']

        # Now that we have the TGT, we should ask for a TGS for cifs

        if TGS is None:
            serverName = Principal(
                'host/%s' % targetName,
                type=constants.PrincipalNameType.NT_SRV_INST.value)
            try:
                tgs, cipher, oldSessionKey, sessionKey = getKerberosTGS(
                    serverName, domain, kdcHost, tgt, cipher, sessionKey)
            except KerberosError as e:
                if e.getErrorCode(
                ) == constants.ErrorCodes.KDC_ERR_ETYPE_NOSUPP.value:
                    # We might face this if the target does not support AES
                    # So, if that's the case we'll force using RC4 by converting
                    # the password to lm/nt hashes and hope for the best. If that's already
                    # done, byebye.
                    if lmhash is '' and nthash is '' and (
                            aesKey is ''
                            or aesKey is None) and TGT is None and TGS is None:
                        from impacket.ntlm import compute_lmhash, compute_nthash
                        LOG.debug('Got KDC_ERR_ETYPE_NOSUPP, fallback to RC4')
                        lmhash = compute_lmhash(password)
                        nthash = compute_nthash(password)
                    else:
                        raise
                else:
                    raise
            else:
                break
        else:
            tgs = TGS['KDC_REP']
            cipher = TGS['cipher']
            sessionKey = TGS['sessionKey']
            break

    # Let's build a NegTokenInit with a Kerberos REQ_AP

    blob = SPNEGO_NegTokenInit()

    # Kerberos
    blob['MechTypes'] = [TypesMech['MS KRB5 - Microsoft Kerberos 5']]

    # Let's extract the ticket from the TGS
    tgs = decoder.decode(tgs, asn1Spec=TGS_REP())[0]
    ticket = Ticket()
    ticket.from_asn1(tgs['ticket'])

    # Now let's build the AP_REQ
    apReq = AP_REQ()
    apReq['pvno'] = 5
    apReq['msg-type'] = int(constants.ApplicationTagNumbers.AP_REQ.value)

    opts = list()
    opts.append(constants.APOptions.mutual_required.value)
    apReq['ap-options'] = constants.encodeFlags(opts)
    seq_set(apReq, 'ticket', ticket.to_asn1)

    authenticator = Authenticator()
    authenticator['authenticator-vno'] = 5
    authenticator['crealm'] = domain
    seq_set(authenticator, 'cname', userName.components_to_asn1)
    now = datetime.datetime.utcnow()

    authenticator['cusec'] = now.microsecond
    authenticator['ctime'] = KerberosTime.to_asn1(now)

    authenticator['cksum'] = None
    authenticator['cksum']['cksumtype'] = 0x8003

    chkField = CheckSumField()
    chkField['Lgth'] = 16

    chkField[
        'Flags'] = GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG | GSS_C_SEQUENCE_FLAG | GSS_C_REPLAY_FLAG | GSS_C_MUTUAL_FLAG | GSS_C_DCE_STYLE
    #chkField['Flags'] = GSS_C_INTEG_FLAG | GSS_C_SEQUENCE_FLAG | GSS_C_REPLAY_FLAG | GSS_C_MUTUAL_FLAG | GSS_C_DCE_STYLE
    authenticator['cksum']['checksum'] = chkField.getData()
    authenticator['seq-number'] = 0
    encodedAuthenticator = encoder.encode(authenticator)

    # Key Usage 11
    # AP-REQ Authenticator (includes application authenticator
    # subkey), encrypted with the application session key
    # (Section 5.5.1)
    encryptedEncodedAuthenticator = cipher.encrypt(sessionKey, 11,
                                                   encodedAuthenticator, None)

    apReq['authenticator'] = None
    apReq['authenticator']['etype'] = cipher.enctype
    apReq['authenticator']['cipher'] = encryptedEncodedAuthenticator

    blob['MechToken'] = encoder.encode(apReq)

    return cipher, sessionKey, blob.getData()
Example #43
0
def getKerberosTGS(serverName, domain, kdcHost, tgt, cipher, sessionKey):

    # Decode the TGT
    try:
        decodedTGT = decoder.decode(tgt, asn1Spec=AS_REP())[0]
    except:
        decodedTGT = decoder.decode(tgt, asn1Spec=TGS_REP())[0]

    domain = domain.upper()
    # Extract the ticket from the TGT
    ticket = Ticket()
    ticket.from_asn1(decodedTGT['ticket'])

    apReq = AP_REQ()
    apReq['pvno'] = 5
    apReq['msg-type'] = int(constants.ApplicationTagNumbers.AP_REQ.value)

    opts = list()
    apReq['ap-options'] = constants.encodeFlags(opts)
    seq_set(apReq, 'ticket', ticket.to_asn1)

    authenticator = Authenticator()
    authenticator['authenticator-vno'] = 5
    authenticator['crealm'] = str(decodedTGT['crealm'])

    clientName = Principal()
    clientName.from_asn1(decodedTGT, 'crealm', 'cname')

    seq_set(authenticator, 'cname', clientName.components_to_asn1)

    now = datetime.datetime.utcnow()
    authenticator['cusec'] = now.microsecond
    authenticator['ctime'] = KerberosTime.to_asn1(now)

    encodedAuthenticator = encoder.encode(authenticator)

    # Key Usage 7
    # TGS-REQ PA-TGS-REQ padata AP-REQ Authenticator (includes
    # TGS authenticator subkey), encrypted with the TGS session
    # key (Section 5.5.1)
    encryptedEncodedAuthenticator = cipher.encrypt(sessionKey, 7,
                                                   encodedAuthenticator, None)

    apReq['authenticator'] = None
    apReq['authenticator']['etype'] = cipher.enctype
    apReq['authenticator']['cipher'] = encryptedEncodedAuthenticator

    encodedApReq = encoder.encode(apReq)

    tgsReq = TGS_REQ()

    tgsReq['pvno'] = 5
    tgsReq['msg-type'] = int(constants.ApplicationTagNumbers.TGS_REQ.value)
    tgsReq['padata'] = None
    tgsReq['padata'][0] = None
    tgsReq['padata'][0]['padata-type'] = int(
        constants.PreAuthenticationDataTypes.PA_TGS_REQ.value)
    tgsReq['padata'][0]['padata-value'] = encodedApReq

    reqBody = seq_set(tgsReq, 'req-body')

    opts = list()
    opts.append(constants.KDCOptions.forwardable.value)
    opts.append(constants.KDCOptions.renewable.value)
    opts.append(constants.KDCOptions.renewable_ok.value)
    opts.append(constants.KDCOptions.canonicalize.value)

    reqBody['kdc-options'] = constants.encodeFlags(opts)
    seq_set(reqBody, 'sname', serverName.components_to_asn1)
    reqBody['realm'] = domain

    now = datetime.datetime.utcnow() + datetime.timedelta(days=1)

    reqBody['till'] = KerberosTime.to_asn1(now)
    reqBody['nonce'] = random.getrandbits(31)
    seq_set_iter(reqBody, 'etype',
                 (int(constants.EncryptionTypes.rc4_hmac.value),
                  int(constants.EncryptionTypes.des3_cbc_sha1_kd.value),
                  int(cipher.enctype)))

    message = encoder.encode(tgsReq)

    r = sendReceive(message, domain, kdcHost)

    # Get the session key

    tgs = decoder.decode(r, asn1Spec=TGS_REP())[0]

    cipherText = tgs['enc-part']['cipher']

    # Key Usage 8
    # TGS-REP encrypted part (includes application session
    # key), encrypted with the TGS session key (Section 5.4.2)
    plainText = cipher.decrypt(sessionKey, 8, str(cipherText))

    encTGSRepPart = decoder.decode(plainText, asn1Spec=EncTGSRepPart())[0]

    newSessionKey = Key(encTGSRepPart['key']['keytype'],
                        str(encTGSRepPart['key']['keyvalue']))
    # Creating new cipher based on received keytype
    cipher = _enctype_table[encTGSRepPart['key']['keytype']]

    # Check we've got what we asked for
    res = decoder.decode(r, asn1Spec=TGS_REP())[0]
    spn = Principal()
    spn.from_asn1(res['ticket'], 'realm', 'sname')

    if spn.components[0] == serverName.components[0]:
        # Yes.. bye bye
        return r, cipher, sessionKey, newSessionKey
    else:
        # Let's extract the Ticket, change the domain and keep asking
        domain = spn.components[1]
        return getKerberosTGS(serverName, domain, kdcHost, r, cipher,
                              newSessionKey)

    return r, cipher, sessionKey, newSessionKey
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())        
Example #45
0
    def doS4U(self, tgt, cipher, oldSessionKey, sessionKey, kdcHost):
        decodedTGT = decoder.decode(tgt, asn1Spec=AS_REP())[0]

        # Extract the ticket from the TGT
        ticket = Ticket()
        ticket.from_asn1(decodedTGT['ticket'])

        apReq = AP_REQ()
        apReq['pvno'] = 5
        apReq['msg-type'] = int(constants.ApplicationTagNumbers.AP_REQ.value)

        opts = list()
        apReq['ap-options'] = constants.encodeFlags(opts)
        seq_set(apReq, 'ticket', ticket.to_asn1)

        authenticator = Authenticator()
        authenticator['authenticator-vno'] = 5
        authenticator['crealm'] = str(decodedTGT['crealm'])

        clientName = Principal()
        clientName.from_asn1(decodedTGT, 'crealm', 'cname')

        seq_set(authenticator, 'cname', clientName.components_to_asn1)

        now = datetime.datetime.utcnow()
        authenticator['cusec'] = now.microsecond
        authenticator['ctime'] = KerberosTime.to_asn1(now)

        if logging.getLogger().level == logging.DEBUG:
            logging.debug('AUTHENTICATOR')
            print(authenticator.prettyPrint())
            print('\n')

        encodedAuthenticator = encoder.encode(authenticator)

        # Key Usage 7
        # TGS-REQ PA-TGS-REQ padata AP-REQ Authenticator (includes
        # TGS authenticator subkey), encrypted with the TGS session
        # key (Section 5.5.1)
        encryptedEncodedAuthenticator = cipher.encrypt(sessionKey, 7,
                                                       encodedAuthenticator,
                                                       None)

        apReq['authenticator'] = noValue
        apReq['authenticator']['etype'] = cipher.enctype
        apReq['authenticator']['cipher'] = encryptedEncodedAuthenticator

        encodedApReq = encoder.encode(apReq)

        tgsReq = TGS_REQ()

        tgsReq['pvno'] = 5
        tgsReq['msg-type'] = int(constants.ApplicationTagNumbers.TGS_REQ.value)

        tgsReq['padata'] = noValue
        tgsReq['padata'][0] = noValue
        tgsReq['padata'][0]['padata-type'] = int(
            constants.PreAuthenticationDataTypes.PA_TGS_REQ.value)
        tgsReq['padata'][0]['padata-value'] = encodedApReq

        # In the S4U2self KRB_TGS_REQ/KRB_TGS_REP protocol extension, a service
        # requests a service ticket to itself on behalf of a user. The user is
        # identified to the KDC by the user's name and realm.
        clientName = Principal(
            self.__options.impersonate,
            type=constants.PrincipalNameType.NT_PRINCIPAL.value)

        S4UByteArray = struct.pack(
            '<I', constants.PrincipalNameType.NT_PRINCIPAL.value)
        S4UByteArray += b(self.__options.impersonate) + b(
            self.__domain) + b'Kerberos'

        if logging.getLogger().level == logging.DEBUG:
            logging.debug('S4UByteArray')
            hexdump(S4UByteArray)

        # Finally cksum is computed by calling the KERB_CHECKSUM_HMAC_MD5 hash
        # with the following three parameters: the session key of the TGT of
        # the service performing the S4U2Self request, the message type value
        # of 17, and the byte array S4UByteArray.
        checkSum = _HMACMD5.checksum(sessionKey, 17, S4UByteArray)

        if logging.getLogger().level == logging.DEBUG:
            logging.debug('CheckSum')
            hexdump(checkSum)

        paForUserEnc = PA_FOR_USER_ENC()
        seq_set(paForUserEnc, 'userName', clientName.components_to_asn1)
        paForUserEnc['userRealm'] = self.__domain
        paForUserEnc['cksum'] = noValue
        paForUserEnc['cksum']['cksumtype'] = int(
            constants.ChecksumTypes.hmac_md5.value)
        paForUserEnc['cksum']['checksum'] = checkSum
        paForUserEnc['auth-package'] = 'Kerberos'

        if logging.getLogger().level == logging.DEBUG:
            logging.debug('PA_FOR_USER_ENC')
            print(paForUserEnc.prettyPrint())

        encodedPaForUserEnc = encoder.encode(paForUserEnc)

        tgsReq['padata'][1] = noValue
        tgsReq['padata'][1]['padata-type'] = int(
            constants.PreAuthenticationDataTypes.PA_FOR_USER.value)
        tgsReq['padata'][1]['padata-value'] = encodedPaForUserEnc

        reqBody = seq_set(tgsReq, 'req-body')

        opts = list()
        opts.append(constants.KDCOptions.forwardable.value)
        opts.append(constants.KDCOptions.renewable.value)
        opts.append(constants.KDCOptions.canonicalize.value)

        reqBody['kdc-options'] = constants.encodeFlags(opts)

        serverName = Principal(
            self.__user, type=constants.PrincipalNameType.NT_UNKNOWN.value)

        seq_set(reqBody, 'sname', serverName.components_to_asn1)
        reqBody['realm'] = str(decodedTGT['crealm'])

        now = datetime.datetime.utcnow() + datetime.timedelta(days=1)

        reqBody['till'] = KerberosTime.to_asn1(now)
        reqBody['nonce'] = random.getrandbits(31)
        seq_set_iter(reqBody, 'etype', (int(
            cipher.enctype), int(constants.EncryptionTypes.rc4_hmac.value)))

        if logging.getLogger().level == logging.DEBUG:
            logging.debug('Final TGS')
            print(tgsReq.prettyPrint())

        logging.info('\tRequesting S4U2self')
        message = encoder.encode(tgsReq)

        r = sendReceive(message, self.__domain, kdcHost)

        tgs = decoder.decode(r, asn1Spec=TGS_REP())[0]

        if logging.getLogger().level == logging.DEBUG:
            logging.debug('TGS_REP')
            print(tgs.prettyPrint())

        ################################################################################
        # Up until here was all the S4USelf stuff. Now let's start with S4U2Proxy
        # So here I have a ST for me.. I now want a ST for another service
        # Extract the ticket from the TGT
        ticketTGT = Ticket()
        ticketTGT.from_asn1(decodedTGT['ticket'])

        ticket = Ticket()
        ticket.from_asn1(tgs['ticket'])

        apReq = AP_REQ()
        apReq['pvno'] = 5
        apReq['msg-type'] = int(constants.ApplicationTagNumbers.AP_REQ.value)

        opts = list()
        apReq['ap-options'] = constants.encodeFlags(opts)
        seq_set(apReq, 'ticket', ticketTGT.to_asn1)

        authenticator = Authenticator()
        authenticator['authenticator-vno'] = 5
        authenticator['crealm'] = str(decodedTGT['crealm'])

        clientName = Principal()
        clientName.from_asn1(decodedTGT, 'crealm', 'cname')

        seq_set(authenticator, 'cname', clientName.components_to_asn1)

        now = datetime.datetime.utcnow()
        authenticator['cusec'] = now.microsecond
        authenticator['ctime'] = KerberosTime.to_asn1(now)

        encodedAuthenticator = encoder.encode(authenticator)

        # Key Usage 7
        # TGS-REQ PA-TGS-REQ padata AP-REQ Authenticator (includes
        # TGS authenticator subkey), encrypted with the TGS session
        # key (Section 5.5.1)
        encryptedEncodedAuthenticator = cipher.encrypt(sessionKey, 7,
                                                       encodedAuthenticator,
                                                       None)

        apReq['authenticator'] = noValue
        apReq['authenticator']['etype'] = cipher.enctype
        apReq['authenticator']['cipher'] = encryptedEncodedAuthenticator

        encodedApReq = encoder.encode(apReq)

        tgsReq = TGS_REQ()

        tgsReq['pvno'] = 5
        tgsReq['msg-type'] = int(constants.ApplicationTagNumbers.TGS_REQ.value)
        tgsReq['padata'] = noValue
        tgsReq['padata'][0] = noValue
        tgsReq['padata'][0]['padata-type'] = int(
            constants.PreAuthenticationDataTypes.PA_TGS_REQ.value)
        tgsReq['padata'][0]['padata-value'] = encodedApReq

        # Add resource-based constrained delegation support
        paPacOptions = PA_PAC_OPTIONS()
        paPacOptions['flags'] = constants.encodeFlags(
            (constants.PAPacOptions.resource_based_constrained_delegation.
             value, ))

        tgsReq['padata'][1] = noValue
        tgsReq['padata'][1][
            'padata-type'] = constants.PreAuthenticationDataTypes.PA_PAC_OPTIONS.value
        tgsReq['padata'][1]['padata-value'] = encoder.encode(paPacOptions)

        reqBody = seq_set(tgsReq, 'req-body')

        opts = list()
        # This specified we're doing S4U
        opts.append(constants.KDCOptions.cname_in_addl_tkt.value)
        opts.append(constants.KDCOptions.canonicalize.value)
        opts.append(constants.KDCOptions.forwardable.value)
        opts.append(constants.KDCOptions.renewable.value)

        reqBody['kdc-options'] = constants.encodeFlags(opts)
        service2 = Principal(
            self.__options.spn,
            type=constants.PrincipalNameType.NT_SRV_INST.value)
        seq_set(reqBody, 'sname', service2.components_to_asn1)
        reqBody['realm'] = self.__domain

        myTicket = ticket.to_asn1(TicketAsn1())
        seq_set_iter(reqBody, 'additional-tickets', (myTicket, ))

        now = datetime.datetime.utcnow() + datetime.timedelta(days=1)

        reqBody['till'] = KerberosTime.to_asn1(now)
        reqBody['nonce'] = random.getrandbits(31)
        seq_set_iter(reqBody, 'etype',
                     (int(constants.EncryptionTypes.rc4_hmac.value),
                      int(constants.EncryptionTypes.des3_cbc_sha1_kd.value),
                      int(constants.EncryptionTypes.des_cbc_md5.value),
                      int(cipher.enctype)))
        message = encoder.encode(tgsReq)

        logging.info('\tRequesting S4U2Proxy')
        r = sendReceive(message, self.__domain, kdcHost)

        tgs = decoder.decode(r, asn1Spec=TGS_REP())[0]

        cipherText = tgs['enc-part']['cipher']

        # Key Usage 8
        # TGS-REP encrypted part (includes application session
        # key), encrypted with the TGS session key (Section 5.4.2)
        plainText = cipher.decrypt(sessionKey, 8, cipherText)

        encTGSRepPart = decoder.decode(plainText, asn1Spec=EncTGSRepPart())[0]

        newSessionKey = Key(encTGSRepPart['key']['keytype'],
                            encTGSRepPart['key']['keyvalue'])

        # Creating new cipher based on received keytype
        cipher = _enctype_table[encTGSRepPart['key']['keytype']]

        return r, cipher, sessionKey, newSessionKey
Example #46
0
class RemoteTimestamper(object):
    def __init__(self, url, certificate=None, capath=None, cafile=None, username=None, password=None, hashname=None, include_tsa_certificate=False, timeout=10):
        self.url = url
        self.certificate = certificate
        self.capath = capath
        self.cafile = cafile
        self.username = username
        self.password = password
        self.hashname = hashname or 'sha1'
        self.include_tsa_certificate = include_tsa_certificate
        self.timeout = timeout

    def check_response(self, response, digest, nonce=None):
        '''
           Check validity of a TimeStampResponse
        '''
        tst = response.time_stamp_token
        return self.check(tst, digest=digest, nonce=nonce)

    def check(self, tst, data=None, digest=None, nonce=None):
        return check_timestamp(tst, digest=digest, data=data, nonce=nonce,
                certificate=self.certificate, hashname=self.hashname)

    def timestamp(self, data=None, digest=None, include_tsa_certificate=None, nonce=None):
        return self(data=data, digest=digest,
                include_tsa_certificate=include_tsa_certificate, nonce=nonce)

    def __call__(self, data=None, digest=None, include_tsa_certificate=None, nonce=None):
        algorithm_identifier = rfc2459.AlgorithmIdentifier()
        algorithm_identifier.setComponentByPosition(0, get_hash_oid(self.hashname))
        message_imprint = rfc3161.MessageImprint()
        message_imprint.setComponentByPosition(0, algorithm_identifier)
        hashobj = hashlib.new(self.hashname)
        if data:
            hashobj.update(data)
            digest = hashobj.digest()
        elif digest:
            assert len(digest) == hashobj.digest_size, 'digest length is wrong'
        else:
            raise ValueError('You must pass some data to digest, or the digest')
        message_imprint.setComponentByPosition(1, digest)
        request = rfc3161.TimeStampReq()
        request.setComponentByPosition(0, 'v1')
        request.setComponentByPosition(1, message_imprint)
        if nonce is not None:
            request.setComponentByPosition(3, int(nonce))
        request.setComponentByPosition(4, include_tsa_certificate if include_tsa_certificate is not None else self.include_tsa_certificate)
        binary_request = encoder.encode(request)
        headers = { 'Content-Type': 'application/timestamp-query' }
        if self.username != None:
            base64string = base64.standard_b64encode('%s:%s' % (self.username, self.password))
            headers['Authorization'] = "Basic %s" % base64string
        try:
            response = requests.post(self.url, data=binary_request,
                    timeout=self.timeout, headers=headers)
        except request.RequestException, e:
            raise TimestampingError('Unable to send the request to %r' % self.url, e)
        tst_response, substrate = decoder.decode(response.content, asn1Spec=rfc3161.TimeStampResp())
        if substrate:
            return False, 'Extra data returned'
        result, message = self.check_response(tst_response, digest, nonce=nonce)
        if result:
            return encoder.encode(tst_response.time_stamp_token), ''
        else:
            return False, message
def get_key(cert):
    # get subjectPublicKey from certificate
    # SubjectPublicKeyInfo->subjectPublicKey
    subjectPublicKey = encoder.encode(decoder.decode(cert)[0][0][6][1])
    return subjectPublicKey
Example #48
0
    def createBasicTicket(self):
        if self.__options.request is True:
            logging.info('Requesting TGT to target domain to use as basis')
            if self.__options.hashes is not None:
                lmhash, nthash = self.__options.hashes.split(':')
            else:
                lmhash = ''
                nthash = ''
            userName = Principal(self.__options.user, type=PrincipalNameType.NT_PRINCIPAL.value)
            tgt, cipher, oldSessionKey, sessionKey = getKerberosTGT(userName, self.__password, self.__domain,
                                                                    lmhash, nthash, None,
                                                                    self.__options.dc_ip)

            kdcRep = decoder.decode(tgt, asn1Spec=AS_REP())[0]

            # Let's check we have all the neccesary data based on the ciphers used. Boring checks
            ticketCipher = int(kdcRep['ticket']['enc-part']['etype'])
            encPartCipher = int(kdcRep['enc-part']['etype'])

            if (ticketCipher == EncryptionTypes.rc4_hmac.value or encPartCipher == EncryptionTypes.rc4_hmac.value) and \
                            self.__options.nthash is None:
                logging.critical('rc4_hmac is used in this ticket and you haven\'t specified the -nthash parameter. Can\'t continue ( or try running again w/o the -request option)')
                return None, None

            if (ticketCipher == EncryptionTypes.aes128_cts_hmac_sha1_96.value or encPartCipher == EncryptionTypes.aes128_cts_hmac_sha1_96.value) and \
                            self.__options.aesKey is None:
                logging.critical(
                    'aes128_cts_hmac_sha1_96 is used in this ticket and you haven\'t specified the -aesKey parameter. Can\'t continue (or try running again w/o the -request option)')
                return None, None

            if (ticketCipher == EncryptionTypes.aes128_cts_hmac_sha1_96.value or encPartCipher == EncryptionTypes.aes128_cts_hmac_sha1_96.value) and \
                                self.__options.aesKey is not None and len(self.__options.aesKey) > 32:
                logging.critical(
                    'aes128_cts_hmac_sha1_96 is used in this ticket and the -aesKey you specified is not aes128. Can\'t continue (or try running again w/o the -request option)')
                return None, None

            if ( ticketCipher == EncryptionTypes.aes256_cts_hmac_sha1_96.value or encPartCipher == EncryptionTypes.aes256_cts_hmac_sha1_96.value) and \
                            self.__options.aesKey is None:
                logging.critical(
                    'aes256_cts_hmac_sha1_96 is used in this ticket and you haven\'t specified the -aesKey parameter. Can\'t continue (or try running again w/o the -request option)')
                return None, None

            if ( ticketCipher == EncryptionTypes.aes256_cts_hmac_sha1_96.value or encPartCipher == EncryptionTypes.aes256_cts_hmac_sha1_96.value) and \
                                 self.__options.aesKey is not None and len(self.__options.aesKey) < 64:
                logging.critical(
                    'aes256_cts_hmac_sha1_96 is used in this ticket and the -aesKey you specified is not aes256. Can\'t continue')
                return None, None
            kdcRep['cname']['name-type'] = PrincipalNameType.NT_PRINCIPAL.value
            kdcRep['cname']['name-string'] = None
            kdcRep['cname']['name-string'][0] = self.__target

        else:
            logging.info('Creating basic skeleton ticket and PAC Infos')
            kdcRep = AS_REP()
            kdcRep['pvno'] = 5
            kdcRep['msg-type'] = ApplicationTagNumbers.AS_REP.value
            if self.__options.nthash is None:
                kdcRep['padata'] = None
                kdcRep['padata'][0] = None
                kdcRep['padata'][0]['padata-type'] = PreAuthenticationDataTypes.PA_ETYPE_INFO2.value

                etype2 = ETYPE_INFO2()
                etype2[0] = None
                if len(self.__options.aesKey) == 64:
                    etype2[0]['etype'] = EncryptionTypes.aes256_cts_hmac_sha1_96.value
                else:
                    etype2[0]['etype'] = EncryptionTypes.aes128_cts_hmac_sha1_96.value
                etype2[0]['salt'] = '%s%s' % (self.__domain.upper(), self.__target)
                encodedEtype2 = encoder.encode(etype2)

                kdcRep['padata'][0]['padata-value'] = encodedEtype2

            kdcRep['crealm'] = self.__domain.upper()
            kdcRep['cname'] = None
            kdcRep['cname']['name-type'] = PrincipalNameType.NT_PRINCIPAL.value
            kdcRep['cname']['name-string'] = None
            kdcRep['cname']['name-string'][0] = self.__target

            kdcRep['ticket'] = None
            kdcRep['ticket']['tkt-vno'] = ProtocolVersionNumber.pvno.value
            kdcRep['ticket']['realm'] = self.__domain.upper()
            kdcRep['ticket']['sname'] = None
            kdcRep['ticket']['sname']['name-type'] = PrincipalNameType.NT_PRINCIPAL.value
            kdcRep['ticket']['sname']['name-string'] = None
            kdcRep['ticket']['sname']['name-string'][0] = 'krbtgt'
            kdcRep['ticket']['sname']['name-string'][1] = self.__domain.upper()

            kdcRep['ticket']['enc-part'] = None
            kdcRep['ticket']['enc-part']['kvno'] = 2
            kdcRep['enc-part'] = None
            if self.__options.nthash is None:
                if len(self.__options.aesKey) == 64:
                    kdcRep['ticket']['enc-part']['etype'] = EncryptionTypes.aes256_cts_hmac_sha1_96.value
                    kdcRep['enc-part']['etype'] = EncryptionTypes.aes256_cts_hmac_sha1_96.value
                else:
                    kdcRep['ticket']['enc-part']['etype'] = EncryptionTypes.aes128_cts_hmac_sha1_96.value
                    kdcRep['enc-part']['etype'] = EncryptionTypes.aes128_cts_hmac_sha1_96.value
            else:
                kdcRep['ticket']['enc-part']['etype'] = EncryptionTypes.rc4_hmac.value
                kdcRep['enc-part']['etype'] = EncryptionTypes.rc4_hmac.value

            kdcRep['enc-part']['kvno'] = 2
            kdcRep['enc-part']['cipher'] = None

        pacInfos = self.createBasicPac(kdcRep)

        return kdcRep, pacInfos
def get_name(cert):
    # get subject DN from certificate
    name = encoder.encode(decoder.decode(cert)[0][0][5])
    return name
 def decode_cert_id_key(self, cert_id):
     return (
         der_encoder.encode(cert_id.getComponentByName('issuerNameHash')),
         der_encoder.encode(cert_id.getComponentByName('issuerKeyHash')),
         der_encoder.encode(cert_id.getComponentByName('serialNumber')))
Example #51
0
# Copyright (c) 2005-2017, Ilya Etingof <*****@*****.**>
# License: http://pyasn1.sf.net/license.html
#
# Read ASN.1/PEM X.509 CRMF request on stdin, parse into
# plain text, then build substrate from it
#
import sys

from pyasn1.codec.der import decoder
from pyasn1.codec.der import encoder

from pyasn1_modules import pem
from pyasn1_modules import rfc2560

if len(sys.argv) != 1:
    print("""Usage:
$ cat ocsp-request.pem | %s""" % sys.argv[0])
    sys.exit(-1)

ocspReq = rfc2560.OCSPRequest()

substrate = pem.readBase64FromFile(sys.stdin)
if not substrate:
    sys.exit(0)

cr, rest = decoder.decode(substrate, asn1Spec=ocspReq)

print(cr.prettyPrint())

assert encoder.encode(cr) == substrate, 'OCSP request recode fails'
    def testOpenTypes(self):
        class ClientInformation(univ.Sequence):
            pass

        ClientInformation.componentType = namedtype.NamedTypes(
            namedtype.NamedType('clientId', univ.Integer()),
            namedtype.NamedType('MachineName', char.UTF8String()),
            namedtype.NamedType('UserName', char.UTF8String()),
            namedtype.NamedType('ProcessName', char.UTF8String()))

        class EnrollmentCSP(univ.Sequence):
            pass

        EnrollmentCSP.componentType = namedtype.NamedTypes(
            namedtype.NamedType('KeySpec', univ.Integer()),
            namedtype.NamedType('Name', char.BMPString()),
            namedtype.NamedType('Signature', univ.BitString()))

        openTypeMap = {
            # attributes
            univ.ObjectIdentifier('1.3.6.1.4.1.311.13.2.3'):
            char.IA5String(),
            univ.ObjectIdentifier('1.3.6.1.4.1.311.13.2.2'):
            EnrollmentCSP(),
            univ.ObjectIdentifier('1.3.6.1.4.1.311.21.20'):
            ClientInformation(),
            # algorithm identifier parameters
            univ.ObjectIdentifier('1.2.840.113549.1.1.1'):
            univ.Null(""),
            univ.ObjectIdentifier('1.2.840.113549.1.1.5'):
            univ.Null(""),
            univ.ObjectIdentifier('1.2.840.113549.1.1.11'):
            univ.Null(""),
        }

        openTypeMap.update(rfc5652.cmsAttributesMap)
        openTypeMap.update(rfc6402.cmcControlAttributesMap)

        substrate = pem.readBase64fromText(self.pem_text)
        asn1Object, rest = der_decoder.decode(substrate,
                                              asn1Spec=rfc5652.ContentInfo(),
                                              decodeOpenTypes=True)
        self.assertFalse(rest)
        self.assertTrue(asn1Object.prettyPrint())
        self.assertEqual(substrate, der_encoder.encode(asn1Object))

        eci = asn1Object['content']['encapContentInfo']

        self.assertIn(eci['eContentType'], rfc5652.cmsContentTypesMap)
        self.assertEqual(rfc6402.id_cct_PKIData, eci['eContentType'])

        pkid, rest = der_decoder.decode(
            eci['eContent'],
            asn1Spec=rfc5652.cmsContentTypesMap[eci['eContentType']],
            openTypes=openTypeMap,
            decodeOpenTypes=True)

        self.assertFalse(rest)
        self.assertTrue(pkid.prettyPrint())
        self.assertEqual(eci['eContent'], der_encoder.encode(pkid))

        for req in pkid['reqSequence']:
            cr = req['tcr']['certificationRequest']

            sig_alg = cr['signatureAlgorithm']

            self.assertIn(sig_alg['algorithm'], openTypeMap)
            self.assertEqual(univ.Null(""), sig_alg['parameters'])

            cri = cr['certificationRequestInfo']
            spki_alg = cri['subjectPublicKeyInfo']['algorithm']

            self.assertIn(spki_alg['algorithm'], openTypeMap)
            self.assertEqual(univ.Null(""), spki_alg['parameters'])

            attrs = cr['certificationRequestInfo']['attributes']

            for attr in attrs:
                self.assertIn(attr['attrType'], openTypeMap)

                if attr['attrType'] == univ.ObjectIdentifier(
                        '1.3.6.1.4.1.311.13.2.3'):
                    self.assertEqual("6.2.9200.2", attr['attrValues'][0])

                else:
                    self.assertTrue(attr['attrValues'][0].hasValue())
Example #53
0
    def fromTGS(self, tgs, oldSessionKey, sessionKey):
        self.headers = []
        header = Header()
        header['tag'] = 1
        header['taglen'] = 8
        header['tagdata'] = b'\xff\xff\xff\xff\x00\x00\x00\x00'
        self.headers.append(header)

        decodedTGS = decoder.decode(tgs, asn1Spec = TGS_REP())[0]

        tmpPrincipal = types.Principal()
        tmpPrincipal.from_asn1(decodedTGS, 'crealm', 'cname')
        self.principal = Principal()
        self.principal.fromPrincipal(tmpPrincipal)

        # Now let's add the credential
        cipherText = decodedTGS['enc-part']['cipher']

        cipher = crypto._enctype_table[decodedTGS['enc-part']['etype']]

        # Key Usage 8
        # TGS-REP encrypted part (includes application session
        # key), encrypted with the TGS session key (Section 5.4.2)
        plainText = cipher.decrypt(oldSessionKey, 8, cipherText)

        encTGSRepPart = decoder.decode(plainText, asn1Spec = EncTGSRepPart())[0]

        credential = Credential()
        server = types.Principal()
        server.from_asn1(encTGSRepPart, 'srealm', 'sname')
        tmpServer = Principal()
        tmpServer.fromPrincipal(server)

        credential['client'] = self.principal
        credential['server'] = tmpServer
        credential['is_skey'] = 0

        credential['key'] = KeyBlock()
        credential['key']['keytype'] = int(encTGSRepPart['key']['keytype'])
        credential['key']['keyvalue'] = encTGSRepPart['key']['keyvalue'].asOctets()
        credential['key']['keylen'] = len(credential['key']['keyvalue'])

        credential['time'] = Times()
        credential['time']['authtime'] = self.toTimeStamp(types.KerberosTime.from_asn1(encTGSRepPart['authtime']))
        credential['time']['starttime'] = self.toTimeStamp(types.KerberosTime.from_asn1(encTGSRepPart['starttime']))
        credential['time']['endtime'] = self.toTimeStamp(types.KerberosTime.from_asn1(encTGSRepPart['endtime']))
        # After KB4586793 for CVE-2020-17049 this timestamp may be omitted
        if encTGSRepPart['renew-till'].hasValue():
            credential['time']['renew_till'] = self.toTimeStamp(types.KerberosTime.from_asn1(encTGSRepPart['renew-till']))

        flags = self.reverseFlags(encTGSRepPart['flags'])
        credential['tktflags'] = flags

        credential['num_address'] = 0

        credential.ticket = CountedOctetString()
        credential.ticket['data'] = encoder.encode(decodedTGS['ticket'].clone(tagSet=Ticket.tagSet, cloneValueFlag=True))
        credential.ticket['length'] = len(credential.ticket['data'])
        credential.secondTicket = CountedOctetString()
        credential.secondTicket['data'] = b''
        credential.secondTicket['length'] = 0
        self.credentials.append(credential)
Example #54
0
from pyasn1_modules import rfc2459, pem
from pyasn1.codec.der import encoder, decoder
import sys

if len(sys.argv) != 1:
    print("""Usage:
$ cat crl.pem | %s""" % sys.argv[0])
    sys.exit(-1)

asn1Spec = rfc2459.CertificateList()

cnt = 0

while 1:
    idx, substrate = pem.readPemBlocksFromFile(
        sys.stdin, ('-----BEGIN X509 CRL-----', '-----END X509 CRL-----'))
    if not substrate:
        break

    key, rest = decoder.decode(substrate, asn1Spec=asn1Spec)

    if rest: substrate = substrate[:-len(rest)]

    print(key.prettyPrint())

    assert encoder.encode(key) == substrate, 'pkcs8 recode fails'

    cnt = cnt + 1

print('*** %s CRL(s) re/serialized' % cnt)
Example #55
0
    def dump(self):
        # Try all requested protocols until one works.

        userName = Principal(
            self.__username,
            type=constants.PrincipalNameType.NT_PRINCIPAL.value)
        tgt, cipher, oldSessionKey, sessionKey = getKerberosTGT(
            userName, self.__password, self.__domain,
            bytes.fromhex(self.__lmhash), bytes.fromhex(self.__nthash))

        decodedTGT = decoder.decode(tgt, asn1Spec=AS_REP())[0]

        # Extract the ticket from the TGT
        ticket = Ticket()
        ticket.from_asn1(decodedTGT['ticket'])

        apReq = AP_REQ()
        apReq['pvno'] = 5
        apReq['msg-type'] = int(constants.ApplicationTagNumbers.AP_REQ.value)

        opts = list()
        apReq['ap-options'] = constants.encodeFlags(opts)
        seq_set(apReq, 'ticket', ticket.to_asn1)

        authenticator = Authenticator()
        authenticator['authenticator-vno'] = 5
        authenticator['crealm'] = str(decodedTGT['crealm'])

        clientName = Principal()
        clientName.from_asn1(decodedTGT, 'crealm', 'cname')

        seq_set(authenticator, 'cname', clientName.components_to_asn1)

        now = datetime.datetime.utcnow()
        authenticator['cusec'] = now.microsecond
        authenticator['ctime'] = KerberosTime.to_asn1(now)

        if logging.getLogger().level == logging.DEBUG:
            logging.debug('AUTHENTICATOR')
            print(authenticator.prettyPrint())
            print('\n')

        encodedAuthenticator = encoder.encode(authenticator)

        # Key Usage 7
        # TGS-REQ PA-TGS-REQ padata AP-REQ Authenticator (includes
        # TGS authenticator subkey), encrypted with the TGS session
        # key (Section 5.5.1)
        encryptedEncodedAuthenticator = cipher.encrypt(sessionKey, 7,
                                                       encodedAuthenticator,
                                                       None)

        apReq['authenticator'] = noValue
        apReq['authenticator']['etype'] = cipher.enctype
        apReq['authenticator']['cipher'] = encryptedEncodedAuthenticator

        encodedApReq = encoder.encode(apReq)

        tgsReq = TGS_REQ()

        tgsReq['pvno'] = 5
        tgsReq['msg-type'] = int(constants.ApplicationTagNumbers.TGS_REQ.value)

        tgsReq['padata'] = noValue
        tgsReq['padata'][0] = noValue
        tgsReq['padata'][0]['padata-type'] = int(
            constants.PreAuthenticationDataTypes.PA_TGS_REQ.value)
        tgsReq['padata'][0]['padata-value'] = encodedApReq

        # In the S4U2self KRB_TGS_REQ/KRB_TGS_REP protocol extension, a service
        # requests a service ticket to itself on behalf of a user. The user is
        # identified to the KDC by the user's name and realm.
        clientName = Principal(
            self.__behalfUser,
            type=constants.PrincipalNameType.NT_PRINCIPAL.value)

        S4UByteArray = struct.pack(
            '<I', constants.PrincipalNameType.NT_PRINCIPAL.value)
        S4UByteArray += self.__behalfUser.encode() + self.__domain.encode(
        ) + b'Kerberos'

        if logging.getLogger().level == logging.DEBUG:
            logging.debug('S4UByteArray')
            hexdump(S4UByteArray)

        # Finally cksum is computed by calling the KERB_CHECKSUM_HMAC_MD5 hash
        # with the following three parameters: the session key of the TGT of
        # the service performing the S4U2Self request, the message type value
        # of 17, and the byte array S4UByteArray.
        checkSum = _HMACMD5.checksum(sessionKey, 17, S4UByteArray)

        if logging.getLogger().level == logging.DEBUG:
            logging.debug('CheckSum')
            hexdump(checkSum)

        paForUserEnc = PA_FOR_USER_ENC()
        seq_set(paForUserEnc, 'userName', clientName.components_to_asn1)
        paForUserEnc['userRealm'] = self.__domain
        paForUserEnc['cksum'] = noValue
        paForUserEnc['cksum']['cksumtype'] = int(
            constants.ChecksumTypes.hmac_md5.value)
        paForUserEnc['cksum']['checksum'] = checkSum
        paForUserEnc['auth-package'] = 'Kerberos'

        if logging.getLogger().level == logging.DEBUG:
            logging.debug('PA_FOR_USER_ENC')
            print(paForUserEnc.prettyPrint())

        encodedPaForUserEnc = encoder.encode(paForUserEnc)

        tgsReq['padata'][1] = noValue
        tgsReq['padata'][1]['padata-type'] = int(
            constants.PreAuthenticationDataTypes.PA_FOR_USER.value)
        tgsReq['padata'][1]['padata-value'] = encodedPaForUserEnc

        reqBody = seq_set(tgsReq, 'req-body')

        opts = list()
        opts.append(constants.KDCOptions.forwardable.value)
        opts.append(constants.KDCOptions.renewable.value)
        opts.append(constants.KDCOptions.renewable_ok.value)
        opts.append(constants.KDCOptions.canonicalize.value)
        opts.append(constants.KDCOptions.enc_tkt_in_skey.value)

        reqBody['kdc-options'] = constants.encodeFlags(opts)

        serverName = Principal(
            self.__username, type=constants.PrincipalNameType.NT_UNKNOWN.value)
        #serverName = Principal('krbtgt/%s' % domain, type=constants.PrincipalNameType.NT_PRINCIPAL.value)

        seq_set(reqBody, 'sname', serverName.components_to_asn1)
        reqBody['realm'] = str(decodedTGT['crealm'])

        now = datetime.datetime.utcnow() + datetime.timedelta(days=1)

        reqBody['till'] = KerberosTime.to_asn1(now)
        reqBody['nonce'] = random.getrandbits(31)
        seq_set_iter(reqBody, 'etype', (int(
            cipher.enctype), int(constants.EncryptionTypes.rc4_hmac.value)))

        # If you comment these two lines plus enc_tkt_in_skey as option, it is bassically a S4USelf
        myTicket = ticket.to_asn1(TicketAsn1())
        seq_set_iter(reqBody, 'additional-tickets', (myTicket, ))

        if logging.getLogger().level == logging.DEBUG:
            logging.debug('Final TGS')
            print(tgsReq.prettyPrint())

        message = encoder.encode(tgsReq)

        r = sendReceive(message, self.__domain, None)

        tgs = decoder.decode(r, asn1Spec=TGS_REP())[0]

        if logging.getLogger().level == logging.DEBUG:
            logging.debug('TGS_REP')
            print(tgs.prettyPrint())

        cipherText = tgs['ticket']['enc-part']['cipher']

        # Key Usage 2
        # AS-REP Ticket and TGS-REP Ticket (includes tgs session key or
        #  application session key), encrypted with the service key
        #  (section 5.4.2)

        newCipher = _enctype_table[int(tgs['ticket']['enc-part']['etype'])]

        # Pass the hash/aes key :P
        if self.__nthash != '' and (isinstance(self.__nthash, bytes)
                                    and self.__nthash != b''):
            key = Key(newCipher.enctype, bytes.fromhex(self.__nthash))
        else:
            if newCipher.enctype == Enctype.RC4:
                key = newCipher.string_to_key(password, '', None)
            else:
                key = newCipher.string_to_key(
                    password,
                    self.__domain.upper() + self.__username, None)

        try:
            # If is was plain U2U, this is the key
            plainText = newCipher.decrypt(key, 2, str(cipherText))
        except:
            # S4USelf + U2U uses this other key
            plainText = cipher.decrypt(sessionKey, 2, cipherText)

        self.printPac(plainText)
 def decode_ocsp_request(self, ocsp_request):
     return der_encoder.encode(ocsp_request)
Example #57
0
#!/usr/bin/python
#
# Read ASN.1/PEM X.509 CRMF request on stdin, parse into
# plain text, then build substrate from it
#
from pyasn1.codec.der import decoder, encoder
from pyasn1_modules import rfc2560, pem
import sys

if len(sys.argv) != 1:
    print("""Usage:
$ cat ocsp-request.pem | %s""" % sys.argv[0])
    sys.exit(-1)

ocspReq = rfc2560.OCSPRequest()

substrate = pem.readBase64FromFile(sys.stdin)
if not substrate:
    sys.exit(0)

cr, rest = decoder.decode(substrate, asn1Spec=ocspReq)

print(cr.prettyPrint())

assert encoder.encode(cr, defMode=False) == substrate or \
       encoder.encode(cr, defMode=True) == substrate, \
       'OCSP request recode fails'
 def _get_issuer_hash(self, cert):
     sha256_hash = hashlib.sha256()
     sha256_hash.update(
         der_encoder.encode(self._get_issuer(cert)))
     return sha256_hash.digest()
Example #59
0
    def getTGT(self, userName, requestPAC=True):

        clientName = Principal(
            userName, type=constants.PrincipalNameType.NT_PRINCIPAL.value)

        asReq = AS_REQ()

        domain = self.__domain.upper()
        serverName = Principal(
            'krbtgt/%s' % domain,
            type=constants.PrincipalNameType.NT_PRINCIPAL.value)

        pacRequest = KERB_PA_PAC_REQUEST()
        pacRequest['include-pac'] = requestPAC
        encodedPacRequest = encoder.encode(pacRequest)

        asReq['pvno'] = 5
        asReq['msg-type'] = int(constants.ApplicationTagNumbers.AS_REQ.value)

        asReq['padata'] = noValue
        asReq['padata'][0] = noValue
        asReq['padata'][0]['padata-type'] = int(
            constants.PreAuthenticationDataTypes.PA_PAC_REQUEST.value)
        asReq['padata'][0]['padata-value'] = encodedPacRequest

        reqBody = seq_set(asReq, 'req-body')

        opts = list()
        opts.append(constants.KDCOptions.forwardable.value)
        opts.append(constants.KDCOptions.renewable.value)
        opts.append(constants.KDCOptions.proxiable.value)
        reqBody['kdc-options'] = constants.encodeFlags(opts)

        seq_set(reqBody, 'sname', serverName.components_to_asn1)
        seq_set(reqBody, 'cname', clientName.components_to_asn1)

        if domain == '':
            raise Exception('Empty Domain not allowed in Kerberos')

        reqBody['realm'] = domain

        now = datetime.datetime.utcnow() + datetime.timedelta(days=1)
        reqBody['till'] = KerberosTime.to_asn1(now)
        reqBody['rtime'] = KerberosTime.to_asn1(now)
        reqBody['nonce'] = random.getrandbits(31)

        supportedCiphers = (int(constants.EncryptionTypes.rc4_hmac.value), )

        seq_set_iter(reqBody, 'etype', supportedCiphers)

        message = encoder.encode(asReq)

        try:
            r = sendReceive(message, domain, self.__kdcHost)
        except KerberosError as e:
            if e.getErrorCode(
            ) == constants.ErrorCodes.KDC_ERR_ETYPE_NOSUPP.value:
                # RC4 not available, OK, let's ask for newer types
                supportedCiphers = (
                    int(constants.EncryptionTypes.aes256_cts_hmac_sha1_96.value
                        ),
                    int(constants.EncryptionTypes.aes128_cts_hmac_sha1_96.value
                        ),
                )
                seq_set_iter(reqBody, 'etype', supportedCiphers)
                message = encoder.encode(asReq)
                r = sendReceive(message, domain, self.__kdcHost)
            else:
                raise e

        # This should be the PREAUTH_FAILED packet or the actual TGT if the target principal has the
        # 'Do not require Kerberos preauthentication' set
        try:
            asRep = decoder.decode(r, asn1Spec=KRB_ERROR())[0]
        except:
            # Most of the times we shouldn't be here, is this a TGT?
            asRep = decoder.decode(r, asn1Spec=AS_REP())[0]
        else:
            # The user doesn't have UF_DONT_REQUIRE_PREAUTH set
            raise Exception(
                'User %s doesn\'t have UF_DONT_REQUIRE_PREAUTH set' % userName)

        if self.__outputFormat == 'john':
            # Let's output the TGT enc-part/cipher in John format, in case somebody wants to use it.
            return '$krb5asrep$%s@%s:%s$%s' % (
                clientName, domain,
                hexlify(asRep['enc-part']['cipher'].asOctets()[:16]).decode(),
                hexlify(asRep['enc-part']['cipher'].asOctets()[16:]).decode())
        else:
            # Let's output the TGT enc-part/cipher in Hashcat format, in case somebody wants to use it.
            return '$krb5asrep$%d$%s@%s:%s$%s' % (
                asRep['enc-part']['etype'], clientName, domain,
                hexlify(asRep['enc-part']['cipher'].asOctets()[:16]).decode(),
                hexlify(asRep['enc-part']['cipher'].asOctets()[16:]).decode())
Example #60
0
File: cs.py Project: sr-gi/paysense
    def registration(self, filename='paysense'):
        certs, certs_der, cert_hashes, blinded_hashes, btc_addresses,rands = [], [], [], [], [], []

        # Create the directories if they don't exist already
        if not path.exists(self.data_path):
            mkdir(self.data_path)

        if not path.exists(self.data_path + "private"):
            mkdir(self.data_path + "private")

        try:
            # Get ACA information
            aca_cert_text = b64decode(urlopen(ACA + '/get_ca_cert').read())
            aca_cert = X509.load_cert_string(aca_cert_text)
            pk = tbRSA.importKey(aca_cert.get_pubkey().as_der())

            # Generate the basic certificates
            for i in range(CERT_COUNT):
                pkey, btc_address = self.generate_keys()
                cert, cert_hash = self.generate_certificate(
                    aca_cert, btc_address, pkey)
                btc_addresses.append(btc_address)
                certs.append(cert)
                cert_hashes.append(cert_hash)

                # Blind the cert hash
                rands.append(getrandbits(RAND_SIZE))
                blinded_hashes.append(pk.blind(cert_hashes[i], rands[i]))

            # Contact the ACA and send her the certificate hash to be signed
            headers = {
                'Content-type': 'application/json',
                'Accept': 'text/plain'
            }
            data = {'cert_hashes': b64encode(str(blinded_hashes)), 'step': 1}

            response = post(ACA + "/sign_in",
                            data=dumps(data),
                            headers=headers)

            # If response is OK
            if response.status_code is 200:
                p = int(b64decode(response.content))

                # Prepare the data to be sent to the ACA
                for i in range(len(certs)):
                    if i != p:
                        certs_der.append(encoder.encode(certs[i]))
                    else:
                        # The data in the chosen position is deleted and not sent to the ACA
                        certs_der.append(None)
                        r = rands[i]
                        rands[i] = 0

                # Send the data to the ACA
                data = {
                    'certs': b64encode(str(certs_der)),
                    'rands': str(rands),
                    'step': 2
                }
                response = post(ACA + "/sign_in",
                                data=dumps(data),
                                headers=headers)

                # If response is OK
                if response.status_code is 200:
                    signed_b_hash = b64decode(response.content)
                    signature = pk.unblind(long(signed_b_hash), r)

                    # Check that the signature is valid
                    if pk.verify(cert_hashes[p], [signature, 0]):
                        # Attach the signature to the certificate
                        bin_signature = Signature(
                            "'%s'H" %
                            ''.join("%02X" % ord(c)
                                    for c in long_to_bytes(signature)))
                        certs[p].setComponentByName("signatureValue",
                                                    bin_signature)

                        # Set the bitcoin address to the chosen one
                        self.btc_address = btc_addresses[p]

                        # Rename and move the keys associated with the chosen bitcoin address
                        if not path.exists(self.data_path + "/private"):
                            mkdir(self.data_path + "private")
                        rename(
                            self.data_path + tmp + self.btc_address +
                            "_key.pem",
                            self.data_path + "/private/paysense.key")
                        rename(
                            self.data_path + tmp + self.btc_address +
                            "_public_key.pem",
                            self.data_path + "paysense_public.key")
                        rename(
                            self.data_path + tmp + self.btc_address +
                            "_WIF.png", self.data_path + "private/wif_qr.png")

                        # Delete the temp folder and all the other keys
                        rmtree(self.data_path + tmp)

                        # Store the certificate
                        der_cert = encoder.encode(certs[p])
                        store_certificate(der_cert, self.data_path + filename)

                        # Send the final certificate to the ACA
                        data = {
                            'certificate': b64encode(der_cert),
                            'bitcoin_address': self.btc_address
                        }
                        response = post(ACA + "/store_certificate",
                                        data=dumps(data),
                                        headers=headers)

                    else:
                        response = "Invalid certificate signature"

            return response

        except URLError as e:
            return e