saip-tool

eSIM profiles are stored as a sequence of profile element (PE) objects in an ASN.1 DER encoded binary file. To inspect, verify or make changes to those files, the saip-tool.py utility can be used.

NOTE: The file format, eSIM SAIP (SimAlliance Interoperable Profile) is specified in TCA eUICC Profile Package: Interoperable Format Technical Specification

Profile Package Examples

pySim ships with a set of TS48 profile package examples. Those examples can be found in pysim/smdpp-data/upp. The files can be used as input for saip-tool.py. (see also GSMA TS.48 - Generic eUICC Test Profile for Device Testing)

See also: https://github.com/GSMATerminals/Generic-eUICC-Test-Profile-for-Device-Testing-Public

JAVA card applets

The saip-tool.py can also be used to manage JAVA-card applets (Application PE) inside a profile package. The user has the option to add, remove and inspect applications and their instances. In the following we will discuss a few JAVA-card related use-cases of saip-tool.py

NOTE: see also contrib folder for script examples (saip-tool_example_*.sh)

Inserting applications

An application is usually inserted in two steps. In the first step, the application PE is created and populated with the executable code from a provided .cap or .ijc file. The user also has to pick a suitable load block AID.

The application instance, which exists inside the application PE, is created in a second step. Here the user must reference the load block AID and pick, among other application related parameters, a suitable class and instance AID.

Example: Adding a JAVA-card applet to an existing profile package

# Step #1: Create the application PE and load the ijc contents from the .cap file:
$ ./contrib/saip-tool.py upp.der add-app --output-file upp_with_app.der --applet-file app.cap --aid '1122334455'
Read 28 PEs from file 'upp.der'
Applying applet file: 'app.cap'...
application PE inserted into PE Sequence after securityDomain PE AID: a000000151000000
Writing 29 PEs to file 'upp_with_app.der'...

# Step #2: Create the application instance inside the application PE created in step #1:
$ ./contrib/saip-tool.py upp_with_app.der add-app-inst --output-file upp_with_app_and_instance.der \
        --aid '1122334455' \
        --class-aid '112233445501' \
        --inst-aid '112233445501' \
        --app-privileges '00' \
        --app-spec-pars '00' \
        --uicc-toolkit-app-spec-pars '01001505000000000000000000000000'
Read 29 PEs from file 'upp_with_app.der'
Found Load Package AID: 1122334455, adding new instance AID: 112233445501 to Application PE...
Writing 29 PEs to file 'upp_with_app_and_instance.der'...

NOTE: The parameters of the sub-commands add-app and add-app-inst are application specific. It is up to the application developer to pick parameters that suit the application correctly. For an exact command reference see section saip-tool syntax. For parameter details see TCA eUICC Profile Package: Interoperable Format Technical Specification, section 8.7 and ETSI TS 102 226, section 8.2.1.3.2

Inspecting applications

To inspect the application PE contents of an existing profile package, sub-command info with parameter ‘–apps’ can be used. This command lists out all application and their parameters in detail. This allows an application developer to check if the applet insertaion was carried out as expected.

Example: Listing applications and their parameters

$ ./contrib/saip-tool.py upp_with_app_and_instance.der info --apps
Read 29 PEs from file 'upp_with_app_and_instance.der'
Application #0:
        loadBlock:
                loadPackageAID: '1122334455' (5 bytes)
                loadBlockObject: '01000fdecaffed010204000105d07002ca440200...681080056810a00633b44104b431066800a10231' (569 bytes)
        instanceList[0]:
                applicationLoadPackageAID: '1122334455' (5 bytes)
                classAID: '112233445501' (8 bytes)
                instanceAID: '112233445501' (8 bytes)
                applicationPrivileges: '00' (1 bytes)
                lifeCycleState: '07' (1 bytes)
                applicationSpecificParametersC9: '00' (1 bytes)
                applicationParameters:
                        uiccToolkitApplicationSpecificParametersField: '01001505000000000000000000000000' (16 bytes)

In case further analysis with external tools or transfer of applications from one profile package to another is necessary, the executable code in the loadBlockObject field can be extracted to an .ijc or an .cap file.

Example: Extracting applications from a profile package

$ ./contrib/saip-tool.py upp_with_app_and_instance.der extract-apps --output-dir ./apps --format ijc
Read 29 PEs from file 'upp_with_app_and_instance.der'
Writing Load Package AID: 1122334455 to file ./apps/8949449999999990023f-1122334455.ijc

Removing applications

An application PE can be removed using sub-command remove-app. The user passes the load package AID as parameter. Then saip-tool.py will search for the related application PE and delete it from the PE sequence.

Example: Remove an application from a profile package

