def _load_ipsec_conf(self, ikeconf, conf_dict): no_esn = [Transform(Transform.Type.ESN, Transform.EsnId.NO_ESN)] ipsec_proto = self._load_from_dict(conf_dict.get('ipsec_proto', 'esp'), _ipsec_proto_name_to_enum) encr = self._load_crypto_algs('encr', conf_dict.get('encr', ['aes256']), _encr_name_to_transform) integ = self._load_crypto_algs('integ', conf_dict.get('integ', ['sha256']), _integ_name_to_transform) dh = self._load_crypto_algs('dh', conf_dict.get('dh', []), _dh_name_to_transform) if ipsec_proto == Proposal.Protocol.AH: encr = [] ip_proto = self._load_from_dict(conf_dict.get('ip_proto', 'any'), _ip_proto_name_to_enum) my_subnet = self._load_ip_network( conf_dict.get('my_subnet', ikeconf.my_addr)) my_port = int(conf_dict.get('my_port', 0)) peer_subnet = self._load_ip_network( conf_dict.get('peer_subnet', ikeconf.peer_addr)) peer_port = int(conf_dict.get('peer_port', 0)) return IpsecConfiguration( index=int(conf_dict.get('index', random.randint(0, 2**20))), my_ts=TrafficSelector.from_network(my_subnet, my_port, ip_proto), peer_ts=TrafficSelector.from_network(peer_subnet, peer_port, ip_proto), lifetime=int(conf_dict.get('lifetime', 5 * 60)), mode=self._load_from_dict(conf_dict.get('mode', 'tunnel'), _mode_name_to_enum), proposal=Proposal(1, ipsec_proto, b'', encr + integ + dh + no_esn), )
def test_queues(self, mockclass): self.test_initial_exchanges_transport() small_tsi = TrafficSelector.from_network( ip_network("192.168.0.1/32"), 8765, TrafficSelector.IpProtocol.TCP) small_tsr = TrafficSelector.from_network( ip_network("192.168.0.2/32"), 23, TrafficSelector.IpProtocol.TCP) create_child_req_1 = self.ike_sa1.process_acquire( small_tsi, small_tsr, 1) create_child_req_2 = self.ike_sa1.process_acquire( small_tsi, small_tsr, 1) delete_request = self.ike_sa1.process_expire( self.ike_sa1.child_sas[0].inbound_spi, hard=True) self.assertIsNone(create_child_req_2) self.assertIsNone(delete_request) create_child_res = self.ike_sa2.process_message(create_child_req_1) create_child_req_2 = self.ike_sa1.process_message(create_child_res) self.assertIsNotNone(create_child_req_2) self.assertEqual(self.ike_sa1.state, IkeSa.State.NEW_CHILD_REQ_SENT) self.assertEqual(self.ike_sa2.state, IkeSa.State.ESTABLISHED) self.assertEqual(len(self.ike_sa1.child_sas), 2) self.assertEqual(len(self.ike_sa2.child_sas), 2) create_child_res_2 = self.ike_sa2.process_message(create_child_req_2) delete_request = self.ike_sa1.process_message(create_child_res_2) self.assertIsNotNone(delete_request) self.assertEqual(self.ike_sa1.state, IkeSa.State.DEL_CHILD_REQ_SENT) self.assertEqual(self.ike_sa2.state, IkeSa.State.ESTABLISHED) self.assertEqual(len(self.ike_sa1.child_sas), 3) self.assertEqual(len(self.ike_sa2.child_sas), 3) delete_res = self.ike_sa2.process_message(delete_request) request = self.ike_sa1.process_message(delete_res) self.assertIsNone(request) self.assertEqual(self.ike_sa1.state, IkeSa.State.ESTABLISHED) self.assertEqual(self.ike_sa2.state, IkeSa.State.ESTABLISHED) self.assertEqual(len(self.ike_sa1.child_sas), 2) self.assertEqual(len(self.ike_sa2.child_sas), 2)
def test_ike_sa_init_invalid_ke(self, mockclass): self.ike_sa1.configuration.dh.insert( 0, Transform(Transform.Type.DH, Transform.DhId.DH_16)) small_tsi = TrafficSelector.from_network( ip_network("192.168.0.1/32"), 8765, TrafficSelector.IpProtocol.TCP) small_tsr = TrafficSelector.from_network( ip_network("192.168.0.2/32"), 23, TrafficSelector.IpProtocol.TCP) ike_sa_init_req = self.ike_sa1.process_acquire(small_tsi, small_tsr, 1) ike_sa_init_res = self.ike_sa2.process_message(ike_sa_init_req) ike_sa_init_req_newgroup = self.ike_sa1.process_message( ike_sa_init_res) ike_sa3 = IkeSa( is_initiator=False, peer_spi=self.ike_sa1.my_spi, my_addr=self.ip2, peer_addr=self.ip1, configuration=self.configuration2.get_ike_configuration(self.ip1)) ike_sa3.process_message(ike_sa_init_req_newgroup) self.assertMessageHasNotification( ike_sa_init_res, self.ike_sa2, PayloadNOTIFY.Type.INVALID_KE_PAYLOAD) self.assertEqual(self.ike_sa1.state, IkeSa.State.INIT_REQ_SENT) self.assertEqual(self.ike_sa2.state, IkeSa.State.DELETED) self.assertEqual(ike_sa3.state, IkeSa.State.INIT_RES_SENT) self.assertEqual(len(self.ike_sa1.child_sas), 0) self.assertEqual(len(self.ike_sa2.child_sas), 0) self.assertEqual(len(ike_sa3.child_sas), 0)
def process_acquire(self, xfrm_acquire, attributes): family = attributes[xfrm.XFRMA_TMPL].family peer_addr = xfrm_acquire.id.daddr.to_ipaddr(family) logging.debug('Received acquire for {}'.format(peer_addr)) # look for an active IKE_SA with the peer try: ike_sa = self._get_ike_sa_by_peer_addr(peer_addr) except StopIteration: my_addr = xfrm_acquire.saddr.to_ipaddr(family) ike_conf = self.configuration.get_ike_configuration(peer_addr) # create new IKE_SA (for now) ike_sa = IkeSa(is_initiator=True, peer_spi=b'\0'*8, configuration=ike_conf, my_addr=my_addr, peer_addr=peer_addr) self.ike_sas.append(ike_sa) logging.info(f'Starting the creation of IKE SA={ike_sa}. Count={len(self.ike_sas)}') sel_family = xfrm_acquire.sel.family small_tsi = TrafficSelector.from_network(ip_network(xfrm_acquire.sel.saddr.to_ipaddr(sel_family)), xfrm_acquire.sel.sport, xfrm_acquire.sel.proto) small_tsr = TrafficSelector.from_network(ip_network(xfrm_acquire.sel.daddr.to_ipaddr(sel_family)), xfrm_acquire.sel.dport, xfrm_acquire.sel.proto) request = ike_sa.process_acquire(small_tsi, small_tsr, xfrm_acquire.policy.index >> 3) # look for ipsec configuration return request, ike_sa.my_addr, ike_sa.peer_addr
def test_acquire_from_unknown_policy(self, mockclass): self.test_initial_exchanges_transport() small_tsi = TrafficSelector.from_network( ip_network("192.168.0.1/32"), 8765, TrafficSelector.IpProtocol.TCP) small_tsr = TrafficSelector.from_network( ip_network("192.168.0.2/32"), 23, TrafficSelector.IpProtocol.TCP) create_child_req_1 = self.ike_sa1.process_acquire( small_tsi, small_tsr, 9) self.assertIsNone(create_child_req_1)
def test_invalid_exchange_type_on_request(self, mockclass): small_tsi = TrafficSelector.from_network( ip_network("192.168.0.1/32"), 8765, TrafficSelector.IpProtocol.TCP) small_tsr = TrafficSelector.from_network( ip_network("192.168.0.2/32"), 23, TrafficSelector.IpProtocol.TCP) ike_sa_init_req = self.ike_sa1.process_acquire(small_tsi, small_tsr, 1) message = Message.parse(ike_sa_init_req, crypto=self.ike_sa1.my_crypto) message.exchange_type = 100 ike_sa_init_req = message.to_bytes() ike_sa_init_res = self.ike_sa2.process_message(ike_sa_init_req) self.assertIsNone(ike_sa_init_res) self.assertEqual(self.ike_sa1.state, IkeSa.State.INIT_REQ_SENT) self.assertEqual(self.ike_sa2.state, IkeSa.State.INITIAL) self.assertEqual(len(self.ike_sa1.child_sas), 0) self.assertEqual(len(self.ike_sa2.child_sas), 0)
def test_create_child_ok(self, mockclass): self.test_initial_exchanges_transport() small_tsi = TrafficSelector.from_network( ip_network("192.168.0.1/32"), 8765, TrafficSelector.IpProtocol.TCP) small_tsr = TrafficSelector.from_network( ip_network("192.168.0.2/32"), 23, TrafficSelector.IpProtocol.TCP) create_child_req = self.ike_sa1.process_acquire( small_tsi, small_tsr, 1) create_child_res = self.ike_sa2.process_message(create_child_req) request = self.ike_sa1.process_message(create_child_res) self.assertIsNone(request) self.assertEqual(self.ike_sa1.state, IkeSa.State.ESTABLISHED) self.assertEqual(self.ike_sa2.state, IkeSa.State.ESTABLISHED) self.assertEqual(len(self.ike_sa1.child_sas), 2) self.assertEqual(len(self.ike_sa2.child_sas), 2)
def test_ike_sa_init_no_proposal_chosen(self, mockclass): self.ike_sa1.configuration.dh[0].id = Transform.DhId.DH_16 small_tsi = TrafficSelector.from_network( ip_network("192.168.0.1/32"), 8765, TrafficSelector.IpProtocol.TCP) small_tsr = TrafficSelector.from_network( ip_network("192.168.0.2/32"), 23, TrafficSelector.IpProtocol.TCP) ike_sa_init_req = self.ike_sa1.process_acquire(small_tsi, small_tsr, 1) ike_sa_init_res = self.ike_sa2.process_message(ike_sa_init_req) ike_auth_req = self.ike_sa1.process_message(ike_sa_init_res) self.assertIsNone(ike_auth_req) self.assertMessageHasNotification( ike_sa_init_res, self.ike_sa2, PayloadNOTIFY.Type.NO_PROPOSAL_CHOSEN) self.assertEqual(self.ike_sa1.state, IkeSa.State.DELETED) self.assertEqual(self.ike_sa2.state, IkeSa.State.DELETED) self.assertEqual(len(self.ike_sa1.child_sas), 0) self.assertEqual(len(self.ike_sa2.child_sas), 0)
def test_max_retransmit(self, mockclass): self.test_initial_exchanges_transport() small_tsi = TrafficSelector.from_network( ip_network("192.168.0.1/32"), 8765, TrafficSelector.IpProtocol.TCP) small_tsr = TrafficSelector.from_network( ip_network("192.168.0.2/32"), 23, TrafficSelector.IpProtocol.TCP) create_child_sa_req = self.ike_sa1.process_acquire( small_tsi, small_tsr, 1) self.assertIsNotNone(create_child_sa_req) for i in range(0, IkeSa.MAX_RETRANSMISSIONS - 1): self.ike_sa1.retransmit_at = time.time() create_child_sa_req = self.ike_sa1.check_retransmission_timer() self.assertIsNotNone(create_child_sa_req) self.ike_sa1.retransmit_at = time.time() create_child_sa_req = self.ike_sa1.check_retransmission_timer() self.assertIsNone(create_child_sa_req) self.assertEqual(self.ike_sa1.state, IkeSa.State.DELETED)
def test_invalid_message_id_on_request(self, mockclass): self.test_initial_exchanges_transport() small_tsi = TrafficSelector.from_network( ip_network("192.168.0.1/32"), 8765, TrafficSelector.IpProtocol.TCP) small_tsr = TrafficSelector.from_network( ip_network("192.168.0.2/32"), 23, TrafficSelector.IpProtocol.TCP) create_child_sa_req = self.ike_sa1.process_acquire( small_tsi, small_tsr, 1) message = Message.parse(create_child_sa_req, crypto=self.ike_sa1.my_crypto) message.message_id = 100 create_child_sa_req = message.to_bytes() create_child_sa_res = self.ike_sa2.process_message(create_child_sa_req) self.assertEqual(self.ike_sa1.state, IkeSa.State.NEW_CHILD_REQ_SENT) self.assertEqual(self.ike_sa2.state, IkeSa.State.ESTABLISHED) self.assertIsNone(create_child_sa_res) self.assertEqual(len(self.ike_sa1.child_sas), 1) self.assertEqual(len(self.ike_sa2.child_sas), 1)
def test_invalid_mode_in_response(self, mockclass): self.test_initial_exchanges_transport() small_tsi = TrafficSelector.from_network( ip_network("192.168.0.1/32"), 8765, TrafficSelector.IpProtocol.TCP) small_tsr = TrafficSelector.from_network( ip_network("192.168.0.2/32"), 23, TrafficSelector.IpProtocol.TCP) create_child_sa_req = self.ike_sa1.process_acquire( small_tsi, small_tsr, 1) create_child_sa_res = self.ike_sa2.process_message(create_child_sa_req) message = Message.parse(create_child_sa_res, crypto=self.ike_sa2.my_crypto) message.encrypted_payloads.remove( message.get_notifies(PayloadNOTIFY.Type.USE_TRANSPORT_MODE, True)[0]) create_child_sa_res = message.to_bytes() request = self.ike_sa1.process_message(create_child_sa_res) self.assertIsNone(request) self.assertEqual(self.ike_sa1.state, IkeSa.State.ESTABLISHED)
def test_ike_auth_no_proposal_chosen(self, mockclass): self.ike_sa1.configuration.protect[ 0] = self.ike_sa1.configuration.protect[0]._replace( ipsec_proto=Proposal.Protocol.AH) small_tsi = TrafficSelector.from_network( ip_network("192.168.0.1/32"), 8765, TrafficSelector.IpProtocol.TCP) small_tsr = TrafficSelector.from_network( ip_network("192.168.0.2/32"), 23, TrafficSelector.IpProtocol.TCP) ike_sa_init_req = self.ike_sa1.process_acquire(small_tsi, small_tsr, 1) ike_sa_init_res = self.ike_sa2.process_message(ike_sa_init_req) ike_auth_req = self.ike_sa1.process_message(ike_sa_init_res) ike_auth_res = self.ike_sa2.process_message(ike_auth_req) request = self.ike_sa1.process_message(ike_auth_res) self.assertMessageHasNotification( ike_auth_res, self.ike_sa2, PayloadNOTIFY.Type.NO_PROPOSAL_CHOSEN) self.assertIsNone(request) self.assertEqual(self.ike_sa1.state, IkeSa.State.ESTABLISHED) self.assertEqual(self.ike_sa2.state, IkeSa.State.ESTABLISHED) self.assertEqual(len(self.ike_sa1.child_sas), 0) self.assertEqual(len(self.ike_sa2.child_sas), 0)
def test_ike_auth_invalid_ts(self, mockclass): self.ike_sa2.configuration.protect[ 0] = self.ike_sa2.configuration.protect[0]._replace( my_subnet=ip_network("10.0.0.0/24")) small_tsi = TrafficSelector.from_network( ip_network("192.168.0.1/32"), 8765, TrafficSelector.IpProtocol.TCP) small_tsr = TrafficSelector.from_network( ip_network("192.168.0.2/32"), 23, TrafficSelector.IpProtocol.TCP) ike_sa_init_req = self.ike_sa1.process_acquire(small_tsi, small_tsr, 1) ike_sa_init_res = self.ike_sa2.process_message(ike_sa_init_req) ike_auth_req = self.ike_sa1.process_message(ike_sa_init_res) ike_auth_res = self.ike_sa2.process_message(ike_auth_req) request = self.ike_sa1.process_message(ike_auth_res) self.assertIsNone(request) self.assertMessageHasNotification(ike_auth_res, self.ike_sa2, PayloadNOTIFY.Type.TS_UNACCEPTABLE) self.assertEqual(self.ike_sa1.state, IkeSa.State.ESTABLISHED) self.assertEqual(self.ike_sa2.state, IkeSa.State.ESTABLISHED) self.assertEqual(len(self.ike_sa1.child_sas), 0) self.assertEqual(len(self.ike_sa2.child_sas), 0)
def test_simultaneous_del_ike_sa_create_child(self, mockclass): self.test_initial_exchanges_transport() small_tsi = TrafficSelector.from_network( ip_network("192.168.0.1/32"), 8765, TrafficSelector.IpProtocol.TCP) small_tsr = TrafficSelector.from_network( ip_network("192.168.0.2/32"), 23, TrafficSelector.IpProtocol.TCP) self.ike_sa1.delete_ike_sa_at = time.time() del_ike_sa_req = self.ike_sa1.check_rekey_ike_sa_timer() create_child_sa_req = self.ike_sa2.process_acquire( small_tsr, small_tsi, 2) del_ike_sa_res = self.ike_sa2.process_message(del_ike_sa_req) create_child_sa_res = self.ike_sa1.process_message(create_child_sa_req) self.assertMessageHasNotification(create_child_sa_res, self.ike_sa1, PayloadNOTIFY.Type.TEMPORARY_FAILURE) request_alice = self.ike_sa1.process_message(del_ike_sa_res) request_bob = self.ike_sa2.process_message(create_child_sa_res) self.assertEqual(self.ike_sa1.state, IkeSa.State.DELETED) self.assertEqual(self.ike_sa2.state, IkeSa.State.DELETED) self.assertIsNone(request_alice) self.assertIsNone(request_bob)
def test_ike_auth_missing_sa_payload(self, mockclass): small_tsi = TrafficSelector.from_network( ip_network("192.168.0.1/32"), 8765, TrafficSelector.IpProtocol.TCP) small_tsr = TrafficSelector.from_network( ip_network("192.168.0.2/32"), 23, TrafficSelector.IpProtocol.TCP) ike_sa_init_req = self.ike_sa1.process_acquire(small_tsi, small_tsr, 1) ike_sa_init_res = self.ike_sa2.process_message(ike_sa_init_req) ike_auth_req = self.ike_sa1.process_message(ike_sa_init_res) message = Message.parse(ike_auth_req, crypto=self.ike_sa1.my_crypto) payload_sa = message.get_payload(Payload.Type.SA, True) message.encrypted_payloads.remove(payload_sa) ike_auth_req = message.to_bytes() ike_auth_res = self.ike_sa2.process_message(ike_auth_req) request = self.ike_sa1.process_message(ike_auth_res) self.assertIsNone(request) self.assertMessageHasNotification( ike_auth_res, self.ike_sa2, PayloadNOTIFY.Type.NO_PROPOSAL_CHOSEN) self.assertEqual(self.ike_sa1.state, IkeSa.State.ESTABLISHED) self.assertEqual(self.ike_sa2.state, IkeSa.State.ESTABLISHED) self.assertEqual(len(self.ike_sa1.child_sas), 0) self.assertEqual(len(self.ike_sa2.child_sas), 0)
def test_ike_auth_invalid_auth_data(self, mockclass): small_tsi = TrafficSelector.from_network( ip_network("192.168.0.1/32"), 8765, TrafficSelector.IpProtocol.TCP) small_tsr = TrafficSelector.from_network( ip_network("192.168.0.2/32"), 23, TrafficSelector.IpProtocol.TCP) ike_sa_init_req = self.ike_sa1.process_acquire(small_tsi, small_tsr, 1) ike_sa_init_res = self.ike_sa2.process_message(ike_sa_init_req) ike_auth_req = self.ike_sa1.process_message(ike_sa_init_res) message = Message.parse(ike_auth_req, crypto=self.ike_sa1.my_crypto) message.get_payload(Payload.Type.AUTH, encrypted=True).auth_data += b'invalid' ike_auth_req = message.to_bytes() ike_auth_res = self.ike_sa2.process_message(ike_auth_req) request = self.ike_sa1.process_message(ike_auth_res) self.assertIsNone(request) self.assertMessageHasNotification( ike_auth_res, self.ike_sa2, PayloadNOTIFY.Type.AUTHENTICATION_FAILED) self.assertEqual(self.ike_sa1.state, IkeSa.State.DELETED) self.assertEqual(self.ike_sa2.state, IkeSa.State.DELETED) self.assertEqual(len(self.ike_sa1.child_sas), 0) self.assertEqual(len(self.ike_sa2.child_sas), 0)
def test_from_network(self): ts = TrafficSelector.from_network( ip_network('192.168.2.0/22', strict=False), 0, 0) self.assertEqual(ts.end_addr, ip_address('192.168.3.255'))