Example #1
0
		def truncate_key(value, keysize):
			output = b''
			currentNum = 0
			while len(output) < keysize:
				currentDigest = hashlib.sha1(bytes([currentNum]) + value).digest()
				if len(output) + len(currentDigest) > keysize:
					output += currentDigest[:keysize - len(output)]
					break
				output += currentDigest
				currentNum += 1
			
			return output
Example #2
0
    def to_kirbi(self):
        filename = '%s@%s_%s' % (
            self.client.to_string(), self.server.to_string(),
            hashlib.sha1(self.ticket.to_asn1()).hexdigest()[:8])
        krbcredinfo = {}
        krbcredinfo['key'] = EncryptionKey(self.key.to_asn1())
        krbcredinfo['prealm'] = self.client.realm.to_string()
        krbcredinfo['pname'] = self.client.to_asn1()[0]
        krbcredinfo['flags'] = core.IntegerBitString(
            self.tktflags).cast(TicketFlags)
        if self.time.authtime != 0:  #this parameter is not mandatory, and most of the time not present
            krbcredinfo['authtime'] = datetime.datetime.fromtimestamp(
                self.time.authtime, datetime.timezone.utc)
        if self.time.starttime != 0:
            krbcredinfo['starttime'] = datetime.datetime.fromtimestamp(
                self.time.starttime, datetime.timezone.utc)
        if self.time.endtime != 0:
            krbcredinfo['endtime'] = datetime.datetime.fromtimestamp(
                self.time.endtime, datetime.timezone.utc)
        if self.time.renew_till != 0:  #this parameter is not mandatory, and sometimes it's not present
            krbcredinfo['renew-till'] = datetime.datetime.fromtimestamp(
                self.time.authtime, datetime.timezone.utc)
        krbcredinfo['srealm'] = self.server.realm.to_string()
        krbcredinfo['sname'] = self.server.to_asn1()[0]

        enc_krbcred = {}
        enc_krbcred['ticket-info'] = [KrbCredInfo(krbcredinfo)]

        krbcred = {}
        krbcred['pvno'] = krb5_pvno
        krbcred['msg-type'] = MESSAGE_TYPE.KRB_CRED.value
        krbcred['tickets'] = [Ticket.load(self.ticket.to_asn1())]
        krbcred['enc-part'] = EncryptedData({
            'etype':
            EncryptionType.NULL.value,
            'cipher':
            EncKrbCredPart(enc_krbcred).dump()
        })

        kirbi = KRBCRED(krbcred)
        return kirbi, filename
Example #3
0
    def sign_authpack_native(self, data, wrap_signed=False):
        """
		Creating PKCS7 blob which contains the following things:

		1. 'data' blob which is an ASN1 encoded "AuthPack" structure
		2. the certificate used to sign the data blob
		3. the singed 'signed_attrs' structure (ASN1) which points to the "data" structure (in point 1)
		"""

        da = {}
        da['algorithm'] = algos.DigestAlgorithmId('1.3.14.3.2.26')  # for sha1

        si = {}
        si['version'] = 'v1'
        si['sid'] = cms.IssuerAndSerialNumber({
            'issuer':
            self.certificate.issuer,
            'serial_number':
            self.certificate.serial_number,
        })

        si['digest_algorithm'] = algos.DigestAlgorithm(da)
        si['signed_attrs'] = [
            cms.CMSAttribute(
                {
                    'type': 'content_type',
                    'values': ['1.3.6.1.5.2.3.1']
                }
            ),  # indicates that the encap_content_info's authdata struct (marked with OID '1.3.6.1.5.2.3.1' is signed )
            cms.CMSAttribute(
                {
                    'type': 'message_digest',
                    'values': [hashlib.sha1(data).digest()]
                }
            ),  ### hash of the data, the data itself will not be signed, but this block of data will be.
        ]
        si['signature_algorithm'] = algos.SignedDigestAlgorithm(
            {'algorithm': '1.2.840.113549.1.1.1'})
        si['signature'] = rsa_pkcs1v15_sign(
            self.privkey,
            cms.CMSAttributes(si['signed_attrs']).dump(), "sha1")

        ec = {}
        ec['content_type'] = '1.3.6.1.5.2.3.1'
        ec['content'] = data

        sd = {}
        sd['version'] = 'v3'
        sd['digest_algorithms'] = [algos.DigestAlgorithm(da)
                                   ]  # must have only one
        sd['encap_content_info'] = cms.EncapsulatedContentInfo(ec)
        sd['certificates'] = [self.certificate]
        sd['signer_infos'] = cms.SignerInfos([cms.SignerInfo(si)])

        if wrap_signed is True:
            ci = {}
            ci['content_type'] = '1.2.840.113549.1.7.2'  # signed data OID
            ci['content'] = cms.SignedData(sd)
            return cms.ContentInfo(ci).dump()

        return cms.SignedData(sd).dump()
