dexter has uploaded this change for review. ( 
https://gerrit.osmocom.org/c/onomondo-ipa/+/43438?usp=email )


Change subject: proc_indirect_prfle_dwnld: refactor module, fix spec references
......................................................................

proc_indirect_prfle_dwnld: refactor module, fix spec references

The Indirect Profile Download Procedure uses incorrect spec
references. As it seems it was a bit mixed up with the Direct
Profile Download Procedure, which is very similar, but not
identical.

With this patch we:
- Move the steps from proc_prfle_dwnld.c into
  proc_indirect_prfle_dwnld.c
- restructure the code
- Fix the incorrect spec references
- Refactor the error handling (session cancellation)
- Add TODOs for parts that are still missing

Related: SYS#8101

Change-Id: I69571280c7b52f2cb09f733bc0466cb77c0d2590
---
M src/ipa/libipa/CMakeLists.txt
M src/ipa/libipa/proc_cmn_mtl_auth.c
M src/ipa/libipa/proc_indirect_prfle_dwnld.c
D src/ipa/libipa/proc_prfle_dwnld.c
D src/ipa/libipa/proc_prfle_dwnld.h
5 files changed, 65 insertions(+), 122 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/onomondo-ipa refs/changes/38/43438/1

diff --git a/src/ipa/libipa/CMakeLists.txt b/src/ipa/libipa/CMakeLists.txt
index 83084e9..ad3670a 100644
--- a/src/ipa/libipa/CMakeLists.txt
+++ b/src/ipa/libipa/CMakeLists.txt
@@ -51,7 +51,6 @@
   proc_euicc_data_req.c
   proc_euicc_pkg_dwnld_exec.c
   proc_notif_delivery.c
-  proc_prfle_dwnld.c
   proc_prfle_inst.c
   utils.c
 )
diff --git a/src/ipa/libipa/proc_cmn_mtl_auth.c 
b/src/ipa/libipa/proc_cmn_mtl_auth.c
index e625c70..c866604 100644
--- a/src/ipa/libipa/proc_cmn_mtl_auth.c
+++ b/src/ipa/libipa/proc_cmn_mtl_auth.c
@@ -5,7 +5,8 @@
  *
  * Author: Philipp Maier <[email protected]> / sysmocom - s.f.m.c. GmbH
  *
- * See also: GSMA SGP.22, section 3.0.1: Common Mutual Authentication Procedure
+ * See also: GSMA SGP.22, section 3.0.2: Common Mutual Authentication Procedure
+ *           and GSMA SGP.32, section 3.2.2: Common Mutual Authentication
  */

 #include <stdio.h>
diff --git a/src/ipa/libipa/proc_indirect_prfle_dwnld.c 
b/src/ipa/libipa/proc_indirect_prfle_dwnld.c
index 9b233d3..a99266f 100644
--- a/src/ipa/libipa/proc_indirect_prfle_dwnld.c
+++ b/src/ipa/libipa/proc_indirect_prfle_dwnld.c
@@ -19,12 +19,13 @@
 #include "utils.h"
 #include "activation_code.h"
 #include "esipa_auth_clnt.h"
-#include "proc_cmn_mtl_auth.h"
-#include "proc_prfle_dwnld.h"
 #include "esipa_get_bnd_prfle_pkg.h"
-#include "proc_cmn_cancel_sess.h"
+#include "esipa_get_bnd_prfle_pkg.h"
+#include "es10b_prep_dwnld.h"
+#include "proc_cmn_mtl_auth.h"
 #include "proc_prfle_inst.h"
 #include "proc_indirect_prfle_dwnld.h"
+#include "proc_cmn_cancel_sess.h"

 /*! Perform Indirect Profile Download Procedure.
  *  \param[inout] ctx pointer to ipa_context.
@@ -33,16 +34,23 @@
 int ipa_proc_indirect_prfle_dwnlod(struct ipa_context *ctx, const struct 
ipa_proc_indirect_prfle_dwnlod_pars *pars)
 {
        struct ipa_activation_code *activation_code = NULL;
-       struct ipa_esipa_auth_clnt_res *auth_clnt_res = NULL;
-       struct ipa_esipa_get_bnd_prfle_pkg_res *get_bnd_prfle_pkg_res = NULL;
        struct ipa_proc_cmn_mtl_auth_pars cmn_mtl_auth_pars = { 0 };
-       struct ipa_proc_cmn_cancel_sess_pars cmn_cancel_sess_pars = { 0 };
-       struct ipa_proc_prfle_dwnlod_pars prfle_dwnlod_pars = { 0 };
+       struct ipa_esipa_auth_clnt_res *auth_clnt_res = NULL;
+       struct ipa_es10b_prep_dwnld_req prep_dwnld_req = { 0 };
+       struct ipa_es10b_prep_dwnld_res *prep_dwnld_res = NULL;
+       struct ipa_esipa_get_bnd_prfle_pkg_req get_bnd_prfle_pkg_req = { 0 };
+       struct ipa_esipa_get_bnd_prfle_pkg_res *get_bnd_prfle_pkg_res = NULL;
        struct ipa_proc_prfle_inst_pars prfle_inst_pars = { 0 };
+       struct ipa_proc_cmn_cancel_sess_pars cmn_cancel_sess_pars = { 0 };
+       bool cancel_session = false;

        /* This procedure is called when the IPAd receives an eIM package with 
a download trigger request
         * (which contains the activation code) */

