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",