ttcn3-asterisk: Validate Asterisk generates correct AKAv1-MD5 digest response
Values taken from pcap "register-unregister-example.pcapng" in SYS#6960
against testing Kamailio as IMS Core.
Related: SYS#6960
Change-Id: I0c6a6ff86a8b32383f17487dc9eb46d0bf2bf7c2
diff --git a/asterisk/Asterisk_Tests.ttcn b/asterisk/Asterisk_Tests.ttcn
index ba7cb38..a96e66a 100644
--- a/asterisk/Asterisk_Tests.ttcn
+++ b/asterisk/Asterisk_Tests.ttcn
@@ -66,13 +66,6 @@
const charstring broadcast_sip_extension := "0500";
-/* TODO: need to find correct RES, CK, IK, values for:
- * Response: "a19de225d030e6e0ec20f6de5f9dd80d"
- * CNonce Value: "9a6460bcc3c84a3eac69455a93b67a77"
- */
-const charstring c_auth_res := "a19de225d030e6e0";
-const charstring c_auth_ck := "9a6460bcc3c84a3eac69455a93b67a77";
-const charstring c_auth_ik := "5238297dfcca759bd05d48ff49bc63fa";
function f_init_ConnHdlrPars(integer idx := 1) runs on test_CT return SIPConnHdlrPars {
var template (value) CallPars cp := t_CallPars(mp_local_sip_host, 1234 + 2*idx);
@@ -384,15 +377,17 @@
/* Trigger registration: */
f_ami_action_PJSIPRegister(AMI_CLIENT, mp_volte_ims_outbound_registration);
- var charstring rand_str := oct2str(pars.subscr.rand);
- var charstring autn_str := oct2str(pars.subscr.autn);
+ var charstring rand_str := oct2str(pars.subscr.auth.rand);
+ var charstring autn_str := oct2str(pars.subscr.auth.autn);
AMI_CLIENT.receive(tr_AMI_Event_AuthRequest(mp_volte_ims_outbound_registration,
rand := pattern @nocase rand_str,
autn := pattern @nocase autn_str));
f_ami_action_AuthResponse_RES(AMI_CLIENT,
mp_volte_ims_outbound_registration,
- c_auth_res, c_auth_ck, c_auth_ik);
+ f_str_tolower(oct2str(pars.subscr.auth.res)),
+ f_str_tolower(oct2str(pars.subscr.auth.ck)),
+ f_str_tolower(oct2str(pars.subscr.auth.ik)));
AMI_CLIENT.receive(tr_AMI_Event_Registry(f_sip_SipAddr_to_str(pars.subscr.local_sip_record),
"sip:" & mp_ims_domain,
diff --git a/asterisk/IMS_ConnectionHandler.ttcn b/asterisk/IMS_ConnectionHandler.ttcn
index 9a37b05..f10e2aa 100644
--- a/asterisk/IMS_ConnectionHandler.ttcn
+++ b/asterisk/IMS_ConnectionHandler.ttcn
@@ -56,6 +56,14 @@
}
type record of IMS_ConnHdlr IMS_ConnHdlrList;
+type record IMS_AuthVector {
+ OCT16 rand,
+ OCT16 autn,
+ OCT8 res,
+ OCT16 ck,
+ OCT16 ik
+}
+
type record IMS_ConnHdlrSubscrPars {
charstring remote_sip_host optional,
uint16_t remote_sip_port optional,
@@ -65,8 +73,7 @@
charstring msisdn,
/* Expected User-Location-Info in P-Access-Network-Info */
charstring uli_str,
- octetstring rand,
- octetstring autn,
+ IMS_AuthVector auth,
charstring ipsec_auth_key,
integer ipsec_local_spi_c,
integer ipsec_local_spi_s,
@@ -158,10 +165,15 @@
password := password,
msisdn := msisdn,
uli_str := "2380100010000101",
- /* The Nonce field is the Base64 encoded version of the RAND value and concatenated with the AUTN: */
- rand := '14987631f65f8e3788a0798b6ebcd08e'O,
- autn := 'f6e19a7ccb028000a06b19c9544516e5'O,
- ipsec_auth_key := "0x5238297dfcca759bd05d48ff49bc63fa00000000",
+ auth := {
+ /* The Nonce field is the Base64 encoded version of the RAND value and concatenated with the AUTN: */
+ rand := 'd5d5de2bce418d7865ed7fa6956618a2'O,
+ autn := 'd42e61db5f15800067393a5b7691a227'O,
+ res := '6f2556bbe4366ab1'O,
+ ck := '0b389d08c833991734936bec55cac800'O,
+ ik := '17141862125bd30c81c4224391a0909a'O
+ },
+ ipsec_auth_key := "0x17141862125bd30c81c4224391a0909a00000000",
ipsec_local_spi_c := 4142,
ipsec_local_spi_s := 4143,
ipsec_remote_spi_c := omit,
@@ -250,8 +262,7 @@
/* HTTP Digest Authentication Using AKA (AKAv1-MD5): RFC 3310 */
function f_tr_Authorization_AKAv1MD5(WwwAuthenticate www_authenticate,
charstring username,
- charstring uri,
- integer nc_int := 1)
+ charstring uri)
return template (present) Authorization {
var CommaParam_List digestCln;
var template (present) Authorization authorization;
@@ -280,6 +291,12 @@
return authorization;
}
+private function f_ims_validate_Authorization_AKAv1MD5_Response(Authorization authorization, charstring method)
+runs on IMS_ConnHdlr {
+ f_sip_digest_validate_Authorization_AKAv1MD5(authorization, method, g_pars.subscr.auth.res);
+}
+
+
private function f_ims_validate_register_contact(Contact rx_contact)
{
/* IMS contact shows up like this:
@@ -532,7 +549,8 @@
ts_Param("realm", f_sip_str_quote(g_pars.realm)),
ts_Param("qop", f_sip_str_quote("auth")),
ts_Param("algorithm", "AKAv1-MD5"),
- ts_Param("nonce", f_sip_str_quote(f_nonce_from_rand_autn(g_pars.subscr.rand, g_pars.subscr.autn)))
+ ts_Param("nonce", f_sip_str_quote(f_nonce_from_rand_autn(g_pars.subscr.auth.rand,
+ g_pars.subscr.auth.autn)))
/* "opaque not needed in IMS "*/
};
wwwAuthenticate := ts_WwwAuthenticate( { ts_Challenge_digestCln(digestCln) } )
@@ -569,17 +587,9 @@
SIP.send(tx_resp);
/* Now we should receive a new REGISTER over ipsec: */
-
- /* TODO: Generate expected Authoritzation based on AKAv1-MD5: */
- /*authorization := f_sip_digest_gen_Authorization(valueof(wwwAuthenticate),
- g_pars.user, g_pars.subscr.password,
- "REGISTER",
- f_sip_SipUrl_to_str(g_pars.subscr.registrar_sip_record.addr.nameAddr.addrSpec))
- */
authorization := f_tr_Authorization_AKAv1MD5(valueof(wwwAuthenticate),
g_pars.subscr.imsi & "@" & g_pars.realm,
f_sip_SipUrl_to_str(g_pars.registrar_sip_req_uri));
- /* TODO: match Authorization from above: */
exp_req :=
tr_SIP_REGISTER(g_pars.registrar_sip_req_uri,
?,
@@ -607,6 +617,9 @@
userAgent := omit);
SIP.send(tx_resp);
+ /* Validate Digest Response: */
+ f_ims_validate_Authorization_AKAv1MD5_Response(g_rx_sip_req.msgHeader.authorization, "REGISTER");
+
/* Validate P-Access-Network-Info: */
f_ims_validate_register_P_Access_Network_info(g_rx_sip_req, exp_present := true);
diff --git a/asterisk/SIP_ConnectionHandler.ttcn b/asterisk/SIP_ConnectionHandler.ttcn
index a14dd03..cd50be6 100644
--- a/asterisk/SIP_ConnectionHandler.ttcn
+++ b/asterisk/SIP_ConnectionHandler.ttcn
@@ -296,10 +296,10 @@
as_SIP_expect_resp(exp);
/* Digest Auth: RFC 2617 */
- authorization := f_sip_digest_gen_Authorization(g_rx_sip_resp.msgHeader.wwwAuthenticate,
- g_pars.user, g_pars.password,
- "REGISTER",
- f_sip_SipUrl_to_str(g_pars.registrar_sip_req_uri))
+ authorization := f_sip_digest_gen_Authorization_MD5(g_rx_sip_resp.msgHeader.wwwAuthenticate,
+ g_pars.user, g_pars.password,
+ "REGISTER",
+ f_sip_SipUrl_to_str(g_pars.registrar_sip_req_uri))
/* New transaction: */
g_pars.registrar_sip_seq_nr := g_pars.registrar_sip_seq_nr + 1;
@@ -381,7 +381,7 @@
as_SIP_expect_resp(exp);
/* Digest Auth: RFC 2617 */
- req.msgHeader.authorization := f_sip_digest_gen_Authorization(
+ req.msgHeader.authorization := f_sip_digest_gen_Authorization_MD5(
g_rx_sip_resp.msgHeader.wwwAuthenticate,
g_pars.user, g_pars.password,
"INVITE",