$ ./contrib/saip-tool.py upp_with_app_and_instance.der remove-app --output-file upp_without_app.der --aid '1122334455'
Read 29 PEs from file 'upp_with_app_and_instance.der'
Found Load Package AID: 1122334455, removing related PE (id=23) from Sequence...
Removing PE application (id=23) from Sequence...
Writing 28 PEs to file 'upp_without_app.der'...

In some cases it is useful to remove only an instance from an existing application PE. This may be the case when the an application developer wants to modify parameters of an application by removing and re-adding the instance. The operation basically rolls the state back to step 1 explained in section Inserting applications

Example: Remove an application instance from an application PE

$ ./contrib/saip-tool.py upp_with_app_and_instance.der remove-app-inst --output-file upp_without_app.der --aid '1122334455' --inst-aid '112233445501'
Read 29 PEs from file 'upp_with_app_and_instance.der'
Found Load Package AID: 1122334455, removing instance AID: 112233445501 from Application PE...
Removing instance from Application PE...
Writing 29 PEs to file 'upp_with_app.der'...

saip-tool syntax

Utility program to work with eSIM SAIP (SimAlliance Interoperable Profile) files.

usage: contrib/saip-tool.py [-h]
                            [--loglevel {DEBUG,INFO,WARNING,ERROR,CRITICAL}]
                            [--debug]
                            INPUT_UPP
                            {split,dump,check,extract-pe,remove-pe,remove-naa,info,extract-apps,add-app,remove-app,add-app-inst,remove-app-inst,edit-mand-srv-list,tree}
                            ...

Positional Arguments

INPUT_UPP

Unprotected Profile Package Input file

command

Possible choices: split, dump, check, extract-pe, remove-pe, remove-naa, info, extract-apps, add-app, remove-app, add-app-inst, remove-app-inst, edit-mand-srv-list, tree

The command to perform

Named Arguments

--loglevel

Possible choices: DEBUG, INFO, WARNING, ERROR, CRITICAL

Set the logging level

Default: 'INFO'

--debug

Enable DEBUG logging

Default: False

Sub-commands

split

Split PE-Sequence into individual PEs

contrib/saip-tool.py split [-h] [--output-prefix OUTPUT_PREFIX]
Named Arguments
--output-prefix

Prefix path/filename for output files

Default: '.'

dump

Dump information on PE-Sequence

contrib/saip-tool.py dump [-h] [--dump-decoded]
                          {all_pe,all_pe_by_type,all_pe_by_naa}
Positional Arguments
mode

Possible choices: all_pe, all_pe_by_type, all_pe_by_naa

Named Arguments
--dump-decoded

Dump decoded PEs

Default: False

check

Run constraint checkers on PE-Sequence

contrib/saip-tool.py check [-h]

extract-pe

Extract specified PE to (DER encoded) file

contrib/saip-tool.py extract-pe [-h] --pe-file PE_FILE
                                [--identification IDENTIFICATION]
Named Arguments
--pe-file

PE file name

--identification

Extract PE matching specified identification

remove-pe

Remove specified PEs from PE-Sequence

contrib/saip-tool.py remove-pe [-h] --output-file OUTPUT_FILE
                               [--identification IDENTIFICATION] [--type TYPE]
Named Arguments
--output-file

Output file name

--identification

Remove PEs matching specified identification

Default: []

--type

Remove PEs matching specified type

Default: []

remove-naa

Remove speciifed NAAs from PE-Sequence

contrib/saip-tool.py remove-naa [-h] --output-file OUTPUT_FILE --naa-type
                                {csim,usim,isim}
Named Arguments
--output-file

Output file name

--naa-type

Possible choices: csim, usim, isim

Network Access Application type to remove

info

Display information about the profile

contrib/saip-tool.py info [-h] [--apps]
Named Arguments
--apps

List applications and their related instances

Default: False

extract-apps

Extract applications as loadblock file

contrib/saip-tool.py extract-apps [-h] [--output-dir OUTPUT_DIR]
                                  [--format {ijc,cap}]
Named Arguments
--output-dir

Output directory (where to store files)

Default: '.'

--format

Possible choices: ijc, cap

Data format of output files

Default: 'cap'

add-app

Add application to PE-Sequence

contrib/saip-tool.py add-app [-h] --output-file OUTPUT_FILE --applet-file
                             APPLET_FILE --aid AID [--sd-aid SD_AID]
                             [--non-volatile-code-limit NON_VOLATILE_CODE_LIMIT]
                             [--volatile-data-limit VOLATILE_DATA_LIMIT]
                             [--non-volatile-data-limit NON_VOLATILE_DATA_LIMIT]
                             [--hash-value HASH_VALUE]
Named Arguments
--output-file