+       /* Preset the CancelSessionReason to "undefinedReason" */
+       cmn_cancel_sess_pars.reason = CancelSessionReason_undefinedReason;
+
+       /* Step #4: Parse activation code */
        activation_code = ipa_activation_code_parse(pars->ac);
        ipa_activation_code_dump(activation_code, 0, SIPA, LDEBUG);
        if (!activation_code) {
@@ -50,7 +58,12 @@
                goto error;
        }

-       /* Execute sub procedure: Common Mutual Authentication Procedure */
+       /* Step #5-#15: Execute sub procedure: Common Mutual Authentication 
Procedure */
+       /* TODO: The Common Mutual Authentication Procedure described in GSMA 
SGP.32, section 3.2.2 is technically
+        * very similar to step #5-#15 of GSMA SGP.32, section 3.2.3.2, but it 
is not identical. Unlinke to the Direct
+        * Profile Download procedure, the Indirect Profile Download procedure 
re-defines the steps of the Common
+        * Mutual Authentication Procedure. Review and compare the affected 
steps and if necessary, re-implement them
+        * according to GSMA SGP.32, section 3.2.3.2. */
        cmn_mtl_auth_pars.tac = pars->tac;
        cmn_mtl_auth_pars.allowed_ca = pars->allowed_ca;
        cmn_mtl_auth_pars.smdp_addr = activation_code->sm_dp_plus_address;
@@ -65,29 +78,60 @@
        /* TODO: Check if ProfileMetadata contains Profile Policy Rulses (PPRs) 
and apply the PPRs as configured on the
         * eUICC. (This is an optional feature, which we currently do not 
support, see also proc_euicc_data_req.c) */

