ikev2: add SA dump API
Type: feature Ticket: VPP-1897 Change-Id: I0245aceeb344efd29b1f9217c35889a8bbe1f744 Signed-off-by: jan_cavojsky <Jan.Cavojsky@pantheon.tech> Signed-off-by: Filip Tehlar <ftehlar@cisco.com>
This commit is contained in:

committed by
Benoît Ganne

parent
7fc88cf3a1
commit
a340fe1ac6
src/plugins/ikev2
@ -1,6 +1,6 @@
|
||||
/* Hey Emacs use -*- mode: C -*- */
|
||||
/*
|
||||
* Copyright (c) 2015-2016 Cisco and/or its affiliates.
|
||||
* Copyright (c) 2015-2020 Cisco and/or its affiliates.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
@ -64,6 +64,129 @@ define ikev2_profile_details
|
||||
option status="in_progress";
|
||||
};
|
||||
|
||||
/** \brief Dump all SAs
|
||||
@param client_index - opaque cookie to identify the sender
|
||||
@param context - sender context, to match reply w/ request
|
||||
*/
|
||||
define ikev2_sa_dump
|
||||
{
|
||||
u32 client_index;
|
||||
u32 context;
|
||||
|
||||
option status = "in_progress";
|
||||
};
|
||||
|
||||
/** \brief Details about IKE SA
|
||||
@param context - sender context, to match reply w/ request
|
||||
@param retval - return code
|
||||
@param sa - SA data
|
||||
*/
|
||||
define ikev2_sa_details
|
||||
{
|
||||
u32 context;
|
||||
i32 retval;
|
||||
|
||||
vl_api_ikev2_sa_t sa;
|
||||
option status = "in_progress";
|
||||
};
|
||||
|
||||
/** \brief Dump child SA of specific SA
|
||||
@param client_index - opaque cookie to identify the sender
|
||||
@param context - sender context, to match reply w/ request
|
||||
@param sa_index - index of specific sa
|
||||
*/
|
||||
define ikev2_child_sa_dump
|
||||
{
|
||||
u32 client_index;
|
||||
u32 context;
|
||||
|
||||
u32 sa_index;
|
||||
option vat_help = "sa_index <index>";
|
||||
option status = "in_progress";
|
||||
};
|
||||
|
||||
/** \brief Child SA details
|
||||
@param context - sender context, to match reply w/ request
|
||||
@param retval - return code
|
||||
@param child_sa - child SA data
|
||||
*/
|
||||
define ikev2_child_sa_details
|
||||
{
|
||||
u32 context;
|
||||
i32 retval;
|
||||
|
||||
vl_api_ikev2_child_sa_t child_sa;
|
||||
option status = "in_progress";
|
||||
};
|
||||
|
||||
/** \brief get specific nonce
|
||||
@param client_index - opaque cookie to identify the sender
|
||||
@param context - sender context, to match reply w/ request
|
||||
@param is_initiator - specify type initiator|responder of nonce
|
||||
@param sa_index - index of specific sa
|
||||
*/
|
||||
define ikev2_nonce_get
|
||||
{
|
||||
u32 client_index;
|
||||
u32 context;
|
||||
|
||||
bool is_initiator;
|
||||
u32 sa_index;
|
||||
option vat_help = "initiator|responder sa_index <index>";
|
||||
option status = "in_progress";
|
||||
};
|
||||
|
||||
/** \brief reply on specific nonce
|
||||
@param context - sender context, to match reply w/ request
|
||||
@param retval - return code
|
||||
@param data_len - nonce length
|
||||
@param nonce - nonce data
|
||||
*/
|
||||
|
||||
define ikev2_nonce_get_reply
|
||||
{
|
||||
u32 context;
|
||||
i32 retval;
|
||||
|
||||
u32 data_len;
|
||||
u8 nonce[data_len];
|
||||
option status = "in_progress";
|
||||
};
|
||||
|
||||
/** \brief dump traffic selectors
|
||||
@param client_index - opaque cookie to identify the sender
|
||||
@param context - sender context, to match reply w/ request
|
||||
@param is_initiator - specify type initiator|responder of nonce
|
||||
@param sa_index - index of specific sa
|
||||
@param child_sa_index - index of specific sa child of specific sa
|
||||
*/
|
||||
|
||||
define ikev2_traffic_selector_dump
|
||||
{
|
||||
u32 client_index;
|
||||
u32 context;
|
||||
|
||||
bool is_initiator;
|
||||
u32 sa_index;
|
||||
u32 child_sa_index;
|
||||
option vat_help = "initiator|responder sa_index <index> child_sa_index <index>";
|
||||
option status = "in_progress";
|
||||
};
|
||||
|
||||
/** \brief details on specific traffic selector
|
||||
@param context - sender context, to match reply w/ request
|
||||
@param retval - return code
|
||||
@param ts - traffic selector data
|
||||
*/
|
||||
|
||||
define ikev2_traffic_selector_details
|
||||
{
|
||||
u32 context;
|
||||
i32 retval;
|
||||
|
||||
vl_api_ikev2_ts_t ts;
|
||||
option status = "in_progress";
|
||||
};
|
||||
|
||||
/** \brief IKEv2: Add/delete profile
|
||||
@param client_index - opaque cookie to identify the sender
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
||||
/* Hey Emacs use -*- mode: C -*- */
|
||||
/*
|
||||
* Copyright (c) 2015-2016 Cisco and/or its affiliates.
|
||||
* Copyright (c) 2015-2020 Cisco and/or its affiliates.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
@ -27,6 +27,9 @@ typedef ikev2_id
|
||||
|
||||
typedef ikev2_ts
|
||||
{
|
||||
u32 sa_index;
|
||||
u32 child_sa_index;
|
||||
|
||||
bool is_local;
|
||||
u8 protocol_id;
|
||||
u16 start_port;
|
||||
@ -83,3 +86,65 @@ typedef ikev2_profile
|
||||
bool udp_encap;
|
||||
vl_api_ikev2_auth_t auth;
|
||||
};
|
||||
|
||||
typedef ikev2_sa_transform
|
||||
{
|
||||
u8 transform_type;
|
||||
u16 transform_id;
|
||||
u16 key_len;
|
||||
u16 key_trunc;
|
||||
u16 block_size;
|
||||
u8 dh_group;
|
||||
};
|
||||
|
||||
typedef ikev2_keys
|
||||
{
|
||||
u8 sk_d[64];
|
||||
u8 sk_d_len;
|
||||
u8 sk_ai[64];
|
||||
u8 sk_ai_len;
|
||||
u8 sk_ar[64];
|
||||
u8 sk_ar_len;
|
||||
u8 sk_ei[64];
|
||||
u8 sk_ei_len;
|
||||
u8 sk_er[64];
|
||||
u8 sk_er_len;
|
||||
u8 sk_pi[64];
|
||||
u8 sk_pi_len;
|
||||
u8 sk_pr[64];
|
||||
u8 sk_pr_len;
|
||||
};
|
||||
|
||||
typedef ikev2_child_sa
|
||||
{
|
||||
u32 sa_index;
|
||||
u32 child_sa_index;
|
||||
u32 i_spi;
|
||||
u32 r_spi;
|
||||
vl_api_ikev2_keys_t keys;
|
||||
vl_api_ikev2_sa_transform_t encryption;
|
||||
vl_api_ikev2_sa_transform_t integrity;
|
||||
vl_api_ikev2_sa_transform_t esn;
|
||||
};
|
||||
|
||||
typedef ikev2_sa
|
||||
{
|
||||
u32 sa_index;
|
||||
u32 profile_index;
|
||||
|
||||
u64 ispi;
|
||||
u64 rspi;
|
||||
vl_api_ip4_address_t iaddr;
|
||||
vl_api_ip4_address_t raddr;
|
||||
|
||||
vl_api_ikev2_keys_t keys;
|
||||
|
||||
/* ID */
|
||||
vl_api_ikev2_id_t i_id;
|
||||
vl_api_ikev2_id_t r_id;
|
||||
|
||||
vl_api_ikev2_sa_transform_t encryption;
|
||||
vl_api_ikev2_sa_transform_t integrity;
|
||||
vl_api_ikev2_sa_transform_t prf;
|
||||
vl_api_ikev2_sa_transform_t dh;
|
||||
};
|
||||
|
@ -415,6 +415,8 @@ class IKEv2SA(object):
|
||||
c = self.child_sas[0]
|
||||
ts1 = ikev2.IPv4TrafficSelector(
|
||||
IP_protocol_ID=0,
|
||||
start_port=0,
|
||||
end_port=0xffff,
|
||||
starting_address_v4=c.local_ts['start_addr'],
|
||||
ending_address_v4=c.local_ts['end_addr'])
|
||||
ts2 = ikev2.IPv4TrafficSelector(
|
||||
@ -692,7 +694,7 @@ class TemplateResponder(VppTestCase):
|
||||
plain = self.sa.hmac_and_decrypt(ike)
|
||||
self.sa.calc_child_keys()
|
||||
|
||||
def verify_child_sas(self):
|
||||
def verify_ipsec_sas(self):
|
||||
sas = self.vapi.ipsec_sa_dump()
|
||||
self.assertEqual(len(sas), 2)
|
||||
sa0 = sas[0].entry
|
||||
@ -726,10 +728,97 @@ class TemplateResponder(VppTestCase):
|
||||
self.assertEqual(sa0.salt.to_bytes(4, 'little'), c.salt_er)
|
||||
self.assertEqual(sa1.salt.to_bytes(4, 'little'), c.salt_ei)
|
||||
|
||||
def verify_keymat(self, api_keys, keys, name):
|
||||
km = getattr(keys, name)
|
||||
api_km = getattr(api_keys, name)
|
||||
api_km_len = getattr(api_keys, name + '_len')
|
||||
self.assertEqual(len(km), api_km_len)
|
||||
self.assertEqual(km, api_km[:api_km_len])
|
||||
|
||||
def verify_id(self, api_id, exp_id):
|
||||
self.assertEqual(api_id.type, IDType.value(exp_id.type))
|
||||
self.assertEqual(api_id.data_len, exp_id.data_len)
|
||||
self.assertEqual(bytes(api_id.data, 'ascii'), exp_id.type)
|
||||
|
||||
def verify_ike_sas(self):
|
||||
r = self.vapi.ikev2_sa_dump()
|
||||
self.assertEqual(len(r), 1)
|
||||
sa = r[0].sa
|
||||
self.assertEqual(self.sa.ispi, (sa.ispi).to_bytes(8, 'little'))
|
||||
self.assertEqual(self.sa.rspi, (sa.rspi).to_bytes(8, 'big'))
|
||||
self.assertEqual(sa.iaddr, IPv4Address(self.pg0.remote_ip4))
|
||||
self.assertEqual(sa.raddr, IPv4Address(self.pg0.local_ip4))
|
||||
self.verify_keymat(sa.keys, self.sa, 'sk_d')
|
||||
self.verify_keymat(sa.keys, self.sa, 'sk_ai')
|
||||
self.verify_keymat(sa.keys, self.sa, 'sk_ar')
|
||||
self.verify_keymat(sa.keys, self.sa, 'sk_ei')
|
||||
self.verify_keymat(sa.keys, self.sa, 'sk_er')
|
||||
self.verify_keymat(sa.keys, self.sa, 'sk_pi')
|
||||
self.verify_keymat(sa.keys, self.sa, 'sk_pr')
|
||||
|
||||
self.assertEqual(sa.i_id.type, self.sa.id_type)
|
||||
self.assertEqual(sa.r_id.type, self.sa.id_type)
|
||||
self.assertEqual(sa.i_id.data_len, len(self.sa.i_id))
|
||||
self.assertEqual(sa.r_id.data_len, len(self.sa.r_id))
|
||||
self.assertEqual(bytes(sa.i_id.data, 'ascii'), self.sa.i_id)
|
||||
self.assertEqual(bytes(sa.r_id.data, 'ascii'), self.sa.r_id)
|
||||
|
||||
r = self.vapi.ikev2_child_sa_dump(sa_index=sa.sa_index)
|
||||
self.assertEqual(len(r), 1)
|
||||
csa = r[0].child_sa
|
||||
self.assertEqual(csa.sa_index, sa.sa_index)
|
||||
c = self.sa.child_sas[0]
|
||||
if hasattr(c, 'sk_ai'):
|
||||
self.verify_keymat(csa.keys, c, 'sk_ai')
|
||||
self.verify_keymat(csa.keys, c, 'sk_ar')
|
||||
self.verify_keymat(csa.keys, c, 'sk_ei')
|
||||
self.verify_keymat(csa.keys, c, 'sk_er')
|
||||
|
||||
tsi, tsr = self.sa.generate_ts()
|
||||
tsi = tsi[0]
|
||||
tsr = tsr[0]
|
||||
r = self.vapi.ikev2_traffic_selector_dump(
|
||||
is_initiator=True, sa_index=sa.sa_index,
|
||||
child_sa_index=csa.child_sa_index)
|
||||
self.assertEqual(len(r), 1)
|
||||
ts = r[0].ts
|
||||
self.verify_ts(r[0].ts, tsi[0], True)
|
||||
|
||||
r = self.vapi.ikev2_traffic_selector_dump(
|
||||
is_initiator=False, sa_index=sa.sa_index,
|
||||
child_sa_index=csa.child_sa_index)
|
||||
self.assertEqual(len(r), 1)
|
||||
self.verify_ts(r[0].ts, tsr[0], False)
|
||||
|
||||
n = self.vapi.ikev2_nonce_get(is_initiator=True,
|
||||
sa_index=sa.sa_index)
|
||||
self.verify_nonce(n, self.sa.i_nonce)
|
||||
n = self.vapi.ikev2_nonce_get(is_initiator=False,
|
||||
sa_index=sa.sa_index)
|
||||
self.verify_nonce(n, self.sa.r_nonce)
|
||||
|
||||
def verify_nonce(self, api_nonce, nonce):
|
||||
self.assertEqual(api_nonce.data_len, len(nonce))
|
||||
self.assertEqual(api_nonce.nonce, nonce)
|
||||
|
||||
def verify_ts(self, api_ts, ts, is_initiator):
|
||||
if is_initiator:
|
||||
self.assertTrue(api_ts.is_local)
|
||||
else:
|
||||
self.assertFalse(api_ts.is_local)
|
||||
self.assertEqual(api_ts.start_addr,
|
||||
IPv4Address(ts.starting_address_v4))
|
||||
self.assertEqual(api_ts.end_addr,
|
||||
IPv4Address(ts.ending_address_v4))
|
||||
self.assertEqual(api_ts.start_port, ts.start_port)
|
||||
self.assertEqual(api_ts.end_port, ts.end_port)
|
||||
self.assertEqual(api_ts.protocol_id, ts.IP_protocol_ID)
|
||||
|
||||
def test_responder(self):
|
||||
self.send_sa_init(self.sa.natt)
|
||||
self.send_sa_auth()
|
||||
self.verify_child_sas()
|
||||
self.verify_ipsec_sas()
|
||||
self.verify_ike_sas()
|
||||
|
||||
|
||||
class Ikev2Params(object):
|
||||
|
Reference in New Issue
Block a user