Output file name

--applet-file

Applet file name

--aid

Load package AID

--sd-aid

Security Domain AID

--non-volatile-code-limit

Non volatile code limit (C6)

--volatile-data-limit

Volatile data limit (C7)

--non-volatile-data-limit

Non volatile data limit (C8)

--hash-value

Hash value

remove-app

Remove application from PE-Sequence

contrib/saip-tool.py remove-app [-h] --output-file OUTPUT_FILE --aid AID
Named Arguments
--output-file

Output file name

--aid

Load package AID

add-app-inst

Add application instance to Application PE

contrib/saip-tool.py add-app-inst [-h] --output-file OUTPUT_FILE --aid AID
                                  --class-aid CLASS_AID --inst-aid INST_AID
                                  [--app-privileges APP_PRIVILEGES]
                                  [--volatile-memory-quota VOLATILE_MEMORY_QUOTA]
                                  [--non-volatile-memory-quota NON_VOLATILE_MEMORY_QUOTA]
                                  [--app-spec-pars APP_SPEC_PARS]
                                  [--uicc-toolkit-app-spec-pars UICC_TOOLKIT_APP_SPEC_PARS]
                                  [--uicc-access-app-spec-pars UICC_ACCESS_APP_SPEC_PARS]
                                  [--uicc-adm-access-app-spec-pars UICC_ADM_ACCESS_APP_SPEC_PARS]
                                  [--process-data PROCESS_DATA]
Named Arguments
--output-file

Output file name

--aid

Load package AID

--class-aid

Class AID

--inst-aid

Instance AID (must match Load package AID)

--app-privileges

Application privileges

Default: '000000'

--volatile-memory-quota

Volatile memory quota (C7)

--non-volatile-memory-quota

Non volatile memory quota (C8)

--app-spec-pars

Application specific parameters (C9)

Default: '00'

--uicc-toolkit-app-spec-pars

UICC toolkit application specific parameters field

--uicc-access-app-spec-pars

UICC Access application specific parameters field

--uicc-adm-access-app-spec-pars

UICC Administrative access application specific parameters field

--process-data

Process personalization APDUs

Default: []

remove-app-inst

Remove application instance from Application PE

contrib/saip-tool.py remove-app-inst [-h] --output-file OUTPUT_FILE --aid AID
                                     --inst-aid INST_AID
Named Arguments
--output-file

Output file name

--aid

Load package AID

--inst-aid

Instance AID

edit-mand-srv-list

Add/Remove service flag from/to mandatory services list

contrib/saip-tool.py edit-mand-srv-list [-h] --output-file OUTPUT_FILE
                                        [--add-flag {contactless,usim,isim,csim,milenage,tuak128,cave,gba-usim,gba-isim,mbms,eap,javacard,multos,multiple-usim,multiple-isim,multiple-csim,tuak256,usim-test-algorithm,ber-tlv,dfLink,cat-tp,get-identity,profile-a-x25519,profile-b-p256,suciCalculatorApi,dns-resolution,scp11ac,scp11c-authorization-mechanism,s16mode,eaka}]
                                        [--remove-flag {contactless,usim,isim,csim,milenage,tuak128,cave,gba-usim,gba-isim,mbms,eap,javacard,multos,multiple-usim,multiple-isim,multiple-csim,tuak256,usim-test-algorithm,ber-tlv,dfLink,cat-tp,get-identity,profile-a-x25519,profile-b-p256,suciCalculatorApi,dns-resolution,scp11ac,scp11c-authorization-mechanism,s16mode,eaka}]
Named Arguments
--output-file

Output file name

--add-flag

Possible choices: contactless, usim, isim, csim, milenage, tuak128, cave, gba-usim, gba-isim, mbms, eap, javacard, multos, multiple-usim, multiple-isim, multiple-csim, tuak256, usim-test-algorithm, ber-tlv, dfLink, cat-tp, get-identity, profile-a-x25519, profile-b-p256, suciCalculatorApi, dns-resolution, scp11ac, scp11c-authorization-mechanism, s16mode, eaka

Add flag to mandatory services list

Default: []

--remove-flag

Possible choices: contactless, usim, isim, csim, milenage, tuak128, cave, gba-usim, gba-isim, mbms, eap, javacard, multos, multiple-usim, multiple-isim, multiple-csim, tuak256, usim-test-algorithm, ber-tlv, dfLink, cat-tp, get-identity, profile-a-x25519, profile-b-p256, suciCalculatorApi, dns-resolution, scp11ac, scp11c-authorization-mechanism, s16mode, eaka

Remove flag from mandatory services list

Default: []

tree

Display the filesystem tree

contrib/saip-tool.py tree [-h]