def test_req_body_addresses(): value = b"".join([ pack_asn1(TagClass.context_specific, True, 0, pack_asn1_bit_string(b"\x00\x00\x00\x00")), pack_asn1(TagClass.context_specific, True, 2, pack_asn1_general_string(b"DOMAIN.LOCAL")), pack_asn1(TagClass.context_specific, True, 7, pack_asn1_integer(1)), pack_asn1( TagClass.context_specific, True, 8, pack_asn1_sequence([ pack_asn1_integer( kerb.KerberosEncryptionType.aes256_cts_hmac_sha1_96) ])), pack_asn1( TagClass.context_specific, True, 9, pack_asn1_sequence([ pack_asn1_sequence([ pack_asn1( TagClass.context_specific, True, 0, pack_asn1_integer(kerb.KerberosHostAddressType.ipv4)), pack_asn1(TagClass.context_specific, True, 1, pack_asn1_octet_string(b"dc01.domain.local")), ]) ])), ]) req_body = kerb.KdcReqBody.unpack(value) assert isinstance(req_body.addresses, list) assert len(req_body.addresses) == 1 assert req_body.addresses[0].addr_type == kerb.KerberosHostAddressType.ipv4 assert req_body.addresses[0].value == b'dc01.domain.local' actual = kerb.parse_kerberos_token(req_body) assert actual['addresses'][0]['addr-type'] == 'IPv4 (2)' assert actual['addresses'][0]['address'] == 'dc01.domain.local'
def pack_mech_type_list(mech_list): # type: (Union[str, List[str], Tuple[str, ...], Set[str]]) -> bytes """Packs a list of OIDs for the mechListMIC value. Will pack a list of object identifiers to the raw byte string value for the mechListMIC. Args: mech_list: The list of OIDs to back Returns: bytes: The byte string of the packed ASN.1 MechTypeList SEQUENCE OF value. """ if not isinstance(mech_list, (list, tuple, set)): mech_list = [mech_list] return pack_asn1_sequence([pack_asn1_object_identifier(oid) for oid in mech_list])
def pack(self): # type: () -> bytes """ Packs the NegTokenResp as a byte string. """ value_map = [ (0, self.neg_state, pack_asn1_enumerated), (1, self.supported_mech, pack_asn1_object_identifier), (2, self.response_token, pack_asn1_octet_string), (3, self.mech_list_mic, pack_asn1_octet_string), ] elements = [] for tag, value, pack_func in value_map: if value is not None: elements.append(pack_asn1(TagClass.context_specific, True, tag, pack_func(value))) # The NegTokenResp will always be wrapped NegotiationToken - CHOICE 1. b_data = pack_asn1_sequence(elements) return pack_asn1(TagClass.context_specific, True, 1, b_data)
def test_unpack_unknown_krb(): sequence = pack_asn1_sequence([ pack_asn1(TagClass.context_specific, True, 0, pack_asn1_integer(5)), pack_asn1(TagClass.context_specific, True, 1, pack_asn1_integer(0)), ]) actual = sp.unpack_token(sequence, unwrap=True) assert isinstance(actual, kerb.KerberosV5Msg) assert actual.PVNO == 5 assert isinstance(actual.sequence, dict) assert actual.sequence[0].tag_class == TagClass.universal assert not actual.sequence[0].constructed assert actual.sequence[0].tag_number == TypeTagNumber.integer assert actual.sequence[0].b_data == b'\x05' assert actual.sequence[1].tag_class == TagClass.universal assert not actual.sequence[1].constructed assert actual.sequence[1].tag_number == TypeTagNumber.integer assert actual.sequence[1].b_data == b'\x00'
def pack(self): # type: () -> bytes """ Packs the NegTokenInit as a byte string. """ def pack_elements(value_map): elements = [] for tag, value, pack_func in value_map: if value is not None: elements.append(pack_asn1(TagClass.context_specific, True, tag, pack_func(value))) return elements req_flags = struct.pack("B", self.req_flags) if self.req_flags is not None else None base_map = [ (0, self.mech_types, pack_mech_type_list), (1, req_flags, pack_asn1_bit_string), (2, self.mech_token, pack_asn1_octet_string), ] # The placement of the mechListMIC is dependent on whether we are packing a NegTokenInit with or without the # negHints field. neg_hints_map = [ (0, self.hint_name, pack_asn1_general_string), (1, self.hint_address, pack_asn1_octet_string), ] neg_hints = pack_elements(neg_hints_map) if neg_hints: base_map.append((3, neg_hints, pack_asn1_sequence)) base_map.append((4, self.mech_list_mic, pack_asn1_octet_string)) else: base_map.append((3, self.mech_list_mic, pack_asn1_octet_string)) init_sequence = pack_elements(base_map) # The NegTokenInit will always be wrapped in an InitialContextToken -> NegotiationToken - CHOICE 0. b_data = pack_asn1_sequence(init_sequence) return InitialContextToken(GSSMech.spnego.value, pack_asn1(TagClass.context_specific, True, 0, b_data)).pack()
def test_req_body_ticket(): ticket = pack_asn1( TagClass.application, True, 1, pack_asn1_sequence([ pack_asn1(TagClass.context_specific, True, 0, pack_asn1_integer(5)), pack_asn1(TagClass.context_specific, True, 1, pack_asn1_general_string(b'DOMAIN.LOCAL')), pack_asn1( TagClass.context_specific, True, 2, pack_asn1_sequence([ pack_asn1( TagClass.context_specific, True, 0, pack_asn1_integer( kerb.KerberosPrincipalNameType.principal)), pack_asn1( TagClass.context_specific, True, 1, pack_asn1_sequence([ pack_asn1_general_string(b"vagrant-domain"), ])), ])), pack_asn1( TagClass.context_specific, True, 3, pack_asn1_sequence([ pack_asn1( TagClass.context_specific, True, 0, pack_asn1_integer(kerb.KerberosEncryptionType. aes256_cts_hmac_sha1_96)), pack_asn1(TagClass.context_specific, True, 2, pack_asn1_octet_string(b"\x00\x01")), ])), ])) value = b"".join([ pack_asn1(TagClass.context_specific, True, 0, pack_asn1_bit_string(b"\x00\x00\x00\x00")), pack_asn1(TagClass.context_specific, True, 2, pack_asn1_general_string(b"DOMAIN.LOCAL")), pack_asn1(TagClass.context_specific, True, 7, pack_asn1_integer(1)), pack_asn1( TagClass.context_specific, True, 8, pack_asn1_sequence([ pack_asn1_integer( kerb.KerberosEncryptionType.aes256_cts_hmac_sha1_96) ])), pack_asn1(TagClass.context_specific, True, 11, pack_asn1_sequence([ticket])), ]) req_body = kerb.KdcReqBody.unpack(value) assert isinstance(req_body.additional_tickets, list) assert len(req_body.additional_tickets) == 1 assert req_body.additional_tickets[0].enc_part.cipher == b"\x00\x01" assert req_body.additional_tickets[ 0].enc_part.etype == kerb.KerberosEncryptionType.aes256_cts_hmac_sha1_96 assert req_body.additional_tickets[0].enc_part.kvno is None assert req_body.additional_tickets[0].realm == b"DOMAIN.LOCAL" assert req_body.additional_tickets[0].sname == kerb.PrincipalName( kerb.KerberosPrincipalNameType.principal, [b'vagrant-domain']) assert req_body.additional_tickets[0].tkt_vno == 5 actual = kerb.parse_kerberos_token(req_body) assert actual['additional-tickets'][0]['tkt-vno'] == 5 assert actual['additional-tickets'][0]['realm'] == 'DOMAIN.LOCAL' assert actual['additional-tickets'][0]['sname'][ 'name-type'] == 'NT-PRINCIPAL (1)' assert actual['additional-tickets'][0]['sname']['name-string'] == [ 'vagrant-domain' ] assert actual['additional-tickets'][0]['enc-part'][ 'etype'] == 'AES256_CTS_HMAC_SHA1_96 (18)' assert actual['additional-tickets'][0]['enc-part']['kvno'] is None assert actual['additional-tickets'][0]['enc-part']['cipher'] == '0001'