Hoernchen has submitted this change. ( https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/40982?usp=email )
Change subject: euicc: changes and extensions to support es9p and es2p testing ......................................................................
euicc: changes and extensions to support es9p and es2p testing
Change-Id: I9c622751e195d33f6f0a832265d6b10674d1c75c --- M library/euicc/RSPDefinitions.asn M library/euicc/RSPDefinitions_EncDec.cc M library/euicc/RSPDefinitions_Templates.ttcn M library/euicc/RSPDefinitions_Types.ttcn M library/euicc/es2p_Types_JSON.ttcn M library/euicc/es9p_Types_JSON.ttcn M library/euicc/esx_header_Types_JSON.ttcn 7 files changed, 206 insertions(+), 11 deletions(-)
Approvals: Jenkins Builder: Verified pespin: Looks good to me, but someone else must approve laforge: Looks good to me, approved
diff --git a/library/euicc/RSPDefinitions.asn b/library/euicc/RSPDefinitions.asn index 56dd1af..66da646 100644 --- a/library/euicc/RSPDefinitions.asn +++ b/library/euicc/RSPDefinitions.asn @@ -472,6 +472,15 @@ smdpSign [APPLICATION 55] OCTET STRING -- SM-DP's signature, tag '5F37' }
+-- for verification, different structure, needs manual skipping of tag + tlv (first 4 bytes) +InitialiseSecureChannelRequest-ver ::= [35] SEQUENCE { -- Tag 'BF23' + remoteOpId RemoteOpId, -- Remote Operation Type Identifier (value SHALL be set to installBoundProfilePackage) + transactionId [0] TransactionId, -- The TransactionID generated by the SM-DP+ + controlRefTemplate[6] IMPLICIT ControlRefTemplate, -- Control Reference Template (Key Agreement). Current specification considers a subset of CRT specified in GlobalPlatform Card Specification [8], section 6.4.2.3 for the Mutual Authentication Data Field + smdpOtpk [APPLICATION 73] OCTET STRING, ---otPK.DP.ECKA as specified in GlobalPlatform Card Specification [8] section 6.4.2.3 for ePK.OCE.ECKA, tag '5F49' + euiccOtpk [APPLICATION 73] OCTET STRING -- otPK.EUICC.ECKA, tag '5F49' +} + ControlRefTemplate ::= SEQUENCE { keyType[0] Octet1, -- Key type according to GlobalPlatform Card Specification [8] Table 11-16, AES= '88', Tag '80' keyLen[1] Octet1, --Key length in number of bytes. For current specification key length SHALL by 0x10 bytes, Tag '81' diff --git a/library/euicc/RSPDefinitions_EncDec.cc b/library/euicc/RSPDefinitions_EncDec.cc index b46a73c..fe4b68d 100644 --- a/library/euicc/RSPDefinitions_EncDec.cc +++ b/library/euicc/RSPDefinitions_EncDec.cc @@ -57,6 +57,57 @@ return msg; }
+OCTETSTRING enc__EuiccSigned1(const EuiccSigned1 &msg) { + TTCN_Buffer buf; + + buf.clear(); + msg.encode(EuiccSigned1_descr_, buf, TTCN_EncDec::CT_BER, BER_ENCODE_DER); + return OCTETSTRING(buf.get_len(), buf.get_data()); +} + +EuiccSigned1 dec__EuiccSigned1(const OCTETSTRING &stream) { + TTCN_Buffer buf; + EuiccSigned1 msg; + buf.put_os(stream); + + msg.decode(EuiccSigned1_descr_, buf, TTCN_EncDec::CT_BER, BER_ACCEPT_ALL); + return msg; +} + +OCTETSTRING enc__EUICCSigned2(const EUICCSigned2 &msg) { + TTCN_Buffer buf; + + buf.clear(); + msg.encode(EUICCSigned2_descr_, buf, TTCN_EncDec::CT_BER, BER_ENCODE_DER); + return OCTETSTRING(buf.get_len(), buf.get_data()); +} + +EUICCSigned2 dec__EUICCSigned2(const OCTETSTRING &stream) { + TTCN_Buffer buf; + EUICCSigned2 msg; + buf.put_os(stream); + + msg.decode(EUICCSigned2_descr_, buf, TTCN_EncDec::CT_BER, BER_ACCEPT_ALL); + return msg; +} + +OCTETSTRING enc__ControlRefTemplate(const ControlRefTemplate &msg) { + TTCN_Buffer buf; + + buf.clear(); + msg.encode(ControlRefTemplate_descr_, buf, TTCN_EncDec::CT_BER, BER_ENCODE_DER); + return OCTETSTRING(buf.get_len(), buf.get_data()); +} + +ControlRefTemplate dec__ControlRefTemplate(const OCTETSTRING &stream) { + TTCN_Buffer buf; + ControlRefTemplate msg; + buf.put_os(stream); + + msg.decode(ControlRefTemplate_descr_, buf, TTCN_EncDec::CT_BER, BER_ACCEPT_ALL); + return msg; +} + OCTETSTRING enc__AuthenticateServerResponse(const AuthenticateServerResponse &msg) { TTCN_Buffer buf;
@@ -312,4 +363,55 @@ return msg; }
+OCTETSTRING enc__EuiccCancelSessionSigned(const EuiccCancelSessionSigned &msg) { + TTCN_Buffer buf; + + buf.clear(); + msg.encode(EuiccCancelSessionSigned_descr_, buf, TTCN_EncDec::CT_BER, BER_ENCODE_DER); + return OCTETSTRING(buf.get_len(), buf.get_data()); +} + +EuiccCancelSessionSigned dec__EuiccCancelSessionSigned(const OCTETSTRING &stream) { + TTCN_Buffer buf; + EuiccCancelSessionSigned msg; + buf.put_os(stream); + + msg.decode(EuiccCancelSessionSigned_descr_, buf, TTCN_EncDec::CT_BER, BER_ACCEPT_ALL); + return msg; +} + +OCTETSTRING enc__OtherSignedNotification(const OtherSignedNotification &msg) { + TTCN_Buffer buf; + + buf.clear(); + msg.encode(OtherSignedNotification_descr_, buf, TTCN_EncDec::CT_BER, BER_ENCODE_DER); + return OCTETSTRING(buf.get_len(), buf.get_data()); +} + +OtherSignedNotification dec__OtherSignedNotification(const OCTETSTRING &stream) { + TTCN_Buffer buf; + OtherSignedNotification msg; + buf.put_os(stream); + + msg.decode(OtherSignedNotification_descr_, buf, TTCN_EncDec::CT_BER, BER_ACCEPT_ALL); + return msg; +} + +OCTETSTRING enc__NotificationMetadata(const NotificationMetadata &msg) { + TTCN_Buffer buf; + + buf.clear(); + msg.encode(NotificationMetadata_descr_, buf, TTCN_EncDec::CT_BER, BER_ENCODE_DER); + return OCTETSTRING(buf.get_len(), buf.get_data()); +} + +NotificationMetadata dec__NotificationMetadata(const OCTETSTRING &stream) { + TTCN_Buffer buf; + NotificationMetadata msg; + buf.put_os(stream); + + msg.decode(NotificationMetadata_descr_, buf, TTCN_EncDec::CT_BER, BER_ACCEPT_ALL); + return msg; +} + } diff --git a/library/euicc/RSPDefinitions_Templates.ttcn b/library/euicc/RSPDefinitions_Templates.ttcn index f717d6a..8c3886e 100644 --- a/library/euicc/RSPDefinitions_Templates.ttcn +++ b/library/euicc/RSPDefinitions_Templates.ttcn @@ -665,4 +665,48 @@ eidValue := eidValue }
+/* NotificationMetadata templates */ +template (present) NotificationMetadata +tr_notificationMetadata(template (present) integer seqNumber := ?, + template (present) NotificationEvent profileManagementOperation := ?, + template (present) charstring notificationAddress := ?, + template octetstring iccid := *) := { + seqNumber := seqNumber, + profileManagementOperation := profileManagementOperation, + notificationAddress := notificationAddress, + iccid := iccid +} +template (value) NotificationMetadata +ts_notificationMetadata(template (value) integer seqNumber := 1, + template (value) NotificationEvent profileManagementOperation := '1000'B, + template (value) charstring notificationAddress := "smdp.example.com", + template (omit) octetstring iccid := omit) := { + seqNumber := seqNumber, + profileManagementOperation := profileManagementOperation, + notificationAddress := notificationAddress, + iccid := iccid +} + +/* OtherSignedNotification templates */ +template (present) OtherSignedNotification +tr_otherSignedNotification(template (present) NotificationMetadata tbsOtherNotification := ?, + template (present) octetstring euiccNotificationSignature := ?, + template (present) Certificate euiccCertificate := ?, + template (present) Certificate eumCertificate := ?) := { + tbsOtherNotification := tbsOtherNotification, + euiccNotificationSignature := euiccNotificationSignature, + euiccCertificate := euiccCertificate, + eumCertificate := eumCertificate +} +template (value) OtherSignedNotification +ts_otherSignedNotification(template (value) NotificationMetadata tbsOtherNotification := ts_notificationMetadata, + template (value) octetstring euiccNotificationSignature := '0123456789ABCDEF'O, + template (value) Certificate euiccCertificate, + template (value) Certificate eumCertificate) := { + tbsOtherNotification := tbsOtherNotification, + euiccNotificationSignature := euiccNotificationSignature, + euiccCertificate := euiccCertificate, + eumCertificate := eumCertificate +} + } diff --git a/library/euicc/RSPDefinitions_Types.ttcn b/library/euicc/RSPDefinitions_Types.ttcn index 5bb3925..8d33f17 100644 --- a/library/euicc/RSPDefinitions_Types.ttcn +++ b/library/euicc/RSPDefinitions_Types.ttcn @@ -42,6 +42,15 @@ external function dec_ServerSigned1(in octetstring stream) return ServerSigned1; external function enc_ServerSigned1(in ServerSigned1 msg) return octetstring;
+external function dec_EuiccSigned1(in octetstring stream) return EuiccSigned1; +external function enc_EuiccSigned1(in EuiccSigned1 msg) return octetstring; + +external function dec_EUICCSigned2(in octetstring stream) return EUICCSigned2; +external function enc_EUICCSigned2(in EUICCSigned2 msg) return octetstring; + +external function dec_ControlRefTemplate(in octetstring stream) return ControlRefTemplate; +external function enc_ControlRefTemplate(in ControlRefTemplate msg) return octetstring; + external function dec_BoundProfilePackage(in octetstring stream) return BoundProfilePackage; external function enc_BoundProfilePackage(in BoundProfilePackage msg) return octetstring;
@@ -57,4 +66,13 @@ external function dec_RemoteProfileProvisioningRequest(in octetstring stream) return RemoteProfileProvisioningRequest; external function enc_RemoteProfileProvisioningRequest(in RemoteProfileProvisioningRequest msg) return octetstring;
+external function dec_EuiccCancelSessionSigned(in octetstring stream) return EuiccCancelSessionSigned; +external function enc_EuiccCancelSessionSigned(in EuiccCancelSessionSigned msg) return octetstring; + +external function dec_OtherSignedNotification(in octetstring stream) return OtherSignedNotification; +external function enc_OtherSignedNotification(in OtherSignedNotification msg) return octetstring; + +external function dec_NotificationMetadata(in octetstring stream) return NotificationMetadata; +external function enc_NotificationMetadata(in NotificationMetadata msg) return octetstring; + } diff --git a/library/euicc/es2p_Types_JSON.ttcn b/library/euicc/es2p_Types_JSON.ttcn index 6a29aed..e8ff74c 100644 --- a/library/euicc/es2p_Types_JSON.ttcn +++ b/library/euicc/es2p_Types_JSON.ttcn @@ -24,7 +24,7 @@ /* GSMA SGP.22, section 6.5.2.1 (SMDP+ to MNO) */ type record JSON_ES2p_DownloadOrderResponse { JSON_ESx_ResponseHeader header, - charstring iccid + charstring iccid optional }; private external function dec_JSON_ES2p_DownloadOrderRequest(in octetstring stream) return JSON_ES2p_DownloadOrderRequest @@ -86,7 +86,7 @@ /* GSMA SGP.22, section 6.5.2.3 (SMDP+ to MNO) */ type record JSON_ES2p_CancelOrderResponse { JSON_ESx_ResponseHeader header, - charstring iccid + charstring iccid optional }; private external function dec_JSON_ES2p_CancelOrderRequest(in octetstring stream) return JSON_ES2p_CancelOrderRequest diff --git a/library/euicc/es9p_Types_JSON.ttcn b/library/euicc/es9p_Types_JSON.ttcn index 601ea8f..3e13c42 100644 --- a/library/euicc/es9p_Types_JSON.ttcn +++ b/library/euicc/es9p_Types_JSON.ttcn @@ -209,8 +209,13 @@ } } with { extension "prototype(fast)" }
+type record DecodedRPPReponse_Wrap { + RemoteProfileProvisioningResponse asn1_pdu optional, + JSON_ESx_FunctionExecutionStatusCodeData err optional +} + /* Converter function to decode a JSON formatted ES9+ response to its ASN.1 ES9+ record representation */ -function dec_RemoteProfileProvisioningResponse_from_JSON(in charstring json_pdu_enc, out RemoteProfileProvisioningResponse asn1_pdu_dec) { +function dec_RemoteProfileProvisioningResponse_from_JSON(in charstring json_pdu_enc, out DecodedRPPReponse_Wrap wrapped_resp) { var JSON_ES9p_RemoteProfileProvisioningResponse json_pdu; json_pdu := dec_JSON_ES9p_RemoteProfileProvisioningResponse(char2oct(json_pdu_enc));
@@ -218,7 +223,7 @@ if (not match(json_pdu.initiateAuthenticationResponse.header, ts_responseHeader)) { setverdict(fail, "unsuccessful request"); } - asn1_pdu_dec := valueof(ts_initiateAuthenticationResponse( + wrapped_resp.asn1_pdu := valueof(ts_initiateAuthenticationResponse( str2oct(json_pdu.initiateAuthenticationResponse.transactionId), dec_ServerSigned1(decode_base64(json_pdu.initiateAuthenticationResponse.serverSigned1)), decode_base64(json_pdu.initiateAuthenticationResponse.serverSignature1), @@ -228,14 +233,14 @@ if (not match(json_pdu.getBoundProfilePackageResponse.header, ts_responseHeader)) { setverdict(fail, "unsuccessful request"); } - asn1_pdu_dec := valueof(ts_getBoundProfilePackageResponse( + wrapped_resp.asn1_pdu := valueof(ts_getBoundProfilePackageResponse( str2oct(json_pdu.getBoundProfilePackageResponse.transactionId), dec_BoundProfilePackage(decode_base64(json_pdu.getBoundProfilePackageResponse.boundProfilePackage)))); } else if (ispresent(json_pdu.authenticateClientResponseEs9)) { if (not match(json_pdu.authenticateClientResponseEs9.header, ts_responseHeader)) { setverdict(fail, "unsuccessful request"); } - asn1_pdu_dec := valueof(ts_authenticateClientResponseEs9( + wrapped_resp.asn1_pdu := valueof(ts_authenticateClientResponseEs9( str2oct(json_pdu.authenticateClientResponseEs9.transactionId), dec_StoreMetadataRequest(decode_base64(json_pdu.authenticateClientResponseEs9.profileMetadata)), dec_SmdpSigned2(decode_base64(json_pdu.authenticateClientResponseEs9.smdpSigned2)), @@ -243,9 +248,12 @@ dec_Certificate(decode_base64(json_pdu.authenticateClientResponseEs9.smdpCertificate)))); } else if (ispresent(json_pdu.emptyResponse)) { if (not match(json_pdu.emptyResponse.header, ts_responseHeader)) { - setverdict(fail, "unsuccessful request"); + wrapped_resp.err := json_pdu.emptyResponse.header.functionExecutionStatus.statusCodeData; + } else { + /* Success case for empty response - initialize optional fields */ + wrapped_resp.asn1_pdu := omit; + wrapped_resp.err := omit; } - /* Empty response, do nothing? */ } else { setverdict(fail, "decoder path not implemented for JSON ES9+ message"); } diff --git a/library/euicc/esx_header_Types_JSON.ttcn b/library/euicc/esx_header_Types_JSON.ttcn index 4a4f4ca..1954341 100644 --- a/library/euicc/esx_header_Types_JSON.ttcn +++ b/library/euicc/esx_header_Types_JSON.ttcn @@ -17,8 +17,20 @@ };
/* GSMA SGP.22, section 6.5.1.4 */ + +type record JSON_ESx_FunctionExecutionStatusCodeData { + charstring subjectCode, + charstring reasonCode, + charstring subjectIdentifier optional, + charstring message_ optional +} with { + encode "JSON"; + variant (message_) "JSON:name as message" +}; + type record JSON_ESx_FunctionExecutionStatus { - charstring status + charstring status, + JSON_ESx_FunctionExecutionStatusCodeData statusCodeData optional }; type record JSON_ESx_ResponseHeader { JSON_ESx_FunctionExecutionStatus functionExecutionStatus @@ -27,13 +39,15 @@ template (value) JSON_ESx_ResponseHeader ts_responseHeader := { functionExecutionStatus := { - status := "Executed-Success" + status := "Executed-Success", + statusCodeData := omit } } template (present) JSON_ESx_ResponseHeader tr_responseHeader := { functionExecutionStatus := { - status := ? + status := ?, + statusCodeData := * } }