-       /* Execute sub procedure: Sub-procedure Profile Download and 
Installation – Download Confirmation */
-       prfle_dwnlod_pars.auth_clnt_ok_dpe = auth_clnt_res->auth_clnt_ok_dpe;
-       get_bnd_prfle_pkg_res = ipa_proc_prfle_dwnlod(ctx, &prfle_dwnlod_pars);
-       if (!get_bnd_prfle_pkg_res) {
-               IPA_LOGP(SIPA, LERROR, "sub procedure profile download has 
failed -- canceling session!\n");
-               cmn_cancel_sess_pars.reason = 
CancelSessionReason_loadBppExecutionError;
-               cmn_cancel_sess_pars.transaction_id = 
*auth_clnt_res->transaction_id;
-               ipa_proc_cmn_cancel_sess(ctx, &cmn_cancel_sess_pars);
+       /* Step #16: ES10b Prepare Download, in case this function call returns 
a PrepareDownloadResponseError, the
+        * procedure is stopped and the RSP session is canceled. In all other 
cases we will forward the unmodified
+        * result to the eIM to continue the procedure normally. */
+       prep_dwnld_req.req.smdpSigned2 = 
auth_clnt_res->auth_clnt_ok_dpe->smdpSigned2;
+       prep_dwnld_req.req.smdpSignature2 = 
auth_clnt_res->auth_clnt_ok_dpe->smdpSignature2;
+       prep_dwnld_req.req.smdpSignature2.size =
+           ipa_strip_tlv_envelope(prep_dwnld_req.req.smdpSignature2.buf, 
prep_dwnld_req.req.smdpSignature2.size,
+                                  0x5f37);
+       prep_dwnld_req.req.hashCc = auth_clnt_res->auth_clnt_ok_dpe->hashCc;
+       prep_dwnld_req.req.smdpCertificate = 
auth_clnt_res->auth_clnt_ok_dpe->smdpCertificate;
+       prep_dwnld_res = ipa_es10b_prep_dwnld(ctx, &prep_dwnld_req);
+       if (!prep_dwnld_res || prep_dwnld_res->prep_dwnld_err) {
+               IPA_LOGP(SIPA, LERROR, "cannot continue, download preparation 
failed!\n");
+               cancel_session = true;
                goto error;
        }

-       /* Execute sub procedure: Sub-procedure Profile Installation (See also 
section 3.1.3.3 of SGP.22) */
+       /* Step #17: ESipa GetBoundProfilePackage */
+       get_bnd_prfle_pkg_req.prep_dwnld_res = prep_dwnld_res->res;
+       get_bnd_prfle_pkg_res = ipa_esipa_get_bnd_prfle_pkg(ctx, 
&get_bnd_prfle_pkg_req);
+       if (!get_bnd_prfle_pkg_res || 
get_bnd_prfle_pkg_res->get_bnd_prfle_pkg_err
+           || !get_bnd_prfle_pkg_res->get_bnd_prfle_pkg_ok) {
+               IPA_LOGP(SIPA, LERROR, "cannot continue, get bound profile 
package failed!\n");
+               cancel_session = true;
+               goto error;
+       }
+
+       /* TODO: SGP.32, section 3.2.3.2, step 19 requires us to compare the 
SGP32_StoreMetadataRequest from
+          pars->auth_clnt_ok_dpe->profileMetaData (optional field) against the 
SGP32_StoreMetadataRequest from
+          the ES8+ StoreMetadata (see SGP.22, section 5.5.3) function call in 
the BoundProfilePackage we have
+          just received.
+
+          The ES8+ StoreMetadata function call is not encrypted, so we can 
decode it and extract the
+          SGP32_StoreMetadataRequest contents from it. Then we can do the 
comparison. In case a mismatch is
+          detected, the session should be cancelled (metadataMismatch) */
+
+       /* Step #20: Execute sub procedure: Sub-procedure Profile Installation 
(See also section 3.1.3.3 of SGP.22) */
        prfle_inst_pars.bound_profile_package = 
&get_bnd_prfle_pkg_res->get_bnd_prfle_pkg_ok->boundProfilePackage;
        if (ipa_proc_prfle_inst(ctx, &prfle_inst_pars) < 0) {
-               IPA_LOGP(SIPA, LERROR, "sub procedure profile installation has 
failed -- canceling session!\n");
                cmn_cancel_sess_pars.reason = 
CancelSessionReason_loadBppExecutionError;
+               cancel_session = true;
+       }
+
+error:
+       /* Cancal the ongoing RSP session */
+       if (cancel_session && auth_clnt_res) {
+               IPA_LOGP(SIPA, LERROR, "profile download has failed -- 
canceling session ...\n");
                cmn_cancel_sess_pars.transaction_id = 
*auth_clnt_res->transaction_id;
                ipa_proc_cmn_cancel_sess(ctx, &cmn_cancel_sess_pars);
        }

-error:
        ipa_activation_code_free(activation_code);
        ipa_esipa_auth_clnt_res_free(auth_clnt_res);
+       ipa_es10b_prep_dwnld_res_free(prep_dwnld_res);
        ipa_esipa_get_bnd_prfle_pkg_res_free(get_bnd_prfle_pkg_res);
        return 0;
 }
diff --git a/src/ipa/libipa/proc_prfle_dwnld.c 
b/src/ipa/libipa/proc_prfle_dwnld.c
deleted file mode 100644
index f9c5176..0000000
--- a/src/ipa/libipa/proc_prfle_dwnld.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (c) 2025-2026 Onomondo ApS & sysmocom - s.f.m.c. GmbH. All rights 
reserved.
- *
- * SPDX-License-Identifier: AGPL-3.0-only
- *
- * Author: Philipp Maier <[email protected]> / sysmocom - s.f.m.c. GmbH
- *
- * See also: GSMA SGP.22, section 3.1.3.2: Sub-procedure Profile Download and 
Installation – Download Confirmation
- */
-
-#include <stdio.h>
-#include <assert.h>
-#include <string.h>
-#include <errno.h>
-#include <onomondo/ipa/mem.h>
-#include <onomondo/ipa/utils.h>
-#include <onomondo/ipa/log.h>
-#include "context.h"
-#include "utils.h"
-#include "es10b_prep_dwnld.h"
-#include "esipa_get_bnd_prfle_pkg.h"
-#include "proc_prfle_dwnld.h"
-
-/*! Perform Sub-procedure Profile Download and Installation – Download 
Confirmation.
- *  \param[inout] ctx pointer to ipa_context.
- *  \param[in] pars pointer to struct that holds the procedure parameters.
- *  \returns pointer newly allocated struct with procedure result, NULL on 
error. */
-struct ipa_esipa_get_bnd_prfle_pkg_res *ipa_proc_prfle_dwnlod(struct 
ipa_context *ctx,
-                                                             const struct 
ipa_proc_prfle_dwnlod_pars *pars)
-{
-       struct ipa_es10b_prep_dwnld_req prep_dwnld_req = { 0 };
-       struct ipa_es10b_prep_dwnld_res *prep_dwnld_res = NULL;
-       struct ipa_esipa_get_bnd_prfle_pkg_req get_bnd_prfle_pkg_req = { 0 };
-       struct ipa_esipa_get_bnd_prfle_pkg_res *get_bnd_prfle_pkg_res = NULL;
-
-       prep_dwnld_req.req.smdpSigned2 = pars->auth_clnt_ok_dpe->smdpSigned2;
-       prep_dwnld_req.req.smdpSignature2 = 
pars->auth_clnt_ok_dpe->smdpSignature2;
-       prep_dwnld_req.req.smdpSignature2.size =
-           ipa_strip_tlv_envelope(prep_dwnld_req.req.smdpSignature2.buf, 
prep_dwnld_req.req.smdpSignature2.size,
-                                  0x5f37);
-       prep_dwnld_req.req.hashCc = pars->auth_clnt_ok_dpe->hashCc;
-       prep_dwnld_req.req.smdpCertificate = 
pars->auth_clnt_ok_dpe->smdpCertificate;
-
-       prep_dwnld_res = ipa_es10b_prep_dwnld(ctx, &prep_dwnld_req);
-       if (!prep_dwnld_res)
-               goto error;
-       if (prep_dwnld_res->prep_dwnld_err)
-               goto error;
-
-       /* In case the ES10b PrepareDownload returns a 
PrepareDownloadResponseError, the procedure is stopped.
-        * In all other cases we will forward the unmodified result to the eIM 
to continue the procedure normally.
-        * (see also: GSMA SGP.32, section 3.2.3.2, step 16) */
-
-       get_bnd_prfle_pkg_req.prep_dwnld_res = prep_dwnld_res->res;
-       get_bnd_prfle_pkg_res = ipa_esipa_get_bnd_prfle_pkg(ctx, 
&get_bnd_prfle_pkg_req);
-       if (!get_bnd_prfle_pkg_res)
-               goto error;
-       else if (get_bnd_prfle_pkg_res->get_bnd_prfle_pkg_err)
-               goto error;
-       else if (!get_bnd_prfle_pkg_res->get_bnd_prfle_pkg_ok)
-               goto error;
-
-       /* TODO: SGP.32, section 3.2.3.2, step 19 requires us to compare the 
SGP32_StoreMetadataRequest from
-          pars->auth_clnt_ok_dpe->profileMetaData (optional field) against the 
SGP32_StoreMetadataRequest from
-          the ES8+ StoreMetadata (see SGP.22, section 5.5.3) function call in 
the BoundProfilePackage we have
-          just received.
-
-          The ES8+ StoreMetadata function call is not encrypted, so we can 
decode it and extract the
-          SGP32_StoreMetadataRequest contents from it. Then we can do the 
comparison. In case a mismatch is
-          detected, the session should be cancelled (metadataMismatch) */
-
-       /* In case of error it is the responsibility of the caller to call the 
Common Cancel Session procedure.
-        * In case of success, the caller should ask the user for consent 
before continuing with the profile
-        * installation. */
-
-       ipa_es10b_prep_dwnld_res_free(prep_dwnld_res);
-       return get_bnd_prfle_pkg_res;
-error:
-       ipa_es10b_prep_dwnld_res_free(prep_dwnld_res);
-       ipa_esipa_get_bnd_prfle_pkg_res_free(get_bnd_prfle_pkg_res);
-       return NULL;
-}
diff --git a/src/ipa/libipa/proc_prfle_dwnld.h 
b/src/ipa/libipa/proc_prfle_dwnld.h
deleted file mode 100644
index 6c16951..0000000
--- a/src/ipa/libipa/proc_prfle_dwnld.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (c) 2025-2026 Onomondo ApS & sysmocom - s.f.m.c. GmbH. All rights 
reserved.
- *
- * SPDX-License-Identifier: AGPL-3.0-only
- */
-
-#pragma once
-
-#include <AuthenticateClientOkDPEsipa.h>
-
-struct ipa_context;
-struct ipa_esipa_get_bnd_prfle_pkg_res;
-
-struct ipa_proc_prfle_dwnlod_pars {
-       const AuthenticateClientOkDPEsipa_t *auth_clnt_ok_dpe;
-};
-
-struct ipa_esipa_get_bnd_prfle_pkg_res *ipa_proc_prfle_dwnlod(struct 
ipa_context *ctx,
-                                                             const struct 
ipa_proc_prfle_dwnlod_pars *pars);

--
To view, visit https://gerrit.osmocom.org/c/onomondo-ipa/+/43438?usp=email
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings?usp=email

Gerrit-MessageType: newchange
Gerrit-Project: onomondo-ipa
Gerrit-Branch: master
Gerrit-Change-Id: I69571280c7b52f2cb09f733bc0466cb77c0d2590
Gerrit-Change-Number: 43438
Gerrit-PatchSet: 1
Gerrit-Owner: dexter <[email protected]>

Reply via email to