Example #4
0
    def build_asreq(
            self,
            target=None,
            cname=None,
            kdcopts=['forwardable', 'renewable', 'proxiable', 'canonicalize']):
        if isinstance(kdcopts, list):
            kdcopts = set(kdcopts)
        if cname is not None:
            if isinstance(cname, str):
                cname = [cname]
        else:
            cname = [self.cname]

        if target is not None:
            if isinstance(target, str):
                target = [target]
        else:
            target = ['127.0.0.1']

        now = datetime.datetime.now(datetime.timezone.utc)

        kdc_req_body_data = {}
        kdc_req_body_data['kdc-options'] = KDCOptions(kdcopts)
        kdc_req_body_data['cname'] = PrincipalName({
            'name-type':
            NAME_TYPE.MS_PRINCIPAL.value,
            'name-string':
            cname
        })
        kdc_req_body_data['realm'] = 'WELLKNOWN:PKU2U'
        kdc_req_body_data['sname'] = PrincipalName({
            'name-type':
            NAME_TYPE.MS_PRINCIPAL.value,
            'name-string':
            target
        })
        kdc_req_body_data['till'] = (now + datetime.timedelta(days=1)).replace(
            microsecond=0)
        kdc_req_body_data['rtime'] = (now +
                                      datetime.timedelta(days=1)).replace(
                                          microsecond=0)
        kdc_req_body_data['nonce'] = secrets.randbits(31)
        kdc_req_body_data['etype'] = [18, 17]  # 23 breaks...
        kdc_req_body_data['addresses'] = [
            HostAddress({
                'addr-type': 20,
                'address': b'127.0.0.1'
            })
        ]  # not sure if this is needed
        kdc_req_body = KDC_REQ_BODY(kdc_req_body_data)

        checksum = hashlib.sha1(kdc_req_body.dump()).digest()

        authenticator = {}
        authenticator['cusec'] = now.microsecond
        authenticator['ctime'] = now.replace(microsecond=0)
        authenticator['nonce'] = secrets.randbits(31)
        authenticator['paChecksum'] = checksum

        dp = {}
        dp['p'] = self.diffie.p
        dp['g'] = self.diffie.g
        dp['q'] = 0  # mandatory parameter, but it is not needed

        pka = {}
        pka['algorithm'] = '1.2.840.10046.2.1'
        pka['parameters'] = keys.DomainParameters(dp)

        spki = {}
        spki['algorithm'] = keys.PublicKeyAlgorithm(pka)
        spki['public_key'] = self.diffie.get_public_key()

        authpack = {}
        authpack['pkAuthenticator'] = PKAuthenticator(authenticator)
        authpack['clientPublicValue'] = keys.PublicKeyInfo(spki)
        authpack['clientDHNonce'] = self.diffie.dh_nonce

        authpack = AuthPack(authpack)
        signed_authpack = self.sign_authpack(authpack.dump(),
                                             wrap_signed=False)

        # ??????? This is absolutely nonsense,
        payload = length_encode(len(signed_authpack)) + signed_authpack
        payload = b'\x80' + payload
        signed_authpack = b'\x30' + length_encode(len(payload)) + payload

        pa_data_1 = {}
        pa_data_1['padata-type'] = PaDataType.PK_AS_REQ.value
        pa_data_1['padata-value'] = signed_authpack

        asreq = {}
        asreq['pvno'] = 5
        asreq['msg-type'] = 10
        asreq['padata'] = [pa_data_1]
        asreq['req-body'] = kdc_req_body

        return AS_REQ(asreq).dump()
