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