Example #5
0
    def build_asreq_pkinit(
            self,
            supported_encryption_method,
            kdcopts=['forwardable', 'renewable', 'renewable-ok']):
        from asn1crypto import keys

        if supported_encryption_method.value == 23:
            raise Exception(
                'RC4 encryption is not supported for certificate auth!')

        now = datetime.datetime.now(datetime.timezone.utc)

        kdc_req_body_data = {}
        kdc_req_body_data['kdc-options'] = KDCOptions(set(kdcopts))
        kdc_req_body_data['cname'] = PrincipalName({
            'name-type':
            NAME_TYPE.PRINCIPAL.value,
            'name-string': [self.usercreds.username]
        })
        kdc_req_body_data['realm'] = self.usercreds.domain.upper()
        kdc_req_body_data['sname'] = PrincipalName({
            'name-type':
            NAME_TYPE.SRV_INST.value,
            'name-string': ['krbtgt', self.usercreds.domain.upper()]
        })
        kdc_req_body_data['till'] = (now + datetime.timedelta(days=1)).replace(
            microsecond=0)
        kdc_req_body_data['rtime'] = (now +
                                      datetime.timedelta(days=1)).replace(
                                          microsecond=0)
        kdc_req_body_data['nonce'] = secrets.randbits(31)
        kdc_req_body_data['etype'] = [supported_encryption_method.value
                                      ]  #[18,17] # 23 breaks...
        kdc_req_body = KDC_REQ_BODY(kdc_req_body_data)

        checksum = hashlib.sha1(kdc_req_body.dump()).digest()

        authenticator = {}
        authenticator['cusec'] = now.microsecond
        authenticator['ctime'] = now.replace(microsecond=0)
        authenticator['nonce'] = secrets.randbits(31)
        authenticator['paChecksum'] = checksum

        dp = {}
        dp['p'] = self.usercreds.dhparams.p
        dp['g'] = self.usercreds.dhparams.g
        dp['q'] = 0  # mandatory parameter, but it is not needed

        pka = {}
        pka['algorithm'] = '1.2.840.10046.2.1'
        pka['parameters'] = keys.DomainParameters(dp)

        spki = {}
        spki['algorithm'] = keys.PublicKeyAlgorithm(pka)
        spki['public_key'] = self.usercreds.dhparams.get_public_key()

        authpack = {}
        authpack['pkAuthenticator'] = PKAuthenticator(authenticator)
        authpack['clientPublicValue'] = keys.PublicKeyInfo(spki)
        authpack['clientDHNonce'] = self.usercreds.dhparams.dh_nonce

        authpack = AuthPack(authpack)
        signed_authpack = self.usercreds.sign_authpack(authpack.dump(),
                                                       wrap_signed=True)

        payload = PA_PK_AS_REQ()
        payload['signedAuthPack'] = signed_authpack

        pa_data_1 = {}
        pa_data_1['padata-type'] = PaDataType.PK_AS_REQ.value
        pa_data_1['padata-value'] = payload.dump()

        pa_data_0 = {}
        pa_data_0['padata-type'] = int(PADATA_TYPE('PA-PAC-REQUEST'))
        pa_data_0['padata-value'] = PA_PAC_REQUEST({
            'include-pac': True
        }).dump()

        asreq = {}
        asreq['pvno'] = 5
        asreq['msg-type'] = 10
        asreq['padata'] = [pa_data_0, pa_data_1]
        asreq['req-body'] = kdc_req_body

        return AS_REQ(asreq)