import LPA library implementation from TruPhone
Converted to gradle build and updated a bunch of dependencies.
This commit is contained in:
parent
93f1d1baf1
commit
9ca4ce2798
|
@ -13,3 +13,4 @@
|
||||||
.externalNativeBuild
|
.externalNativeBuild
|
||||||
.cxx
|
.cxx
|
||||||
local.properties
|
local.properties
|
||||||
|
/libs/**/build
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="CompilerConfiguration">
|
<component name="CompilerConfiguration">
|
||||||
<bytecodeTargetLevel target="11" />
|
<bytecodeTargetLevel target="1.8">
|
||||||
|
<module name="OpenEUICC.app" target="11" />
|
||||||
|
</bytecodeTargetLevel>
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
|
@ -1,5 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
|
<component name="GradleMigrationSettings" migrationVersion="1" />
|
||||||
<component name="GradleSettings">
|
<component name="GradleSettings">
|
||||||
<option name="linkedExternalProjectsSettings">
|
<option name="linkedExternalProjectsSettings">
|
||||||
<GradleProjectSettings>
|
<GradleProjectSettings>
|
||||||
|
@ -11,6 +12,8 @@
|
||||||
<set>
|
<set>
|
||||||
<option value="$PROJECT_DIR$" />
|
<option value="$PROJECT_DIR$" />
|
||||||
<option value="$PROJECT_DIR$/app" />
|
<option value="$PROJECT_DIR$/app" />
|
||||||
|
<option value="$PROJECT_DIR$/libs" />
|
||||||
|
<option value="$PROJECT_DIR$/libs/lpad-sm-dp-plus-connector" />
|
||||||
</set>
|
</set>
|
||||||
</option>
|
</option>
|
||||||
<option name="resolveModulePerSourceSet" value="false" />
|
<option name="resolveModulePerSourceSet" value="false" />
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectType">
|
<component name="ProjectType">
|
||||||
|
|
|
@ -32,7 +32,7 @@ android {
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
implementation project(":libs:lpad-sm-dp-plus-connector")
|
||||||
implementation 'androidx.core:core-ktx:1.7.0'
|
implementation 'androidx.core:core-ktx:1.7.0'
|
||||||
implementation 'androidx.appcompat:appcompat:1.4.1'
|
implementation 'androidx.appcompat:appcompat:1.4.1'
|
||||||
implementation 'com.google.android.material:material:1.5.0'
|
implementation 'com.google.android.material:material:1.5.0'
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<classpath>
|
||||||
|
<classpathentry kind="src" output="target/classes" path="src/main/java">
|
||||||
|
<attributes>
|
||||||
|
<attribute name="optional" value="true"/>
|
||||||
|
<attribute name="maven.pomderived" value="true"/>
|
||||||
|
</attributes>
|
||||||
|
</classpathentry>
|
||||||
|
<classpathentry kind="src" output="target/classes" path="target/generated-sources/asn1">
|
||||||
|
<attributes>
|
||||||
|
<attribute name="optional" value="true"/>
|
||||||
|
<attribute name="maven.pomderived" value="true"/>
|
||||||
|
</attributes>
|
||||||
|
</classpathentry>
|
||||||
|
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
|
||||||
|
<attributes>
|
||||||
|
<attribute name="maven.pomderived" value="true"/>
|
||||||
|
</attributes>
|
||||||
|
</classpathentry>
|
||||||
|
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
|
||||||
|
<attributes>
|
||||||
|
<attribute name="optional" value="true"/>
|
||||||
|
<attribute name="maven.pomderived" value="true"/>
|
||||||
|
<attribute name="test" value="true"/>
|
||||||
|
</attributes>
|
||||||
|
</classpathentry>
|
||||||
|
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11">
|
||||||
|
<attributes>
|
||||||
|
<attribute name="maven.pomderived" value="true"/>
|
||||||
|
</attributes>
|
||||||
|
</classpathentry>
|
||||||
|
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
|
||||||
|
<attributes>
|
||||||
|
<attribute name="maven.pomderived" value="true"/>
|
||||||
|
</attributes>
|
||||||
|
</classpathentry>
|
||||||
|
<classpathentry kind="src" path="target/generated-sources/annotations">
|
||||||
|
<attributes>
|
||||||
|
<attribute name="optional" value="true"/>
|
||||||
|
<attribute name="maven.pomderived" value="true"/>
|
||||||
|
<attribute name="ignore_optional_problems" value="true"/>
|
||||||
|
<attribute name="m2e-apt" value="true"/>
|
||||||
|
</attributes>
|
||||||
|
</classpathentry>
|
||||||
|
<classpathentry kind="src" output="target/test-classes" path="target/generated-test-sources/test-annotations">
|
||||||
|
<attributes>
|
||||||
|
<attribute name="optional" value="true"/>
|
||||||
|
<attribute name="maven.pomderived" value="true"/>
|
||||||
|
<attribute name="ignore_optional_problems" value="true"/>
|
||||||
|
<attribute name="m2e-apt" value="true"/>
|
||||||
|
<attribute name="test" value="true"/>
|
||||||
|
</attributes>
|
||||||
|
</classpathentry>
|
||||||
|
<classpathentry kind="output" path="target/classes"/>
|
||||||
|
</classpath>
|
|
@ -0,0 +1,23 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<projectDescription>
|
||||||
|
<name>lpad-sm-dp-plus-connector</name>
|
||||||
|
<comment></comment>
|
||||||
|
<projects>
|
||||||
|
</projects>
|
||||||
|
<buildSpec>
|
||||||
|
<buildCommand>
|
||||||
|
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
<buildCommand>
|
||||||
|
<name>org.eclipse.m2e.core.maven2Builder</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
</buildSpec>
|
||||||
|
<natures>
|
||||||
|
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||||
|
<nature>org.eclipse.m2e.core.maven2Nature</nature>
|
||||||
|
</natures>
|
||||||
|
</projectDescription>
|
|
@ -0,0 +1,6 @@
|
||||||
|
eclipse.preferences.version=1
|
||||||
|
encoding//src/main/java=UTF-8
|
||||||
|
encoding//src/main/resources=UTF-8
|
||||||
|
encoding//src/test/java=UTF-8
|
||||||
|
encoding//target/generated-sources/asn1=UTF-8
|
||||||
|
encoding/<project>=UTF-8
|
|
@ -0,0 +1,2 @@
|
||||||
|
eclipse.preferences.version=1
|
||||||
|
org.eclipse.jdt.apt.aptEnabled=false
|
|
@ -0,0 +1,9 @@
|
||||||
|
eclipse.preferences.version=1
|
||||||
|
org.eclipse.jdt.core.compiler.codegen.targetPlatform=11
|
||||||
|
org.eclipse.jdt.core.compiler.compliance=11
|
||||||
|
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
|
||||||
|
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
|
||||||
|
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore
|
||||||
|
org.eclipse.jdt.core.compiler.processAnnotations=disabled
|
||||||
|
org.eclipse.jdt.core.compiler.release=disabled
|
||||||
|
org.eclipse.jdt.core.compiler.source=11
|
|
@ -0,0 +1,4 @@
|
||||||
|
activeProfiles=
|
||||||
|
eclipse.preferences.version=1
|
||||||
|
resolveWorkspaceProjects=true
|
||||||
|
version=1
|
|
@ -0,0 +1,36 @@
|
||||||
|
apply plugin: 'java'
|
||||||
|
|
||||||
|
configurations {
|
||||||
|
tool
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
tool 'javax.xml.bind:jaxb-api:2.3.0'
|
||||||
|
tool 'com.beanit:asn1bean-compiler:1.13.0'
|
||||||
|
implementation 'com.beanit:asn1bean:1.13.0'
|
||||||
|
implementation 'com.fazecast:jSerialComm:1.3.11'
|
||||||
|
implementation 'org.apache.commons:commons-lang3:3.7'
|
||||||
|
implementation 'commons-io:commons-io:2.6'
|
||||||
|
implementation 'commons-codec:commons-codec:1.11'
|
||||||
|
implementation 'com.google.code.gson:gson:2.8.4'
|
||||||
|
testImplementation 'junit:junit:4.12'
|
||||||
|
testImplementation 'org.mockito:mockito-all:1.10.19'
|
||||||
|
testImplementation 'com.github.tomakehurst:wiremock:2.17.0'
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceSets.main.java.srcDirs = ['build/generated-sources/asn1','src/main/java']
|
||||||
|
|
||||||
|
task genAsn1(type: JavaExec) {
|
||||||
|
mainClass = 'com.beanit.asn1bean.compiler.Compiler'
|
||||||
|
args "-o", "$projectDir/build/generated-sources/asn1", "-p", "com.truphone.rsp.dto.asn1", "-f", "$projectDir/src/main/resources/PKIXExplicit88.asn", "$projectDir/src/main/resources/PKIXImplicit88.asn", "$projectDir/src/main/resources/rsp.asn"
|
||||||
|
classpath configurations.tool
|
||||||
|
}
|
||||||
|
|
||||||
|
compileJava.dependsOn genAsn1
|
||||||
|
|
||||||
|
description = 'LPAd SM-DP+ Connector'
|
||||||
|
|
||||||
|
java {
|
||||||
|
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||||
|
targetCompatibility = JavaVersion.VERSION_1_8
|
||||||
|
}
|
|
@ -0,0 +1,170 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<artifactId>lpad-sm-dp-plus-parent</artifactId>
|
||||||
|
<groupId>com.truphone.lpad</groupId>
|
||||||
|
<version>1.0.4</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>lpad-sm-dp-plus-connector</artifactId>
|
||||||
|
<name>LPAd SM-DP+ Connector</name>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.openmuc</groupId>
|
||||||
|
<artifactId>jasn1-compiler</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fazecast</groupId>
|
||||||
|
<artifactId>jSerialComm</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-lang3</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-io</groupId>
|
||||||
|
<artifactId>commons-io</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-codec</groupId>
|
||||||
|
<artifactId>commons-codec</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.code.gson</groupId>
|
||||||
|
<artifactId>gson</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mockito</groupId>
|
||||||
|
<artifactId>mockito-all</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.tomakehurst</groupId>
|
||||||
|
<artifactId>wiremock</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<compilerVersion>${java.version}</compilerVersion>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
|
<artifactId>exec-maven-plugin</artifactId>
|
||||||
|
<version>${exec-maven-plugin.version}</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>generate-resources</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>java</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
<configuration>
|
||||||
|
<executable>java</executable>
|
||||||
|
<mainClass>org.openmuc.jasn1.compiler.Compiler</mainClass>
|
||||||
|
<arguments>
|
||||||
|
<argument>-o</argument>
|
||||||
|
<argument>${project.basedir}/target/generated-sources/asn1/</argument>
|
||||||
|
<argument>-p</argument>
|
||||||
|
<argument>com.truphone.rsp.dto.asn1</argument>
|
||||||
|
<argument>-f</argument>
|
||||||
|
<argument>${project.basedir}/src/main/resources/PKIXExplicit88.asn</argument>
|
||||||
|
<argument>${project.basedir}/src/main/resources/PKIXImplicit88.asn</argument>
|
||||||
|
<argument>${project.basedir}/src/main/resources/rsp.asn</argument>
|
||||||
|
</arguments>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
|
<artifactId>build-helper-maven-plugin</artifactId>
|
||||||
|
<version>${build-helper-maven-plugin}</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>generate-sources</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>add-source</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<sources>
|
||||||
|
<source>${project.basedir}/target/generated-sources/asn1/</source>
|
||||||
|
</sources>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<!-- Build an executable JAR -->
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
<version>${maven-jar-plugin.version}</version>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifest>
|
||||||
|
<addClasspath>true</addClasspath>
|
||||||
|
<classpathPrefix>lib/</classpathPrefix>
|
||||||
|
<mainClass>com.truphone.lpa.ProfileAssistant</mainClass>
|
||||||
|
</manifest>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
<version>${maven-assembly-plugin.version}</version>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifest>
|
||||||
|
<mainClass>com.truphone.lpa.ProfileAssistant</mainClass>
|
||||||
|
</manifest>
|
||||||
|
</archive>
|
||||||
|
<descriptorRefs>
|
||||||
|
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||||
|
</descriptorRefs>
|
||||||
|
</configuration>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>make-assembly</id> <!-- this is used for inheritance merges -->
|
||||||
|
<phase>package</phase> <!-- bind to the packaging phase -->
|
||||||
|
<goals>
|
||||||
|
<goal>single</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.jacoco</groupId>
|
||||||
|
<artifactId>jacoco-maven-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-failsafe-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>integration-test</goal>
|
||||||
|
<goal>verify</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
|
@ -0,0 +1,59 @@
|
||||||
|
package com.truphone.es9plus;
|
||||||
|
|
||||||
|
public class AllocateProfileResponse {
|
||||||
|
private String acFormat;
|
||||||
|
private String smDpPlusAddress;
|
||||||
|
private String acToken;
|
||||||
|
private String smDpPlusOid;
|
||||||
|
private String confirmationCodeRequiredFlag;
|
||||||
|
|
||||||
|
public String getAcFormat() {
|
||||||
|
|
||||||
|
return acFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAcFormat(String acFormat) {
|
||||||
|
|
||||||
|
this.acFormat = acFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSmDpPlusAddress() {
|
||||||
|
|
||||||
|
return smDpPlusAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSmDpPlusAddress(String smDpPlusAddress) {
|
||||||
|
|
||||||
|
this.smDpPlusAddress = smDpPlusAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAcToken() {
|
||||||
|
|
||||||
|
return acToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAcToken(String acToken) {
|
||||||
|
|
||||||
|
this.acToken = acToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSmDpPlusOid() {
|
||||||
|
|
||||||
|
return smDpPlusOid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSmDpPlusOid(String smDpPlusOid) {
|
||||||
|
|
||||||
|
this.smDpPlusOid = smDpPlusOid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getConfirmationCodeRequiredFlag() {
|
||||||
|
|
||||||
|
return confirmationCodeRequiredFlag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setConfirmationCodeRequiredFlag(String confirmationCodeRequiredFlag) {
|
||||||
|
|
||||||
|
this.confirmationCodeRequiredFlag = confirmationCodeRequiredFlag;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,216 @@
|
||||||
|
package com.truphone.es9plus;
|
||||||
|
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
|
import com.truphone.es9plus.message.request.AuthenticateClientReq;
|
||||||
|
import com.truphone.es9plus.message.request.GetBoundProfilePackageReq;
|
||||||
|
import com.truphone.es9plus.message.request.HandleNotificationReq;
|
||||||
|
import com.truphone.es9plus.message.request.InitiateAuthenticationReq;
|
||||||
|
import com.truphone.es9plus.message.response.AuthenticateClientResp;
|
||||||
|
import com.truphone.es9plus.message.response.GetBoundProfilePackageResp;
|
||||||
|
import com.truphone.es9plus.message.response.InitiateAuthenticationResp;
|
||||||
|
import com.truphone.util.LogStub;
|
||||||
|
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
public class Es9PlusImpl {
|
||||||
|
private static final Gson GS = new GsonBuilder().disableHtmlEscaping().create();
|
||||||
|
private static final Logger LOG = Logger.getLogger(Es9PlusImpl.class.getName());
|
||||||
|
private static final String INITIATE_AUTHENTICATION_PATH = "/gsma/rsp2/es9plus/initiateAuthentication";
|
||||||
|
private static final String AUTHENTICATE_CLIENT_PATH = "/gsma/rsp2/es9plus/authenticateClient";
|
||||||
|
private static final String GET_BOUND_PROFILE_PACKAGE_PATH = "/gsma/rsp2/es9plus/getBoundProfilePackage";
|
||||||
|
private static final String HANDLE_NOTIFICATION_PATH = "/gsma/rsp2/es9plus/handleNotification";
|
||||||
|
//private static final String ALLOCATE_PROFILE_PATH = "/custom/profile/";
|
||||||
|
|
||||||
|
// private String rspServerUrl;
|
||||||
|
|
||||||
|
// public void configure(String rspServerUrl) {
|
||||||
|
//
|
||||||
|
// this.rspServerUrl = rspServerUrl;
|
||||||
|
// }
|
||||||
|
|
||||||
|
public InitiateAuthenticationResp initiateAuthentication(final String euiccChallenge,
|
||||||
|
final String euiccInfo1,
|
||||||
|
final String smdpAddress) {
|
||||||
|
try {
|
||||||
|
InitiateAuthenticationReq initiateAuthenticationReq = new InitiateAuthenticationReq();
|
||||||
|
initiateAuthenticationReq.setEuiccChallenge(euiccChallenge);
|
||||||
|
initiateAuthenticationReq.setEuiccInfo1(euiccInfo1);
|
||||||
|
initiateAuthenticationReq.setSmdpAddress(smdpAddress);
|
||||||
|
String body = GS.toJson(initiateAuthenticationReq);
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, "RSP Request: " + body);
|
||||||
|
}
|
||||||
|
|
||||||
|
HttpResponse result = new HttpRSPClient().clientRSPRequest(body, "https://"+smdpAddress, INITIATE_AUTHENTICATION_PATH);
|
||||||
|
if (result != null && !"".equals(result.getContent())) {
|
||||||
|
String response = toJsonString(result.getContent());
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, "RSP Response: " + response);
|
||||||
|
}
|
||||||
|
return GS.fromJson(response, InitiateAuthenticationResp.class);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOG.log(Level.SEVERE, "Error contacting RSP Server", e);
|
||||||
|
|
||||||
|
throw new RuntimeException("Unable to communicate with RSP Server");
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AuthenticateClientResp authenticateClient(final String transactionId,
|
||||||
|
final String authenticateServerResponse,
|
||||||
|
final String smdpAddress) {
|
||||||
|
try {
|
||||||
|
AuthenticateClientReq authenticateClientReq = new AuthenticateClientReq();
|
||||||
|
authenticateClientReq.setTransactionId(transactionId);
|
||||||
|
authenticateClientReq.setAuthenticateServerResponse(authenticateServerResponse);
|
||||||
|
String body = GS.toJson(authenticateClientReq);
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, "RSP Request: " + body);
|
||||||
|
}
|
||||||
|
|
||||||
|
HttpResponse result = new HttpRSPClient().clientRSPRequest(body, "https://" + smdpAddress, AUTHENTICATE_CLIENT_PATH);
|
||||||
|
if (result != null && !"".equals(result.getContent())) {
|
||||||
|
String response = toJsonString(result.getContent());
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, "RSP Response: " + response);
|
||||||
|
}
|
||||||
|
|
||||||
|
return GS.fromJson(response, AuthenticateClientResp.class);
|
||||||
|
} else {
|
||||||
|
LOG.severe("Error contacting RSP Server");
|
||||||
|
|
||||||
|
throw new RuntimeException("Unable to communicate with RSP Server");
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOG.log(Level.SEVERE, "Error contacting RSP Server", e);
|
||||||
|
|
||||||
|
throw new RuntimeException("Unable to communicate with RSP Server");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public GetBoundProfilePackageResp getBoundProfilePackage(final String transactionId,
|
||||||
|
final String prepareDownloadResponse,
|
||||||
|
final String smdpAddress) {
|
||||||
|
try {
|
||||||
|
GetBoundProfilePackageReq getBoundProfilePackageReq = new GetBoundProfilePackageReq();
|
||||||
|
getBoundProfilePackageReq.setTransactionId(transactionId);
|
||||||
|
getBoundProfilePackageReq.setPrepareDownloadResponse(prepareDownloadResponse);
|
||||||
|
String body = GS.toJson(getBoundProfilePackageReq);
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, "RSP Request: " + body);
|
||||||
|
}
|
||||||
|
|
||||||
|
HttpResponse result = new HttpRSPClient().clientRSPRequest(body, "https://" + smdpAddress, GET_BOUND_PROFILE_PACKAGE_PATH);
|
||||||
|
if (result != null && !"".equals(result.getContent())) {
|
||||||
|
String response = toJsonString(result.getContent());
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, "RSP Response: " + response);
|
||||||
|
}
|
||||||
|
|
||||||
|
return GS.fromJson(response, GetBoundProfilePackageResp.class);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOG.log(Level.SEVERE, "Error contacting RSP Server", e);
|
||||||
|
|
||||||
|
throw new RuntimeException("Unable to communicate with RSP Server");
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ES9+.handleNotification
|
||||||
|
*/
|
||||||
|
public void handleNotification(final String pendingNotification, String serverAddress) {
|
||||||
|
try {
|
||||||
|
HandleNotificationReq handleNotificationReq = new HandleNotificationReq();
|
||||||
|
|
||||||
|
handleNotificationReq.setPendingNotification(pendingNotification);
|
||||||
|
|
||||||
|
String body = GS.toJson(handleNotificationReq);
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, "RSP Request: " + body);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HttpResponse result = new HttpRSPClient().clientRSPRequest(body, "https://"+serverAddress, HANDLE_NOTIFICATION_PATH);
|
||||||
|
|
||||||
|
if (result != null && result.getStatusCode() == 204) {
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, "RSP Response was 204 ");
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
LOG.severe("Error contacting RSP Server or not 204: " + result);
|
||||||
|
|
||||||
|
throw new RuntimeException("Unable to handle notification with RSP Server");
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOG.log(Level.SEVERE, "Error contacting RSP Server", e);
|
||||||
|
|
||||||
|
throw new RuntimeException("Unable to handle notification with RSP Server");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// public AllocateProfileResponse allocateProfile(final String eid,
|
||||||
|
// final String mcc) {
|
||||||
|
//
|
||||||
|
// try {
|
||||||
|
// String body = "eid=" + eid + "&mcc=" + mcc;
|
||||||
|
//
|
||||||
|
// if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
// LogStub.getInstance().logDebug(LOG, "RSP Request: " + body);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// HttpResponse result = new HttpRSPClient().clientSimpleRequest(body, rspServerUrl, ALLOCATE_PROFILE_PATH);
|
||||||
|
//
|
||||||
|
// if (result != null && !"".equals(result.getContent())) {
|
||||||
|
// if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
// LogStub.getInstance().logDebug(LOG, "RSP Response: " + result);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return getAllocateProfileResponse(result.getContent());
|
||||||
|
// } else {
|
||||||
|
// throw new RuntimeException("No profile could be allocated");
|
||||||
|
// }
|
||||||
|
// } catch (Exception e) {
|
||||||
|
// LOG.log(Level.SEVERE, e.getMessage(), e);
|
||||||
|
//
|
||||||
|
// throw new RuntimeException("Unable to allocate profile with RSP Server");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
private AllocateProfileResponse getAllocateProfileResponse(final String content) {
|
||||||
|
AllocateProfileResponse allocateProfileResponse = null;
|
||||||
|
String fixedContent = content != null ? (content.startsWith("$") ? content.substring(1) : content) : "";
|
||||||
|
String[] responseTokens = fixedContent.split("\\$");
|
||||||
|
|
||||||
|
if (responseTokens.length > 1) {
|
||||||
|
allocateProfileResponse = new AllocateProfileResponse();
|
||||||
|
allocateProfileResponse.setAcFormat(responseTokens[0]);
|
||||||
|
allocateProfileResponse.setSmDpPlusAddress(responseTokens[1]);
|
||||||
|
allocateProfileResponse.setAcToken(responseTokens.length > 2 ? responseTokens[2] : "");
|
||||||
|
allocateProfileResponse.setSmDpPlusOid(responseTokens.length > 3 ? responseTokens[3] : null);
|
||||||
|
allocateProfileResponse.setConfirmationCodeRequiredFlag(responseTokens.length > 4 ? responseTokens[4] : null);
|
||||||
|
}
|
||||||
|
|
||||||
|
return allocateProfileResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String toJsonString(final String msg) {
|
||||||
|
int index = msg.indexOf("{");
|
||||||
|
|
||||||
|
return msg.substring(index);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,122 @@
|
||||||
|
package com.truphone.es9plus;
|
||||||
|
|
||||||
|
import com.truphone.util.LogStub;
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import java.io.BufferedWriter;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.io.OutputStreamWriter;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
public class HttpRSPClient {
|
||||||
|
private static final Logger LOG = Logger.getLogger(HttpRSPClient.class.getName());
|
||||||
|
|
||||||
|
public HttpResponse clientRSPRequest(final String body,
|
||||||
|
final String rspServerUrl,
|
||||||
|
final String url) throws Exception {
|
||||||
|
|
||||||
|
Pair<String, String> contentType = new Pair<>("Content-Type", "application/json");
|
||||||
|
Pair<String, String> accept = new Pair<>("Accept", "application/json");
|
||||||
|
Pair<String, String> userAgent = new Pair<>("User-Agent", "gsma-rsp-com.truphone.lpad");
|
||||||
|
Pair<String, String> xAdminProtocol = new Pair<>("X-Admin-Protocol", "gsma/rsp/v2.2.0");
|
||||||
|
|
||||||
|
return invoke("POST", body, rspServerUrl, url, Arrays.asList(contentType, accept, userAgent, xAdminProtocol));
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpResponse clientSimpleRequest(final String body,
|
||||||
|
final String rspServerUrl,
|
||||||
|
final String url) throws Exception {
|
||||||
|
|
||||||
|
Pair<String, String> contentType = new Pair<>("Content-type", "application/x-www-form-urlencoded");
|
||||||
|
Pair<String, String> userAgent = new Pair<>("User-Agent", "gsma-rsp-com.truphone.lpad");
|
||||||
|
Pair<String, String> xAdminProtocol = new Pair<>("X-Admin-Protocol", "gsma/rsp/v2.2.0");
|
||||||
|
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - HttpRSPClient - clientSimpleRequest parameters - body : " +
|
||||||
|
body + " rspServerUrl:" + rspServerUrl + " contentType: " + contentType + " user agent: " + userAgent +
|
||||||
|
" xAdminProtocol: " + xAdminProtocol + " url: " + url);
|
||||||
|
}
|
||||||
|
|
||||||
|
return invoke("POST", body, rspServerUrl, url, Arrays.asList(contentType, userAgent, xAdminProtocol));
|
||||||
|
}
|
||||||
|
|
||||||
|
private HttpResponse invoke(final String method,
|
||||||
|
final String body,
|
||||||
|
final String rspServerUrl,
|
||||||
|
final String url,
|
||||||
|
final List<Pair<String, String>> headers) throws Exception {
|
||||||
|
|
||||||
|
StringBuilder endpoint = new StringBuilder(rspServerUrl);
|
||||||
|
HttpResponse httpResponse = new HttpResponse();
|
||||||
|
|
||||||
|
if (StringUtils.isNotBlank(url)) {
|
||||||
|
endpoint.append(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - HttpRSPClient - invoke URL: " + endpoint.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
URL urlResource = new URL(endpoint.toString());
|
||||||
|
HttpURLConnection con = (HttpURLConnection) urlResource.openConnection();
|
||||||
|
|
||||||
|
con.setDoInput(true);
|
||||||
|
con.setDoOutput(true);
|
||||||
|
con.setRequestMethod(method);
|
||||||
|
con.setConnectTimeout(600000);
|
||||||
|
con.setReadTimeout(600000);
|
||||||
|
|
||||||
|
if (headers != null) {
|
||||||
|
for (Pair<String, String> header : headers) {
|
||||||
|
con.setRequestProperty(header.getKey(), header.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
OutputStream os = con.getOutputStream();
|
||||||
|
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
|
||||||
|
|
||||||
|
writer.write(body);
|
||||||
|
writer.flush();
|
||||||
|
writer.close();
|
||||||
|
|
||||||
|
os.close();
|
||||||
|
|
||||||
|
httpResponse.setStatusCode(con.getResponseCode());
|
||||||
|
httpResponse.setContent(IOUtils.toString(con.getInputStream(), StandardCharsets.UTF_8));
|
||||||
|
|
||||||
|
return httpResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class Pair<T, E> {
|
||||||
|
private T key;
|
||||||
|
private E value;
|
||||||
|
|
||||||
|
public Pair(T key, E value) {
|
||||||
|
this.key = key;
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T getKey() {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setKey(T key) {
|
||||||
|
this.key = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public E getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValue(E value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
package com.truphone.es9plus;
|
||||||
|
|
||||||
|
public class HttpResponse {
|
||||||
|
private String content;
|
||||||
|
private int statusCode;
|
||||||
|
|
||||||
|
public String getContent() {
|
||||||
|
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setContent(String content) {
|
||||||
|
|
||||||
|
this.content = content;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getStatusCode() {
|
||||||
|
|
||||||
|
return statusCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatusCode(int statusCode) {
|
||||||
|
|
||||||
|
this.statusCode = statusCode;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
package com.truphone.es9plus;
|
||||||
|
|
||||||
|
public class LpaUtils {
|
||||||
|
public static String generateCtxParams1() {
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
package com.truphone.es9plus.message;
|
||||||
|
|
||||||
|
public interface MsgBody {
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package com.truphone.es9plus.message;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
@Target(ElementType.TYPE)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface MsgType {
|
||||||
|
String value();
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
package com.truphone.es9plus.message.request;
|
||||||
|
|
||||||
|
|
||||||
|
import com.truphone.es9plus.message.MsgType;
|
||||||
|
import com.truphone.es9plus.message.request.base.RequestMsgBody;
|
||||||
|
|
||||||
|
@MsgType("/gsma/rsp2/es9plus/authenticateClient")
|
||||||
|
public class AuthenticateClientReq extends RequestMsgBody {
|
||||||
|
private String transactionId;
|
||||||
|
private String authenticateServerResponse;
|
||||||
|
|
||||||
|
public String getTransactionId() {
|
||||||
|
return transactionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTransactionId(String transactionId) {
|
||||||
|
this.transactionId = transactionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAuthenticateServerResponse() {
|
||||||
|
return authenticateServerResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAuthenticateServerResponse(String authenticateServerResponse) {
|
||||||
|
this.authenticateServerResponse = authenticateServerResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
package com.truphone.es9plus.message.request;
|
||||||
|
|
||||||
|
|
||||||
|
import com.truphone.es9plus.message.MsgType;
|
||||||
|
import com.truphone.es9plus.message.request.base.RequestMsgBody;
|
||||||
|
|
||||||
|
@MsgType("/gsma/rsp2/es9plus/cancelSession")
|
||||||
|
public class CancelSessionReq extends RequestMsgBody {
|
||||||
|
private String transactionId;
|
||||||
|
private String euiccCancelSessionSigned;
|
||||||
|
private String euiccCancelSessionSignature;
|
||||||
|
|
||||||
|
public String getTransactionId() {
|
||||||
|
return transactionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTransactionId(String transactionId) {
|
||||||
|
this.transactionId = transactionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEuiccCancelSessionSigned() {
|
||||||
|
return euiccCancelSessionSigned;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEuiccCancelSessionSigned(String euiccCancelSessionSigned) {
|
||||||
|
this.euiccCancelSessionSigned = euiccCancelSessionSigned;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEuiccCancelSessionSignature() {
|
||||||
|
return euiccCancelSessionSignature;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEuiccCancelSessionSignature(String euiccCancelSessionSignature) {
|
||||||
|
this.euiccCancelSessionSignature = euiccCancelSessionSignature;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
package com.truphone.es9plus.message.request;
|
||||||
|
|
||||||
|
|
||||||
|
import com.truphone.es9plus.message.MsgType;
|
||||||
|
import com.truphone.es9plus.message.request.base.RequestMsgBody;
|
||||||
|
|
||||||
|
@MsgType("/gsma/rsp2/es2plus/confirmOrder")
|
||||||
|
public class ConfirmOrderReq extends RequestMsgBody {
|
||||||
|
private String iccid;
|
||||||
|
private String eid;
|
||||||
|
private String matchingId;
|
||||||
|
private String comfirmationCode;
|
||||||
|
private String smdsAddress;
|
||||||
|
private boolean releaseFlag;
|
||||||
|
public String getIccid() {
|
||||||
|
return iccid;
|
||||||
|
}
|
||||||
|
public void setIccid(String iccid) {
|
||||||
|
this.iccid = iccid;
|
||||||
|
}
|
||||||
|
public String getEid() {
|
||||||
|
return eid;
|
||||||
|
}
|
||||||
|
public void setEid(String eid) {
|
||||||
|
this.eid = eid;
|
||||||
|
}
|
||||||
|
public String getMatchingId() {
|
||||||
|
return matchingId;
|
||||||
|
}
|
||||||
|
public void setMatchingId(String matchingId) {
|
||||||
|
this.matchingId = matchingId;
|
||||||
|
}
|
||||||
|
public String getComfirmationCode() {
|
||||||
|
return comfirmationCode;
|
||||||
|
}
|
||||||
|
public void setComfirmationCode(String comfirmationCode) {
|
||||||
|
this.comfirmationCode = comfirmationCode;
|
||||||
|
}
|
||||||
|
public String getSmdsAddress() {
|
||||||
|
return smdsAddress;
|
||||||
|
}
|
||||||
|
public void setSmdsAddress(String smdsAddress) {
|
||||||
|
this.smdsAddress = smdsAddress;
|
||||||
|
}
|
||||||
|
public boolean getReleaseFlag() {
|
||||||
|
return releaseFlag;
|
||||||
|
}
|
||||||
|
public void setReleaseFlag(boolean releaseFlag) {
|
||||||
|
this.releaseFlag = releaseFlag;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
package com.truphone.es9plus.message.request;
|
||||||
|
|
||||||
|
import com.truphone.es9plus.message.MsgType;
|
||||||
|
import com.truphone.es9plus.message.request.base.RequestMsgBody;
|
||||||
|
|
||||||
|
@MsgType("/gsma/rsp2/es2plus/downloadOrder")
|
||||||
|
public class DownloadOrderReq extends RequestMsgBody {
|
||||||
|
private String eid;
|
||||||
|
private String iccid;
|
||||||
|
private String profileType;
|
||||||
|
private String msisdn;
|
||||||
|
|
||||||
|
public String getMsisdn() {
|
||||||
|
return msisdn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMsisdn(String msisdn) {
|
||||||
|
this.msisdn = msisdn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEid() {
|
||||||
|
return eid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEid(String eid) {
|
||||||
|
this.eid = eid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getIccid() {
|
||||||
|
return iccid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIccid(String iccid) {
|
||||||
|
this.iccid = iccid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getProfileType() {
|
||||||
|
return profileType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProfileType(String profileType) {
|
||||||
|
this.profileType = profileType;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
package com.truphone.es9plus.message.request;
|
||||||
|
|
||||||
|
|
||||||
|
import com.truphone.es9plus.message.MsgType;
|
||||||
|
import com.truphone.es9plus.message.request.base.RequestMsgBody;
|
||||||
|
|
||||||
|
@MsgType("/gsma/rsp2/es9plus/getBoundProfilePackage")
|
||||||
|
public class GetBoundProfilePackageReq extends RequestMsgBody {
|
||||||
|
private String transactionId;
|
||||||
|
private String prepareDownloadResponse;
|
||||||
|
|
||||||
|
public String getTransactionId() {
|
||||||
|
return transactionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTransactionId(String transactionId) {
|
||||||
|
this.transactionId = transactionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPrepareDownloadResponse() {
|
||||||
|
return prepareDownloadResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPrepareDownloadResponse(String prepareDownloadResponse) {
|
||||||
|
this.prepareDownloadResponse = prepareDownloadResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,74 @@
|
||||||
|
package com.truphone.es9plus.message.request;
|
||||||
|
|
||||||
|
import com.truphone.es9plus.message.MsgType;
|
||||||
|
import com.truphone.es9plus.message.request.base.RequestMsgBody;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
@MsgType("/gsma/rsp2/es2plus/handleDownloadProgressInfo")
|
||||||
|
public class HandleDownloadProgressInfoReq extends RequestMsgBody {
|
||||||
|
private String eid;
|
||||||
|
private String iccid;
|
||||||
|
private String profileType;
|
||||||
|
private Date timestamp;
|
||||||
|
private int notificationPointId;
|
||||||
|
private String notificationPointStatus;
|
||||||
|
private String resultData;
|
||||||
|
|
||||||
|
public String getEid() {
|
||||||
|
return eid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEid(String eid) {
|
||||||
|
this.eid = eid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getIccid() {
|
||||||
|
return iccid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIccid(String iccid) {
|
||||||
|
this.iccid = iccid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getProfileType() {
|
||||||
|
return profileType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProfileType(String profileType) {
|
||||||
|
this.profileType = profileType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getTimestamp() {
|
||||||
|
return timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTimestamp(Date timestamp) {
|
||||||
|
this.timestamp = timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getNotificationPointId() {
|
||||||
|
return notificationPointId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNotificationPointId(int notificationPointId) {
|
||||||
|
this.notificationPointId = notificationPointId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNotificationPointStatus() {
|
||||||
|
return notificationPointStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNotificationPointStatus(String notificationPointStatus) {
|
||||||
|
this.notificationPointStatus = notificationPointStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getResultData() {
|
||||||
|
return resultData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setResultData(String resultData) {
|
||||||
|
this.resultData = resultData;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package com.truphone.es9plus.message.request;
|
||||||
|
|
||||||
|
|
||||||
|
import com.truphone.es9plus.message.MsgType;
|
||||||
|
import com.truphone.es9plus.message.request.base.RequestMsgBody;
|
||||||
|
|
||||||
|
@MsgType("/gsma/rsp2/es9plus/handleNotification")
|
||||||
|
public class HandleNotificationReq extends RequestMsgBody {
|
||||||
|
private String pendingNotification;
|
||||||
|
|
||||||
|
public String getPendingNotification() {
|
||||||
|
return pendingNotification;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPendingNotification(String pendingNotification) {
|
||||||
|
this.pendingNotification = pendingNotification;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
package com.truphone.es9plus.message.request;
|
||||||
|
|
||||||
|
|
||||||
|
import com.truphone.es9plus.message.MsgType;
|
||||||
|
import com.truphone.es9plus.message.request.base.RequestMsgBody;
|
||||||
|
|
||||||
|
@MsgType("/gsma/rsp2/es9plus/initiateAuthentication")
|
||||||
|
public class InitiateAuthenticationReq extends RequestMsgBody {
|
||||||
|
private String euiccChallenge;
|
||||||
|
private String euiccInfo1;
|
||||||
|
private String smdpAddress;
|
||||||
|
|
||||||
|
public String getEuiccChallenge() {
|
||||||
|
return euiccChallenge;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEuiccChallenge(String euiccChallenge) {
|
||||||
|
this.euiccChallenge = euiccChallenge;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEuiccInfo1() {
|
||||||
|
return euiccInfo1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEuiccInfo1(String euiccInfo1) {
|
||||||
|
this.euiccInfo1 = euiccInfo1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSmdpAddress() {
|
||||||
|
return smdpAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSmdpAddress(String smdpAddress) {
|
||||||
|
this.smdpAddress = smdpAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package com.truphone.es9plus.message.request;
|
||||||
|
|
||||||
|
|
||||||
|
import com.truphone.es9plus.message.MsgType;
|
||||||
|
import com.truphone.es9plus.message.request.base.RequestMsgBody;
|
||||||
|
|
||||||
|
@MsgType("/gsma/rsp2/es2plus/releaseProfile")
|
||||||
|
public class ReleaseProfileReq extends RequestMsgBody {
|
||||||
|
private String iccid;
|
||||||
|
|
||||||
|
public String getIccid() {
|
||||||
|
return iccid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIccid(String iccid) {
|
||||||
|
this.iccid = iccid;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package com.truphone.es9plus.message.request.base;
|
||||||
|
|
||||||
|
|
||||||
|
import com.truphone.es9plus.message.MsgBody;
|
||||||
|
|
||||||
|
import java.security.InvalidParameterException;
|
||||||
|
|
||||||
|
public abstract class RequestMsgBody implements MsgBody {
|
||||||
|
|
||||||
|
public void checkParameters() throws InvalidParameterException {
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
package com.truphone.es9plus.message.response;
|
||||||
|
|
||||||
|
|
||||||
|
import com.truphone.es9plus.message.response.base.ResponseMsgBody;
|
||||||
|
|
||||||
|
public class AuthenticateClientResp extends ResponseMsgBody {
|
||||||
|
private String transactionID;
|
||||||
|
private String profileMetadata;
|
||||||
|
private String smdpSigned2;
|
||||||
|
private String smdpSignature2;
|
||||||
|
private String smdpCertificate;
|
||||||
|
|
||||||
|
public String getTransactionID() {
|
||||||
|
return transactionID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTransactionID(String transactionID) {
|
||||||
|
this.transactionID = transactionID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getProfileMetadata() {
|
||||||
|
return profileMetadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProfileMetadata(String profileMetadata) {
|
||||||
|
this.profileMetadata = profileMetadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSmdpSigned2() {
|
||||||
|
return smdpSigned2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSmdpSigned2(String smdpSigned2) {
|
||||||
|
this.smdpSigned2 = smdpSigned2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSmdpSignature2() {
|
||||||
|
return smdpSignature2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSmdpSignature2(String smdpSignature2) {
|
||||||
|
this.smdpSignature2 = smdpSignature2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSmdpCertificate() {
|
||||||
|
return smdpCertificate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSmdpCertificate(String smdpCertificate) {
|
||||||
|
this.smdpCertificate = smdpCertificate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "AuthenticateClientResp{" +
|
||||||
|
"transactionID='" + transactionID + '\'' +
|
||||||
|
", profileMetadata='" + profileMetadata + '\'' +
|
||||||
|
", smdpSigned2='" + smdpSigned2 + '\'' +
|
||||||
|
", smdpSignature2='" + smdpSignature2 + '\'' +
|
||||||
|
", smdpCertificate='" + smdpCertificate + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
package com.truphone.es9plus.message.response;
|
||||||
|
|
||||||
|
|
||||||
|
import com.truphone.es9plus.message.response.base.ResponseMsgBody;
|
||||||
|
|
||||||
|
public class CancelSessionResp extends ResponseMsgBody {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
package com.truphone.es9plus.message.response;
|
||||||
|
|
||||||
|
import com.truphone.es9plus.message.response.base.ResponseMsgBody;
|
||||||
|
|
||||||
|
public class ConfirmOrderResp extends ResponseMsgBody {
|
||||||
|
private String eid;
|
||||||
|
private String matchingId;
|
||||||
|
private String smdpAddress;
|
||||||
|
|
||||||
|
public String getEid() {
|
||||||
|
return eid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEid(String eid) {
|
||||||
|
this.eid = eid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMatchingId() {
|
||||||
|
return matchingId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMatchingId(String matchingId) {
|
||||||
|
this.matchingId = matchingId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSmdpAddress() {
|
||||||
|
return smdpAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSmdpAddress(String smdpAddress) {
|
||||||
|
this.smdpAddress = smdpAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package com.truphone.es9plus.message.response;
|
||||||
|
|
||||||
|
import com.truphone.es9plus.message.response.base.ResponseMsgBody;
|
||||||
|
|
||||||
|
public class DownloadOrderResp extends ResponseMsgBody {
|
||||||
|
private String iccid;
|
||||||
|
|
||||||
|
public String getIccid() {
|
||||||
|
return iccid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIccid(String iccid) {
|
||||||
|
this.iccid = iccid;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
package com.truphone.es9plus.message.response;
|
||||||
|
|
||||||
|
|
||||||
|
import com.truphone.es9plus.message.response.base.ResponseMsgBody;
|
||||||
|
|
||||||
|
public class GetBoundProfilePackageResp extends ResponseMsgBody {
|
||||||
|
private String transactionID;
|
||||||
|
private String boundProfilePackage;
|
||||||
|
|
||||||
|
public String getTransactionID() {
|
||||||
|
return transactionID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTransactionID(String transactionID) {
|
||||||
|
this.transactionID = transactionID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBoundProfilePackage() {
|
||||||
|
return boundProfilePackage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBoundProfilePackage(String boundProfilePackage) {
|
||||||
|
this.boundProfilePackage = boundProfilePackage;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
package com.truphone.es9plus.message.response;
|
||||||
|
|
||||||
|
|
||||||
|
import com.truphone.es9plus.message.response.base.ResponseMsgBody;
|
||||||
|
|
||||||
|
public class HandleDownloadProgressInfoResp extends ResponseMsgBody {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
package com.truphone.es9plus.message.response;
|
||||||
|
|
||||||
|
|
||||||
|
import com.truphone.es9plus.message.response.base.ResponseMsgBody;
|
||||||
|
|
||||||
|
public class HandleNotificationResp extends ResponseMsgBody {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
package com.truphone.es9plus.message.response;
|
||||||
|
|
||||||
|
|
||||||
|
import com.truphone.es9plus.message.response.base.ResponseMsgBody;
|
||||||
|
|
||||||
|
public class InitiateAuthenticationResp extends ResponseMsgBody {
|
||||||
|
private String transactionId;
|
||||||
|
private String serverSigned1;
|
||||||
|
private String serverSignature1;
|
||||||
|
private String euiccCiPKIdToBeUsed;
|
||||||
|
private String serverCertificate;
|
||||||
|
|
||||||
|
public String getTransactionId() {
|
||||||
|
return transactionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTransactionId(String transactionId) {
|
||||||
|
this.transactionId = transactionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getServerSigned1() {
|
||||||
|
return serverSigned1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setServerSigned1(String serverSigned1) {
|
||||||
|
this.serverSigned1 = serverSigned1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getServerSignature1() {
|
||||||
|
return serverSignature1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setServerSignature1(String serverSignature1) {
|
||||||
|
this.serverSignature1 = serverSignature1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEuiccCiPKIdToBeUsed() {
|
||||||
|
return euiccCiPKIdToBeUsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEuiccCiPKIdToBeUsed(String euiccCiPKIdToBeUsed) {
|
||||||
|
this.euiccCiPKIdToBeUsed = euiccCiPKIdToBeUsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getServerCertificate() {
|
||||||
|
return serverCertificate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setServerCertificate(String serverCertificate) {
|
||||||
|
this.serverCertificate = serverCertificate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
|
||||||
|
return "InitiateAuthenticationResp{" +
|
||||||
|
"transactionId='" + transactionId + '\'' +
|
||||||
|
", serverSigned1='" + serverSigned1 + '\'' +
|
||||||
|
", serverSignature1='" + serverSignature1 + '\'' +
|
||||||
|
", euiccCiPKIdToBeUsed='" + euiccCiPKIdToBeUsed + '\'' +
|
||||||
|
", serverCertificate='" + serverCertificate + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
package com.truphone.es9plus.message.response;
|
||||||
|
|
||||||
|
|
||||||
|
import com.truphone.es9plus.message.response.base.ResponseMsgBody;
|
||||||
|
|
||||||
|
public class ReleaseProfileResp extends ResponseMsgBody {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
package com.truphone.es9plus.message.response.base;
|
||||||
|
|
||||||
|
public class FunctionExecutionStatus {
|
||||||
|
private String status;
|
||||||
|
private StatusCodeData statusCodeData;
|
||||||
|
|
||||||
|
public FunctionExecutionStatus(String status) {
|
||||||
|
super();
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FunctionExecutionStatus(String status, StatusCodeData statusCodeData) {
|
||||||
|
super();
|
||||||
|
this.status = status;
|
||||||
|
this.statusCodeData = statusCodeData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatus(String status) {
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StatusCodeData getStatusCodeData() {
|
||||||
|
return statusCodeData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatusCodeData(StatusCodeData statusCodeData) {
|
||||||
|
this.statusCodeData = statusCodeData;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package com.truphone.es9plus.message.response.base;
|
||||||
|
|
||||||
|
public class HeaderResp {
|
||||||
|
private FunctionExecutionStatus functionExecutionStatus;
|
||||||
|
|
||||||
|
public HeaderResp(FunctionExecutionStatus functionExecutionStatus) {
|
||||||
|
super();
|
||||||
|
this.functionExecutionStatus = functionExecutionStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FunctionExecutionStatus getFunctionExecutionStatus() {
|
||||||
|
return functionExecutionStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFunctionExecutionStatus(FunctionExecutionStatus functionExecutionStatus) {
|
||||||
|
this.functionExecutionStatus = functionExecutionStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
package com.truphone.es9plus.message.response.base;
|
||||||
|
|
||||||
|
public class NotificationPointStatus {
|
||||||
|
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
private StatusCodeData statusCodeData;
|
||||||
|
|
||||||
|
public String getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatus(String status) {
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StatusCodeData getStatusCodeData() {
|
||||||
|
return statusCodeData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatusCodeData(StatusCodeData statusCodeData) {
|
||||||
|
this.statusCodeData = statusCodeData;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package com.truphone.es9plus.message.response.base;
|
||||||
|
|
||||||
|
import com.truphone.es9plus.message.MsgBody;
|
||||||
|
|
||||||
|
public abstract class ResponseMsgBody implements MsgBody {
|
||||||
|
private HeaderResp header;
|
||||||
|
|
||||||
|
public HeaderResp getHeader() {
|
||||||
|
return header;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHeader(HeaderResp header) {
|
||||||
|
this.header = header;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
package com.truphone.es9plus.message.response.base;
|
||||||
|
|
||||||
|
public class StatusCodeData {
|
||||||
|
|
||||||
|
private String subjectCode;
|
||||||
|
|
||||||
|
private String reasonCode;
|
||||||
|
|
||||||
|
private String message;
|
||||||
|
|
||||||
|
private String subjectIdentifier;
|
||||||
|
|
||||||
|
public StatusCodeData() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public StatusCodeData(String subjectCode, String reasonCode, String message) {
|
||||||
|
super();
|
||||||
|
this.subjectCode = subjectCode;
|
||||||
|
this.reasonCode = reasonCode;
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StatusCodeData(String subjectCode, String reasonCode, String message, String subjectIdentifier) {
|
||||||
|
super();
|
||||||
|
this.subjectCode = subjectCode;
|
||||||
|
this.reasonCode = reasonCode;
|
||||||
|
this.message = message;
|
||||||
|
this.subjectIdentifier = subjectIdentifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSubjectCode() {
|
||||||
|
return subjectCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSubjectCode(String subjectCode) {
|
||||||
|
this.subjectCode = subjectCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getReasonCode() {
|
||||||
|
return reasonCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setReasonCode(String reasonCode) {
|
||||||
|
this.reasonCode = reasonCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMessage(String message) {
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSubjectIdentifier() {
|
||||||
|
return subjectIdentifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSubjectIdentifier(String subjectIdentifier) {
|
||||||
|
this.subjectIdentifier = subjectIdentifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package com.truphone.lpa;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface ApduChannel {
|
||||||
|
String transmitAPDU(String apdu);
|
||||||
|
|
||||||
|
String transmitAPDUS(List<String> apdus);
|
||||||
|
|
||||||
|
void sendStatus();
|
||||||
|
|
||||||
|
void setApduTransmittedListener(ApduTransmittedListener apduTransmittedListener);
|
||||||
|
|
||||||
|
void removeApduTransmittedListener(ApduTransmittedListener apduTransmittedListener);
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
package com.truphone.lpa;
|
||||||
|
|
||||||
|
public interface ApduTransmittedListener {
|
||||||
|
void onApduTransmitted();
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
package com.truphone.lpa;
|
||||||
|
|
||||||
|
import com.truphone.lpa.progress.DownloadProgress;
|
||||||
|
import com.truphone.lpad.progress.Progress;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public interface LocalProfileAssistant {
|
||||||
|
|
||||||
|
String enableProfile(String iccid, Progress progress);
|
||||||
|
|
||||||
|
String disableProfile(String iccid, Progress progress);
|
||||||
|
|
||||||
|
String deleteProfile(String iccid, Progress progress);
|
||||||
|
|
||||||
|
String getDefaultSMDP();
|
||||||
|
|
||||||
|
String setDefaultSMDP(String smdpAddress, Progress progress);
|
||||||
|
|
||||||
|
|
||||||
|
void downloadProfile(String matchingId, DownloadProgress progress) throws Exception;
|
||||||
|
|
||||||
|
List<Map<String, String>> getProfiles();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the EID from the eUICC
|
||||||
|
* @return the EID from the eUICC
|
||||||
|
*/
|
||||||
|
String getEID();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allocates the Protected Profile Packages to specified EIDs based on given MCC
|
||||||
|
* @param mcc Mobile country code
|
||||||
|
* @return Activation Code Token
|
||||||
|
*/
|
||||||
|
String allocateProfile(String mcc);
|
||||||
|
|
||||||
|
void processPendingNotifications();
|
||||||
|
}
|
|
@ -0,0 +1,362 @@
|
||||||
|
package com.truphone.lpa.apdu;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import com.truphone.util.ToTLV;
|
||||||
|
import com.truphone.util.Tools;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ApduUtils {
|
||||||
|
|
||||||
|
private static final String CLA = "81";
|
||||||
|
private static final String INSTRUCTION = "E2";
|
||||||
|
private static final String P1_11 = "11";
|
||||||
|
private static final String P1_91 = "91";
|
||||||
|
private static final String P2 = "00";
|
||||||
|
private static final int len = 120;
|
||||||
|
|
||||||
|
public static String getEuiccInfo1Apdu() {
|
||||||
|
String data = ToTLV.toTLV("BF20", "");
|
||||||
|
StringBuilder apdu = new StringBuilder().append(CLA).append(INSTRUCTION).append(P1_91).append(P2).append(ToTLV.toTLV(data));
|
||||||
|
return apdu.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getEuiccInfo2Apdu() {
|
||||||
|
String data = ToTLV.toTLV("BF22", "");
|
||||||
|
StringBuilder apdu = new StringBuilder().append(CLA).append(INSTRUCTION).append(P1_91).append(P2).append(ToTLV.toTLV(data));
|
||||||
|
return apdu.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getEUICCChallengeApdu() {
|
||||||
|
String data = ToTLV.toTLV("BF2E", "");
|
||||||
|
StringBuilder apdu = new StringBuilder().append(CLA).append(INSTRUCTION).append(P1_91).append(P2).append(ToTLV.toTLV(data));
|
||||||
|
return apdu.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<String> authenticateServerApdu(String smdpSigned1, String smdpSignature1, String euiccCiPKIdToBeUsed,
|
||||||
|
String cert, String matchingId) {
|
||||||
|
String sctxParams1 = ToTLV.toTLV("A0", ToTLV.toTLV("80", matchingId) + ToTLV.toTLV("A1", ToTLV.toTLV("80", "35550607") + ToTLV.toTLV("A1", "")));
|
||||||
|
String data = ToTLV.toTLV("BF38", smdpSigned1 + smdpSignature1 + euiccCiPKIdToBeUsed + cert + sctxParams1);
|
||||||
|
|
||||||
|
return subCommandData(data, len, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<String> prepareDownloadApdu(String smdpSigned2, String smdpSignature2, String cert, String hashCc) {
|
||||||
|
StringBuilder data = new StringBuilder().append(smdpSigned2).append(smdpSignature2);
|
||||||
|
if (hashCc != null) {
|
||||||
|
data.append(ToTLV.toTLV("04", hashCc));
|
||||||
|
}
|
||||||
|
data.append(cert);
|
||||||
|
return subCommandData(ToTLV.toTLV("BF21", data.toString()), len, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<String> loadInitialiseSecureChannelApdu(List<String[]> data) {
|
||||||
|
if (data.size() != 4 && data.size() != 5) {
|
||||||
|
throw new RuntimeException("SBPP Error");
|
||||||
|
}
|
||||||
|
return subCommandData(data.get(0)[0], len, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<String> loadConfigureISDPApdu(List<String[]> data) {
|
||||||
|
if (data.size() != 4 && data.size() != 5) {
|
||||||
|
throw new RuntimeException("SBPP Error");
|
||||||
|
}
|
||||||
|
List<String> SBPPList = new ArrayList<>();
|
||||||
|
String configureISDP = data.get(1)[0];
|
||||||
|
String configureISDPLength = Tools.toHex(String.valueOf(configureISDP.length() / 2));
|
||||||
|
StringBuilder configureISDPApdu = new StringBuilder().append(CLA).append(INSTRUCTION).append(P1_91).append(P2)
|
||||||
|
.append(configureISDPLength).append(configureISDP);
|
||||||
|
SBPPList.add(configureISDPApdu.toString());
|
||||||
|
return SBPPList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<String> loadStoreMetadataApdu(List<String[]> data) {
|
||||||
|
if (data.size() != 4 && data.size() != 5) {
|
||||||
|
throw new RuntimeException("SBPP Error");
|
||||||
|
}
|
||||||
|
List<String> SBPPList = new ArrayList<>();
|
||||||
|
|
||||||
|
String[] storeMetadata = data.get(2);
|
||||||
|
for (int i = 0; i < storeMetadata.length; i++) {
|
||||||
|
List<String> storeMetadataList = subCommandData(storeMetadata[i], len, true);
|
||||||
|
SBPPList.addAll(storeMetadataList);
|
||||||
|
}
|
||||||
|
return SBPPList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<String> loadProfileProtectionKeys(List<String[]> data) {
|
||||||
|
if (data.size() != 5) {
|
||||||
|
throw new RuntimeException("SBPP Error");
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> SBPPList = new ArrayList<>();
|
||||||
|
String[] profileProtectionKeys = data.get(3);
|
||||||
|
|
||||||
|
for (int i = 0; i < profileProtectionKeys.length; i++) {
|
||||||
|
List<String> loadProfileElementsList = subCommandData(profileProtectionKeys[i], len, true);
|
||||||
|
SBPPList.addAll(loadProfileElementsList);
|
||||||
|
}
|
||||||
|
|
||||||
|
return SBPPList;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<String> loadBoundProfilePackageApdu(List<String[]> data) {
|
||||||
|
|
||||||
|
if (data.size() != 4 && data.size() != 5) {
|
||||||
|
throw new RuntimeException("SBPP Error");
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> SBPPList = new ArrayList<>();
|
||||||
|
String[] loadProfileElements = (data.size() == 4) ? data.get(3) : data.get(4);
|
||||||
|
|
||||||
|
for (int i = 0; i < loadProfileElements.length; i++) {
|
||||||
|
List<String> loadProfileElementsList = subCommandData(loadProfileElements[i], len, true);
|
||||||
|
SBPPList.addAll(loadProfileElementsList);
|
||||||
|
}
|
||||||
|
|
||||||
|
return SBPPList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String removeNotificationFromListApdu(int notifycounter) {
|
||||||
|
String data = ToTLV.toTLV("BF30", ToTLV.integerToTLV("80", notifycounter));
|
||||||
|
StringBuilder apdu = new StringBuilder().append(CLA).append(INSTRUCTION).append(P1_91).append(P2).append(ToTLV.toTLV(data));
|
||||||
|
return apdu.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String listNotificationApdu(String notificationType) {
|
||||||
|
String data;
|
||||||
|
|
||||||
|
if (StringUtils.isNotBlank(notificationType)) {
|
||||||
|
data = ToTLV.toTLV("BF28", ToTLV.toTLV("81", "04" + notificationType));
|
||||||
|
} else {
|
||||||
|
data = ToTLV.toTLV("BF28", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
return new StringBuilder().append(CLA).append(INSTRUCTION).append(P1_91).append(P2).append(ToTLV.toTLV(data)).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String retrievePendingNotificationsListApdu(int notifyCounter) {
|
||||||
|
|
||||||
|
String data = ToTLV.toTLV("BF2B", ToTLV.toTLV("A0", ToTLV.integerToTLV("80", notifyCounter)));
|
||||||
|
|
||||||
|
|
||||||
|
StringBuilder apdu = new StringBuilder().append(CLA).append(INSTRUCTION).append(P1_91).append(P2).append(ToTLV.toTLV(data));
|
||||||
|
|
||||||
|
return apdu.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getProfilesInfoApdu(String isdp1) {
|
||||||
|
String searchCriteria = "";
|
||||||
|
if (!StringUtils.isEmpty(isdp1)) {
|
||||||
|
searchCriteria = ToTLV.toTLV("A0", ToTLV.toTLV("4F", isdp1));
|
||||||
|
}
|
||||||
|
String data = ToTLV.toTLV("BF2D", searchCriteria);// + tagList);
|
||||||
|
StringBuilder apdu = new StringBuilder().append(CLA).append(INSTRUCTION).append(P1_91).append(P2).append(ToTLV.toTLV(data));
|
||||||
|
return apdu.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getEIDApdu() {
|
||||||
|
String data = ToTLV.toTLV("BF3E", ToTLV.toTLV("5C", "5A"));
|
||||||
|
StringBuilder apdu = new StringBuilder().append(CLA).append(INSTRUCTION).append(P1_91).append(P2).append(ToTLV.toTLV(data));
|
||||||
|
return apdu.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String setNicknameApdu(String iccid, String profileNickname) {
|
||||||
|
String data = ToTLV.toTLV("BF29", ToTLV.toTLV("5A", iccid) + ToTLV.toTLV("90", profileNickname));
|
||||||
|
StringBuilder apdu = new StringBuilder().append(CLA).append(INSTRUCTION).append(P1_91).append(P2).append(ToTLV.toTLV(data));
|
||||||
|
return apdu.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String enableProfileApdu(String iccidOrISDPaid, String refreshflag) {
|
||||||
|
String data;
|
||||||
|
if (iccidOrISDPaid.length() / 2 == 10) {
|
||||||
|
data = ToTLV.toTLV("BF31", ToTLV.toTLV("A0", ToTLV.toTLV("5A", iccidOrISDPaid)) + ToTLV.toTLV("81", refreshflag));
|
||||||
|
} else if (iccidOrISDPaid.length() / 2 == 16) {
|
||||||
|
data = ToTLV.toTLV("BF31", ToTLV.toTLV("A0", ToTLV.toTLV("4F", iccidOrISDPaid)) + ToTLV.toTLV("81", refreshflag));
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException("No iccid Or ISDPaid supplied");
|
||||||
|
}
|
||||||
|
StringBuilder apdu = new StringBuilder().append(CLA).append(INSTRUCTION).append(P1_91).append(P2).append(ToTLV.toTLV(data));
|
||||||
|
return apdu.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String disableProfileApdu(String iccidOrISDPaid, String refreshflag) {
|
||||||
|
String data;
|
||||||
|
if (iccidOrISDPaid.length() / 2 == 10) {
|
||||||
|
data = ToTLV.toTLV("BF32", ToTLV.toTLV("A0", ToTLV.toTLV("5A", iccidOrISDPaid)) + ToTLV.toTLV("81", refreshflag));
|
||||||
|
} else if (iccidOrISDPaid.length() / 2 == 16) {
|
||||||
|
data = ToTLV.toTLV("BF32", ToTLV.toTLV("A0", ToTLV.toTLV("4F", iccidOrISDPaid)) + ToTLV.toTLV("81", refreshflag));
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException("No iccid Or ISDPaid supplied");
|
||||||
|
}
|
||||||
|
StringBuilder apdu = new StringBuilder().append(CLA).append(INSTRUCTION).append(P1_91).append(P2).append(ToTLV.toTLV(data));
|
||||||
|
return apdu.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String deleteProfileApdu(String iccidOrISDPaid) {
|
||||||
|
String data;
|
||||||
|
if (iccidOrISDPaid.length() / 2 == 10) {
|
||||||
|
data = ToTLV.toTLV("BF33", ToTLV.toTLV("5A", iccidOrISDPaid));
|
||||||
|
} else if (iccidOrISDPaid.length() / 2 == 16) {
|
||||||
|
data = ToTLV.toTLV("BF33", ToTLV.toTLV("4F", iccidOrISDPaid));
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException("No iccid Or ISDPaid supplied");
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder apdu = new StringBuilder().append(CLA).append(INSTRUCTION).append(P1_91).append(P2).append(ToTLV.toTLV(data));
|
||||||
|
return apdu.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getEuiccConfiguredAddressesApdu() {
|
||||||
|
String data = "BF3C00";
|
||||||
|
StringBuilder apdu = new StringBuilder().append(CLA).append(INSTRUCTION).append(P1_91).append(P2).append(ToTLV.toTLV(data));
|
||||||
|
|
||||||
|
return apdu.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String setDefaultDpAddressApdu(String dpAddrNew) {
|
||||||
|
String data = ToTLV.toTLV("BF3F", ToTLV.toTLV("80", dpAddrNew));
|
||||||
|
StringBuilder apdu = new StringBuilder().append(CLA).append(INSTRUCTION).append(P1_91).append(P2).append(ToTLV.toTLV(data));
|
||||||
|
return apdu.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getProfilesInfo_profileStateApdu(String iccidOrISDPaid) {
|
||||||
|
String taglist = ToTLV.toTLV("5C", "9F70");
|
||||||
|
String searchCriteria = null;
|
||||||
|
if (iccidOrISDPaid.length() / 2 == 10) {
|
||||||
|
searchCriteria = ToTLV.toTLV("A0", ToTLV.toTLV("5A", iccidOrISDPaid));
|
||||||
|
} else if (iccidOrISDPaid.length() / 2 == 16) {
|
||||||
|
searchCriteria = ToTLV.toTLV("A0", ToTLV.toTLV("4F", iccidOrISDPaid));
|
||||||
|
}
|
||||||
|
String data = ToTLV.toTLV("BF2D", searchCriteria + taglist);
|
||||||
|
StringBuilder apdu = new StringBuilder().append(CLA).append(INSTRUCTION).append(P1_91).append(P2).append(ToTLV.toTLV(data));
|
||||||
|
return apdu.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getEUICCInfo_spaceApdu() {
|
||||||
|
String data = ToTLV.toTLV("BF22", "");
|
||||||
|
StringBuilder apdu = new StringBuilder().append(CLA).append(INSTRUCTION).append(P1_91).append(P2).append(ToTLV.toTLV(data));
|
||||||
|
return apdu.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getProfilesInfo_ISDPaidApdu(String iccid) {
|
||||||
|
String taglist = ToTLV.toTLV("5C", "4F");
|
||||||
|
String searchCriteria = ToTLV.toTLV("A0", ToTLV.toTLV("5A", iccid));
|
||||||
|
String data = ToTLV.toTLV("BF2D", searchCriteria + taglist);
|
||||||
|
StringBuilder apdu = new StringBuilder().append(CLA).append(INSTRUCTION).append(P1_91).append(P2).append(ToTLV.toTLV(data));
|
||||||
|
return apdu.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String checkIfAnyEnabledProfileApdu() {
|
||||||
|
String taglist = ToTLV.toTLV("5C", "9F70");
|
||||||
|
String searchCriteria = "";
|
||||||
|
String data = ToTLV.toTLV("BF2D", searchCriteria + taglist);
|
||||||
|
StringBuilder apdu = new StringBuilder().append(CLA).append(INSTRUCTION).append(P1_91).append(P2).append(ToTLV.toTLV(data));
|
||||||
|
return apdu.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getNotifyCounterApdu() {
|
||||||
|
String data = ToTLV.toTLV("BF28", "");
|
||||||
|
StringBuilder apdu = new StringBuilder().append(CLA).append(INSTRUCTION).append(P1_91).append(P2).append(ToTLV.toTLV(data));
|
||||||
|
return apdu.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getNotifyTypeApdu() {
|
||||||
|
String data = ToTLV.toTLV("BF28", "");
|
||||||
|
StringBuilder apdu = new StringBuilder().append(CLA).append(INSTRUCTION).append(P1_91).append(P2).append(ToTLV.toTLV(data));
|
||||||
|
return apdu.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String removeNotificationApdu(String notifyCounter) {
|
||||||
|
String data = ToTLV.toTLV("BF30", ToTLV.toTLV("80", notifyCounter));
|
||||||
|
StringBuilder apdu = new StringBuilder().append(CLA).append(INSTRUCTION).append(P1_91).append(P2).append(ToTLV.toTLV(data));
|
||||||
|
return apdu.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String nextNotifyCounterApdu(String iccGp_notifycounter) {
|
||||||
|
String nextNotifyCounter = "";
|
||||||
|
int inotifycounter = Integer.valueOf(iccGp_notifycounter, 16);
|
||||||
|
String inotifycounterHex = Tools.toHex(String.valueOf(++inotifycounter));
|
||||||
|
inotifycounterHex = "000000" + inotifycounterHex;
|
||||||
|
if (inotifycounter < 127) {
|
||||||
|
nextNotifyCounter = inotifycounterHex.substring(inotifycounterHex.length() - 2);
|
||||||
|
} else if (inotifycounter < 32767) {
|
||||||
|
nextNotifyCounter = inotifycounterHex.substring(inotifycounterHex.length() - 4);
|
||||||
|
} else if (inotifycounter < 8388607) {
|
||||||
|
nextNotifyCounter = inotifycounterHex.substring(inotifycounterHex.length() - 6);
|
||||||
|
} else {
|
||||||
|
nextNotifyCounter = inotifycounterHex.substring(inotifycounterHex.length() - 8);
|
||||||
|
}
|
||||||
|
return nextNotifyCounter;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<String> subCommandData(String data, int len, boolean isLenSub) {
|
||||||
|
List<String> commandDataList = new ArrayList<>();
|
||||||
|
int dataLen = data.length() / 2;
|
||||||
|
int cP2 = 0;
|
||||||
|
while (dataLen != 0) {
|
||||||
|
if (dataLen > len) {
|
||||||
|
String subData = data.substring(0, 2 * len);
|
||||||
|
StringBuilder apdu = new StringBuilder();
|
||||||
|
if (isLenSub) {
|
||||||
|
apdu.append(CLA).append(INSTRUCTION).append(P1_11).append(Tools.toHex(String.valueOf(cP2))).append(Tools.itoa(len, 1)).append(subData);
|
||||||
|
} else {
|
||||||
|
apdu.append(CLA).append(INSTRUCTION).append(P1_11).append(Tools.toHex(String.valueOf(cP2))).append(Tools.toHex(String.valueOf(len))).append(subData);
|
||||||
|
}
|
||||||
|
commandDataList.add(apdu.toString());
|
||||||
|
data = data.substring(2 * len);
|
||||||
|
dataLen = dataLen - len;
|
||||||
|
cP2++;
|
||||||
|
} else {
|
||||||
|
StringBuilder apdu = new StringBuilder();
|
||||||
|
if (isLenSub) {
|
||||||
|
apdu.append(CLA).append(INSTRUCTION).append(P1_91).append(Tools.toHex(String.valueOf(cP2))).append(Tools.itoa(dataLen, 1)).append(data);
|
||||||
|
} else {
|
||||||
|
apdu.append(CLA).append(INSTRUCTION).append(P1_91).append(Tools.toHex(String.valueOf(cP2))).append(Tools.toHex(String.valueOf(dataLen))).append(data);
|
||||||
|
}
|
||||||
|
dataLen = 0;
|
||||||
|
commandDataList.add(apdu.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return commandDataList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getResponse() {
|
||||||
|
StringBuilder apdu = new StringBuilder();
|
||||||
|
apdu.append(CLA).append("C0").append("00").append("00").append("00");
|
||||||
|
return apdu.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * Proprietary Commands *
|
||||||
|
*/
|
||||||
|
public static String getLPAeDownloadProfileApdu() {
|
||||||
|
StringBuilder apdu = new StringBuilder();
|
||||||
|
apdu.append(CLA).append("B0").append("00").append("00").append("01").append("02");
|
||||||
|
return apdu.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getLPAeGetProgressInfoApdu() {
|
||||||
|
StringBuilder apdu = new StringBuilder();
|
||||||
|
apdu.append(CLA).append("B0").append("00").append("00").append("01").append("08");
|
||||||
|
return apdu.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getLPAeMemoryResetApdu() {
|
||||||
|
StringBuilder apdu = new StringBuilder();
|
||||||
|
apdu.append(CLA).append("B0").append("00").append("00").append("01").append("06");
|
||||||
|
return apdu.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getLPAeSetLPAModeApdu(String mode) {
|
||||||
|
StringBuilder apdu = new StringBuilder();
|
||||||
|
apdu.append(CLA).append("B0").append("00").append("00").append("02").append("09").append(mode);
|
||||||
|
return apdu.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getSendStatusAPDU() {
|
||||||
|
return "80F20100";
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package com.truphone.lpa.apdu;
|
||||||
|
|
||||||
|
public enum NotificationType {
|
||||||
|
ALL(""), INSTALLED("80"), ENABLED("40"), DISABLED("20"), DELETED("10");
|
||||||
|
|
||||||
|
private final String text;
|
||||||
|
|
||||||
|
NotificationType(final String text) {
|
||||||
|
this.text = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,275 @@
|
||||||
|
package com.truphone.lpa.apdu;
|
||||||
|
|
||||||
|
import com.truphone.util.LogStub;
|
||||||
|
import com.truphone.util.TLVBean;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
public class ProfileUtil {
|
||||||
|
private static final Logger LOG = Logger.getLogger(ProfileUtil.class
|
||||||
|
.getName());
|
||||||
|
|
||||||
|
public ArrayList<String[]> generateSBPP(String BPP) {
|
||||||
|
if (!BPP.substring(0, 4).equals("BF36")) {
|
||||||
|
throw new RuntimeException("Incorrect format in BPP");
|
||||||
|
}
|
||||||
|
ArrayList<String[]> array = new ArrayList<String[]>();
|
||||||
|
int endOfSeg = 0;
|
||||||
|
String[] initChannel = new String[1];
|
||||||
|
initChannel[0] = headAndInitChannel(BPP);
|
||||||
|
array.add(initChannel);
|
||||||
|
endOfSeg += initChannel[0].length();
|
||||||
|
String[] isdp = new String[1];
|
||||||
|
isdp[0] = configIsdp(BPP.substring(endOfSeg));
|
||||||
|
array.add(isdp);
|
||||||
|
endOfSeg += isdp[0].length();
|
||||||
|
String[] metaData = metaData(BPP.substring(endOfSeg));
|
||||||
|
array.add(metaData);
|
||||||
|
for (int i = 0; i < metaData.length; i++) {
|
||||||
|
endOfSeg += metaData[i].length();
|
||||||
|
}
|
||||||
|
int beginOfSeg = BPP.substring(endOfSeg).indexOf("A2");
|
||||||
|
|
||||||
|
if (beginOfSeg == 0) {
|
||||||
|
String[] ppk = new String[1];
|
||||||
|
ppk[0] = ppk(BPP.substring(endOfSeg));
|
||||||
|
array.add(ppk);
|
||||||
|
endOfSeg += ppk[0].length();
|
||||||
|
}
|
||||||
|
String[] ppp = ppp(BPP.substring(endOfSeg));
|
||||||
|
array.add(ppp);
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String headAndInitChannel(String data) {
|
||||||
|
int beginOfSeg = data.indexOf("BF36");
|
||||||
|
if (!(beginOfSeg == 0)) {
|
||||||
|
throw new RuntimeException("Incorrect format in BPP");
|
||||||
|
}
|
||||||
|
data += "FFFF";// endTag
|
||||||
|
TLVBean tlv = null;
|
||||||
|
tlv = selectTlv(data, "BF36", "FFFF");
|
||||||
|
if (tlv == null) {
|
||||||
|
throw new RuntimeException("Incorrect format in BPP");
|
||||||
|
}
|
||||||
|
String head = tlv.getTaglen();
|
||||||
|
data = tlv.getValue();
|
||||||
|
// InitChannel
|
||||||
|
beginOfSeg = data.indexOf("BF23");
|
||||||
|
if (!(beginOfSeg == 0)) {
|
||||||
|
throw new RuntimeException("Incorrect format in InitialiseSecureChannel of BPP");
|
||||||
|
}
|
||||||
|
tlv = null;
|
||||||
|
|
||||||
|
tlv = selectTlv(data, "BF23", "A0");
|
||||||
|
if (tlv == null) {
|
||||||
|
throw new RuntimeException("Incorrect format in InitialiseSecureChannel of BPP");
|
||||||
|
}
|
||||||
|
String initChannel = tlv.getTaglen() + tlv.getValue();
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug (LOG,"headAndInitChannel: " + head + initChannel);
|
||||||
|
}
|
||||||
|
|
||||||
|
return head + initChannel;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private String configIsdp(String data) {
|
||||||
|
int beginOfSeg = data.indexOf("A0");
|
||||||
|
|
||||||
|
if (!(beginOfSeg == 0)) {
|
||||||
|
throw new RuntimeException("Incorrect format in configIsdp of BPP");
|
||||||
|
}
|
||||||
|
String str = null;
|
||||||
|
TLVBean tlv = null;
|
||||||
|
|
||||||
|
tlv = selectTlv(data, "A0", "A1");
|
||||||
|
if (tlv == null) {
|
||||||
|
throw new RuntimeException("Incorrect format in configIsdp of BPP");
|
||||||
|
}
|
||||||
|
str = tlv.getTaglen() + tlv.getValue();
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug (LOG,"configIsdp: " + str);
|
||||||
|
}
|
||||||
|
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private String[] metaData(String data) {
|
||||||
|
int beginOfSeg = data.indexOf("A1");
|
||||||
|
if (!(beginOfSeg == 0)) {
|
||||||
|
throw new RuntimeException("Incorrect format in head of metaData");
|
||||||
|
}
|
||||||
|
TLVBean tlv = null;
|
||||||
|
|
||||||
|
tlv = selectTlv(data, "A1", "A2");
|
||||||
|
if (tlv == null) {
|
||||||
|
tlv = selectTlv(data, "A1", "A3");
|
||||||
|
if (tlv == null) {
|
||||||
|
throw new RuntimeException("Incorrect format in head of metaData");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String head = tlv.getTaglen();
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug (LOG,"headOfMetadata: " + head);
|
||||||
|
}
|
||||||
|
|
||||||
|
data = tlv.getValue();
|
||||||
|
|
||||||
|
ArrayList<String> array = new ArrayList<String>();
|
||||||
|
|
||||||
|
beginOfSeg = data.indexOf("88");
|
||||||
|
if (!(beginOfSeg == 0)) {
|
||||||
|
throw new RuntimeException("Incorrect format in body of metaData");
|
||||||
|
}
|
||||||
|
tlv = null;
|
||||||
|
data += "FFFF";
|
||||||
|
TLVBean tlvBean = null;
|
||||||
|
while (tlvBean == null) {
|
||||||
|
tlv = selectTlv(data, "88", "FFFF");
|
||||||
|
tlvBean = tlv;
|
||||||
|
if (tlvBean == null) {
|
||||||
|
tlv = selectTlv(data, "88", "88");
|
||||||
|
if (tlv == null) {
|
||||||
|
throw new RuntimeException("Incorrect format in body of metaData");
|
||||||
|
}
|
||||||
|
String segBody = tlv.getTaglen() + tlv.getValue();
|
||||||
|
array.add(segBody);
|
||||||
|
data = data.substring(segBody.length());
|
||||||
|
} else {
|
||||||
|
array.add(tlv.getTaglen() + tlv.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug (LOG,"bodyOfMetadata: " + tlv.getTaglen() + tlv.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String[] body = (String[]) array.toArray(new String[0]);
|
||||||
|
ArrayList<String> metaData = new ArrayList<String>();
|
||||||
|
metaData.add(head);
|
||||||
|
for (int i = 0, n = body.length; i < n; i++) {
|
||||||
|
metaData.add(body[i]);
|
||||||
|
}
|
||||||
|
return metaData.toArray(new String[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String ppk(String data) {
|
||||||
|
int beginOfSeg = data.indexOf("A2");
|
||||||
|
|
||||||
|
if (!(beginOfSeg == 0)) {
|
||||||
|
throw new RuntimeException("Incorrect format in ppk of BPP");
|
||||||
|
}
|
||||||
|
String ppk = null;
|
||||||
|
TLVBean tlvBean = null;
|
||||||
|
|
||||||
|
tlvBean = selectTlv(data, "A2", "A3");
|
||||||
|
if (tlvBean == null) {
|
||||||
|
throw new RuntimeException("Incorrect format in ppk of BPP");
|
||||||
|
}
|
||||||
|
ppk = tlvBean.getTaglen() + tlvBean.getValue();
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug (LOG,"ppk: " + ppk);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ppk;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String[] ppp(String data) {
|
||||||
|
int beginOfSeg = data.indexOf("A3");
|
||||||
|
if (!(beginOfSeg == 0)) {
|
||||||
|
throw new RuntimeException("Incorrect format in head of ppp");
|
||||||
|
}
|
||||||
|
TLVBean tlvBean = null;
|
||||||
|
|
||||||
|
data += "FFFF";
|
||||||
|
tlvBean = selectTlv(data, "A3", "FFFF");
|
||||||
|
if (tlvBean == null) {
|
||||||
|
throw new RuntimeException("Incorrect format in head of ppp");
|
||||||
|
}
|
||||||
|
String head = tlvBean.getTaglen();
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug (LOG,"headOfPPP: " + head);
|
||||||
|
}
|
||||||
|
|
||||||
|
data = tlvBean.getValue();
|
||||||
|
|
||||||
|
ArrayList<String> array = new ArrayList<String>();
|
||||||
|
|
||||||
|
beginOfSeg = data.indexOf("86");
|
||||||
|
if (!(beginOfSeg == 0)) {
|
||||||
|
throw new RuntimeException("Incorrect format in body of ppp");
|
||||||
|
}
|
||||||
|
tlvBean = null;
|
||||||
|
data += "FFFF";
|
||||||
|
TLVBean tlvBeanAux = null;
|
||||||
|
while (tlvBeanAux == null) {
|
||||||
|
tlvBean = selectTlv(data, "86", "FFFF");
|
||||||
|
tlvBeanAux = tlvBean;
|
||||||
|
if (tlvBeanAux == null) {
|
||||||
|
tlvBean = selectTlv(data, "86", "86");
|
||||||
|
if (tlvBean == null) {
|
||||||
|
throw new RuntimeException("Incorrect format in body of ppp");
|
||||||
|
}
|
||||||
|
String segBody = tlvBean.getTaglen() + tlvBean.getValue();
|
||||||
|
array.add(segBody);
|
||||||
|
data = data.substring(segBody.length());
|
||||||
|
} else {
|
||||||
|
array.add(tlvBean.getTaglen() + tlvBean.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug (LOG,"bodyOfPPP: " + tlvBean.getTaglen() + tlvBean.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String[] body = (String[]) array.toArray(new String[0]);
|
||||||
|
ArrayList<String> ppp = new ArrayList<String>();
|
||||||
|
ppp.add(head);
|
||||||
|
for (int i = 0, n = body.length; i < n; i++) {
|
||||||
|
ppp.add(body[i]);
|
||||||
|
}
|
||||||
|
return ppp.toArray(new String[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TLVBean selectTlv(String inputData, String beginTag, String endTag) {
|
||||||
|
int beginOfSeg = inputData.indexOf(beginTag);
|
||||||
|
String s = inputData.substring(beginOfSeg + beginTag.length());
|
||||||
|
if (s.substring(0, 2).equals("83")) {
|
||||||
|
int num83 = Integer.parseInt("83", 16) * 2 + 2;
|
||||||
|
int num = Integer.parseInt(s.substring(2, 8), 16) * 2 + 8;
|
||||||
|
if ((num <= s.length()) && (s.substring(num).indexOf(endTag) == 0)) {
|
||||||
|
return new TLVBean(beginTag + s.substring(0, 8), s.substring(8, num));
|
||||||
|
} else if ((num83 <= s.length()) && (s.substring(num83).indexOf(endTag) == 0)) {
|
||||||
|
return new TLVBean(beginTag + "83", s.substring(2, num83));
|
||||||
|
}
|
||||||
|
} else if (s.substring(0, 2).equals("82")) {
|
||||||
|
int num82 = Integer.parseInt("82", 16) * 2 + 2;
|
||||||
|
int num = Integer.parseInt(s.substring(2, 6), 16) * 2 + 6;
|
||||||
|
if ((num <= s.length()) && (s.substring(num).indexOf(endTag) == 0)) {
|
||||||
|
return new TLVBean(beginTag + s.substring(0, 6), s.substring(6, num));
|
||||||
|
} else if ((num82 <= s.length()) && (s.substring(num82).indexOf(endTag) == 0)) {
|
||||||
|
return new TLVBean(beginTag + "82", s.substring(2, num82));
|
||||||
|
}
|
||||||
|
} else if (s.substring(0, 2).equals("81")) {
|
||||||
|
int num81 = Integer.parseInt("81", 16) * 2 + 2;
|
||||||
|
int num = Integer.parseInt(s.substring(2, 4), 16) * 2 + 4;
|
||||||
|
if ((num <= s.length()) && (s.substring(num).indexOf(endTag) == 0)) {
|
||||||
|
return new TLVBean(beginTag + s.substring(0, 4), s.substring(4, num));
|
||||||
|
} else if ((num81 <= s.length()) && (s.substring(num81).indexOf(endTag) == 0)) {
|
||||||
|
return new TLVBean(beginTag + "81", s.substring(2, num81));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int num = Integer.parseInt(s.substring(0, 2), 16) * 2 + 2;
|
||||||
|
if ((num <= s.length()) && (s.substring(num).indexOf(endTag) == 0)) {
|
||||||
|
return new TLVBean(beginTag + s.substring(0, 2), s.substring(2, num));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
package com.truphone.lpa.impl;
|
||||||
|
|
||||||
|
public class AuthenticateClientSmDp {
|
||||||
|
private String smdpSigned2;
|
||||||
|
private String smdpSignature2;
|
||||||
|
private String smdpCertificate;
|
||||||
|
|
||||||
|
public AuthenticateClientSmDp() {
|
||||||
|
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSmdpSigned2() {
|
||||||
|
|
||||||
|
return smdpSigned2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSmdpSignature2() {
|
||||||
|
|
||||||
|
return smdpSignature2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSmdpCertificate() {
|
||||||
|
|
||||||
|
return smdpCertificate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSmdpSigned2(String smdpSigned2) {
|
||||||
|
|
||||||
|
this.smdpSigned2 = smdpSigned2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSmdpSignature2(String smdpSignature2) {
|
||||||
|
|
||||||
|
this.smdpSignature2 = smdpSignature2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSmdpCertificate(String smdpCertificate) {
|
||||||
|
|
||||||
|
this.smdpCertificate = smdpCertificate;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,101 @@
|
||||||
|
package com.truphone.lpa.impl;
|
||||||
|
|
||||||
|
|
||||||
|
import com.truphone.lpa.ApduChannel;
|
||||||
|
import com.truphone.lpa.apdu.ApduUtils;
|
||||||
|
import com.truphone.lpad.progress.Progress;
|
||||||
|
import com.truphone.lpad.progress.ProgressStep;
|
||||||
|
import com.truphone.rsp.dto.asn1.rspdefinitions.DisableProfileResponse;
|
||||||
|
import com.truphone.util.LogStub;
|
||||||
|
import org.apache.commons.codec.DecoderException;
|
||||||
|
import org.apache.commons.codec.binary.Hex;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
class DisableProfileWorker {
|
||||||
|
private static final Logger LOG = Logger.getLogger(DisableProfileWorker.class.getName());
|
||||||
|
|
||||||
|
private final String iccid;
|
||||||
|
private final Progress progress;
|
||||||
|
private final ApduChannel apduChannel;
|
||||||
|
|
||||||
|
DisableProfileWorker(String iccid, Progress progress, ApduChannel apduChannel) {
|
||||||
|
|
||||||
|
this.iccid = iccid;
|
||||||
|
this.progress = progress;
|
||||||
|
this.apduChannel = apduChannel;
|
||||||
|
}
|
||||||
|
|
||||||
|
String run() {
|
||||||
|
String eResponse = transmitDisableProfile(iccid, progress);
|
||||||
|
|
||||||
|
return convertDisableProfileResponse(iccid, progress, eResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String convertDisableProfileResponse(String iccid, Progress progress, String eResponse) {
|
||||||
|
|
||||||
|
progress.stepExecuted(ProgressStep.DISABLE_PROFILE_CONVERTING_RESPONSE, "Converting response");
|
||||||
|
|
||||||
|
try {
|
||||||
|
InputStream is = new ByteArrayInputStream(Hex.decodeHex(eResponse.toCharArray()));
|
||||||
|
DisableProfileResponse disableProfileResponse = new DisableProfileResponse();
|
||||||
|
|
||||||
|
disableProfileResponse.decode(is);
|
||||||
|
|
||||||
|
if (LocalProfileAssistantImpl.PROFILE_RESULT_SUCESS.equals(disableProfileResponse.getDisableResult().toString())) {
|
||||||
|
progress.stepExecuted(ProgressStep.DISABLE_PROFILE_DISABLED, iccid + " disabled");
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - SEND Status to APDU Channel");
|
||||||
|
}
|
||||||
|
|
||||||
|
apduChannel.sendStatus();
|
||||||
|
|
||||||
|
progress.stepExecuted(ProgressStep.DISABLE_PROFILE_TRIGGERED_PROFILE_SWITCH, iccid + " triggered profile switch");
|
||||||
|
} else {
|
||||||
|
progress.stepExecuted(ProgressStep.DISABLE_PROFILE_NOT_DISABLED, iccid + " profile not disabled");
|
||||||
|
|
||||||
|
LOG.info(LogStub.getInstance().getTag() + " - iccid:" + iccid + " profile not disabled");
|
||||||
|
}
|
||||||
|
|
||||||
|
return disableProfileResponse.getDisableResult().toString();
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
LOG.log(Level.SEVERE, LogStub.getInstance().getTag() + " - iccid: " + iccid + " profile failed to be disabled");
|
||||||
|
|
||||||
|
throw new RuntimeException("Unable to disable profile: " + iccid + ", response: " + eResponse);
|
||||||
|
} catch (DecoderException e) {
|
||||||
|
LOG.log(Level.SEVERE, LogStub.getInstance().getTag() + " - " + e.getMessage(), e);
|
||||||
|
LOG.log(Level.SEVERE, LogStub.getInstance().getTag() + " - iccid: " + iccid + " profile failed to be disabled. Exception in Decoder:" + e.getMessage());
|
||||||
|
|
||||||
|
throw new RuntimeException("Unable to disable profile: " + iccid + ", response: " + eResponse);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String transmitDisableProfile(String iccid, Progress progress) {
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - Disabling profile: " + iccid);
|
||||||
|
}
|
||||||
|
|
||||||
|
progress.setTotalSteps(4);
|
||||||
|
progress.stepExecuted(ProgressStep.DISABLE_PROFILE_DISABLING_PROFILE, iccid + " disabling profile");
|
||||||
|
|
||||||
|
String apdu = ApduUtils.disableProfileApdu(iccid, LocalProfileAssistantImpl.TRIGGER_PROFILE_REFRESH);
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - Disable profile apdu: " + apdu);
|
||||||
|
}
|
||||||
|
|
||||||
|
String eResponse = apduChannel.transmitAPDU(apdu);
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - Disable response: " + eResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
return eResponse;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,77 @@
|
||||||
|
package com.truphone.lpa.impl;
|
||||||
|
|
||||||
|
import com.truphone.es9plus.Es9PlusImpl;
|
||||||
|
import com.truphone.lpa.ApduChannel;
|
||||||
|
import com.truphone.lpa.impl.download.*;
|
||||||
|
import com.truphone.lpa.progress.DownloadProgress;
|
||||||
|
import com.truphone.util.LogStub;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
class DownloadProfileWorker {
|
||||||
|
private static final Logger LOG = Logger.getLogger(DownloadProfileWorker.class.getName());
|
||||||
|
|
||||||
|
private final DownloadProgress progress;
|
||||||
|
private final Es9PlusImpl es9Module;
|
||||||
|
private String matchingId;
|
||||||
|
private ApduTransmitter apduTransmitter;
|
||||||
|
|
||||||
|
DownloadProfileWorker(String matchingId, DownloadProgress progress, ApduChannel apduChannel, Es9PlusImpl es9Module) {
|
||||||
|
|
||||||
|
this.matchingId = matchingId;
|
||||||
|
this.progress = progress;
|
||||||
|
this.es9Module = es9Module;
|
||||||
|
apduTransmitter = new ApduTransmitter(apduChannel);
|
||||||
|
}
|
||||||
|
|
||||||
|
void run() throws Exception {
|
||||||
|
AuthenticatingPhaseWorker authenticatingPhaseWorker = new AuthenticatingPhaseWorker(progress, apduTransmitter, es9Module);
|
||||||
|
DownloadPhaseWorker downloadPhaseWorker = new DownloadPhaseWorker(progress, apduTransmitter, es9Module);
|
||||||
|
|
||||||
|
LOG.info(LogStub.getInstance().getTag() + " - Downloading profile with matching Id: " + matchingId);
|
||||||
|
|
||||||
|
|
||||||
|
//AP Added this to support Activation Codes
|
||||||
|
//If matchingId is an Activation Code, parses AC to retrieve DP Address and Matching ID.
|
||||||
|
//Otherwise LPA shall use the default SMDP configured on the cards
|
||||||
|
|
||||||
|
String serverAddress;
|
||||||
|
if(matchingId.contains("$")){
|
||||||
|
//Its activation code
|
||||||
|
String[] acParts = matchingId.split("\\$");
|
||||||
|
if(acParts.length<3 )
|
||||||
|
throw new RuntimeException("Invalid ActivationCode format");
|
||||||
|
|
||||||
|
serverAddress = acParts[1];
|
||||||
|
matchingId = acParts[2];
|
||||||
|
}else
|
||||||
|
{
|
||||||
|
serverAddress = new ConnectingPhaseWorker(progress, apduTransmitter).getEuiccConfiguredAddress(matchingId);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
InitialAuthenticationKeys initialAuthenticationKeys = new InitialAuthenticationKeys(matchingId,
|
||||||
|
serverAddress,
|
||||||
|
authenticatingPhaseWorker.getEuiccInfo(),
|
||||||
|
authenticatingPhaseWorker.getEuiccChallenge(matchingId));
|
||||||
|
|
||||||
|
authenticatingPhaseWorker.initiateAuthentication(initialAuthenticationKeys);
|
||||||
|
downloadAndInstallProfilePackage(initialAuthenticationKeys,
|
||||||
|
downloadPhaseWorker.prepareDownload(authenticatingPhaseWorker.authenticateClient(initialAuthenticationKeys,
|
||||||
|
authenticatingPhaseWorker.authenticateWithEuicc(initialAuthenticationKeys))), downloadPhaseWorker);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void downloadAndInstallProfilePackage(InitialAuthenticationKeys initialAuthenticationKeys,
|
||||||
|
String encodedPrepareDownloadResponse, DownloadPhaseWorker downloadPhaseWorker) throws IOException {
|
||||||
|
String bpp = downloadPhaseWorker.getBoundProfilePackage(initialAuthenticationKeys, encodedPrepareDownloadResponse);
|
||||||
|
Map<SbppApdu, List<String>> sbpp = new GeneratePhaseWorker(progress).generateSbpp(bpp);
|
||||||
|
|
||||||
|
new InstallationPhaseWorker(progress, apduTransmitter).loadingSbppApdu(sbpp);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,106 @@
|
||||||
|
package com.truphone.lpa.impl;
|
||||||
|
|
||||||
|
|
||||||
|
import com.truphone.lpa.ApduChannel;
|
||||||
|
import com.truphone.lpa.apdu.ApduUtils;
|
||||||
|
import com.truphone.lpad.progress.Progress;
|
||||||
|
import com.truphone.lpad.progress.ProgressStep;
|
||||||
|
import com.truphone.rsp.dto.asn1.rspdefinitions.EnableProfileResponse;
|
||||||
|
import com.truphone.util.LogStub;
|
||||||
|
import org.apache.commons.codec.DecoderException;
|
||||||
|
import org.apache.commons.codec.binary.Hex;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
class EnableProfileWorker {
|
||||||
|
private static final Logger LOG = Logger.getLogger(EnableProfileWorker.class.getName());
|
||||||
|
|
||||||
|
private final String iccid;
|
||||||
|
private final Progress progress;
|
||||||
|
private final ApduChannel apduChannel;
|
||||||
|
|
||||||
|
EnableProfileWorker(String iccid, Progress progress, ApduChannel apduChannel) {
|
||||||
|
|
||||||
|
this.iccid = iccid;
|
||||||
|
this.progress = progress;
|
||||||
|
this.apduChannel = apduChannel;
|
||||||
|
}
|
||||||
|
|
||||||
|
String run() {
|
||||||
|
String eResponse = transmitEnableProfile();
|
||||||
|
|
||||||
|
return convertEnableProfileResponse(eResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String convertEnableProfileResponse(String eResponse) {
|
||||||
|
|
||||||
|
progress.stepExecuted(ProgressStep.ENABLE_PROFILE_CONVERTING_RESPONSE, "Enable profile APDU");
|
||||||
|
|
||||||
|
try {
|
||||||
|
EnableProfileResponse enableProfileResponse = new EnableProfileResponse();
|
||||||
|
InputStream is = new ByteArrayInputStream(Hex.decodeHex(eResponse.toCharArray()));
|
||||||
|
|
||||||
|
enableProfileResponse.decode(is);
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - Enable response: " + enableProfileResponse.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LocalProfileAssistantImpl.PROFILE_RESULT_SUCESS.equals(enableProfileResponse.getEnableResult().toString())) {
|
||||||
|
progress.stepExecuted(ProgressStep.ENABLE_PROFILE_PROFILE_ENABLED, iccid + " profile enabled successfully");
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - iccid:" + iccid + " profile enabled successfully");
|
||||||
|
}
|
||||||
|
|
||||||
|
apduChannel.sendStatus();
|
||||||
|
|
||||||
|
progress.stepExecuted(ProgressStep.ENABLE_PROFILE_TRIGGERED_PROFILE_SWITCH, iccid + " triggered profile switch");
|
||||||
|
} else {
|
||||||
|
progress.stepExecuted(ProgressStep.ENABLE_PROFILE_PROFILE_NOT_ENABLED, iccid + " profile not enabled");
|
||||||
|
|
||||||
|
LOG.info(LogStub.getInstance().getTag() + " - iccid: " + iccid + " profile not enabled");
|
||||||
|
}
|
||||||
|
|
||||||
|
return enableProfileResponse.getEnableResult().toString();
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOG.log(Level.SEVERE, LogStub.getInstance().getTag() + " - " + e.getMessage(), e);
|
||||||
|
LOG.severe(LogStub.getInstance().getTag() + " - iccid: " + iccid + " profile failed to be enabled. message: " + e.getMessage());
|
||||||
|
|
||||||
|
throw new RuntimeException("Unable to enable profile: " + iccid + ", response: " + eResponse);
|
||||||
|
} catch (DecoderException e) {
|
||||||
|
LOG.log(Level.SEVERE, LogStub.getInstance().getTag() + " - " + e.getMessage(), e);
|
||||||
|
LOG.severe(LogStub.getInstance().getTag() + " - iccid: " + iccid + " profile failed to be enabled. Exception in Decoder:" + e.getMessage());
|
||||||
|
|
||||||
|
throw new RuntimeException("Unable to enable profile: " + iccid + ", response: " + eResponse);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String transmitEnableProfile() {
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - Enabling profile: " + iccid);
|
||||||
|
}
|
||||||
|
|
||||||
|
progress.setTotalSteps(4);
|
||||||
|
progress.stepExecuted(ProgressStep.ENABLE_PROFILE_ENABLING_PROFILE, "Enabling profile");
|
||||||
|
|
||||||
|
String apdu = ApduUtils.enableProfileApdu(iccid, LocalProfileAssistantImpl.TRIGGER_PROFILE_REFRESH);
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - Enable profile APDU: " + apdu);
|
||||||
|
}
|
||||||
|
|
||||||
|
String eResponse = apduChannel.transmitAPDU(apdu);
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - Enable profile response: " + eResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
return eResponse;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
* To change this license header, choose License Headers in Project Properties.
|
||||||
|
* To change this template file, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
package com.truphone.lpa.impl;
|
||||||
|
|
||||||
|
import com.truphone.lpa.ApduChannel;
|
||||||
|
import com.truphone.lpa.apdu.ApduUtils;
|
||||||
|
import com.truphone.lpad.progress.Progress;
|
||||||
|
import com.truphone.lpad.progress.ProgressStep;
|
||||||
|
import com.truphone.rsp.dto.asn1.rspdefinitions.EuiccConfiguredAddressesResponse;
|
||||||
|
import com.truphone.util.LogStub;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
import org.apache.commons.codec.DecoderException;
|
||||||
|
import org.apache.commons.codec.binary.Hex;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author amilcar.pereira
|
||||||
|
*/
|
||||||
|
public class GetSMDPAddressWorker {
|
||||||
|
|
||||||
|
private static final Logger LOG = Logger.getLogger(EnableProfileWorker.class.getName());
|
||||||
|
private final ApduChannel apduChannel;
|
||||||
|
private final Progress progress;
|
||||||
|
|
||||||
|
public GetSMDPAddressWorker(ApduChannel apduChannel, Progress progress) {
|
||||||
|
this.apduChannel = apduChannel;
|
||||||
|
this.progress = progress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String run(){
|
||||||
|
return transmitGetSMDPAddress();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String transmitGetSMDPAddress() {
|
||||||
|
|
||||||
|
String apdu = ApduUtils.getEuiccConfiguredAddressesApdu();
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - getEuiccConfiguredAddressesApdu APDU: " + apdu);
|
||||||
|
}
|
||||||
|
|
||||||
|
String eResponse = apduChannel.transmitAPDU(apdu);
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - getEuiccConfiguredAddressesApdu response: " + eResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
return eResponse;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,193 @@
|
||||||
|
package com.truphone.lpa.impl;
|
||||||
|
|
||||||
|
import com.truphone.rsp.dto.asn1.rspdefinitions.*;
|
||||||
|
import org.apache.commons.codec.DecoderException;
|
||||||
|
import org.apache.commons.codec.binary.Base64;
|
||||||
|
import org.apache.commons.codec.binary.Hex;
|
||||||
|
import com.beanit.asn1bean.ber.ReverseByteArrayOutputStream;
|
||||||
|
import com.truphone.es9plus.Es9PlusImpl;
|
||||||
|
import com.truphone.lpa.ApduChannel;
|
||||||
|
import com.truphone.lpa.apdu.ApduUtils;
|
||||||
|
import com.truphone.lpa.apdu.NotificationType;
|
||||||
|
import com.truphone.util.LogStub;
|
||||||
|
import com.truphone.util.Util;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
public class HandleNotificationsWorker {
|
||||||
|
private static final Logger LOG = Logger.getLogger(HandleNotificationsWorker.class.getName());
|
||||||
|
|
||||||
|
private final ApduChannel apduChannel;
|
||||||
|
private final Es9PlusImpl es9Module;
|
||||||
|
|
||||||
|
HandleNotificationsWorker(ApduChannel apduChannel, Es9PlusImpl es9Module) {
|
||||||
|
|
||||||
|
this.apduChannel = apduChannel;
|
||||||
|
this.es9Module = es9Module;
|
||||||
|
}
|
||||||
|
|
||||||
|
void run(NotificationType notificationType) {
|
||||||
|
String notificationList = getNotificationsList(notificationType);
|
||||||
|
ListNotificationResponse list = new ListNotificationResponse();
|
||||||
|
|
||||||
|
try {
|
||||||
|
decodeNotificationList(notificationList, list);
|
||||||
|
|
||||||
|
for (NotificationMetadata notification : list.getNotificationMetadataList().getNotificationMetadata()) {
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - Notification: " + notification.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
int seqNo = notification.getSeqNumber().intValue();
|
||||||
|
RetrieveNotificationsListResponse notificationListResponse = getRetrieveNotificationsListResponse(seqNo);
|
||||||
|
|
||||||
|
handlePendingNotification(seqNo, notificationListResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (DecoderException e) {
|
||||||
|
LOG.log(Level.SEVERE, LogStub.getInstance().getTag() + " - " + e.getMessage(), e);
|
||||||
|
LOG.log(Level.SEVERE, LogStub.getInstance().getTag() + " - Unable to retrieve profiles. Exception in Decoder:" + e.getMessage());
|
||||||
|
|
||||||
|
throw new RuntimeException("Unable to retrieve profiles");
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
LOG.log(Level.SEVERE, LogStub.getInstance().getTag() + " - " + ioe.getMessage(), ioe);
|
||||||
|
|
||||||
|
throw new RuntimeException("Unable to retrieve profiles");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void decodeNotificationList(String notificationList, ListNotificationResponse list) throws DecoderException, IOException {
|
||||||
|
InputStream is = new ByteArrayInputStream(Hex.decodeHex(notificationList.toCharArray()));
|
||||||
|
|
||||||
|
list.decode(is, true);
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - List of notifications: " + list.toString());
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - Number of notifications: " + list.getNotificationMetadataList().getNotificationMetadata().size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getNotificationsList(NotificationType notificationType) {
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - Listing notification for type: " + notificationType.toString() +
|
||||||
|
"[" + notificationType.name() + "]");
|
||||||
|
}
|
||||||
|
|
||||||
|
String listNotificationsApdu = ApduUtils.listNotificationApdu(notificationType.toString());
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - Listing notifications apdu: " + listNotificationsApdu);
|
||||||
|
}
|
||||||
|
|
||||||
|
String notificationList = apduChannel.transmitAPDU(listNotificationsApdu);
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - Notification list response: " + notificationList);
|
||||||
|
}
|
||||||
|
|
||||||
|
return notificationList;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handlePendingNotification(int seqNo, RetrieveNotificationsListResponse notificationListResponse) throws IOException, DecoderException {
|
||||||
|
|
||||||
|
if (notificationListResponse != null && notificationListResponse.getNotificationList() != null &&
|
||||||
|
notificationListResponse.getNotificationList().getPendingNotification() != null)
|
||||||
|
for (PendingNotification pendingNotification : notificationListResponse.getNotificationList().getPendingNotification()) {
|
||||||
|
String encodedPendingNotification = getEncodedPendingNotification(pendingNotification);
|
||||||
|
|
||||||
|
String serverAddress="";
|
||||||
|
if(pendingNotification.getProfileInstallationResult()!=null){
|
||||||
|
//It's a PIR
|
||||||
|
serverAddress = pendingNotification.getProfileInstallationResult().getProfileInstallationResultData().getNotificationMetadata().getNotificationAddress().toString();
|
||||||
|
}else{
|
||||||
|
serverAddress = pendingNotification.getOtherSignedNotification().getTbsOtherNotification().getNotificationAddress().toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
es9Module.handleNotification(encodedPendingNotification, serverAddress);
|
||||||
|
|
||||||
|
removeNotification(seqNo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private RetrieveNotificationsListResponse getRetrieveNotificationsListResponse(int seqNo) throws DecoderException, IOException {
|
||||||
|
String retrieveNotificationFromListApdu = ApduUtils.retrievePendingNotificationsListApdu(seqNo);
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - Retrieving notification: " + retrieveNotificationFromListApdu);
|
||||||
|
}
|
||||||
|
|
||||||
|
String notificationResponse = apduChannel.transmitAPDU(retrieveNotificationFromListApdu);
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - Notification response: " + notificationResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
return decodeNotificationResponse(notificationResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
private RetrieveNotificationsListResponse decodeNotificationResponse(String notificationResponse) throws DecoderException, IOException {
|
||||||
|
InputStream is3 = new ByteArrayInputStream(Hex.decodeHex(notificationResponse.toCharArray()));
|
||||||
|
RetrieveNotificationsListResponse notificationListResponse = new RetrieveNotificationsListResponse();
|
||||||
|
|
||||||
|
notificationListResponse.decode(is3, true);
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - Notification: " + notificationListResponse.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
return notificationListResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getEncodedPendingNotification(PendingNotification pendingNotification) throws IOException {
|
||||||
|
ReverseByteArrayOutputStream berByteArrayOutputStream = new ReverseByteArrayOutputStream(4000, true);
|
||||||
|
|
||||||
|
pendingNotification.encode(berByteArrayOutputStream);
|
||||||
|
|
||||||
|
String pendingNotificationStr = Util.byteArrayToHexString(berByteArrayOutputStream.getArray(), "");
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - Pending notification: " + pendingNotificationStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
String encodedPendingNotification = Base64.encodeBase64String(Util.hexStringToByteArray(pendingNotificationStr));
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - Encoded pending notification: " + encodedPendingNotification);
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - Sending notification to SM-DP+");
|
||||||
|
}
|
||||||
|
|
||||||
|
return encodedPendingNotification;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeNotification(int seqNo) throws DecoderException, IOException {
|
||||||
|
String removeNotificationApdu = ApduUtils.removeNotificationFromListApdu(seqNo);
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - Remove notification apdu: " + removeNotificationApdu);
|
||||||
|
}
|
||||||
|
|
||||||
|
String removeNotificationResponse = apduChannel.transmitAPDU(removeNotificationApdu);
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - Remove notification response: " + removeNotificationResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
decodeRemoveNotification(removeNotificationResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void decodeRemoveNotification(String removeNotificationResponse) throws DecoderException, IOException {
|
||||||
|
InputStream is2 = new ByteArrayInputStream(Hex.decodeHex(removeNotificationResponse.toCharArray()));
|
||||||
|
NotificationSentResponse notificationSentResponse = new NotificationSentResponse();
|
||||||
|
|
||||||
|
notificationSentResponse.decode(is2, true);
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - Notification removal response: " + notificationSentResponse.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,123 @@
|
||||||
|
package com.truphone.lpa.impl;
|
||||||
|
|
||||||
|
public class InitialAuthenticationKeys {
|
||||||
|
private String matchingId;
|
||||||
|
private String euiccConfiguredAddress;
|
||||||
|
private String euiccInfo1;
|
||||||
|
private String euiccChallenge;
|
||||||
|
private String serverSigned1;
|
||||||
|
private String serverSignature1;
|
||||||
|
private String euiccCiPKIdTobeUsed;
|
||||||
|
private String serverCertificate;
|
||||||
|
private String transactionId;
|
||||||
|
private String ctxParams1;
|
||||||
|
|
||||||
|
InitialAuthenticationKeys(String matchingId, String euiccConfiguredAddress, String euiccInfo1, String euiccChallenge) {
|
||||||
|
|
||||||
|
this.matchingId = matchingId;
|
||||||
|
this.euiccConfiguredAddress = euiccConfiguredAddress;
|
||||||
|
this.euiccInfo1 = euiccInfo1;
|
||||||
|
this.euiccChallenge = euiccChallenge;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMatchingId() {
|
||||||
|
|
||||||
|
return matchingId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getServerSigned1() {
|
||||||
|
|
||||||
|
return serverSigned1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getServerSignature1() {
|
||||||
|
|
||||||
|
return serverSignature1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEuiccCiPKIdTobeUsed() {
|
||||||
|
|
||||||
|
return euiccCiPKIdTobeUsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getServerCertificate() {
|
||||||
|
|
||||||
|
return serverCertificate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTransactionId() {
|
||||||
|
|
||||||
|
return transactionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCtxParams1() {
|
||||||
|
|
||||||
|
return ctxParams1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEuiccConfiguredAddress() {
|
||||||
|
|
||||||
|
return euiccConfiguredAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEuiccInfo1() {
|
||||||
|
|
||||||
|
return euiccInfo1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEuiccChallenge() {
|
||||||
|
|
||||||
|
return euiccChallenge;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMatchingId(String matchingId) {
|
||||||
|
|
||||||
|
this.matchingId = matchingId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setServerSigned1(String serverSigned1) {
|
||||||
|
|
||||||
|
this.serverSigned1 = serverSigned1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setServerSignature1(String serverSignature1) {
|
||||||
|
|
||||||
|
this.serverSignature1 = serverSignature1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEuiccCiPKIdTobeUsed(String euiccCiPKIdTobeUsed) {
|
||||||
|
|
||||||
|
this.euiccCiPKIdTobeUsed = euiccCiPKIdTobeUsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setServerCertificate(String serverCertificate) {
|
||||||
|
|
||||||
|
this.serverCertificate = serverCertificate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTransactionId(String transactionId) {
|
||||||
|
|
||||||
|
this.transactionId = transactionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCtxParams1(String ctxParams1) {
|
||||||
|
|
||||||
|
this.ctxParams1 = ctxParams1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "InitialAuthenticationKeys{" +
|
||||||
|
"matchingId='" + matchingId + '\'' +
|
||||||
|
", euiccConfiguredAddress='" + euiccConfiguredAddress + '\'' +
|
||||||
|
", euiccInfo1='" + euiccInfo1 + '\'' +
|
||||||
|
", euiccChallenge='" + euiccChallenge + '\'' +
|
||||||
|
", serverSigned1='" + serverSigned1 + '\'' +
|
||||||
|
", serverSignature1='" + serverSignature1 + '\'' +
|
||||||
|
", euiccCiPKIdTobeUsed='" + euiccCiPKIdTobeUsed + '\'' +
|
||||||
|
", serverCertificate='" + serverCertificate + '\'' +
|
||||||
|
", transactionId='" + transactionId + '\'' +
|
||||||
|
", ctxParams1='" + ctxParams1 + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,95 @@
|
||||||
|
package com.truphone.lpa.impl;
|
||||||
|
|
||||||
|
import com.truphone.rsp.dto.asn1.rspdefinitions.ProfileInfo;
|
||||||
|
import com.truphone.rsp.dto.asn1.rspdefinitions.ProfileInfoListResponse;
|
||||||
|
import org.apache.commons.codec.DecoderException;
|
||||||
|
import org.apache.commons.codec.binary.Hex;
|
||||||
|
import com.truphone.lpa.ApduChannel;
|
||||||
|
import com.truphone.lpa.apdu.ApduUtils;
|
||||||
|
import com.truphone.util.LogStub;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
class ListProfilesWorker {
|
||||||
|
private static final Logger LOG = Logger.getLogger(ListProfilesWorker.class.getName());
|
||||||
|
|
||||||
|
private final ApduChannel apduChannel;
|
||||||
|
|
||||||
|
ListProfilesWorker(ApduChannel apduChannel) {
|
||||||
|
|
||||||
|
this.apduChannel = apduChannel;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Map<String, String>> run() {
|
||||||
|
String profilesInfo = getProfileInfoListResponse();
|
||||||
|
ProfileInfoListResponse profiles = new ProfileInfoListResponse();
|
||||||
|
List<Map<String, String>> profileList = new ArrayList<>();
|
||||||
|
|
||||||
|
try {
|
||||||
|
decodeProfiles(profilesInfo, profiles);
|
||||||
|
|
||||||
|
for (ProfileInfo info : profiles.getProfileInfoListOk().getProfileInfo()) {
|
||||||
|
Map<String, String> profileMap = new HashMap<>();
|
||||||
|
|
||||||
|
profileMap.put(ProfileKey.STATE.name(), LocalProfileAssistantImpl.DISABLED_STATE.equals(info.getProfileState().toString()) ? "Disabled" : "Enabled");
|
||||||
|
profileMap.put(ProfileKey.ICCID.name(), info.getIccid().toString());
|
||||||
|
profileMap.put(ProfileKey.NAME.name(), (info.getProfileName()!=null)?info.getProfileName().toString():"");
|
||||||
|
profileMap.put(ProfileKey.PROVIDER_NAME.name(), (info.getServiceProviderName()!=null)?info.getServiceProviderName().toString():"");
|
||||||
|
profileMap.put(ProfileKey.ISDP_AID.name(), (info.getIsdpAid()!=null)?info.getIsdpAid().toString():"");
|
||||||
|
profileMap.put(ProfileKey.PROFILE_CLASS.name(), (info.getProfileClass()!=null)?info.getProfileClass().toString():"");
|
||||||
|
profileMap.put(ProfileKey.PROFILE_STATE.name(), info.getProfileState().toString());
|
||||||
|
|
||||||
|
profileList.add(profileMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug (LOG, LogStub.getInstance().getTag() + " - getProfiles - returning: " + profileList.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
return profileList;
|
||||||
|
|
||||||
|
} catch (DecoderException e) {
|
||||||
|
LOG.log(Level.SEVERE, LogStub.getInstance().getTag() + " - " + e.getMessage(), e);
|
||||||
|
LOG.log(Level.SEVERE, LogStub.getInstance().getTag() + " - Unable to retrieve profiles. Exception in Decoder:" + e.getMessage());
|
||||||
|
|
||||||
|
throw new RuntimeException("Unable to retrieve profiles");
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
LOG.log(Level.SEVERE, LogStub.getInstance().getTag() + " - " + ioe.getMessage(), ioe);
|
||||||
|
|
||||||
|
throw new RuntimeException("Unable to retrieve profiles");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void decodeProfiles(String profilesInfo, ProfileInfoListResponse profiles) throws DecoderException, IOException {
|
||||||
|
InputStream is = new ByteArrayInputStream(Hex.decodeHex(profilesInfo.toCharArray()));
|
||||||
|
|
||||||
|
profiles.decode(is);
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug (LOG,"Profile list object: " + profiles.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getProfileInfoListResponse() {
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug (LOG, LogStub.getInstance().getTag() + " - Getting Profiles");
|
||||||
|
}
|
||||||
|
|
||||||
|
String apdu = ApduUtils.getProfilesInfoApdu(null);
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug (LOG,"List profiles APDU: " + apdu);
|
||||||
|
}
|
||||||
|
|
||||||
|
return apduChannel.transmitAPDU(apdu);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,142 @@
|
||||||
|
package com.truphone.lpa.impl;
|
||||||
|
|
||||||
|
import com.truphone.es9plus.Es9PlusImpl;
|
||||||
|
import com.truphone.lpa.ApduChannel;
|
||||||
|
import com.truphone.lpa.LocalProfileAssistant;
|
||||||
|
import com.truphone.lpa.apdu.ApduUtils;
|
||||||
|
import com.truphone.lpa.apdu.NotificationType;
|
||||||
|
import com.truphone.lpa.progress.DownloadProgress;
|
||||||
|
import com.truphone.lpad.progress.Progress;
|
||||||
|
import com.truphone.lpad.worker.AllocateProfileWorker;
|
||||||
|
import com.truphone.lpad.worker.DeleteProfileWorker;
|
||||||
|
import com.truphone.lpad.worker.GetEidLpadWorker;
|
||||||
|
import com.truphone.lpad.worker.LpadWorkerExchange;
|
||||||
|
import com.truphone.util.LogStub;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
public class LocalProfileAssistantImpl implements LocalProfileAssistant {
|
||||||
|
static final String PROFILE_RESULT_SUCESS = "0";
|
||||||
|
static final String TRIGGER_PROFILE_REFRESH = "FF";
|
||||||
|
static final String DISABLED_STATE = PROFILE_RESULT_SUCESS;
|
||||||
|
|
||||||
|
private static final Logger LOG = Logger.getLogger(LocalProfileAssistantImpl.class.getName());
|
||||||
|
|
||||||
|
private final ApduChannel apduChannel;
|
||||||
|
private Es9PlusImpl es9Module;
|
||||||
|
|
||||||
|
// public LocalProfileAssistantImpl(final ApduChannel apduChannel,
|
||||||
|
// final String rspServerUrl) {
|
||||||
|
public LocalProfileAssistantImpl(final ApduChannel apduChannel){
|
||||||
|
this.apduChannel = apduChannel;
|
||||||
|
es9Module = new Es9PlusImpl();
|
||||||
|
|
||||||
|
//LOG.info(LogStub.getInstance().getTag() + " - Init SM-DP connection - " + rspServerUrl);
|
||||||
|
|
||||||
|
// if (!StringUtils.isNotBlank(rspServerUrl) || !checkRspServerURL(rspServerUrl)) {
|
||||||
|
// if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
// LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - Fixing RSP Server URL to default - " + rspServerUrl);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// throw new IllegalArgumentException("RSP Server URL is invalid: " + rspServerUrl);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// es9Module.configure(rspServerUrl);
|
||||||
|
//es9Module.configure();
|
||||||
|
LOG.log(Level.INFO, LogStub.getInstance().getTag() + " - SM-DP connection initiated.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean checkRspServerURL(final String rspServerUrl) {
|
||||||
|
|
||||||
|
return rspServerUrl.matches("^(https?:\\/\\/)?([\\da-z\\.-]+\\.[a-z\\.]{2,6}|[\\d\\.]+)([\\/:?=&#]{1}[\\da-z\\.-]+)*[\\/\\?]?$");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String enableProfile(final String iccid,
|
||||||
|
final Progress progress) {
|
||||||
|
|
||||||
|
return new EnableProfileWorker(iccid, progress, apduChannel).run();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String disableProfile(final String iccid,
|
||||||
|
final Progress progress) {
|
||||||
|
|
||||||
|
return new DisableProfileWorker(iccid, progress, apduChannel).run();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String deleteProfile(final String iccid,
|
||||||
|
final Progress progress) {
|
||||||
|
|
||||||
|
DeleteProfileWorker deleteProfileWorker = new DeleteProfileWorker(progress, apduChannel);
|
||||||
|
|
||||||
|
LpadWorkerExchange<DeleteProfileWorker.DeleteProfileInputParams> exchange =
|
||||||
|
new LpadWorkerExchange<>(deleteProfileWorker.new DeleteProfileInputParams(iccid));
|
||||||
|
|
||||||
|
return deleteProfileWorker.run(exchange);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void downloadProfile(final String matchingId,
|
||||||
|
final DownloadProgress progress) throws Exception {
|
||||||
|
|
||||||
|
new DownloadProfileWorker(matchingId, progress, apduChannel, es9Module).run();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Map<String, String>> getProfiles() {
|
||||||
|
|
||||||
|
return new ListProfilesWorker(apduChannel).run();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getEID() {
|
||||||
|
|
||||||
|
LpadWorkerExchange<String> exchange = new LpadWorkerExchange<>(ApduUtils.getEIDApdu());
|
||||||
|
|
||||||
|
return new GetEidLpadWorker(new Progress(), apduChannel).run(exchange);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String allocateProfile(final String mcc) {
|
||||||
|
Progress progress = new Progress();
|
||||||
|
|
||||||
|
AllocateProfileWorker allocateProfileWorker = new AllocateProfileWorker(progress, es9Module);
|
||||||
|
|
||||||
|
LpadWorkerExchange<AllocateProfileWorker.AllocateProfileInputParams> exchange
|
||||||
|
= new LpadWorkerExchange<>(allocateProfileWorker.new AllocateProfileInputParams(mcc, getEID()));
|
||||||
|
|
||||||
|
return allocateProfileWorker.run(exchange);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void processPendingNotifications() {
|
||||||
|
|
||||||
|
new HandleNotificationsWorker(apduChannel, es9Module).run(NotificationType.ALL);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDefaultSMDP() {
|
||||||
|
//LpadWorkerExchange<String> exchange = new LpadWorkerExchange<>(ApduUtils.setDefaultDpAddressApdu(smdpAddress));
|
||||||
|
|
||||||
|
return new GetSMDPAddressWorker(apduChannel, new Progress()).run();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String setDefaultSMDP(String smdpAddress, Progress progress) {
|
||||||
|
|
||||||
|
return new SetSMDPAddressWorker(apduChannel, progress, smdpAddress).run();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void smdsRetrieveEvents(Progress progress) {
|
||||||
|
// return new SmdsRetrieveEvents();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package com.truphone.lpa.impl;
|
||||||
|
|
||||||
|
public enum ProfileKey {
|
||||||
|
ICCID,
|
||||||
|
STATE,
|
||||||
|
NAME,
|
||||||
|
PROVIDER_NAME,
|
||||||
|
ISDP_AID,
|
||||||
|
PROFILE_CLASS,
|
||||||
|
PROFILE_STATE
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* To change this license header, choose License Headers in Project Properties.
|
||||||
|
* To change this template file, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
package com.truphone.lpa.impl;
|
||||||
|
|
||||||
|
import com.truphone.lpa.ApduChannel;
|
||||||
|
import com.truphone.lpa.apdu.ApduUtils;
|
||||||
|
import com.truphone.lpad.progress.Progress;
|
||||||
|
import com.truphone.util.LogStub;
|
||||||
|
import com.truphone.util.TextUtil;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author amilcar.pereira
|
||||||
|
*/
|
||||||
|
public class SetSMDPAddressWorker {
|
||||||
|
|
||||||
|
private static final Logger LOG = Logger.getLogger(EnableProfileWorker.class.getName());
|
||||||
|
private final ApduChannel apduChannel;
|
||||||
|
private final Progress progress;
|
||||||
|
private String dpAddrNew;
|
||||||
|
|
||||||
|
public SetSMDPAddressWorker(ApduChannel apduChannel, Progress progress, String dpAddrNew) {
|
||||||
|
this.apduChannel = apduChannel;
|
||||||
|
this.progress = progress;
|
||||||
|
this.dpAddrNew=dpAddrNew;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String run() {
|
||||||
|
String hexDPAddress = TextUtil.toHexString(dpAddrNew.getBytes());
|
||||||
|
String apdu = ApduUtils.setDefaultDpAddressApdu(hexDPAddress);
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - setEuiccConfiguredAddressesApdu APDU: " + apdu);
|
||||||
|
}
|
||||||
|
|
||||||
|
String eResponse = apduChannel.transmitAPDU(apdu);
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - setEuiccConfiguredAddressesApdu response: " + eResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
return eResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
* To change this license header, choose License Headers in Project Properties.
|
||||||
|
* To change this template file, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
package com.truphone.lpa.impl;
|
||||||
|
|
||||||
|
import com.truphone.lpa.ApduChannel;
|
||||||
|
import com.truphone.lpa.apdu.ApduUtils;
|
||||||
|
import com.truphone.lpad.progress.Progress;
|
||||||
|
import com.truphone.lpad.progress.ProgressStep;
|
||||||
|
import com.truphone.rsp.dto.asn1.rspdefinitions.EuiccConfiguredAddressesResponse;
|
||||||
|
import com.truphone.util.LogStub;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
import org.apache.commons.codec.DecoderException;
|
||||||
|
import org.apache.commons.codec.binary.Hex;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author amilcar.pereira
|
||||||
|
*/
|
||||||
|
public class SmdsRetrieveEventsWorker {
|
||||||
|
|
||||||
|
// private static final Logger LOG = Logger.getLogger(EnableProfileWorker.class.getName());
|
||||||
|
// private final ApduChannel apduChannel;
|
||||||
|
// private final Progress progress;
|
||||||
|
//
|
||||||
|
// public SmdsRetrieveEventsWorker(ApduChannel apduChannel, Progress progress) {
|
||||||
|
// this.apduChannel = apduChannel;
|
||||||
|
// this.progress = progress;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// public String run(){
|
||||||
|
// return transmitGetSMDPAddress();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// private String transmitGetSMDPAddress() {
|
||||||
|
//
|
||||||
|
// String apdu = ApduUtils.getEuiccConfiguredAddressesApdu();
|
||||||
|
//
|
||||||
|
// if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
// LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - getEuiccConfiguredAddressesApdu APDU: " + apdu);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// String eResponse = apduChannel.transmitAPDU(apdu);
|
||||||
|
//
|
||||||
|
// if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
// LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - getEuiccConfiguredAddressesApdu response: " + eResponse);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return eResponse;
|
||||||
|
// }
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
package com.truphone.lpa.impl.download;
|
||||||
|
|
||||||
|
import com.truphone.lpa.ApduChannel;
|
||||||
|
import com.truphone.lpa.ApduTransmittedListener;
|
||||||
|
import com.truphone.util.LogStub;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
public class ApduTransmitter {
|
||||||
|
private static final Logger LOG = Logger.getLogger(ApduTransmitter.class.getName());
|
||||||
|
|
||||||
|
private ApduChannel apduChannel;
|
||||||
|
|
||||||
|
public ApduTransmitter(ApduChannel apduChannel) {
|
||||||
|
|
||||||
|
this.apduChannel = apduChannel;
|
||||||
|
}
|
||||||
|
|
||||||
|
String transmitApdu(String apdu) {
|
||||||
|
String apduResponse;
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - APDU to transmit: " + apdu);
|
||||||
|
}
|
||||||
|
|
||||||
|
apduResponse = apduChannel.transmitAPDU(apdu);
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - Transmit APDU response: " + apduResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
return apduResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
String transmitApdus(List<String> apdus) {
|
||||||
|
String apduResponse;
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - APDUs to transmit: " + apdus);
|
||||||
|
}
|
||||||
|
|
||||||
|
apduResponse = apduChannel.transmitAPDUS(apdus);
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - Transmit APDUs response: " + apduResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
return apduResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
void addApduTransmittedListener(ApduTransmittedListener apduTransmittedListener) {
|
||||||
|
|
||||||
|
apduChannel.setApduTransmittedListener(apduTransmittedListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeApduTransmittedListener(ApduTransmittedListener apduTransmittedListener) {
|
||||||
|
|
||||||
|
apduChannel.removeApduTransmittedListener(apduTransmittedListener);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,290 @@
|
||||||
|
package com.truphone.lpa.impl.download;
|
||||||
|
|
||||||
|
|
||||||
|
import com.truphone.es9plus.Es9PlusImpl;
|
||||||
|
import com.truphone.es9plus.LpaUtils;
|
||||||
|
import com.truphone.es9plus.message.response.AuthenticateClientResp;
|
||||||
|
import com.truphone.es9plus.message.response.InitiateAuthenticationResp;
|
||||||
|
import com.truphone.lpa.apdu.ApduUtils;
|
||||||
|
import com.truphone.lpa.impl.AuthenticateClientSmDp;
|
||||||
|
import com.truphone.lpa.impl.InitialAuthenticationKeys;
|
||||||
|
import com.truphone.lpa.progress.DownloadProgress;
|
||||||
|
import com.truphone.lpa.progress.DownloadProgressPhase;
|
||||||
|
import com.truphone.rsp.dto.asn1.rspdefinitions.GetEuiccChallengeResponse;
|
||||||
|
import com.truphone.util.LogStub;
|
||||||
|
import com.truphone.util.Util;
|
||||||
|
import org.apache.commons.codec.DecoderException;
|
||||||
|
import org.apache.commons.codec.binary.Base64;
|
||||||
|
import org.apache.commons.codec.binary.Hex;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import static com.truphone.lpad.progress.ProgressStep.*;
|
||||||
|
|
||||||
|
public class AuthenticatingPhaseWorker {
|
||||||
|
private static final Logger LOG = Logger.getLogger(AuthenticatingPhaseWorker.class.getName());
|
||||||
|
|
||||||
|
private final DownloadProgress progress;
|
||||||
|
private final ApduTransmitter apduTransmitter;
|
||||||
|
private final Es9PlusImpl es9Module;
|
||||||
|
|
||||||
|
public AuthenticatingPhaseWorker(DownloadProgress progress, ApduTransmitter apduTransmitter, Es9PlusImpl es9Module) {
|
||||||
|
|
||||||
|
this.progress = progress;
|
||||||
|
this.apduTransmitter = apduTransmitter;
|
||||||
|
this.es9Module = es9Module;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEuiccInfo() {
|
||||||
|
|
||||||
|
progress.setCurrentPhase(DownloadProgressPhase.AUTHENTICATING);
|
||||||
|
progress.stepExecuted(DOWNLOAD_PROFILE_GET_EUICC_INFO, "getEuiccInfo retrieving...");
|
||||||
|
|
||||||
|
return convertEuiccInfo1(apduTransmitter.transmitApdu(ApduUtils.getEuiccInfo1Apdu()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private String convertEuiccInfo1(String euicInfo1APDUResponse) {
|
||||||
|
String euiccInfo1;
|
||||||
|
|
||||||
|
progress.stepExecuted(DOWNLOAD_PROFILE_CONVERTING_EUICC_INFO, "getEUICCInfo1 Success!");
|
||||||
|
|
||||||
|
euiccInfo1 = euicInfo1APDUResponse.toUpperCase();
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - EUICC Info Object: " + euiccInfo1);
|
||||||
|
}
|
||||||
|
|
||||||
|
euiccInfo1 = Base64.encodeBase64String(Util.hexStringToByteArray(euiccInfo1));
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - EUICC Info Object (Base 64): " + euiccInfo1);
|
||||||
|
}
|
||||||
|
|
||||||
|
progress.stepExecuted(DOWNLOAD_PROFILE_CONVERTED_EUICC_INFO, "getEUICCInfo1 Success!");
|
||||||
|
|
||||||
|
return euiccInfo1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEuiccChallenge(String matchingId) {
|
||||||
|
|
||||||
|
progress.stepExecuted(DOWNLOAD_PROFILE_GET_EUICC_CHALLENGE, "getEuiccChallenge retrieving...");
|
||||||
|
|
||||||
|
return convertEuiccChallenge(apduTransmitter.transmitApdu(ApduUtils.getEUICCChallengeApdu()), matchingId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String convertEuiccChallenge(String euiccChallengeApduResponse, String matchingId) {
|
||||||
|
String euiccChallenge;
|
||||||
|
|
||||||
|
progress.stepExecuted(DOWNLOAD_PROFILE_CONVERTING_EUICC_CHALLENGE, "convertEuiccChallenge converting...");
|
||||||
|
|
||||||
|
try {
|
||||||
|
euiccChallenge = Base64.encodeBase64String(Util.hexStringToByteArray(decodeGetEuiccChallengeResponse(euiccChallengeApduResponse)));
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - eUICCChallenge is " + euiccChallenge);
|
||||||
|
}
|
||||||
|
} catch (DecoderException e) {
|
||||||
|
LOG.log(Level.SEVERE, "KOL.007" + e.getMessage(), e);
|
||||||
|
LOG.severe(LogStub.getInstance().getTag() + " - matchingId: " + matchingId +
|
||||||
|
" Unable to retrieve eUICC challenge. Exception in Decoder:" + e.getMessage());
|
||||||
|
|
||||||
|
throw new RuntimeException("Unable to retrieve eUICC challenge: " + matchingId);
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
LOG.log(Level.SEVERE, "KOL.007" + ioe.getMessage(), ioe);
|
||||||
|
LOG.severe(LogStub.getInstance().getTag() + " - matchingId: " + matchingId +
|
||||||
|
" Unable to retrieve eUICC challenge. IOException:" + ioe.getMessage());
|
||||||
|
|
||||||
|
throw new RuntimeException("Unable to retrieve eUICC challenge");
|
||||||
|
}
|
||||||
|
|
||||||
|
progress.stepExecuted(DOWNLOAD_PROFILE_CONVERTED_EUICC_CHALLENGE, "convertEuiccChallenge converted...");
|
||||||
|
|
||||||
|
return euiccChallenge;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String decodeGetEuiccChallengeResponse(String euiccChallengeApduResponse) throws DecoderException, IOException {
|
||||||
|
InputStream is = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
GetEuiccChallengeResponse euiccChallengeResponse = new GetEuiccChallengeResponse();
|
||||||
|
|
||||||
|
is = new ByteArrayInputStream(Hex.decodeHex(euiccChallengeApduResponse.toCharArray()));
|
||||||
|
|
||||||
|
euiccChallengeResponse.decode(is);
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - Decoded euiccChallengeResponse: " + euiccChallengeResponse.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
return euiccChallengeResponse.getEuiccChallenge().toString();
|
||||||
|
} finally {
|
||||||
|
CloseResources.closeResources(is);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void initiateAuthentication(InitialAuthenticationKeys initialAuthenticationKeys) {
|
||||||
|
|
||||||
|
progress.stepExecuted(DOWNLOAD_PROFILE_INITIATE_AUTHENTICATION, "initiateAuthentication retrieving...");
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - Initiating Auth with SM-DP+");
|
||||||
|
}
|
||||||
|
|
||||||
|
InitiateAuthenticationResp initiateAuthenticationResp = getInitiateAuthenticationResp(initialAuthenticationKeys);
|
||||||
|
|
||||||
|
setServerSigned1(initialAuthenticationKeys, initiateAuthenticationResp);
|
||||||
|
setServerSignature1(initialAuthenticationKeys, initiateAuthenticationResp);
|
||||||
|
setEuiccCiPKIdToveUsed(initialAuthenticationKeys, initiateAuthenticationResp);
|
||||||
|
setServerCertificate(initialAuthenticationKeys, initiateAuthenticationResp);
|
||||||
|
setTransactionId(initialAuthenticationKeys, initiateAuthenticationResp);
|
||||||
|
setMatchingId(initialAuthenticationKeys);
|
||||||
|
setCtxParams1(initialAuthenticationKeys);
|
||||||
|
|
||||||
|
progress.stepExecuted(DOWNLOAD_PROFILE_INITIATED_AUTHENTICATION, "initiateAuthentication initiated...");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setCtxParams1(InitialAuthenticationKeys initialAuthenticationKeys) {
|
||||||
|
|
||||||
|
initialAuthenticationKeys.setCtxParams1(LpaUtils.generateCtxParams1());
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - ctxParams1: " + initialAuthenticationKeys.getCtxParams1());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setMatchingId(InitialAuthenticationKeys initialAuthenticationKeys) {
|
||||||
|
|
||||||
|
initialAuthenticationKeys.setMatchingId(Util.ASCIIToHex(initialAuthenticationKeys.getMatchingId()));
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - matchingId: " + initialAuthenticationKeys.getMatchingId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setTransactionId(InitialAuthenticationKeys initialAuthenticationKeys, InitiateAuthenticationResp initiateAuthenticationResp) {
|
||||||
|
|
||||||
|
initialAuthenticationKeys.setTransactionId(initiateAuthenticationResp.getTransactionId());
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - transactionId: " + initialAuthenticationKeys.getTransactionId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setServerCertificate(InitialAuthenticationKeys initialAuthenticationKeys, InitiateAuthenticationResp initiateAuthenticationResp) {
|
||||||
|
|
||||||
|
initialAuthenticationKeys.setServerCertificate(initiateAuthenticationResp.getServerCertificate());
|
||||||
|
initialAuthenticationKeys.setServerCertificate(Util.byteArrayToHexString(Base64.decodeBase64(initialAuthenticationKeys.getServerCertificate()), ""));
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - serverCertificate: " + initialAuthenticationKeys.getServerCertificate());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setEuiccCiPKIdToveUsed(InitialAuthenticationKeys initialAuthenticationKeys, InitiateAuthenticationResp initiateAuthenticationResp) {
|
||||||
|
|
||||||
|
initialAuthenticationKeys.setEuiccCiPKIdTobeUsed(initiateAuthenticationResp.getEuiccCiPKIdToBeUsed());
|
||||||
|
initialAuthenticationKeys.setEuiccCiPKIdTobeUsed(Util.byteArrayToHexString(Base64.decodeBase64(initialAuthenticationKeys.getEuiccCiPKIdTobeUsed()), ""));
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - euiccCiPKIdTobeUsed: " + initialAuthenticationKeys.getEuiccCiPKIdTobeUsed());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setServerSignature1(InitialAuthenticationKeys initialAuthenticationKeys, InitiateAuthenticationResp initiateAuthenticationResp) {
|
||||||
|
|
||||||
|
initialAuthenticationKeys.setServerSignature1(initiateAuthenticationResp.getServerSignature1());
|
||||||
|
initialAuthenticationKeys.setServerSignature1(Util.byteArrayToHexString(Base64.decodeBase64(initialAuthenticationKeys.getServerSignature1()), ""));
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - serverSignature1: " + initialAuthenticationKeys.getServerSignature1());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setServerSigned1(InitialAuthenticationKeys initialAuthenticationKeys, InitiateAuthenticationResp initiateAuthenticationResp) {
|
||||||
|
|
||||||
|
initialAuthenticationKeys.setServerSigned1(initiateAuthenticationResp.getServerSigned1());
|
||||||
|
initialAuthenticationKeys.setServerSigned1(Util.byteArrayToHexString(Base64.decodeBase64(initialAuthenticationKeys.getServerSigned1()), ""));
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - serverSigned1: " + initialAuthenticationKeys.getServerSigned1());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private InitiateAuthenticationResp getInitiateAuthenticationResp(InitialAuthenticationKeys initialAuthenticationKeys) {
|
||||||
|
InitiateAuthenticationResp initiateAuthenticationResp = es9Module.initiateAuthentication(initialAuthenticationKeys.getEuiccChallenge(),
|
||||||
|
initialAuthenticationKeys.getEuiccInfo1(), initialAuthenticationKeys.getEuiccConfiguredAddress());
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - Initiating Auth with SM-DP+ - Response: " + initiateAuthenticationResp);
|
||||||
|
}
|
||||||
|
|
||||||
|
return initiateAuthenticationResp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AuthenticateClientSmDp authenticateClient(InitialAuthenticationKeys initialAuthenticationKeys, String encodedAuthenticateServerResponse) {
|
||||||
|
|
||||||
|
progress.stepExecuted(DOWNLOAD_PROFILE_AUTHENTICATE_CLIENT, "authenticateClient retrieving...");
|
||||||
|
|
||||||
|
AuthenticateClientResp authenticateClientResp = getAuthenticateClientResponse(initialAuthenticationKeys, encodedAuthenticateServerResponse);
|
||||||
|
AuthenticateClientSmDp authenticateClientSmDp = convertAuthenticateClientResp(authenticateClientResp);
|
||||||
|
|
||||||
|
progress.stepExecuted(DOWNLOAD_PROFILE_AUTHENTICATED_CLIENT, "authenticateClient authenticated...");
|
||||||
|
|
||||||
|
return authenticateClientSmDp;
|
||||||
|
}
|
||||||
|
|
||||||
|
private AuthenticateClientSmDp convertAuthenticateClientResp(AuthenticateClientResp authenticateClientResp) {
|
||||||
|
AuthenticateClientSmDp authenticateClientSmDp = new AuthenticateClientSmDp();
|
||||||
|
|
||||||
|
authenticateClientSmDp.setSmdpSigned2(Util.byteArrayToHexString(Base64.decodeBase64(authenticateClientResp.getSmdpSigned2()), ""));
|
||||||
|
authenticateClientSmDp.setSmdpSignature2(Util.byteArrayToHexString(Base64.decodeBase64(authenticateClientResp.getSmdpSignature2()), ""));
|
||||||
|
authenticateClientSmDp.setSmdpCertificate(Util.byteArrayToHexString(Base64.decodeBase64(authenticateClientResp.getSmdpCertificate()), ""));
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - authenticateClient returning: " + authenticateClientSmDp);
|
||||||
|
}
|
||||||
|
|
||||||
|
return authenticateClientSmDp;
|
||||||
|
}
|
||||||
|
|
||||||
|
private AuthenticateClientResp getAuthenticateClientResponse(InitialAuthenticationKeys initialAuthenticationKeys, String encodedAuthenticateServerResponse) {
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - Authenticate client with SM-DP+ with initialAuthenticationKeys: " +
|
||||||
|
initialAuthenticationKeys +
|
||||||
|
" encodedAuthenticateServerResponse: " +
|
||||||
|
encodedAuthenticateServerResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
AuthenticateClientResp authenticateClientResp = es9Module.authenticateClient(initialAuthenticationKeys.getTransactionId(), encodedAuthenticateServerResponse, initialAuthenticationKeys.getEuiccConfiguredAddress());
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - Authenticate client with SM-DP+ - Response : " + authenticateClientResp);
|
||||||
|
}
|
||||||
|
|
||||||
|
return authenticateClientResp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String authenticateWithEuicc(InitialAuthenticationKeys initialAuthenticationKeys) {
|
||||||
|
|
||||||
|
progress.stepExecuted(DOWNLOAD_PROFILE_AUTHENTICATE_WITH_EUICC, "authenticateWithEuicc retrieving...");
|
||||||
|
|
||||||
|
String authenticateServerResponse = apduTransmitter.transmitApdus(ApduUtils.authenticateServerApdu(initialAuthenticationKeys.getServerSigned1(),
|
||||||
|
initialAuthenticationKeys.getServerSignature1(),
|
||||||
|
initialAuthenticationKeys.getEuiccCiPKIdTobeUsed(), initialAuthenticationKeys.getServerCertificate(),
|
||||||
|
initialAuthenticationKeys.getMatchingId()));
|
||||||
|
String encodedAuthenticateServerResponse = Base64.encodeBase64String(Util.hexStringToByteArray(authenticateServerResponse));
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - Authenticate server response (base64): " + encodedAuthenticateServerResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
progress.stepExecuted(DOWNLOAD_PROFILE_AUTHENTICATED_WITH_EUICC, "authenticateWithEuicc authenticated...");
|
||||||
|
|
||||||
|
return encodedAuthenticateServerResponse;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package com.truphone.lpa.impl.download;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
public class CloseResources {
|
||||||
|
|
||||||
|
static void closeResources(InputStream is) {
|
||||||
|
|
||||||
|
if (is != null) {
|
||||||
|
try {
|
||||||
|
is.close();
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,94 @@
|
||||||
|
package com.truphone.lpa.impl.download;
|
||||||
|
|
||||||
|
|
||||||
|
import com.truphone.lpa.apdu.ApduUtils;
|
||||||
|
import com.truphone.lpa.progress.DownloadProgress;
|
||||||
|
import com.truphone.lpa.progress.DownloadProgressPhase;
|
||||||
|
import com.truphone.lpad.progress.ProgressStep;
|
||||||
|
import com.truphone.rsp.dto.asn1.rspdefinitions.EuiccConfiguredAddressesResponse;
|
||||||
|
import com.truphone.util.LogStub;
|
||||||
|
import org.apache.commons.codec.DecoderException;
|
||||||
|
import org.apache.commons.codec.binary.Hex;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
public class ConnectingPhaseWorker {
|
||||||
|
private static final Logger LOG = Logger.getLogger(ConnectingPhaseWorker.class.getName());
|
||||||
|
|
||||||
|
private DownloadProgress progress;
|
||||||
|
private ApduTransmitter apduTransmitter;
|
||||||
|
|
||||||
|
public ConnectingPhaseWorker(DownloadProgress progress, ApduTransmitter apduTransmitter) {
|
||||||
|
|
||||||
|
this.progress = progress;
|
||||||
|
this.apduTransmitter = apduTransmitter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEuiccConfiguredAddress(String matchingId) {
|
||||||
|
|
||||||
|
progress.setCurrentPhase(DownloadProgressPhase.CONNECTING);
|
||||||
|
progress.stepExecuted(ProgressStep.DOWNLOAD_PROFILE_RETRIEVING_EUICC_ADDRESS, "getEuiccConfiguredAddress - retrieving...");
|
||||||
|
|
||||||
|
return convertEuiccConfiguredAddress(apduTransmitter.transmitApdu(ApduUtils.getEuiccConfiguredAddressesApdu()), matchingId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String convertEuiccConfiguredAddress(String euiCCConfiguredAddressAPDUResponse, String matchingId) {
|
||||||
|
|
||||||
|
progress.stepExecuted(ProgressStep.DOWNLOAD_PROFILE_CONVERTING_EUICC_CONFIGURED_ADDRESS, "getEuiccConfiguredAddresses Success!");
|
||||||
|
|
||||||
|
String euiccConfiguredAddresses = getEuiccConfiguredAddress(euiCCConfiguredAddressAPDUResponse, matchingId);
|
||||||
|
|
||||||
|
progress.stepExecuted(ProgressStep.DOWNLOAD_PROFILE_CONVERTED_EUICC_ADDRESS, "Converted EUICC Address Success!");
|
||||||
|
|
||||||
|
return euiccConfiguredAddresses;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getEuiccConfiguredAddress(String euiCCConfiguredAddressAPDUResponse, String matchingId) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
EuiccConfiguredAddressesResponse euiccConfiguredAddressesResponse = decodeEuiccConfiguredAddressesResponse(euiCCConfiguredAddressAPDUResponse);
|
||||||
|
|
||||||
|
String euiccConfiguredAddress = euiccConfiguredAddressesResponse.getDefaultDpAddress().toString();
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - SM-DP+ configured address: " + euiccConfiguredAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
return euiccConfiguredAddress;
|
||||||
|
} catch (DecoderException e) {
|
||||||
|
LOG.log(Level.SEVERE, "KOL.007" + e.getMessage(), e);
|
||||||
|
LOG.severe(LogStub.getInstance().getTag() + " - matchingId: " + matchingId +
|
||||||
|
" Unable to retrieve eUICC configured address. Exception in Decoder:" + e.getMessage());
|
||||||
|
|
||||||
|
throw new RuntimeException("Unable to retrieve eUICC configured address: " + matchingId);
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
LOG.log(Level.SEVERE, "KOL.007" + ioe.getMessage(), ioe);
|
||||||
|
LOG.severe(LogStub.getInstance().getTag() + " - matchingId: " + matchingId +
|
||||||
|
" Unable to retrieve eUICC configured address. IOException:" + ioe.getMessage());
|
||||||
|
|
||||||
|
throw new RuntimeException("Unable to retrieve eUICC configured address");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private EuiccConfiguredAddressesResponse decodeEuiccConfiguredAddressesResponse(String euiCCConfiguredAddressAPDUResponse) throws DecoderException, IOException {
|
||||||
|
InputStream is = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
EuiccConfiguredAddressesResponse euiccConfiguredAddressesResponse = new EuiccConfiguredAddressesResponse();
|
||||||
|
is = new ByteArrayInputStream(Hex.decodeHex(euiCCConfiguredAddressAPDUResponse.toCharArray()));
|
||||||
|
|
||||||
|
euiccConfiguredAddressesResponse.decode(is);
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - decoded euiccConfiguredAddressesResponse: " + euiccConfiguredAddressesResponse.toString());
|
||||||
|
}
|
||||||
|
return euiccConfiguredAddressesResponse;
|
||||||
|
} finally {
|
||||||
|
CloseResources.closeResources(is);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,85 @@
|
||||||
|
package com.truphone.lpa.impl.download;
|
||||||
|
|
||||||
|
|
||||||
|
import com.truphone.lpa.impl.InitialAuthenticationKeys;
|
||||||
|
import org.apache.commons.codec.binary.Base64;
|
||||||
|
import com.truphone.es9plus.Es9PlusImpl;
|
||||||
|
import com.truphone.es9plus.message.response.GetBoundProfilePackageResp;
|
||||||
|
import com.truphone.lpa.apdu.ApduUtils;
|
||||||
|
import com.truphone.lpa.impl.AuthenticateClientSmDp;
|
||||||
|
import com.truphone.lpa.progress.DownloadProgress;
|
||||||
|
import com.truphone.lpa.progress.DownloadProgressPhase;
|
||||||
|
import com.truphone.lpad.progress.ProgressStep;
|
||||||
|
import com.truphone.util.LogStub;
|
||||||
|
import com.truphone.util.Util;
|
||||||
|
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
public class DownloadPhaseWorker {
|
||||||
|
private static final Logger LOG = Logger.getLogger(DownloadPhaseWorker.class.getName());
|
||||||
|
|
||||||
|
private final DownloadProgress progress;
|
||||||
|
private final ApduTransmitter apduTransmitter;
|
||||||
|
private final Es9PlusImpl es9Module;
|
||||||
|
|
||||||
|
public DownloadPhaseWorker(DownloadProgress progress, ApduTransmitter apduTransmitter, Es9PlusImpl es9Module) {
|
||||||
|
|
||||||
|
this.progress = progress;
|
||||||
|
this.apduTransmitter = apduTransmitter;
|
||||||
|
this.es9Module = es9Module;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String prepareDownload(AuthenticateClientSmDp authenticateClientSmDp) {
|
||||||
|
|
||||||
|
progress.setCurrentPhase(DownloadProgressPhase.DOWNLOADING);
|
||||||
|
progress.stepExecuted(ProgressStep.DOWNLOAD_PROFILE_PREPARE_DOWNLOAD, "prepareDownload retrieving...");
|
||||||
|
|
||||||
|
String prepareDownloadResponse = apduTransmitter.transmitApdus(ApduUtils.prepareDownloadApdu(authenticateClientSmDp.getSmdpSigned2(),
|
||||||
|
authenticateClientSmDp.getSmdpSignature2(), authenticateClientSmDp.getSmdpCertificate(),
|
||||||
|
null));
|
||||||
|
String encodedPrepareDownloadResponse = Base64.encodeBase64String(Util.hexStringToByteArray(prepareDownloadResponse));
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - Prepare download response (base64): " + encodedPrepareDownloadResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
progress.stepExecuted(ProgressStep.DOWNLOAD_PROFILE_PREPARED_DOWNLOAD, "prepareDownload retrieved...");
|
||||||
|
|
||||||
|
return encodedPrepareDownloadResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBoundProfilePackage(InitialAuthenticationKeys initialAuthenticationKeys, String encodedPrepareDownloadResponse) {
|
||||||
|
|
||||||
|
progress.stepExecuted(ProgressStep.DOWNLOAD_PROFILE_GET_BOUND_PROFILE_PACKAGE,
|
||||||
|
"downloadAndInstallProfilePackage retrieving...");
|
||||||
|
|
||||||
|
GetBoundProfilePackageResp getBoundProfilePackageResp = getGetBoundProfilePackageResp(initialAuthenticationKeys, encodedPrepareDownloadResponse, initialAuthenticationKeys.getEuiccConfiguredAddress());
|
||||||
|
String bpp = Util.byteArrayToHexString(Base64.decodeBase64(getBoundProfilePackageResp.getBoundProfilePackage()), "");
|
||||||
|
|
||||||
|
progress.stepExecuted(ProgressStep.DOWNLOAD_PROFILE_BOUND_PROFILE_PACKAGE_RETRIEVED,
|
||||||
|
"downloadAndInstallProfilePackage retrieved...");
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - getBoundProfilePackage - BPP is: " + bpp);
|
||||||
|
}
|
||||||
|
|
||||||
|
return bpp;
|
||||||
|
}
|
||||||
|
|
||||||
|
private GetBoundProfilePackageResp getGetBoundProfilePackageResp(InitialAuthenticationKeys initialAuthenticationKeys, String encodedPrepareDownloadResponse, String smdpAddress) {
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - Getting bound profile package from SM-DP+");
|
||||||
|
}
|
||||||
|
|
||||||
|
GetBoundProfilePackageResp getBoundProfilePackageResp = es9Module.getBoundProfilePackage(initialAuthenticationKeys.getTransactionId(),
|
||||||
|
encodedPrepareDownloadResponse,smdpAddress);
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - Getting bound profile package from SM-DP+ - Response - " +
|
||||||
|
encodedPrepareDownloadResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
return getBoundProfilePackageResp;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,115 @@
|
||||||
|
package com.truphone.lpa.impl.download;
|
||||||
|
|
||||||
|
|
||||||
|
import com.truphone.lpa.apdu.ApduUtils;
|
||||||
|
import com.truphone.lpa.apdu.ProfileUtil;
|
||||||
|
import com.truphone.lpa.progress.DownloadProgress;
|
||||||
|
import com.truphone.lpa.progress.DownloadProgressPhase;
|
||||||
|
import com.truphone.lpad.progress.ProgressStep;
|
||||||
|
import com.truphone.rsp.dto.asn1.rspdefinitions.BoundProfilePackage;
|
||||||
|
import com.truphone.util.LogStub;
|
||||||
|
import org.apache.commons.codec.DecoderException;
|
||||||
|
import org.apache.commons.codec.binary.Hex;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
public class GeneratePhaseWorker {
|
||||||
|
private static final Logger LOG = Logger.getLogger(GeneratePhaseWorker.class.getName());
|
||||||
|
|
||||||
|
private final DownloadProgress progress;
|
||||||
|
|
||||||
|
public GeneratePhaseWorker(DownloadProgress progress) {
|
||||||
|
|
||||||
|
this.progress = progress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<SbppApdu, List<String>> generateSbpp(String bpp) throws IOException {
|
||||||
|
|
||||||
|
progress.setCurrentPhase(DownloadProgressPhase.GENERATING);
|
||||||
|
List<String[]> sbpp = generateSbpps(bpp);
|
||||||
|
|
||||||
|
return generateSbppMap(sbpp);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<SbppApdu, List<String>> generateSbppMap(List<String[]> sbpp) {
|
||||||
|
Map<SbppApdu, List<String>> sbppApduMap = new HashMap<>();
|
||||||
|
|
||||||
|
progress.stepExecuted(ProgressStep.DOWNLOAD_PROFILE_GENERATING_SBPP_APDUS,
|
||||||
|
"generateSbpp generating...");
|
||||||
|
|
||||||
|
sbppApduMap.put(SbppApdu.BOUND_PROFILE_PACKAGE, ApduUtils.loadBoundProfilePackageApdu(sbpp));
|
||||||
|
if(sbpp.size()==5){
|
||||||
|
//secondSequenceOf87
|
||||||
|
sbppApduMap.put(SbppApdu.REPLACE_SESSIONS_KEYS, ApduUtils.loadProfileProtectionKeys(sbpp));
|
||||||
|
}
|
||||||
|
sbppApduMap.put(SbppApdu.STORE_METADATA, ApduUtils.loadStoreMetadataApdu(sbpp));
|
||||||
|
sbppApduMap.put(SbppApdu.CONFIGURE_ISDPA, ApduUtils.loadConfigureISDPApdu(sbpp));
|
||||||
|
sbppApduMap.put(SbppApdu.INITIALIZE_SECURE_CHANNEL, ApduUtils.loadInitialiseSecureChannelApdu(sbpp));
|
||||||
|
|
||||||
|
progress.stepExecuted(ProgressStep.DOWNLOAD_PROFILE_GENERATED_SBPP_APDUS,
|
||||||
|
"generateSbpp generated...");
|
||||||
|
|
||||||
|
return sbppApduMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String[]> generateSbpps(String bpp) throws IOException {
|
||||||
|
|
||||||
|
progress.stepExecuted(ProgressStep.DOWNLOAD_PROFILE_GENERATING_SBPP,
|
||||||
|
"generateSbpp generating...");
|
||||||
|
|
||||||
|
ProfileUtil util = new ProfileUtil();
|
||||||
|
|
||||||
|
logPrintBpp(bpp);
|
||||||
|
|
||||||
|
// TODO: This should be refactored to use the jASN1 objects
|
||||||
|
List<String[]> sbpp = util.generateSBPP(bpp);
|
||||||
|
|
||||||
|
logPrintSbpp(sbpp);
|
||||||
|
|
||||||
|
progress.stepExecuted(ProgressStep.DOWNLOAD_PROFILE_GENERATED_SBPP,
|
||||||
|
"generateSbpp generated...");
|
||||||
|
|
||||||
|
return sbpp;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void logPrintSbpp(List<String[]> sbpp) {
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - SBPP count: " + sbpp.size());
|
||||||
|
|
||||||
|
for (String[] s : sbpp) {
|
||||||
|
for (String s1 : s) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - generateSbpp - SBPP is: " + s1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void logPrintBpp(String bpp) throws IOException {
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
InputStream bppIs = null;
|
||||||
|
BoundProfilePackage bppObj = new BoundProfilePackage();
|
||||||
|
|
||||||
|
try {
|
||||||
|
bppIs = new ByteArrayInputStream(Hex.decodeHex(bpp.toCharArray()));
|
||||||
|
|
||||||
|
bppObj.decode(bppIs);
|
||||||
|
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - BPP Object is: " + bppObj);
|
||||||
|
} catch (DecoderException e) {
|
||||||
|
LOG.log(Level.INFO, LogStub.getInstance().getTag() + " - " + e.getMessage(), e);
|
||||||
|
} finally {
|
||||||
|
CloseResources.closeResources(bppIs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,249 @@
|
||||||
|
package com.truphone.lpa.impl.download;
|
||||||
|
|
||||||
|
import com.truphone.lpa.ApduTransmittedListener;
|
||||||
|
import com.truphone.lpa.progress.DownloadProgress;
|
||||||
|
import com.truphone.lpa.progress.DownloadProgressPhase;
|
||||||
|
import com.truphone.lpad.progress.ProgressStep;
|
||||||
|
import com.truphone.rsp.dto.asn1.rspdefinitions.ProfileInstallationResult;
|
||||||
|
import com.truphone.rsp.dto.asn1.rspdefinitions.ProfileInstallationResultData;
|
||||||
|
import com.truphone.util.LogStub;
|
||||||
|
import org.apache.commons.codec.DecoderException;
|
||||||
|
import org.apache.commons.codec.binary.Hex;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
public class InstallationPhaseWorker {
|
||||||
|
|
||||||
|
private static final Logger LOG = Logger.getLogger(InstallationPhaseWorker.class
|
||||||
|
.getName());
|
||||||
|
|
||||||
|
private final DownloadProgress progress;
|
||||||
|
private final ApduTransmitter apduTransmitter;
|
||||||
|
|
||||||
|
public InstallationPhaseWorker(DownloadProgress progress, ApduTransmitter apduTransmitter) {
|
||||||
|
|
||||||
|
this.progress = progress;
|
||||||
|
this.apduTransmitter = apduTransmitter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void loadingSbppApdu(Map<SbppApdu, List<String>> sbpp) {
|
||||||
|
ApduTransmittedListener apduTransmittedListener;
|
||||||
|
|
||||||
|
progress.setCurrentPhase(DownloadProgressPhase.INSTALLING, getTotalApdus(sbpp)
|
||||||
|
+ DownloadProgressPhase.INSTALLING.getProgressSteps().size());
|
||||||
|
progress.stepExecuted(ProgressStep.DOWNLOAD_PROFILE_LOADING_SBPP,
|
||||||
|
"generateSbpp generating...");
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - Sending SBPP to eUICC");
|
||||||
|
}
|
||||||
|
|
||||||
|
apduTransmittedListener = addApduTransmittedListener();
|
||||||
|
|
||||||
|
loadInitialiseSecureChannel(sbpp.get(SbppApdu.INITIALIZE_SECURE_CHANNEL));
|
||||||
|
loadConfigureIsdpa(sbpp.get(SbppApdu.CONFIGURE_ISDPA));
|
||||||
|
loadStoreMetadata(sbpp.get(SbppApdu.STORE_METADATA));
|
||||||
|
|
||||||
|
if (sbpp.size() == 5) {
|
||||||
|
loadReplaceSessionKeys(sbpp.get(SbppApdu.REPLACE_SESSIONS_KEYS));
|
||||||
|
}
|
||||||
|
|
||||||
|
loadBoundProfilePackage(sbpp.get(SbppApdu.BOUND_PROFILE_PACKAGE));
|
||||||
|
removeApduTransmittedListener(apduTransmittedListener);
|
||||||
|
|
||||||
|
progress.stepExecuted(ProgressStep.DOWNLOAD_PROFILE_INSTALLED,
|
||||||
|
"INSTALLED!");
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getTotalApdus(Map<SbppApdu, List<String>> sbpp) {
|
||||||
|
int totalApdus = 0;
|
||||||
|
|
||||||
|
for (List<String> apdus : sbpp.values()) {
|
||||||
|
totalApdus += apdus.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
return totalApdus;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ApduTransmittedListener addApduTransmittedListener() {
|
||||||
|
ApduTransmittedListener apduTransmittedListener = new ApduTransmittedListener() {
|
||||||
|
@Override
|
||||||
|
public void onApduTransmitted() {
|
||||||
|
|
||||||
|
progress.stepExecuted(ProgressStep.DOWNLOAD_PROFILE_APDU_TRANSMITTED, "Apdu transmitted");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
apduTransmitter.addApduTransmittedListener(apduTransmittedListener);
|
||||||
|
|
||||||
|
return apduTransmittedListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeApduTransmittedListener(ApduTransmittedListener apduTransmittedListener) {
|
||||||
|
|
||||||
|
apduTransmitter.removeApduTransmittedListener(apduTransmittedListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadBoundProfilePackage(List<String> sbpp) {
|
||||||
|
|
||||||
|
progress.stepExecuted(ProgressStep.DOWNLOAD_PROFILE_BOUND_PROFILE_PACKAGE,
|
||||||
|
"loadBoundProfilePackage...");
|
||||||
|
|
||||||
|
String profileInstallationResult = apduTransmitter.transmitApdus(sbpp);
|
||||||
|
|
||||||
|
if (StringUtils.isNotBlank(profileInstallationResult) && profileInstallationResult.length() > 4) {
|
||||||
|
checkProfileInstallationResult(profileInstallationResult);
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException("Unexpected response on loadBoundProfilePackage");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadStoreMetadata(List<String> sbpp) {
|
||||||
|
|
||||||
|
progress.stepExecuted(ProgressStep.DOWNLOAD_PROFILE_STORE_METADATA,
|
||||||
|
"loadStoreMetadata...");
|
||||||
|
|
||||||
|
String profileInstallationResult = apduTransmitter.transmitApdus(sbpp);
|
||||||
|
|
||||||
|
if (profileInstallationResult.compareTo("9000") != 0) {
|
||||||
|
if (StringUtils.isNotBlank(profileInstallationResult) && profileInstallationResult.length() > 4) {
|
||||||
|
checkProfileInstallationResult(profileInstallationResult);
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException("Unexpected response on loadStoreMetadata");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadConfigureIsdpa(List<String> sbpp) {
|
||||||
|
|
||||||
|
progress.stepExecuted(ProgressStep.DOWNLOAD_PROFILE_CONFIGURE_ISDPA,
|
||||||
|
"loadConfigureIsdpa...");
|
||||||
|
|
||||||
|
String profileInstallationResult = apduTransmitter.transmitApdus(sbpp);
|
||||||
|
|
||||||
|
if (profileInstallationResult.compareTo("9000") != 0) {
|
||||||
|
if (StringUtils.isNotBlank(profileInstallationResult) && profileInstallationResult.length() > 4) {
|
||||||
|
checkProfileInstallationResult(profileInstallationResult);
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException("Unexpected response on loadConfigureIsdpa");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadInitialiseSecureChannel(List<String> sbpp) {
|
||||||
|
|
||||||
|
progress.stepExecuted(ProgressStep.DOWNLOAD_PROFILE_INITIALIZE_SECURE_CHANNEL,
|
||||||
|
"loadInitialiseSecureChannel...");
|
||||||
|
|
||||||
|
String profileInstallationResult = apduTransmitter.transmitApdus(sbpp);
|
||||||
|
|
||||||
|
if (profileInstallationResult.compareTo("9000") != 0) {
|
||||||
|
if (StringUtils.isNotBlank(profileInstallationResult) && profileInstallationResult.length() > 4) {
|
||||||
|
checkProfileInstallationResult(profileInstallationResult);
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException("Unexpected response on loadInitialiseSecureChannel");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkProfileInstallationResult(String profileInstallationResultRaw) {
|
||||||
|
boolean success = false;
|
||||||
|
String errorMessage = "";
|
||||||
|
|
||||||
|
try {
|
||||||
|
ProfileInstallationResult profileInstallationResult = getProfileInstallationResult(profileInstallationResultRaw);
|
||||||
|
|
||||||
|
if (profileInstallationResult.getProfileInstallationResultData() != null
|
||||||
|
&& profileInstallationResult.getProfileInstallationResultData().getFinalResult() != null) {
|
||||||
|
|
||||||
|
ProfileInstallationResultData.FinalResult finalResult = profileInstallationResult.getProfileInstallationResultData().getFinalResult();
|
||||||
|
|
||||||
|
if (finalResult.getSuccessResult() != null) {
|
||||||
|
LOG.info(LogStub.getInstance().getTag() + " - Decoded Success Result: " + finalResult.getSuccessResult().toString());
|
||||||
|
|
||||||
|
success = true;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
errorMessage = invalidFinalResult(finalResult);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
errorMessage = invalidProfileInstallationData();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
throw new RuntimeException(errorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (DecoderException e) {
|
||||||
|
LOG.log(Level.SEVERE, LogStub.getInstance().getTag() + " - " + e.getMessage(), e);
|
||||||
|
LOG.severe(LogStub.getInstance().getTag() + " - Unable to retrieve Profile Installation Result. Exception in Decoder:" + e.getMessage());
|
||||||
|
|
||||||
|
throw new RuntimeException("Unable to retrieve Profile Installation Result.");
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
LOG.log(Level.SEVERE, LogStub.getInstance().getTag() + " - " + ioe.getMessage(), ioe);
|
||||||
|
LOG.severe(LogStub.getInstance().getTag() + " - Unable to retrieve Profile Installation Result. IOException:" + ioe.getMessage());
|
||||||
|
|
||||||
|
throw new RuntimeException("Unable to retrieve Profile Installation Result.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String invalidFinalResult(ProfileInstallationResultData.FinalResult finalResult) {
|
||||||
|
String errorMessage = finalResult.getErrorResult().getErrorReason().toString() + ":"
|
||||||
|
+ finalResult.getErrorResult().getBppCommandId().toString() + ":"
|
||||||
|
+ finalResult.getErrorResult().getSimaResponse().toString();
|
||||||
|
|
||||||
|
LOG.info(LogStub.getInstance().getTag() + " - Decoded ERROR Result: " + finalResult.getErrorResult().toString());
|
||||||
|
|
||||||
|
return errorMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String invalidProfileInstallationData() {
|
||||||
|
String errorMessage = "Could not parse Profile Installation Result";
|
||||||
|
|
||||||
|
LOG.info(LogStub.getInstance().getTag() + " - Profile Installation Result Data or Final result is null.");
|
||||||
|
|
||||||
|
return errorMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ProfileInstallationResult getProfileInstallationResult(String profileInstallationResultRaw) throws DecoderException, IOException {
|
||||||
|
InputStream is = null;
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - Check Profile Installation Result input: " + profileInstallationResultRaw);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
ProfileInstallationResult profileInstallationResult = new ProfileInstallationResult();
|
||||||
|
|
||||||
|
is = new ByteArrayInputStream(Hex.decodeHex(profileInstallationResultRaw.toCharArray()));
|
||||||
|
|
||||||
|
profileInstallationResult.decode(is, true);
|
||||||
|
|
||||||
|
return profileInstallationResult;
|
||||||
|
} finally {
|
||||||
|
CloseResources.closeResources(is);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadReplaceSessionKeys(List<String> sbpp) {
|
||||||
|
progress.stepExecuted(ProgressStep.DOWNLOAD_PROFILE_REPLACE_SESSIONS_KEYS,
|
||||||
|
"loadReplaceSessionsKeys...");
|
||||||
|
|
||||||
|
String profileInstallationResult = apduTransmitter.transmitApdus(sbpp);
|
||||||
|
|
||||||
|
if (profileInstallationResult.compareTo("9000") != 0) {
|
||||||
|
if (StringUtils.isNotBlank(profileInstallationResult) && profileInstallationResult.length() > 4) {
|
||||||
|
checkProfileInstallationResult(profileInstallationResult);
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException("Unexpected response on loadReplaceSessionsKeys");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
package com.truphone.lpa.impl.download;
|
||||||
|
|
||||||
|
public enum SbppApdu {
|
||||||
|
INITIALIZE_SECURE_CHANNEL,
|
||||||
|
CONFIGURE_ISDPA,
|
||||||
|
STORE_METADATA,
|
||||||
|
REPLACE_SESSIONS_KEYS,
|
||||||
|
BOUND_PROFILE_PACKAGE
|
||||||
|
}
|
|
@ -0,0 +1,132 @@
|
||||||
|
package com.truphone.lpa.progress;
|
||||||
|
|
||||||
|
import com.truphone.lpad.progress.ProgressListener;
|
||||||
|
import com.truphone.lpad.progress.ProgressStep;
|
||||||
|
import com.truphone.util.LogStub;
|
||||||
|
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
public class DownloadProgress {
|
||||||
|
private static final Logger LOG = Logger.getLogger(DownloadProgress.class.getName());
|
||||||
|
|
||||||
|
private final Executor executor;
|
||||||
|
|
||||||
|
private ProgressListener progressListener;
|
||||||
|
private DownloadProgressPhase downloadProgressPhase;
|
||||||
|
private int totalPhaseSteps;
|
||||||
|
private int currentPhaseStepSum;
|
||||||
|
|
||||||
|
public DownloadProgress() {
|
||||||
|
|
||||||
|
executor = Executors.newSingleThreadExecutor();
|
||||||
|
downloadProgressPhase = DownloadProgressPhase.AUTHENTICATING;
|
||||||
|
totalPhaseSteps = DownloadProgressPhase.AUTHENTICATING.getProgressSteps().size();
|
||||||
|
currentPhaseStepSum = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stepExecuted(final ProgressStep step,
|
||||||
|
final String message) {
|
||||||
|
|
||||||
|
if (progressListener != null) {
|
||||||
|
++currentPhaseStepSum;
|
||||||
|
|
||||||
|
final DownloadProgressPhase downloadProgressPhaseAux = downloadProgressPhase;
|
||||||
|
final int totalPhaseStepsAux = totalPhaseSteps;
|
||||||
|
final int currentPhaseStepSumAux = currentPhaseStepSum;
|
||||||
|
|
||||||
|
executor.execute(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
double percentage;
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() +
|
||||||
|
" - DownloadProgress - stepExecuted - step: " + step + "; currentPhaseStepSum: " + currentPhaseStepSumAux +
|
||||||
|
"; message: " + message + "; currentProgressPhase: " + downloadProgressPhaseAux +
|
||||||
|
"; totalPhaseSteps: " + totalPhaseStepsAux);
|
||||||
|
}
|
||||||
|
|
||||||
|
percentage = calculatePercentage(downloadProgressPhaseAux, currentPhaseStepSumAux, totalPhaseStepsAux);
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() +
|
||||||
|
" - DownloadProgress - stepExecuted - onAction - step: " + step.name() +
|
||||||
|
"; message: " + message + "; percentage: " + percentage +
|
||||||
|
"; downloadProgressPhase: " + downloadProgressPhaseAux.name());
|
||||||
|
}
|
||||||
|
|
||||||
|
progressListener.onAction(downloadProgressPhaseAux.name(), step.name(), percentage, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
private double calculatePercentage(final DownloadProgressPhase downloadProgressPhaseAux,
|
||||||
|
final int currentPhaseStepSumAux,
|
||||||
|
final int totalPhaseStepsAux) {
|
||||||
|
double percentage;
|
||||||
|
|
||||||
|
if (currentPhaseStepSumAux == totalPhaseStepsAux) {
|
||||||
|
percentage = 1.0;
|
||||||
|
} else {
|
||||||
|
percentage = (double) currentPhaseStepSumAux / totalPhaseStepsAux;
|
||||||
|
|
||||||
|
if (percentage > 1.0) {
|
||||||
|
percentage = 1.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() +
|
||||||
|
" - DownloadProgress - calculatePercentage - percentage_1: " + percentage);
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() +
|
||||||
|
" - DownloadProgress - calculatePercentage - percentage_f: " +
|
||||||
|
(percentage * downloadProgressPhaseAux.getPhaseTotalPercentage() / 1.0 + getTotalPreviousPhases(downloadProgressPhaseAux)));
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() +
|
||||||
|
" - DownloadProgress - calculatePercentage - previous: " + getTotalPreviousPhases(downloadProgressPhaseAux));
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() +
|
||||||
|
" - DownloadProgress - calculatePercentage - current: " + (percentage * downloadProgressPhaseAux.getPhaseTotalPercentage()));
|
||||||
|
}
|
||||||
|
|
||||||
|
percentage = percentage * downloadProgressPhaseAux.getPhaseTotalPercentage() / 1.0 + getTotalPreviousPhases(downloadProgressPhaseAux);
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() +
|
||||||
|
" - DownloadProgress - calculatePercentage - final: " + percentage);
|
||||||
|
}
|
||||||
|
|
||||||
|
return percentage > 1.0 ? 1.0 : percentage;
|
||||||
|
}
|
||||||
|
|
||||||
|
private double getTotalPreviousPhases(DownloadProgressPhase downloadProgressPhase) {
|
||||||
|
int currentPhaseNumber = downloadProgressPhase.ordinal();
|
||||||
|
double total = 0.0;
|
||||||
|
|
||||||
|
for (int i = 0; i < currentPhaseNumber; i++) {
|
||||||
|
total += DownloadProgressPhase.values()[i].getPhaseTotalPercentage();
|
||||||
|
}
|
||||||
|
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProgressListener(ProgressListener progressListener) {
|
||||||
|
|
||||||
|
this.progressListener = progressListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCurrentPhase(DownloadProgressPhase downloadProgressPhase,
|
||||||
|
int totalPhaseSteps) {
|
||||||
|
|
||||||
|
this.downloadProgressPhase = downloadProgressPhase;
|
||||||
|
this.totalPhaseSteps = totalPhaseSteps;
|
||||||
|
currentPhaseStepSum = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCurrentPhase(DownloadProgressPhase downloadProgressPhase) {
|
||||||
|
|
||||||
|
setCurrentPhase(downloadProgressPhase, downloadProgressPhase.getProgressSteps().size());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
package com.truphone.lpa.progress;
|
||||||
|
|
||||||
|
|
||||||
|
import com.truphone.lpad.progress.ProgressStep;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public enum DownloadProgressPhase {
|
||||||
|
CONNECTING(0.05, ProgressStep.DOWNLOAD_PROFILE_RETRIEVING_EUICC_ADDRESS,
|
||||||
|
ProgressStep.DOWNLOAD_PROFILE_CONVERTING_EUICC_CONFIGURED_ADDRESS,
|
||||||
|
ProgressStep.DOWNLOAD_PROFILE_CONVERTED_EUICC_ADDRESS),
|
||||||
|
AUTHENTICATING(0.3, ProgressStep.DOWNLOAD_PROFILE_GET_EUICC_INFO,
|
||||||
|
ProgressStep.DOWNLOAD_PROFILE_CONVERTING_EUICC_INFO,
|
||||||
|
ProgressStep.DOWNLOAD_PROFILE_CONVERTED_EUICC_INFO,
|
||||||
|
ProgressStep.DOWNLOAD_PROFILE_GET_EUICC_CHALLENGE,
|
||||||
|
ProgressStep.DOWNLOAD_PROFILE_CONVERTING_EUICC_CHALLENGE,
|
||||||
|
ProgressStep.DOWNLOAD_PROFILE_CONVERTED_EUICC_CHALLENGE,
|
||||||
|
ProgressStep.DOWNLOAD_PROFILE_INITIATE_AUTHENTICATION,
|
||||||
|
ProgressStep.DOWNLOAD_PROFILE_INITIATED_AUTHENTICATION,
|
||||||
|
ProgressStep.DOWNLOAD_PROFILE_AUTHENTICATE_WITH_EUICC,
|
||||||
|
ProgressStep.DOWNLOAD_PROFILE_AUTHENTICATED_WITH_EUICC,
|
||||||
|
ProgressStep.DOWNLOAD_PROFILE_AUTHENTICATE_CLIENT,
|
||||||
|
ProgressStep.DOWNLOAD_PROFILE_AUTHENTICATED_CLIENT),
|
||||||
|
DOWNLOADING(0.1,
|
||||||
|
ProgressStep.DOWNLOAD_PROFILE_PREPARE_DOWNLOAD,
|
||||||
|
ProgressStep.DOWNLOAD_PROFILE_PREPARED_DOWNLOAD,
|
||||||
|
ProgressStep.DOWNLOAD_PROFILE_GET_BOUND_PROFILE_PACKAGE,
|
||||||
|
ProgressStep.DOWNLOAD_PROFILE_BOUND_PROFILE_PACKAGE_RETRIEVED),
|
||||||
|
GENERATING(0.05,
|
||||||
|
ProgressStep.DOWNLOAD_PROFILE_GENERATING_SBPP,
|
||||||
|
ProgressStep.DOWNLOAD_PROFILE_GENERATED_SBPP,
|
||||||
|
ProgressStep.DOWNLOAD_PROFILE_GENERATING_SBPP_APDUS,
|
||||||
|
ProgressStep.DOWNLOAD_PROFILE_GENERATED_SBPP_APDUS),
|
||||||
|
INSTALLING(0.5,
|
||||||
|
ProgressStep.DOWNLOAD_PROFILE_LOADING_SBPP,
|
||||||
|
ProgressStep.DOWNLOAD_PROFILE_INITIALIZE_SECURE_CHANNEL,
|
||||||
|
ProgressStep.DOWNLOAD_PROFILE_CONFIGURE_ISDPA,
|
||||||
|
ProgressStep.DOWNLOAD_PROFILE_STORE_METADATA,
|
||||||
|
ProgressStep.DOWNLOAD_PROFILE_BOUND_PROFILE_PACKAGE,
|
||||||
|
ProgressStep.DOWNLOAD_PROFILE_INSTALLED);
|
||||||
|
|
||||||
|
private List<ProgressStep> progressSteps;
|
||||||
|
private double phaseTotalPercentage;
|
||||||
|
|
||||||
|
DownloadProgressPhase(double phaseTotalPercentage, ProgressStep... progressSteps) {
|
||||||
|
|
||||||
|
this.progressSteps = Arrays.asList(progressSteps);
|
||||||
|
this.phaseTotalPercentage = phaseTotalPercentage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ProgressStep> getProgressSteps() {
|
||||||
|
|
||||||
|
return progressSteps;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getPhaseTotalPercentage() {
|
||||||
|
|
||||||
|
return phaseTotalPercentage;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
package com.truphone.lpa.progress;
|
||||||
|
|
||||||
|
public enum ProgressPhase {
|
||||||
|
RUNNING
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package com.truphone.lpad;
|
||||||
|
|
||||||
|
import com.truphone.lpad.worker.WorkerExchange;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Representation of all classes that contains the implementation of LPAD operations
|
||||||
|
*/
|
||||||
|
public interface LpadWorker<T extends WorkerExchange, E> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute operation
|
||||||
|
*
|
||||||
|
* @param input Input parameters
|
||||||
|
* @return Result of the LPAD operation
|
||||||
|
*/
|
||||||
|
E run(T input);
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
package com.truphone.lpad.progress;
|
||||||
|
|
||||||
|
import com.truphone.util.LogStub;
|
||||||
|
import com.truphone.lpa.progress.ProgressPhase;
|
||||||
|
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
|
||||||
|
public class Progress {
|
||||||
|
private static final Logger LOG = Logger.getLogger(Progress.class.getName());
|
||||||
|
|
||||||
|
private final Executor executor;
|
||||||
|
|
||||||
|
private ProgressListener progressListener;
|
||||||
|
private ProgressPhase progressPhase;
|
||||||
|
private int totalSteps;
|
||||||
|
private int currentStep;
|
||||||
|
|
||||||
|
public Progress() {
|
||||||
|
|
||||||
|
executor = Executors.newSingleThreadExecutor();
|
||||||
|
progressPhase = ProgressPhase.RUNNING;
|
||||||
|
totalSteps = 1;
|
||||||
|
currentStep = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stepExecuted(final ProgressStep step,
|
||||||
|
final String message) {
|
||||||
|
|
||||||
|
if (progressListener != null) {
|
||||||
|
++currentStep;
|
||||||
|
|
||||||
|
executor.execute(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
double percentage;
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() +
|
||||||
|
" - Progress - setAction - phase: " +
|
||||||
|
progressPhase + "; step: " + step + "; currentStep: " + currentStep +
|
||||||
|
"; message: " + message + "; totalSteps: " + totalSteps);
|
||||||
|
}
|
||||||
|
|
||||||
|
percentage = currentStep / totalSteps;
|
||||||
|
|
||||||
|
if (percentage > 1.0) {
|
||||||
|
percentage = 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
progressListener.onAction(progressPhase.name(), step.name(), percentage, message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProgressListener(ProgressListener progressListener) {
|
||||||
|
|
||||||
|
this.progressListener = progressListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTotalSteps(int totalSteps) {
|
||||||
|
|
||||||
|
this.totalSteps = totalSteps;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
package com.truphone.lpad.progress;
|
||||||
|
|
||||||
|
public interface ProgressListener {
|
||||||
|
|
||||||
|
void onAction(String phase,
|
||||||
|
String step,
|
||||||
|
Double percentage,
|
||||||
|
String message);
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
package com.truphone.lpad.progress;
|
||||||
|
|
||||||
|
public enum ProgressStep {
|
||||||
|
ENABLE_PROFILE_PROFILE_ENABLED,
|
||||||
|
ENABLE_PROFILE_PROFILE_NOT_ENABLED,
|
||||||
|
ENABLE_PROFILE_ENABLING_PROFILE,
|
||||||
|
ENABLE_PROFILE_CONVERTING_RESPONSE,
|
||||||
|
ENABLE_PROFILE_TRIGGERED_PROFILE_SWITCH,
|
||||||
|
|
||||||
|
DISABLE_PROFILE_DISABLING_PROFILE,
|
||||||
|
DISABLE_PROFILE_DISABLED,
|
||||||
|
DISABLE_PROFILE_NOT_DISABLED,
|
||||||
|
DISABLE_PROFILE_CONVERTING_RESPONSE,
|
||||||
|
DISABLE_PROFILE_TRIGGERED_PROFILE_SWITCH,
|
||||||
|
|
||||||
|
DELETE_PROFILE_DELETING_PROFILE,
|
||||||
|
DELETE_PROFILE_NOT_DELETED,
|
||||||
|
DELETE_PROFILE_DELETED,
|
||||||
|
DELETE_PROFILE_CONVERTING_RESPONSE,
|
||||||
|
|
||||||
|
MEMORY_RESET_SUCCESS,
|
||||||
|
MEMORY_RESET_RESETING,
|
||||||
|
|
||||||
|
DOWNLOAD_PROFILE_RETRIEVING_EUICC_ADDRESS,
|
||||||
|
DOWNLOAD_PROFILE_CONVERTING_EUICC_CONFIGURED_ADDRESS,
|
||||||
|
DOWNLOAD_PROFILE_CONVERTED_EUICC_ADDRESS,
|
||||||
|
DOWNLOAD_PROFILE_GET_EUICC_INFO,
|
||||||
|
DOWNLOAD_PROFILE_CONVERTING_EUICC_INFO,
|
||||||
|
DOWNLOAD_PROFILE_CONVERTED_EUICC_INFO,
|
||||||
|
DOWNLOAD_PROFILE_GET_EUICC_CHALLENGE,
|
||||||
|
DOWNLOAD_PROFILE_CONVERTING_EUICC_CHALLENGE,
|
||||||
|
DOWNLOAD_PROFILE_CONVERTED_EUICC_CHALLENGE,
|
||||||
|
DOWNLOAD_PROFILE_INITIATE_AUTHENTICATION,
|
||||||
|
DOWNLOAD_PROFILE_INITIATED_AUTHENTICATION,
|
||||||
|
DOWNLOAD_PROFILE_AUTHENTICATE_WITH_EUICC,
|
||||||
|
DOWNLOAD_PROFILE_AUTHENTICATED_WITH_EUICC,
|
||||||
|
DOWNLOAD_PROFILE_AUTHENTICATE_CLIENT,
|
||||||
|
DOWNLOAD_PROFILE_AUTHENTICATED_CLIENT,
|
||||||
|
DOWNLOAD_PROFILE_PREPARE_DOWNLOAD,
|
||||||
|
DOWNLOAD_PROFILE_PREPARED_DOWNLOAD,
|
||||||
|
DOWNLOAD_PROFILE_GET_BOUND_PROFILE_PACKAGE,
|
||||||
|
DOWNLOAD_PROFILE_BOUND_PROFILE_PACKAGE_RETRIEVED,
|
||||||
|
DOWNLOAD_PROFILE_GENERATING_SBPP,
|
||||||
|
DOWNLOAD_PROFILE_GENERATED_SBPP,
|
||||||
|
DOWNLOAD_PROFILE_GENERATING_SBPP_APDUS,
|
||||||
|
DOWNLOAD_PROFILE_GENERATED_SBPP_APDUS,
|
||||||
|
DOWNLOAD_PROFILE_LOADING_SBPP,
|
||||||
|
DOWNLOAD_PROFILE_INITIALIZE_SECURE_CHANNEL,
|
||||||
|
DOWNLOAD_PROFILE_CONFIGURE_ISDPA,
|
||||||
|
DOWNLOAD_PROFILE_STORE_METADATA,
|
||||||
|
DOWNLOAD_PROFILE_REPLACE_SESSIONS_KEYS,
|
||||||
|
DOWNLOAD_PROFILE_BOUND_PROFILE_PACKAGE,
|
||||||
|
DOWNLOAD_PROFILE_INSTALLED,
|
||||||
|
DOWNLOAD_PROFILE_APDU_TRANSMITTED,
|
||||||
|
|
||||||
|
ALLOCATE_PROFILE_ALLOCATING,
|
||||||
|
ALLOCATE_PROFILE_ALLOCATED,
|
||||||
|
|
||||||
|
GET_EID_RETRIEVING,
|
||||||
|
GET_EID_CONVERTING,
|
||||||
|
GET_EID_CONVERTED
|
||||||
|
}
|
|
@ -0,0 +1,119 @@
|
||||||
|
package com.truphone.lpad.worker;
|
||||||
|
|
||||||
|
import com.truphone.es9plus.AllocateProfileResponse;
|
||||||
|
import com.truphone.es9plus.Es9PlusImpl;
|
||||||
|
import com.truphone.util.LogStub;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import com.truphone.lpad.LpadWorker;
|
||||||
|
import com.truphone.lpad.progress.Progress;
|
||||||
|
import com.truphone.lpad.progress.ProgressStep;
|
||||||
|
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
import org.apache.commons.lang3.NotImplementedException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Worker containing all logic to allocate a profile for a MCC with a specific EID
|
||||||
|
*/
|
||||||
|
public class AllocateProfileWorker implements LpadWorker<LpadWorkerExchange<AllocateProfileWorker.AllocateProfileInputParams>, String> {
|
||||||
|
private static final Logger LOG = Logger.getLogger(AllocateProfileWorker.class.getName());
|
||||||
|
|
||||||
|
private final Progress progress;
|
||||||
|
private final Es9PlusImpl es9PlusImpl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param progress Progress Bar
|
||||||
|
* @param es9PlusImpl RSP29 Client
|
||||||
|
*/
|
||||||
|
public AllocateProfileWorker(final Progress progress,
|
||||||
|
final Es9PlusImpl es9PlusImpl) {
|
||||||
|
|
||||||
|
inputValidation(progress == null, "Progress must not be null");
|
||||||
|
inputValidation(es9PlusImpl == null, "Es9PlusImpl must not be null");
|
||||||
|
|
||||||
|
this.progress = progress;
|
||||||
|
this.es9PlusImpl = es9PlusImpl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allocates the Protected Profile Packages to specified EIDs based on given MCC
|
||||||
|
*
|
||||||
|
* @param lpadWorkerExchange Exchange that must contain in its body the {@link AllocateProfileInputParams}
|
||||||
|
* @return Activation Code Token
|
||||||
|
*/
|
||||||
|
public String run(final LpadWorkerExchange<AllocateProfileInputParams> lpadWorkerExchange) {
|
||||||
|
// inputValidation(lpadWorkerExchange == null, "Input params to invoke Allocate Profile must not be null");
|
||||||
|
// inputValidation(lpadWorkerExchange.getBody() == null, "Input params must have body defined");
|
||||||
|
// inputValidation(StringUtils.isBlank(lpadWorkerExchange.getBody().getEid()), "EID must not be null/empty");
|
||||||
|
// inputValidation(StringUtils.isBlank(lpadWorkerExchange.getBody().getMcc()), "MCC must not be null/empty");
|
||||||
|
//
|
||||||
|
// progress.setTotalSteps(2);
|
||||||
|
// progress.stepExecuted(ProgressStep.ALLOCATE_PROFILE_ALLOCATING, "allocateProfile allocating...");
|
||||||
|
//
|
||||||
|
// logDebug(" - Allocating profile for MCC: " + lpadWorkerExchange.getBody().getMcc()
|
||||||
|
// + " and EID: " + lpadWorkerExchange.getBody().getEid());
|
||||||
|
//
|
||||||
|
// AllocateProfileResponse allocateProfileResponse
|
||||||
|
// = es9PlusImpl.allocateProfile(lpadWorkerExchange.getBody().getEid(), lpadWorkerExchange.getBody().getMcc());
|
||||||
|
//
|
||||||
|
// if (allocateProfileResponse != null) {
|
||||||
|
// progress.stepExecuted(ProgressStep.ALLOCATE_PROFILE_ALLOCATED, "allocateProfile allocated!");
|
||||||
|
//
|
||||||
|
// logDebug(" - Allocate Profile Response: " + allocateProfileResponse);
|
||||||
|
//
|
||||||
|
// return allocateProfileResponse.getAcToken();
|
||||||
|
// } else {
|
||||||
|
// logDebug(" - No matching id returned from profile broker, please check profiles are available");
|
||||||
|
//
|
||||||
|
// throw new RuntimeException("Unable to allocate profile");
|
||||||
|
// }
|
||||||
|
throw new NotImplementedException("Not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void logDebug(final String errorMessage) {
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + errorMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void inputValidation(final boolean invalidCondition, final String errorMessage) {
|
||||||
|
if (invalidCondition) {
|
||||||
|
LOG.log(Level.SEVERE, LogStub.getInstance().getTag() + " - " + errorMessage);
|
||||||
|
throw new IllegalArgumentException(errorMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is responsible to gather the mandatory params to allocate a profile, which are:
|
||||||
|
* <ul>
|
||||||
|
* <li>mcc: Mobile country code</li>
|
||||||
|
* <li>eid: eUICC-ID</li>
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
public class AllocateProfileInputParams {
|
||||||
|
private final String mcc;
|
||||||
|
private final String eid;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Input params to allocate the Protected Profile Packages
|
||||||
|
*
|
||||||
|
* @param mcc Mobile country code
|
||||||
|
* @param eid eUICC-ID
|
||||||
|
*/
|
||||||
|
public AllocateProfileInputParams(final String mcc, final String eid) {
|
||||||
|
this.mcc = mcc;
|
||||||
|
this.eid = eid;
|
||||||
|
}
|
||||||
|
|
||||||
|
String getMcc() {
|
||||||
|
return mcc;
|
||||||
|
}
|
||||||
|
|
||||||
|
String getEid() {
|
||||||
|
return eid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,162 @@
|
||||||
|
package com.truphone.lpad.worker;
|
||||||
|
|
||||||
|
import com.truphone.lpa.ApduChannel;
|
||||||
|
import com.truphone.lpa.apdu.ApduUtils;
|
||||||
|
import com.truphone.lpad.LpadWorker;
|
||||||
|
import com.truphone.lpad.progress.Progress;
|
||||||
|
import com.truphone.lpad.progress.ProgressStep;
|
||||||
|
import com.truphone.rsp.dto.asn1.rspdefinitions.DeleteProfileResponse;
|
||||||
|
import com.truphone.util.LogStub;
|
||||||
|
import org.apache.commons.codec.DecoderException;
|
||||||
|
import org.apache.commons.codec.binary.Hex;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
public class DeleteProfileWorker implements LpadWorker<LpadWorkerExchange<DeleteProfileWorker.DeleteProfileInputParams>, String> {
|
||||||
|
private static final Logger LOG = Logger.getLogger(DeleteProfileWorker.class.getName());
|
||||||
|
|
||||||
|
private final Progress progress;
|
||||||
|
private final ApduChannel apduChannel;
|
||||||
|
|
||||||
|
static final String PROFILE_RESULT_SUCCESS = "0";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param progress Progress Bar
|
||||||
|
* @param apduChannel aPDU Channel
|
||||||
|
*/
|
||||||
|
public DeleteProfileWorker(Progress progress, ApduChannel apduChannel) {
|
||||||
|
inputValidation(progress == null, "Progress must not be null");
|
||||||
|
inputValidation(apduChannel == null, "ApduChannel must not be null");
|
||||||
|
|
||||||
|
this.progress = progress;
|
||||||
|
this.apduChannel = apduChannel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes the Profile from the ICC and converts the response to be readable
|
||||||
|
*
|
||||||
|
* @param lpadWorkerExchange Exchange that must contain in its body the {@link DeleteProfileInputParams}
|
||||||
|
* @return Delete response Code
|
||||||
|
*/
|
||||||
|
public String run(final LpadWorkerExchange<DeleteProfileInputParams> lpadWorkerExchange) {
|
||||||
|
|
||||||
|
inputValidation(lpadWorkerExchange == null, "Input params to invoke Delete Profile must not be null");
|
||||||
|
inputValidation(lpadWorkerExchange.getBody() == null, "Input params must have body defined");
|
||||||
|
inputValidation(StringUtils.isBlank(lpadWorkerExchange.getBody().getIccid()), "ICCID must not be null/empty");
|
||||||
|
|
||||||
|
String iccid = lpadWorkerExchange.getBody().getIccid(); // Get ICCID From Body
|
||||||
|
String eResponse = transmitDeleteProfile(iccid, progress);
|
||||||
|
|
||||||
|
return convertDeleteProfile(iccid, progress, eResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts the response from the transmission, checks if there are errors in the transmission
|
||||||
|
*
|
||||||
|
* @param iccid Integrated Circuit Card ID
|
||||||
|
* @param progress Progress Bar
|
||||||
|
* @param eResponse Response from transmitDeleteProfile
|
||||||
|
* @return Delete response Code
|
||||||
|
*/
|
||||||
|
private String convertDeleteProfile(String iccid, Progress progress, String eResponse) {
|
||||||
|
|
||||||
|
progress.stepExecuted(ProgressStep.DELETE_PROFILE_CONVERTING_RESPONSE, "Converting response");
|
||||||
|
|
||||||
|
DeleteProfileResponse deleteProfileResponse = new DeleteProfileResponse();
|
||||||
|
|
||||||
|
try {
|
||||||
|
InputStream is = new ByteArrayInputStream(Hex.decodeHex(eResponse.toCharArray()));
|
||||||
|
deleteProfileResponse.decode(is);
|
||||||
|
|
||||||
|
logDebug(" - Delete response: " + deleteProfileResponse);
|
||||||
|
if (PROFILE_RESULT_SUCCESS.equals(deleteProfileResponse.getDeleteResult().toString())) {
|
||||||
|
logDebug(" - iccid: " + iccid + " profile deleted");
|
||||||
|
logDebug(" - iccid: " + iccid + " Refreshing SIM card on Delete.");
|
||||||
|
apduChannel.sendStatus();
|
||||||
|
|
||||||
|
progress.stepExecuted(ProgressStep.DELETE_PROFILE_DELETED, iccid + " deleted successfully");
|
||||||
|
} else {
|
||||||
|
progress.stepExecuted(ProgressStep.DELETE_PROFILE_NOT_DELETED, iccid + " profile not deleted");
|
||||||
|
|
||||||
|
LOG.info(LogStub.getInstance().getTag() + " - iccid:" + iccid + " profile not deleted");
|
||||||
|
}
|
||||||
|
|
||||||
|
return deleteProfileResponse.getDeleteResult().toString();
|
||||||
|
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
LOG.severe(LogStub.getInstance().getTag() + " - iccid:" + iccid + " profile failed to be deleted");
|
||||||
|
|
||||||
|
throw new RuntimeException("Unable to delete profile: " + iccid + ", response: " + eResponse);
|
||||||
|
} catch (DecoderException e) {
|
||||||
|
LOG.severe(LogStub.getInstance().getTag() + " - " + e.getMessage());
|
||||||
|
LOG.severe(LogStub.getInstance().getTag() + " - iccid: " + iccid + " profile failed to be deleted. Exception in Decoder:" + e.getMessage());
|
||||||
|
|
||||||
|
throw new RuntimeException("Unable to delete profile: " + iccid + ", response: " + eResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transmits the action to deletes the profile for the specific ICC
|
||||||
|
*
|
||||||
|
* @param iccid Integrated Circuit Card ID
|
||||||
|
* @param progress Progress Bar
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private String transmitDeleteProfile(String iccid, Progress progress) {
|
||||||
|
|
||||||
|
progress.setTotalSteps(3);
|
||||||
|
progress.stepExecuted(ProgressStep.DELETE_PROFILE_DELETING_PROFILE, iccid + " delete profile");
|
||||||
|
logDebug(" - Deleting profile: " + iccid);
|
||||||
|
|
||||||
|
String apdu = ApduUtils.deleteProfileApdu(iccid);
|
||||||
|
logDebug(" - Delete profile apdu: " + apdu);
|
||||||
|
|
||||||
|
String eResponse = apduChannel.transmitAPDU(apdu);
|
||||||
|
logDebug(" - Delete Response: " + eResponse);
|
||||||
|
|
||||||
|
return eResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void logDebug(final String errorMessage) {
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + errorMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void inputValidation(final boolean invalidCondition, final String errorMessage) {
|
||||||
|
if (invalidCondition) {
|
||||||
|
LOG.log(Level.SEVERE, LogStub.getInstance().getTag() + " - " + errorMessage);
|
||||||
|
throw new IllegalArgumentException(errorMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is responsible to gather the mandatory params to delete a profile, which are:
|
||||||
|
* <ul>
|
||||||
|
* <li>iccid: Integrated Circuit Card ID</li>
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
public class DeleteProfileInputParams {
|
||||||
|
private final String iccid;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Input params to allocate the Protected Profile Packages
|
||||||
|
*
|
||||||
|
* @param iccid Integrated Circuit Card ID
|
||||||
|
*/
|
||||||
|
public DeleteProfileInputParams(final String iccid) {
|
||||||
|
this.iccid = iccid;
|
||||||
|
}
|
||||||
|
|
||||||
|
String getIccid() {
|
||||||
|
return iccid;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,109 @@
|
||||||
|
package com.truphone.lpad.worker;
|
||||||
|
|
||||||
|
|
||||||
|
import com.truphone.lpa.ApduChannel;
|
||||||
|
import com.truphone.lpad.LpadWorker;
|
||||||
|
import com.truphone.lpad.progress.Progress;
|
||||||
|
import com.truphone.lpad.progress.ProgressStep;
|
||||||
|
import com.truphone.rsp.dto.asn1.rspdefinitions.GetEuiccDataResponse;
|
||||||
|
import com.truphone.util.LogStub;
|
||||||
|
import org.apache.commons.codec.DecoderException;
|
||||||
|
import org.apache.commons.codec.binary.Hex;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
public class GetEidLpadWorker implements LpadWorker<LpadWorkerExchange<String>, String> {
|
||||||
|
private static final Logger LOG = Logger.getLogger(GetEidLpadWorker.class.getName());
|
||||||
|
|
||||||
|
private final Progress progress;
|
||||||
|
private final ApduChannel apduChannel;
|
||||||
|
|
||||||
|
public GetEidLpadWorker(final Progress progress,
|
||||||
|
final ApduChannel apduChannel) {
|
||||||
|
|
||||||
|
inputValidation(progress == null, "received an invalid progress: " + progress);
|
||||||
|
inputValidation(apduChannel == null, "received an invalid apduChannel: " + apduChannel);
|
||||||
|
|
||||||
|
this.progress = progress;
|
||||||
|
this.apduChannel = apduChannel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the EID from the eUICC, using its apdu
|
||||||
|
*
|
||||||
|
* @param lpadWorkerExchange Exchange that must contain in its body the APDU related with the EID which we want to obtain
|
||||||
|
* @return The EID from the eUICC, using its APDU
|
||||||
|
*/
|
||||||
|
public String run(final LpadWorkerExchange<String> lpadWorkerExchange) {
|
||||||
|
|
||||||
|
progress.setTotalSteps(3);
|
||||||
|
progress.stepExecuted(ProgressStep.GET_EID_RETRIEVING, "getEID retrieving...");
|
||||||
|
|
||||||
|
inputValidation(lpadWorkerExchange == null, "Lpa dWorker Exchange must be provided");
|
||||||
|
inputValidation(StringUtils.isBlank(lpadWorkerExchange.getBody()), "EID APDU must be provided");
|
||||||
|
|
||||||
|
logDebug("EID APDU: " + lpadWorkerExchange);
|
||||||
|
|
||||||
|
|
||||||
|
String eidapduResponseStr = apduChannel.transmitAPDU(lpadWorkerExchange.getBody());
|
||||||
|
|
||||||
|
logDebug("Response: " + eidapduResponseStr);
|
||||||
|
|
||||||
|
return convertGetEuiccData(eidapduResponseStr, progress);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String convertGetEuiccData(final String eidapduResponseStr,
|
||||||
|
final Progress progress) {
|
||||||
|
|
||||||
|
progress.stepExecuted(ProgressStep.GET_EID_CONVERTING, "getEID converting...");
|
||||||
|
|
||||||
|
inputValidation(StringUtils.isBlank(eidapduResponseStr), "received an invalid eidapduResponseStr: " + eidapduResponseStr);
|
||||||
|
|
||||||
|
GetEuiccDataResponse eidResponse = new GetEuiccDataResponse();
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
logDebug("Decoding response: " + eidapduResponseStr);
|
||||||
|
|
||||||
|
InputStream is = new ByteArrayInputStream(Hex.decodeHex(eidapduResponseStr.toCharArray()));
|
||||||
|
|
||||||
|
logDebug("Decoding with GetEuiccDataResponse");
|
||||||
|
|
||||||
|
eidResponse.decode(is, true);
|
||||||
|
|
||||||
|
logDebug("EID is: " + eidResponse.getEidValue().toString());
|
||||||
|
|
||||||
|
progress.stepExecuted(ProgressStep.GET_EID_CONVERTED, "getEID converted...");
|
||||||
|
|
||||||
|
return eidResponse.getEidValue().toString();
|
||||||
|
} catch (DecoderException e) {
|
||||||
|
LOG.log(Level.SEVERE, LogStub.getInstance().getTag() + " - " + e.getMessage(), e);
|
||||||
|
LOG.log(Level.SEVERE, LogStub.getInstance().getTag() + " - Unable to retrieve EID. Exception in Decoder:" + e.getMessage());
|
||||||
|
|
||||||
|
throw new RuntimeException("Unable to retrieve EID");
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
LOG.log(Level.SEVERE, LogStub.getInstance().getTag() + " - " + ioe.getMessage(), ioe);
|
||||||
|
|
||||||
|
throw new RuntimeException("Invalid EID response, unable to retrieve EID");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void logDebug(final String errorMessage) {
|
||||||
|
|
||||||
|
if (LogStub.getInstance().isDebugEnabled()) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - " + errorMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void inputValidation(final boolean invalidCondition, final String errorMessage) {
|
||||||
|
if (invalidCondition) {
|
||||||
|
LOG.log(Level.SEVERE, LogStub.getInstance().getTag() + " - " + errorMessage);
|
||||||
|
throw new IllegalArgumentException(errorMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
package com.truphone.lpad.worker;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Message used within LPAD Workers containing all necessary data
|
||||||
|
*
|
||||||
|
* @param <T> Data to be used on LPAD Workers operations
|
||||||
|
*/
|
||||||
|
public class LpadWorkerExchange<T> implements WorkerExchange<T> {
|
||||||
|
|
||||||
|
private final T body;
|
||||||
|
|
||||||
|
public LpadWorkerExchange(final T body) {
|
||||||
|
this.body = body;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get data to be used on LPAD Workers operations
|
||||||
|
*
|
||||||
|
* @return The data to be used on LPAD Workers operations
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public T getBody() {
|
||||||
|
return this.body;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package com.truphone.lpad.worker;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Message used within Workers containing all necessary data
|
||||||
|
* @param <T> Data to be used on Workers operations
|
||||||
|
*/
|
||||||
|
public interface WorkerExchange<T> {
|
||||||
|
/**
|
||||||
|
* Get data to be used on Workers operations
|
||||||
|
*
|
||||||
|
* @return The data to be used on Workers operations
|
||||||
|
*/
|
||||||
|
T getBody();
|
||||||
|
}
|
|
@ -0,0 +1,73 @@
|
||||||
|
package com.truphone.util;
|
||||||
|
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
public class LogStub {
|
||||||
|
private static LogStub instance;
|
||||||
|
|
||||||
|
private Level logLevel;
|
||||||
|
private String tag;
|
||||||
|
private boolean androidLog;
|
||||||
|
|
||||||
|
private LogStub() {
|
||||||
|
|
||||||
|
logLevel = Level.ALL;
|
||||||
|
tag = "";
|
||||||
|
androidLog = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LogStub getInstance() {
|
||||||
|
|
||||||
|
if (instance == null) {
|
||||||
|
instance = new LogStub();
|
||||||
|
}
|
||||||
|
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLogLevel(Level logLevel) {
|
||||||
|
|
||||||
|
this.logLevel = logLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDebugEnabled() {
|
||||||
|
|
||||||
|
return logLevel.intValue() <= Level.FINE.intValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isTraceEnabled() {
|
||||||
|
|
||||||
|
return logLevel.intValue() <= Level.FINEST.intValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTag() {
|
||||||
|
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTag(String tag) {
|
||||||
|
|
||||||
|
this.tag = tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAndroidLog(boolean androidLog) {
|
||||||
|
|
||||||
|
this.androidLog = androidLog;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isAndroidLog() {
|
||||||
|
|
||||||
|
return androidLog;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void logDebug(Logger logger, String message) {
|
||||||
|
logger.info(message);
|
||||||
|
// if (isAndroidLog()) {
|
||||||
|
// logger.info(message);
|
||||||
|
// } else {
|
||||||
|
// //logger.fine(message);
|
||||||
|
// System.out.println(message);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
package com.truphone.util;
|
||||||
|
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
public class PropUtil {
|
||||||
|
|
||||||
|
|
||||||
|
public static String getMandatoryProperty(final Properties props,
|
||||||
|
final String key) {
|
||||||
|
if (!props.containsKey(key)) {
|
||||||
|
throw new IllegalArgumentException("mandatory property missing: "
|
||||||
|
+ key);
|
||||||
|
}
|
||||||
|
return props.getProperty(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getIntProperty(final Properties props, final String key,
|
||||||
|
final int defaultValue) {
|
||||||
|
if (props.containsKey(key)) {
|
||||||
|
try {
|
||||||
|
return Integer.decode(props.getProperty(key));
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"syntax error in int property: " + key, e);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
package com.truphone.util;
|
||||||
|
|
||||||
|
public class TLVBean {
|
||||||
|
private String taglen;
|
||||||
|
private String value;
|
||||||
|
|
||||||
|
public TLVBean(String taglen, String value) {
|
||||||
|
super();
|
||||||
|
this.taglen = taglen;
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
public String getTaglen() {
|
||||||
|
return taglen;
|
||||||
|
}
|
||||||
|
public String getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
public void setValue(String value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
package com.truphone.util;
|
||||||
|
|
||||||
|
public class TextUtil {
|
||||||
|
private static final char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5',
|
||||||
|
'6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts the given byte array to its hex representation.
|
||||||
|
*
|
||||||
|
* @param data The byte array to convert.
|
||||||
|
* @return Hex-encoded data as a string.
|
||||||
|
* @see #toHexString(byte[], int, int)
|
||||||
|
*/
|
||||||
|
public static String toHexString(byte[] data) {
|
||||||
|
return data == null ? null : toHexString(data, 0, data.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts the given byte array slice to its hex representation.
|
||||||
|
*
|
||||||
|
* @param data The byte array to convert.
|
||||||
|
* @param offset Slice start.
|
||||||
|
* @param length Slice length.
|
||||||
|
* @return Hex-encoded data as a string.
|
||||||
|
*/
|
||||||
|
public static String toHexString(final byte[] data, int offset, int length) {
|
||||||
|
final char[] result = new char[length << 1];
|
||||||
|
length += offset;
|
||||||
|
for (int i = 0; offset < length; ++offset) {
|
||||||
|
result[i++] = HEX_DIGITS[(data[offset] >>> 4) & 0x0F];
|
||||||
|
result[i++] = HEX_DIGITS[data[offset] & 0x0F];
|
||||||
|
}
|
||||||
|
return new String(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
package com.truphone.util;
|
||||||
|
|
||||||
|
|
||||||
|
public class ToTLV {
|
||||||
|
public static String toTLV(String tag,String input){
|
||||||
|
if("".equals(tag))return toTLV(input);
|
||||||
|
return tag+toTLV(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String integerToTLV(String tag,int input){
|
||||||
|
if("".equals(tag))return integerToTLV(input);
|
||||||
|
return tag+integerToTLV(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String integerToTLV(int input) {
|
||||||
|
String tlv;
|
||||||
|
if(input<=127){
|
||||||
|
tlv=String.format("01%02X", input);
|
||||||
|
}else{
|
||||||
|
tlv=String.format("02%04X", input);
|
||||||
|
}
|
||||||
|
|
||||||
|
return tlv;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static String toTLV(String input) {
|
||||||
|
int inputLen = input.length()/2;
|
||||||
|
String strInputLenString = toHex(String.valueOf(inputLen));
|
||||||
|
if (inputLen > 65535) {
|
||||||
|
input = "83" + strInputLenString + input;
|
||||||
|
} else if (inputLen > 255) {
|
||||||
|
input = "82" + strInputLenString + input;
|
||||||
|
} else if(inputLen > 127) {
|
||||||
|
input = "81" + strInputLenString + input;
|
||||||
|
} else {
|
||||||
|
input = strInputLenString + input;
|
||||||
|
}
|
||||||
|
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String toHex(String num) {
|
||||||
|
String hex = Integer.toHexString(Integer.valueOf(num));
|
||||||
|
if (hex.length() % 2 != 0) {
|
||||||
|
hex = "0" + hex;
|
||||||
|
}
|
||||||
|
return hex.toUpperCase();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package com.truphone.util;
|
||||||
|
|
||||||
|
public class Tools {
|
||||||
|
|
||||||
|
public static String itoa(int value, int len) {
|
||||||
|
String result = Integer.toHexString(value).toUpperCase();
|
||||||
|
int rLen = result.length();
|
||||||
|
len = 2 * len;
|
||||||
|
if (rLen > len) {
|
||||||
|
return result.substring(rLen - len, rLen);
|
||||||
|
}
|
||||||
|
if (rLen == len) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
StringBuffer strBuff = new StringBuffer(result);
|
||||||
|
for (int i = 0; i < len - rLen; i++) {
|
||||||
|
strBuff.insert(0, '0');
|
||||||
|
}
|
||||||
|
return strBuff.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String toHex(String num) {
|
||||||
|
String hex = Integer.toHexString(Integer.valueOf(num));
|
||||||
|
if (hex.length() % 2 != 0) {
|
||||||
|
hex = "0" + hex;
|
||||||
|
}
|
||||||
|
return hex.toUpperCase();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
package com.truphone.util;
|
||||||
|
|
||||||
|
public class Util {
|
||||||
|
public static String byteToHexString(byte b) {
|
||||||
|
StringBuffer s = new StringBuffer();
|
||||||
|
|
||||||
|
if ((b & 0xFF) < 16)
|
||||||
|
s.append("0");
|
||||||
|
s.append(Integer.toHexString(b & 0xFF).toUpperCase());
|
||||||
|
return s.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String byteArrayToHexString(byte[] buffer, String separator) {
|
||||||
|
StringBuffer s = new StringBuffer();
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < buffer.length; i++) {
|
||||||
|
s.append(byteToHexString(buffer[i]) + separator);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s.length() > 0) {
|
||||||
|
s.delete(s.length() - separator.length(), s.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] hexStringToByteArray(String s) {
|
||||||
|
if (s == null)
|
||||||
|
return null;
|
||||||
|
s = s.replaceAll(" ", "").replaceAll(":", "").replaceAll("0x", "").replaceAll("0X", "");
|
||||||
|
if (s.length() % 2 != 0)
|
||||||
|
throw new IllegalArgumentException("The length cannot be odd.");
|
||||||
|
byte[] output = new byte[s.length() / 2];
|
||||||
|
for (int i = 0; i < s.length(); i += 2)
|
||||||
|
output[(i / 2)] = ((byte) Integer.parseInt(s.substring(i, i + 2), 16));
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static String ASCIIToHex(String s) {
|
||||||
|
String ret = "";
|
||||||
|
|
||||||
|
if (s != null) {
|
||||||
|
byte[] buffer = s.getBytes();
|
||||||
|
|
||||||
|
ret = byteArrayToHexString(buffer, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,619 @@
|
||||||
|
PKIX1Explicit88 { iso(1) identified-organization(3) dod(6) internet(1)
|
||||||
|
security(5) mechanisms(5) pkix(7) id-mod(0) id-pkix1-explicit(18) }
|
||||||
|
|
||||||
|
DEFINITIONS EXPLICIT TAGS ::=
|
||||||
|
|
||||||
|
BEGIN
|
||||||
|
|
||||||
|
-- EXPORTS ALL --
|
||||||
|
|
||||||
|
-- IMPORTS NONE --
|
||||||
|
|
||||||
|
-- UNIVERSAL Types defined in 1993 and 1998 ASN.1
|
||||||
|
-- and required by this specification
|
||||||
|
|
||||||
|
-- UniversalString ::= [UNIVERSAL 28] IMPLICIT OCTET STRING
|
||||||
|
-- UniversalString is defined in ASN.1:1993
|
||||||
|
|
||||||
|
-- BMPString ::= [UNIVERSAL 30] IMPLICIT OCTET STRING
|
||||||
|
-- BMPString is the subtype of UniversalString and models
|
||||||
|
-- the Basic Multilingual Plane of ISO/IEC/ITU 10646-1
|
||||||
|
|
||||||
|
-- UTF8String ::= [UNIVERSAL 12] IMPLICIT OCTET STRING
|
||||||
|
-- The content of this type conforms to RFC 2279.
|
||||||
|
|
||||||
|
-- PKIX specific OIDs
|
||||||
|
|
||||||
|
id-pkix OBJECT IDENTIFIER ::=
|
||||||
|
{ iso(1) identified-organization(3) dod(6) internet(1)
|
||||||
|
security(5) mechanisms(5) pkix(7) }
|
||||||
|
|
||||||
|
-- PKIX arcs
|
||||||
|
|
||||||
|
id-pe OBJECT IDENTIFIER ::= { id-pkix 1 }
|
||||||
|
-- arc for private certificate extensions
|
||||||
|
id-qt OBJECT IDENTIFIER ::= { id-pkix 2 }
|
||||||
|
-- arc for policy qualifier types
|
||||||
|
id-kp OBJECT IDENTIFIER ::= { id-pkix 3 }
|
||||||
|
-- arc for extended key purpose OIDS
|
||||||
|
id-ad OBJECT IDENTIFIER ::= { id-pkix 48 }
|
||||||
|
-- arc for access descriptors
|
||||||
|
|
||||||
|
-- policyQualifierIds for Internet policy qualifiers
|
||||||
|
|
||||||
|
id-qt-cps OBJECT IDENTIFIER ::= { id-qt 1 }
|
||||||
|
-- OID for CPS qualifier
|
||||||
|
id-qt-unotice OBJECT IDENTIFIER ::= { id-qt 2 }
|
||||||
|
-- OID for user notice qualifier
|
||||||
|
|
||||||
|
-- access descriptor definitions
|
||||||
|
|
||||||
|
id-ad-ocsp OBJECT IDENTIFIER ::= { id-ad 1 }
|
||||||
|
id-ad-caIssuers OBJECT IDENTIFIER ::= { id-ad 2 }
|
||||||
|
id-ad-timeStamping OBJECT IDENTIFIER ::= { id-ad 3 }
|
||||||
|
id-ad-caRepository OBJECT IDENTIFIER ::= { id-ad 5 }
|
||||||
|
|
||||||
|
-- attribute data types
|
||||||
|
|
||||||
|
Attribute ::= SEQUENCE {
|
||||||
|
type AttributeType,
|
||||||
|
values SET OF AttributeValue }
|
||||||
|
-- at least one value is required
|
||||||
|
|
||||||
|
AttributeType ::= OBJECT IDENTIFIER
|
||||||
|
|
||||||
|
AttributeValue ::= ANY
|
||||||
|
|
||||||
|
AttributeTypeAndValue ::= SEQUENCE {
|
||||||
|
type AttributeType,
|
||||||
|
value AttributeValue }
|
||||||
|
|
||||||
|
-- suggested naming attributes: Definition of the following
|
||||||
|
-- information object set may be augmented to meet local
|
||||||
|
-- requirements. Note that deleting members of the set may
|
||||||
|
-- prevent interoperability with conforming implementations.
|
||||||
|
-- presented in pairs: the AttributeType followed by the
|
||||||
|
-- type definition for the corresponding AttributeValue
|
||||||
|
--Arc for standard naming attributes
|
||||||
|
id-at OBJECT IDENTIFIER ::= { joint-iso-ccitt(2) ds(5) 4 }
|
||||||
|
|
||||||
|
-- Naming attributes of type X520name
|
||||||
|
|
||||||
|
id-at-name AttributeType ::= { id-at 41 }
|
||||||
|
id-at-surname AttributeType ::= { id-at 4 }
|
||||||
|
id-at-givenName AttributeType ::= { id-at 42 }
|
||||||
|
id-at-initials AttributeType ::= { id-at 43 }
|
||||||
|
id-at-generationQualifier AttributeType ::= { id-at 44 }
|
||||||
|
|
||||||
|
X520name ::= CHOICE {
|
||||||
|
teletexString TeletexString (SIZE (1..ub-name)),
|
||||||
|
printableString PrintableString (SIZE (1..ub-name)),
|
||||||
|
universalString UniversalString (SIZE (1..ub-name)),
|
||||||
|
utf8String UTF8String (SIZE (1..ub-name)),
|
||||||
|
bmpString BMPString (SIZE (1..ub-name)) }
|
||||||
|
|
||||||
|
-- Naming attributes of type X520CommonName
|
||||||
|
|
||||||
|
id-at-commonName AttributeType ::= { id-at 3 }
|
||||||
|
|
||||||
|
X520CommonName ::= CHOICE {
|
||||||
|
teletexString TeletexString (SIZE (1..ub-common-name)),
|
||||||
|
printableString PrintableString (SIZE (1..ub-common-name)),
|
||||||
|
universalString UniversalString (SIZE (1..ub-common-name)),
|
||||||
|
utf8String UTF8String (SIZE (1..ub-common-name)),
|
||||||
|
bmpString BMPString (SIZE (1..ub-common-name)) }
|
||||||
|
|
||||||
|
-- Naming attributes of type X520LocalityName
|
||||||
|
|
||||||
|
id-at-localityName AttributeType ::= { id-at 7 }
|
||||||
|
|
||||||
|
X520LocalityName ::= CHOICE {
|
||||||
|
teletexString TeletexString (SIZE (1..ub-locality-name)),
|
||||||
|
printableString PrintableString (SIZE (1..ub-locality-name)),
|
||||||
|
universalString UniversalString (SIZE (1..ub-locality-name)),
|
||||||
|
utf8String UTF8String (SIZE (1..ub-locality-name)),
|
||||||
|
bmpString BMPString (SIZE (1..ub-locality-name)) }
|
||||||
|
|
||||||
|
-- Naming attributes of type X520StateOrProvinceName
|
||||||
|
|
||||||
|
id-at-stateOrProvinceName AttributeType ::= { id-at 8 }
|
||||||
|
|
||||||
|
X520StateOrProvinceName ::= CHOICE {
|
||||||
|
teletexString TeletexString (SIZE (1..ub-state-name)),
|
||||||
|
printableString PrintableString (SIZE (1..ub-state-name)),
|
||||||
|
universalString UniversalString (SIZE (1..ub-state-name)),
|
||||||
|
utf8String UTF8String (SIZE (1..ub-state-name)),
|
||||||
|
bmpString BMPString (SIZE(1..ub-state-name)) }
|
||||||
|
|
||||||
|
-- Naming attributes of type X520OrganizationName
|
||||||
|
|
||||||
|
id-at-organizationName AttributeType ::= { id-at 10 }
|
||||||
|
|
||||||
|
X520OrganizationName ::= CHOICE {
|
||||||
|
teletexString TeletexString
|
||||||
|
(SIZE (1..ub-organization-name)),
|
||||||
|
printableString PrintableString
|
||||||
|
(SIZE (1..ub-organization-name)),
|
||||||
|
universalString UniversalString
|
||||||
|
(SIZE (1..ub-organization-name)),
|
||||||
|
utf8String UTF8String
|
||||||
|
(SIZE (1..ub-organization-name)),
|
||||||
|
bmpString BMPString
|
||||||
|
(SIZE (1..ub-organization-name)) }
|
||||||
|
|
||||||
|
-- Naming attributes of type X520OrganizationalUnitName
|
||||||
|
|
||||||
|
id-at-organizationalUnitName AttributeType ::= { id-at 11 }
|
||||||
|
|
||||||
|
X520OrganizationalUnitName ::= CHOICE {
|
||||||
|
teletexString TeletexString
|
||||||
|
(SIZE (1..ub-organizational-unit-name)),
|
||||||
|
printableString PrintableString
|
||||||
|
(SIZE (1..ub-organizational-unit-name)),
|
||||||
|
universalString UniversalString
|
||||||
|
(SIZE (1..ub-organizational-unit-name)),
|
||||||
|
utf8String UTF8String
|
||||||
|
(SIZE (1..ub-organizational-unit-name)),
|
||||||
|
bmpString BMPString
|
||||||
|
(SIZE (1..ub-organizational-unit-name)) }
|
||||||
|
|
||||||
|
-- Naming attributes of type X520Title
|
||||||
|
|
||||||
|
id-at-title AttributeType ::= { id-at 12 }
|
||||||
|
|
||||||
|
X520Title ::= CHOICE {
|
||||||
|
teletexString TeletexString (SIZE (1..ub-title)),
|
||||||
|
printableString PrintableString (SIZE (1..ub-title)),
|
||||||
|
universalString UniversalString (SIZE (1..ub-title)),
|
||||||
|
utf8String UTF8String (SIZE (1..ub-title)),
|
||||||
|
bmpString BMPString (SIZE (1..ub-title)) }
|
||||||
|
|
||||||
|
-- Naming attributes of type X520dnQualifier
|
||||||
|
|
||||||
|
id-at-dnQualifier AttributeType ::= { id-at 46 }
|
||||||
|
|
||||||
|
X520dnQualifier ::= PrintableString
|
||||||
|
|
||||||
|
-- Naming attributes of type X520countryName (digraph from IS 3166)
|
||||||
|
|
||||||
|
id-at-countryName AttributeType ::= { id-at 6 }
|
||||||
|
|
||||||
|
X520countryName ::= PrintableString (SIZE (2))
|
||||||
|
|
||||||
|
-- Naming attributes of type X520SerialNumber
|
||||||
|
|
||||||
|
id-at-serialNumber AttributeType ::= { id-at 5 }
|
||||||
|
|
||||||
|
X520SerialNumber ::= PrintableString (SIZE (1..ub-serial-number))
|
||||||
|
|
||||||
|
-- Naming attributes of type X520Pseudonym
|
||||||
|
|
||||||
|
id-at-pseudonym AttributeType ::= { id-at 65 }
|
||||||
|
|
||||||
|
X520Pseudonym ::= CHOICE {
|
||||||
|
teletexString TeletexString (SIZE (1..ub-pseudonym)),
|
||||||
|
printableString PrintableString (SIZE (1..ub-pseudonym)),
|
||||||
|
universalString UniversalString (SIZE (1..ub-pseudonym)),
|
||||||
|
utf8String UTF8String (SIZE (1..ub-pseudonym)),
|
||||||
|
bmpString BMPString (SIZE (1..ub-pseudonym)) }
|
||||||
|
|
||||||
|
-- Naming attributes of type DomainComponent (from RFC 2247)
|
||||||
|
|
||||||
|
id-domainComponent AttributeType ::=
|
||||||
|
{ 0 9 2342 19200300 100 1 25 }
|
||||||
|
|
||||||
|
DomainComponent ::= IA5String
|
||||||
|
|
||||||
|
-- Legacy attributes
|
||||||
|
|
||||||
|
pkcs-9 OBJECT IDENTIFIER ::=
|
||||||
|
{ iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 9 }
|
||||||
|
|
||||||
|
id-emailAddress AttributeType ::= { pkcs-9 1 }
|
||||||
|
|
||||||
|
EmailAddress ::= IA5String (SIZE (1..ub-emailaddress-length))
|
||||||
|
|
||||||
|
-- naming data types --
|
||||||
|
|
||||||
|
Name ::= CHOICE { -- only one possibility for now --
|
||||||
|
rdnSequence RDNSequence }
|
||||||
|
|
||||||
|
RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
|
||||||
|
|
||||||
|
DistinguishedName ::= RDNSequence
|
||||||
|
|
||||||
|
RelativeDistinguishedName ::=
|
||||||
|
SET SIZE (1 .. MAX) OF AttributeTypeAndValue
|
||||||
|
|
||||||
|
-- Directory string type --
|
||||||
|
|
||||||
|
DirectoryString ::= CHOICE {
|
||||||
|
teletexString TeletexString (SIZE (1..MAX)),
|
||||||
|
printableString PrintableString (SIZE (1..MAX)),
|
||||||
|
universalString UniversalString (SIZE (1..MAX)),
|
||||||
|
utf8String UTF8String (SIZE (1..MAX)),
|
||||||
|
bmpString BMPString (SIZE (1..MAX)) }
|
||||||
|
|
||||||
|
-- certificate and CRL specific structures begin here
|
||||||
|
|
||||||
|
Certificate ::= SEQUENCE {
|
||||||
|
tbsCertificate TBSCertificate,
|
||||||
|
signatureAlgorithm AlgorithmIdentifier,
|
||||||
|
signature BIT STRING }
|
||||||
|
|
||||||
|
TBSCertificate ::= SEQUENCE {
|
||||||
|
version [0] Version DEFAULT v1,
|
||||||
|
serialNumber CertificateSerialNumber,
|
||||||
|
signature AlgorithmIdentifier,
|
||||||
|
issuer Name,
|
||||||
|
validity Validity,
|
||||||
|
subject Name,
|
||||||
|
subjectPublicKeyInfo SubjectPublicKeyInfo,
|
||||||
|
issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
|
||||||
|
-- If present, version MUST be v2 or v3
|
||||||
|
subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
|
||||||
|
-- If present, version MUST be v2 or v3
|
||||||
|
extensions [3] Extensions OPTIONAL
|
||||||
|
-- If present, version MUST be v3 -- }
|
||||||
|
|
||||||
|
Version ::= INTEGER { v1(0), v2(1), v3(2) }
|
||||||
|
|
||||||
|
CertificateSerialNumber ::= INTEGER
|
||||||
|
|
||||||
|
Validity ::= SEQUENCE {
|
||||||
|
notBefore Time,
|
||||||
|
notAfter Time }
|
||||||
|
|
||||||
|
Time ::= CHOICE {
|
||||||
|
utcTime UTCTime,
|
||||||
|
generalTime GeneralizedTime }
|
||||||
|
|
||||||
|
UniqueIdentifier ::= BIT STRING
|
||||||
|
|
||||||
|
SubjectPublicKeyInfo ::= SEQUENCE {
|
||||||
|
algorithm AlgorithmIdentifier,
|
||||||
|
subjectPublicKey BIT STRING }
|
||||||
|
|
||||||
|
Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
|
||||||
|
|
||||||
|
Extension ::= SEQUENCE {
|
||||||
|
extnID OBJECT IDENTIFIER,
|
||||||
|
critical BOOLEAN DEFAULT FALSE,
|
||||||
|
extnValue OCTET STRING }
|
||||||
|
|
||||||
|
-- CRL structures
|
||||||
|
|
||||||
|
CertificateList ::= SEQUENCE {
|
||||||
|
tbsCertList TBSCertList,
|
||||||
|
signatureAlgorithm AlgorithmIdentifier,
|
||||||
|
signature BIT STRING }
|
||||||
|
|
||||||
|
TBSCertList ::= SEQUENCE {
|
||||||
|
version Version OPTIONAL,
|
||||||
|
-- if present, MUST be v2
|
||||||
|
signature AlgorithmIdentifier,
|
||||||
|
issuer Name,
|
||||||
|
thisUpdate Time,
|
||||||
|
nextUpdate Time OPTIONAL,
|
||||||
|
revokedCertificates SEQUENCE OF SEQUENCE {
|
||||||
|
userCertificate CertificateSerialNumber,
|
||||||
|
revocationDate Time,
|
||||||
|
crlEntryExtensions Extensions OPTIONAL
|
||||||
|
-- if present, MUST be v2
|
||||||
|
} OPTIONAL,
|
||||||
|
crlExtensions [0] Extensions OPTIONAL }
|
||||||
|
-- if present, MUST be v2
|
||||||
|
|
||||||
|
-- Version, Time, CertificateSerialNumber, and Extensions were
|
||||||
|
-- defined earlier for use in the certificate structure
|
||||||
|
|
||||||
|
AlgorithmIdentifier ::= SEQUENCE {
|
||||||
|
algorithm OBJECT IDENTIFIER,
|
||||||
|
parameters ANY DEFINED BY algorithm OPTIONAL }
|
||||||
|
-- contains a value of the type
|
||||||
|
-- registered for use with the
|
||||||
|
-- algorithm object identifier value
|
||||||
|
|
||||||
|
-- X.400 address syntax starts here
|
||||||
|
|
||||||
|
ORAddress ::= SEQUENCE {
|
||||||
|
built-in-standard-attributes BuiltInStandardAttributes,
|
||||||
|
built-in-domain-defined-attributes
|
||||||
|
BuiltInDomainDefinedAttributes OPTIONAL,
|
||||||
|
-- see also teletex-domain-defined-attributes
|
||||||
|
extension-attributes ExtensionAttributes OPTIONAL }
|
||||||
|
|
||||||
|
-- Built-in Standard Attributes
|
||||||
|
|
||||||
|
BuiltInStandardAttributes ::= SEQUENCE {
|
||||||
|
country-name CountryName OPTIONAL,
|
||||||
|
administration-domain-name AdministrationDomainName OPTIONAL,
|
||||||
|
network-address [0] IMPLICIT NetworkAddress OPTIONAL,
|
||||||
|
-- see also extended-network-address
|
||||||
|
terminal-identifier [1] IMPLICIT TerminalIdentifier OPTIONAL,
|
||||||
|
private-domain-name [2] PrivateDomainName OPTIONAL,
|
||||||
|
organization-name [3] IMPLICIT OrganizationName OPTIONAL,
|
||||||
|
-- see also teletex-organization-name
|
||||||
|
numeric-user-identifier [4] IMPLICIT NumericUserIdentifier
|
||||||
|
OPTIONAL,
|
||||||
|
personal-name [5] IMPLICIT PersonalName OPTIONAL,
|
||||||
|
-- see also teletex-personal-name
|
||||||
|
organizational-unit-names [6] IMPLICIT OrganizationalUnitNames
|
||||||
|
OPTIONAL }
|
||||||
|
-- see also teletex-organizational-unit-names
|
||||||
|
|
||||||
|
CountryName ::= [APPLICATION 1] CHOICE {
|
||||||
|
x121-dcc-code NumericString
|
||||||
|
(SIZE (ub-country-name-numeric-length)),
|
||||||
|
iso-3166-alpha2-code PrintableString
|
||||||
|
(SIZE (ub-country-name-alpha-length)) }
|
||||||
|
|
||||||
|
AdministrationDomainName ::= [APPLICATION 2] CHOICE {
|
||||||
|
numeric NumericString (SIZE (0..ub-domain-name-length)),
|
||||||
|
printable PrintableString (SIZE (0..ub-domain-name-length)) }
|
||||||
|
|
||||||
|
NetworkAddress ::= X121Address -- see also extended-network-address
|
||||||
|
|
||||||
|
X121Address ::= NumericString (SIZE (1..ub-x121-address-length))
|
||||||
|
|
||||||
|
TerminalIdentifier ::= PrintableString (SIZE
|
||||||
|
(1..ub-terminal-id-length))
|
||||||
|
|
||||||
|
PrivateDomainName ::= CHOICE {
|
||||||
|
numeric NumericString (SIZE (1..ub-domain-name-length)),
|
||||||
|
printable PrintableString (SIZE (1..ub-domain-name-length)) }
|
||||||
|
|
||||||
|
OrganizationName ::= PrintableString
|
||||||
|
(SIZE (1..ub-organization-name-length))
|
||||||
|
-- see also teletex-organization-name
|
||||||
|
|
||||||
|
NumericUserIdentifier ::= NumericString
|
||||||
|
(SIZE (1..ub-numeric-user-id-length))
|
||||||
|
|
||||||
|
PersonalName ::= SET {
|
||||||
|
surname [0] IMPLICIT PrintableString
|
||||||
|
(SIZE (1..ub-surname-length)),
|
||||||
|
given-name [1] IMPLICIT PrintableString
|
||||||
|
(SIZE (1..ub-given-name-length)) OPTIONAL,
|
||||||
|
initials [2] IMPLICIT PrintableString
|
||||||
|
(SIZE (1..ub-initials-length)) OPTIONAL,
|
||||||
|
generation-qualifier [3] IMPLICIT PrintableString
|
||||||
|
(SIZE (1..ub-generation-qualifier-length))
|
||||||
|
OPTIONAL }
|
||||||
|
-- see also teletex-personal-name
|
||||||
|
|
||||||
|
OrganizationalUnitNames ::= SEQUENCE SIZE (1..ub-organizational-units)
|
||||||
|
OF OrganizationalUnitName
|
||||||
|
-- see also teletex-organizational-unit-names
|
||||||
|
|
||||||
|
OrganizationalUnitName ::= PrintableString (SIZE
|
||||||
|
(1..ub-organizational-unit-name-length))
|
||||||
|
|
||||||
|
-- Built-in Domain-defined Attributes
|
||||||
|
|
||||||
|
BuiltInDomainDefinedAttributes ::= SEQUENCE SIZE
|
||||||
|
(1..ub-domain-defined-attributes) OF
|
||||||
|
BuiltInDomainDefinedAttribute
|
||||||
|
|
||||||
|
BuiltInDomainDefinedAttribute ::= SEQUENCE {
|
||||||
|
type PrintableString (SIZE
|
||||||
|
(1..ub-domain-defined-attribute-type-length)),
|
||||||
|
value PrintableString (SIZE
|
||||||
|
(1..ub-domain-defined-attribute-value-length)) }
|
||||||
|
|
||||||
|
-- Extension Attributes
|
||||||
|
|
||||||
|
ExtensionAttributes ::= SET SIZE (1..ub-extension-attributes) OF
|
||||||
|
ExtensionAttribute
|
||||||
|
|
||||||
|
ExtensionAttribute ::= SEQUENCE {
|
||||||
|
extension-attribute-type [0] IMPLICIT INTEGER
|
||||||
|
(0..ub-extension-attributes),
|
||||||
|
extension-attribute-value [1]
|
||||||
|
ANY DEFINED BY extension-attribute-type }
|
||||||
|
|
||||||
|
-- Extension types and attribute values
|
||||||
|
|
||||||
|
common-name INTEGER ::= 1
|
||||||
|
|
||||||
|
CommonName ::= PrintableString (SIZE (1..ub-common-name-length))
|
||||||
|
|
||||||
|
teletex-common-name INTEGER ::= 2
|
||||||
|
|
||||||
|
TeletexCommonName ::= TeletexString (SIZE (1..ub-common-name-length))
|
||||||
|
|
||||||
|
teletex-organization-name INTEGER ::= 3
|
||||||
|
|
||||||
|
TeletexOrganizationName ::=
|
||||||
|
TeletexString (SIZE (1..ub-organization-name-length))
|
||||||
|
|
||||||
|
teletex-personal-name INTEGER ::= 4
|
||||||
|
|
||||||
|
TeletexPersonalName ::= SET {
|
||||||
|
surname [0] IMPLICIT TeletexString
|
||||||
|
(SIZE (1..ub-surname-length)),
|
||||||
|
given-name [1] IMPLICIT TeletexString
|
||||||
|
(SIZE (1..ub-given-name-length)) OPTIONAL,
|
||||||
|
initials [2] IMPLICIT TeletexString
|
||||||
|
(SIZE (1..ub-initials-length)) OPTIONAL,
|
||||||
|
generation-qualifier [3] IMPLICIT TeletexString
|
||||||
|
(SIZE (1..ub-generation-qualifier-length))
|
||||||
|
OPTIONAL }
|
||||||
|
|
||||||
|
teletex-organizational-unit-names INTEGER ::= 5
|
||||||
|
|
||||||
|
TeletexOrganizationalUnitNames ::= SEQUENCE SIZE
|
||||||
|
(1..ub-organizational-units) OF TeletexOrganizationalUnitName
|
||||||
|
|
||||||
|
TeletexOrganizationalUnitName ::= TeletexString
|
||||||
|
(SIZE (1..ub-organizational-unit-name-length))
|
||||||
|
|
||||||
|
pds-name INTEGER ::= 7
|
||||||
|
|
||||||
|
PDSName ::= PrintableString (SIZE (1..ub-pds-name-length))
|
||||||
|
|
||||||
|
physical-delivery-country-name INTEGER ::= 8
|
||||||
|
|
||||||
|
PhysicalDeliveryCountryName ::= CHOICE {
|
||||||
|
x121-dcc-code NumericString (SIZE
|
||||||
|
(ub-country-name-numeric-length)),
|
||||||
|
iso-3166-alpha2-code PrintableString
|
||||||
|
(SIZE (ub-country-name-alpha-length)) }
|
||||||
|
|
||||||
|
postal-code INTEGER ::= 9
|
||||||
|
|
||||||
|
PostalCode ::= CHOICE {
|
||||||
|
numeric-code NumericString (SIZE (1..ub-postal-code-length)),
|
||||||
|
printable-code PrintableString (SIZE (1..ub-postal-code-length)) }
|
||||||
|
|
||||||
|
physical-delivery-office-name INTEGER ::= 10
|
||||||
|
|
||||||
|
PhysicalDeliveryOfficeName ::= PDSParameter
|
||||||
|
|
||||||
|
physical-delivery-office-number INTEGER ::= 11
|
||||||
|
|
||||||
|
PhysicalDeliveryOfficeNumber ::= PDSParameter
|
||||||
|
|
||||||
|
extension-OR-address-components INTEGER ::= 12
|
||||||
|
|
||||||
|
ExtensionORAddressComponents ::= PDSParameter
|
||||||
|
|
||||||
|
physical-delivery-personal-name INTEGER ::= 13
|
||||||
|
|
||||||
|
PhysicalDeliveryPersonalName ::= PDSParameter
|
||||||
|
|
||||||
|
physical-delivery-organization-name INTEGER ::= 14
|
||||||
|
|
||||||
|
PhysicalDeliveryOrganizationName ::= PDSParameter
|
||||||
|
|
||||||
|
extension-physical-delivery-address-components INTEGER ::= 15
|
||||||
|
|
||||||
|
ExtensionPhysicalDeliveryAddressComponents ::= PDSParameter
|
||||||
|
|
||||||
|
unformatted-postal-address INTEGER ::= 16
|
||||||
|
|
||||||
|
UnformattedPostalAddress ::= SET {
|
||||||
|
printable-address SEQUENCE SIZE (1..ub-pds-physical-address-lines)
|
||||||
|
OF PrintableString (SIZE (1..ub-pds-parameter-length))
|
||||||
|
OPTIONAL,
|
||||||
|
teletex-string TeletexString
|
||||||
|
(SIZE (1..ub-unformatted-address-length)) OPTIONAL }
|
||||||
|
|
||||||
|
street-address INTEGER ::= 17
|
||||||
|
|
||||||
|
StreetAddress ::= PDSParameter
|
||||||
|
|
||||||
|
post-office-box-address INTEGER ::= 18
|
||||||
|
|
||||||
|
PostOfficeBoxAddress ::= PDSParameter
|
||||||
|
|
||||||
|
poste-restante-address INTEGER ::= 19
|
||||||
|
|
||||||
|
PosteRestanteAddress ::= PDSParameter
|
||||||
|
|
||||||
|
unique-postal-name INTEGER ::= 20
|
||||||
|
|
||||||
|
UniquePostalName ::= PDSParameter
|
||||||
|
|
||||||
|
local-postal-attributes INTEGER ::= 21
|
||||||
|
|
||||||
|
LocalPostalAttributes ::= PDSParameter
|
||||||
|
|
||||||
|
PDSParameter ::= SET {
|
||||||
|
printable-string PrintableString
|
||||||
|
(SIZE(1..ub-pds-parameter-length)) OPTIONAL,
|
||||||
|
teletex-string TeletexString
|
||||||
|
(SIZE(1..ub-pds-parameter-length)) OPTIONAL }
|
||||||
|
|
||||||
|
extended-network-address INTEGER ::= 22
|
||||||
|
|
||||||
|
ExtendedNetworkAddress ::= CHOICE {
|
||||||
|
e163-4-address SEQUENCE {
|
||||||
|
number [0] IMPLICIT NumericString
|
||||||
|
(SIZE (1..ub-e163-4-number-length)),
|
||||||
|
sub-address [1] IMPLICIT NumericString
|
||||||
|
(SIZE (1..ub-e163-4-sub-address-length))
|
||||||
|
OPTIONAL },
|
||||||
|
psap-address [0] IMPLICIT PresentationAddress }
|
||||||
|
|
||||||
|
PresentationAddress ::= SEQUENCE {
|
||||||
|
pSelector [0] EXPLICIT OCTET STRING OPTIONAL,
|
||||||
|
sSelector [1] EXPLICIT OCTET STRING OPTIONAL,
|
||||||
|
tSelector [2] EXPLICIT OCTET STRING OPTIONAL,
|
||||||
|
nAddresses [3] EXPLICIT SET SIZE (1..MAX) OF OCTET STRING }
|
||||||
|
|
||||||
|
terminal-type INTEGER ::= 23
|
||||||
|
|
||||||
|
TerminalType ::= INTEGER {
|
||||||
|
telex (3),
|
||||||
|
teletex (4),
|
||||||
|
g3-facsimile (5),
|
||||||
|
g4-facsimile (6),
|
||||||
|
ia5-terminal (7),
|
||||||
|
videotex (8) }
|
||||||
|
|
||||||
|
-- Extension Domain-defined Attributes
|
||||||
|
|
||||||
|
teletex-domain-defined-attributes INTEGER ::= 6
|
||||||
|
|
||||||
|
TeletexDomainDefinedAttributes ::= SEQUENCE SIZE
|
||||||
|
(1..ub-domain-defined-attributes) OF TeletexDomainDefinedAttribute
|
||||||
|
|
||||||
|
TeletexDomainDefinedAttribute ::= SEQUENCE {
|
||||||
|
type TeletexString
|
||||||
|
(SIZE (1..ub-domain-defined-attribute-type-length)),
|
||||||
|
value TeletexString
|
||||||
|
(SIZE (1..ub-domain-defined-attribute-value-length)) }
|
||||||
|
|
||||||
|
-- specifications of Upper Bounds MUST be regarded as mandatory
|
||||||
|
-- from Annex B of ITU-T X.411 Reference Definition of MTS Parameter
|
||||||
|
-- Upper Bounds
|
||||||
|
|
||||||
|
-- Upper Bounds
|
||||||
|
ub-name INTEGER ::= 32768
|
||||||
|
ub-common-name INTEGER ::= 64
|
||||||
|
ub-locality-name INTEGER ::= 128
|
||||||
|
ub-state-name INTEGER ::= 128
|
||||||
|
ub-organization-name INTEGER ::= 64
|
||||||
|
ub-organizational-unit-name INTEGER ::= 64
|
||||||
|
ub-title INTEGER ::= 64
|
||||||
|
ub-serial-number INTEGER ::= 64
|
||||||
|
ub-match INTEGER ::= 128
|
||||||
|
ub-emailaddress-length INTEGER ::= 255
|
||||||
|
ub-common-name-length INTEGER ::= 64
|
||||||
|
ub-country-name-alpha-length INTEGER ::= 2
|
||||||
|
ub-country-name-numeric-length INTEGER ::= 3
|
||||||
|
ub-domain-defined-attributes INTEGER ::= 4
|
||||||
|
ub-domain-defined-attribute-type-length INTEGER ::= 8
|
||||||
|
ub-domain-defined-attribute-value-length INTEGER ::= 128
|
||||||
|
ub-domain-name-length INTEGER ::= 16
|
||||||
|
ub-extension-attributes INTEGER ::= 256
|
||||||
|
ub-e163-4-number-length INTEGER ::= 15
|
||||||
|
ub-e163-4-sub-address-length INTEGER ::= 40
|
||||||
|
ub-generation-qualifier-length INTEGER ::= 3
|
||||||
|
ub-given-name-length INTEGER ::= 16
|
||||||
|
ub-initials-length INTEGER ::= 5
|
||||||
|
ub-integer-options INTEGER ::= 256
|
||||||
|
ub-numeric-user-id-length INTEGER ::= 32
|
||||||
|
ub-organization-name-length INTEGER ::= 64
|
||||||
|
ub-organizational-unit-name-length INTEGER ::= 32
|
||||||
|
ub-organizational-units INTEGER ::= 4
|
||||||
|
ub-pds-name-length INTEGER ::= 16
|
||||||
|
ub-pds-parameter-length INTEGER ::= 30
|
||||||
|
ub-pds-physical-address-lines INTEGER ::= 6
|
||||||
|
ub-postal-code-length INTEGER ::= 16
|
||||||
|
ub-pseudonym INTEGER ::= 128
|
||||||
|
ub-surname-length INTEGER ::= 40
|
||||||
|
ub-terminal-id-length INTEGER ::= 24
|
||||||
|
ub-unformatted-address-length INTEGER ::= 180
|
||||||
|
ub-x121-address-length INTEGER ::= 16
|
||||||
|
|
||||||
|
-- Note - upper bounds on string types, such as TeletexString, are
|
||||||
|
-- measured in characters. Excepting PrintableString or IA5String, a
|
||||||
|
-- significantly greater number of octets will be required to hold
|
||||||
|
-- such a value. As a minimum, 16 octets, or twice the specified
|
||||||
|
-- upper bound, whichever is the larger, should be allowed for
|
||||||
|
-- TeletexString. For UTF8String or UniversalString at least four
|
||||||
|
-- times the upper bound should be allowed.
|
||||||
|
|
||||||
|
END
|
|
@ -0,0 +1,387 @@
|
||||||
|
|
||||||
|
--
|
||||||
|
-- ASN.1 module found by ./crfc2asn1.pl in rfc3280.txt at line 5850
|
||||||
|
--
|
||||||
|
|
||||||
|
PKIX1Implicit88 { iso(1) identified-organization(3) dod(6) internet(1)
|
||||||
|
security(5) mechanisms(5) pkix(7) id-mod(0) id-pkix1-implicit(19) }
|
||||||
|
|
||||||
|
DEFINITIONS IMPLICIT TAGS ::=
|
||||||
|
|
||||||
|
BEGIN
|
||||||
|
|
||||||
|
-- EXPORTS ALL --
|
||||||
|
|
||||||
|
IMPORTS
|
||||||
|
id-pe, id-kp, id-qt-unotice, id-qt-cps,
|
||||||
|
ORAddress, Name, RelativeDistinguishedName,
|
||||||
|
CertificateSerialNumber, Attribute, DirectoryString
|
||||||
|
FROM PKIX1Explicit88 { iso(1) identified-organization(3)
|
||||||
|
dod(6) internet(1) security(5) mechanisms(5) pkix(7)
|
||||||
|
id-mod(0) id-pkix1-explicit(18) };
|
||||||
|
|
||||||
|
|
||||||
|
-- ISO arc for standard certificate and CRL extensions
|
||||||
|
|
||||||
|
id-ce OBJECT IDENTIFIER ::= {joint-iso-ccitt(2) ds(5) 29}
|
||||||
|
|
||||||
|
-- authority key identifier OID and syntax
|
||||||
|
|
||||||
|
id-ce-authorityKeyIdentifier OBJECT IDENTIFIER ::= { id-ce 35 }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AuthorityKeyIdentifier ::= SEQUENCE {
|
||||||
|
keyIdentifier [0] KeyIdentifier OPTIONAL,
|
||||||
|
authorityCertIssuer [1] GeneralNames OPTIONAL,
|
||||||
|
authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL }
|
||||||
|
-- authorityCertIssuer and authorityCertSerialNumber MUST both
|
||||||
|
-- be present or both be absent
|
||||||
|
|
||||||
|
KeyIdentifier ::= OCTET STRING
|
||||||
|
|
||||||
|
-- subject key identifier OID and syntax
|
||||||
|
|
||||||
|
id-ce-subjectKeyIdentifier OBJECT IDENTIFIER ::= { id-ce 14 }
|
||||||
|
|
||||||
|
SubjectKeyIdentifier ::= KeyIdentifier
|
||||||
|
|
||||||
|
-- key usage extension OID and syntax
|
||||||
|
|
||||||
|
id-ce-keyUsage OBJECT IDENTIFIER ::= { id-ce 15 }
|
||||||
|
|
||||||
|
KeyUsage ::= BIT STRING {
|
||||||
|
digitalSignature (0),
|
||||||
|
nonRepudiation (1),
|
||||||
|
keyEncipherment (2),
|
||||||
|
dataEncipherment (3),
|
||||||
|
keyAgreement (4),
|
||||||
|
keyCertSign (5),
|
||||||
|
cRLSign (6),
|
||||||
|
encipherOnly (7),
|
||||||
|
decipherOnly (8) }
|
||||||
|
|
||||||
|
-- private key usage period extension OID and syntax
|
||||||
|
|
||||||
|
id-ce-privateKeyUsagePeriod OBJECT IDENTIFIER ::= { id-ce 16 }
|
||||||
|
|
||||||
|
PrivateKeyUsagePeriod ::= SEQUENCE {
|
||||||
|
notBefore [0] GeneralizedTime OPTIONAL,
|
||||||
|
notAfter [1] GeneralizedTime OPTIONAL }
|
||||||
|
-- either notBefore or notAfter MUST be present
|
||||||
|
|
||||||
|
-- certificate policies extension OID and syntax
|
||||||
|
|
||||||
|
id-ce-certificatePolicies OBJECT IDENTIFIER ::= { id-ce 32 }
|
||||||
|
|
||||||
|
anyPolicy OBJECT IDENTIFIER ::= { id-ce-certificatePolicies 0 }
|
||||||
|
|
||||||
|
CertificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation
|
||||||
|
|
||||||
|
PolicyInformation ::= SEQUENCE {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
policyIdentifier CertPolicyId,
|
||||||
|
policyQualifiers SEQUENCE SIZE (1..MAX) OF
|
||||||
|
PolicyQualifierInfo OPTIONAL }
|
||||||
|
|
||||||
|
CertPolicyId ::= OBJECT IDENTIFIER
|
||||||
|
|
||||||
|
PolicyQualifierInfo ::= SEQUENCE {
|
||||||
|
policyQualifierId PolicyQualifierId,
|
||||||
|
qualifier ANY DEFINED BY policyQualifierId }
|
||||||
|
|
||||||
|
-- Implementations that recognize additional policy qualifiers MUST
|
||||||
|
-- augment the following definition for PolicyQualifierId
|
||||||
|
|
||||||
|
PolicyQualifierId ::=
|
||||||
|
OBJECT IDENTIFIER -- ( id-qt-cps | id-qt-unotice )
|
||||||
|
|
||||||
|
-- CPS pointer qualifier
|
||||||
|
|
||||||
|
CPSuri ::= IA5String
|
||||||
|
|
||||||
|
-- user notice qualifier
|
||||||
|
|
||||||
|
UserNotice ::= SEQUENCE {
|
||||||
|
noticeRef NoticeReference OPTIONAL,
|
||||||
|
explicitText DisplayText OPTIONAL}
|
||||||
|
|
||||||
|
NoticeReference ::= SEQUENCE {
|
||||||
|
organization DisplayText,
|
||||||
|
noticeNumbers SEQUENCE OF INTEGER }
|
||||||
|
|
||||||
|
DisplayText ::= CHOICE {
|
||||||
|
ia5String IA5String (SIZE (1..200)),
|
||||||
|
visibleString VisibleString (SIZE (1..200)),
|
||||||
|
bmpString BMPString (SIZE (1..200)),
|
||||||
|
utf8String UTF8String (SIZE (1..200)) }
|
||||||
|
|
||||||
|
-- policy mapping extension OID and syntax
|
||||||
|
|
||||||
|
id-ce-policyMappings OBJECT IDENTIFIER ::= { id-ce 33 }
|
||||||
|
|
||||||
|
PolicyMappings ::= SEQUENCE SIZE (1..MAX) OF SEQUENCE {
|
||||||
|
issuerDomainPolicy CertPolicyId,
|
||||||
|
subjectDomainPolicy CertPolicyId }
|
||||||
|
|
||||||
|
-- subject alternative name extension OID and syntax
|
||||||
|
|
||||||
|
id-ce-subjectAltName OBJECT IDENTIFIER ::= { id-ce 17 }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
SubjectAltName ::= GeneralNames
|
||||||
|
|
||||||
|
GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
|
||||||
|
|
||||||
|
GeneralName ::= CHOICE {
|
||||||
|
otherName [0] AnotherName,
|
||||||
|
rfc822Name [1] IA5String,
|
||||||
|
dNSName [2] IA5String,
|
||||||
|
x400Address [3] ORAddress,
|
||||||
|
directoryName [4] Name,
|
||||||
|
ediPartyName [5] EDIPartyName,
|
||||||
|
uniformResourceIdentifier [6] IA5String,
|
||||||
|
iPAddress [7] OCTET STRING,
|
||||||
|
registeredID [8] OBJECT IDENTIFIER }
|
||||||
|
|
||||||
|
-- AnotherName replaces OTHER-NAME ::= TYPE-IDENTIFIER, as
|
||||||
|
-- TYPE-IDENTIFIER is not supported in the '88 ASN.1 syntax
|
||||||
|
|
||||||
|
AnotherName ::= SEQUENCE {
|
||||||
|
type-id OBJECT IDENTIFIER,
|
||||||
|
value [0] EXPLICIT ANY DEFINED BY type-id }
|
||||||
|
|
||||||
|
EDIPartyName ::= SEQUENCE {
|
||||||
|
nameAssigner [0] DirectoryString OPTIONAL,
|
||||||
|
partyName [1] DirectoryString }
|
||||||
|
|
||||||
|
-- issuer alternative name extension OID and syntax
|
||||||
|
|
||||||
|
id-ce-issuerAltName OBJECT IDENTIFIER ::= { id-ce 18 }
|
||||||
|
|
||||||
|
IssuerAltName ::= GeneralNames
|
||||||
|
|
||||||
|
id-ce-subjectDirectoryAttributes OBJECT IDENTIFIER ::= { id-ce 9 }
|
||||||
|
|
||||||
|
SubjectDirectoryAttributes ::= SEQUENCE SIZE (1..MAX) OF Attribute
|
||||||
|
|
||||||
|
-- basic constraints extension OID and syntax
|
||||||
|
|
||||||
|
id-ce-basicConstraints OBJECT IDENTIFIER ::= { id-ce 19 }
|
||||||
|
|
||||||
|
BasicConstraints ::= SEQUENCE {
|
||||||
|
cA BOOLEAN DEFAULT FALSE,
|
||||||
|
pathLenConstraint INTEGER (0..MAX) OPTIONAL }
|
||||||
|
|
||||||
|
-- name constraints extension OID and syntax
|
||||||
|
|
||||||
|
id-ce-nameConstraints OBJECT IDENTIFIER ::= { id-ce 30 }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
NameConstraints ::= SEQUENCE {
|
||||||
|
permittedSubtrees [0] GeneralSubtrees OPTIONAL,
|
||||||
|
excludedSubtrees [1] GeneralSubtrees OPTIONAL }
|
||||||
|
|
||||||
|
GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree
|
||||||
|
|
||||||
|
GeneralSubtree ::= SEQUENCE {
|
||||||
|
base GeneralName,
|
||||||
|
minimum [0] BaseDistance DEFAULT 0,
|
||||||
|
maximum [1] BaseDistance OPTIONAL }
|
||||||
|
|
||||||
|
BaseDistance ::= INTEGER (0..MAX)
|
||||||
|
|
||||||
|
-- policy constraints extension OID and syntax
|
||||||
|
|
||||||
|
id-ce-policyConstraints OBJECT IDENTIFIER ::= { id-ce 36 }
|
||||||
|
|
||||||
|
PolicyConstraints ::= SEQUENCE {
|
||||||
|
requireExplicitPolicy [0] SkipCerts OPTIONAL,
|
||||||
|
inhibitPolicyMapping [1] SkipCerts OPTIONAL }
|
||||||
|
|
||||||
|
SkipCerts ::= INTEGER (0..MAX)
|
||||||
|
|
||||||
|
-- CRL distribution points extension OID and syntax
|
||||||
|
|
||||||
|
id-ce-cRLDistributionPoints OBJECT IDENTIFIER ::= {id-ce 31}
|
||||||
|
|
||||||
|
CRLDistributionPoints ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint
|
||||||
|
|
||||||
|
DistributionPoint ::= SEQUENCE {
|
||||||
|
distributionPoint [0] DistributionPointName OPTIONAL,
|
||||||
|
reasons [1] ReasonFlags OPTIONAL,
|
||||||
|
cRLIssuer [2] GeneralNames OPTIONAL }
|
||||||
|
|
||||||
|
DistributionPointName ::= CHOICE {
|
||||||
|
fullName [0] GeneralNames,
|
||||||
|
nameRelativeToCRLIssuer [1] RelativeDistinguishedName }
|
||||||
|
|
||||||
|
ReasonFlags ::= BIT STRING {
|
||||||
|
unused (0),
|
||||||
|
keyCompromise (1),
|
||||||
|
cACompromise (2),
|
||||||
|
affiliationChanged (3),
|
||||||
|
superseded (4),
|
||||||
|
cessationOfOperation (5),
|
||||||
|
certificateHold (6),
|
||||||
|
privilegeWithdrawn (7),
|
||||||
|
aACompromise (8) }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- extended key usage extension OID and syntax
|
||||||
|
|
||||||
|
id-ce-extKeyUsage OBJECT IDENTIFIER ::= {id-ce 37}
|
||||||
|
|
||||||
|
ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
|
||||||
|
|
||||||
|
|
||||||
|
KeyPurposeId ::= OBJECT IDENTIFIER
|
||||||
|
|
||||||
|
-- permit unspecified key uses
|
||||||
|
|
||||||
|
anyExtendedKeyUsage OBJECT IDENTIFIER ::= { id-ce-extKeyUsage 0 }
|
||||||
|
|
||||||
|
-- extended key purpose OIDs
|
||||||
|
|
||||||
|
id-kp-serverAuth OBJECT IDENTIFIER ::= { id-kp 1 }
|
||||||
|
id-kp-clientAuth OBJECT IDENTIFIER ::= { id-kp 2 }
|
||||||
|
id-kp-codeSigning OBJECT IDENTIFIER ::= { id-kp 3 }
|
||||||
|
id-kp-emailProtection OBJECT IDENTIFIER ::= { id-kp 4 }
|
||||||
|
id-kp-timeStamping OBJECT IDENTIFIER ::= { id-kp 8 }
|
||||||
|
id-kp-OCSPSigning OBJECT IDENTIFIER ::= { id-kp 9 }
|
||||||
|
|
||||||
|
-- inhibit any policy OID and syntax
|
||||||
|
|
||||||
|
id-ce-inhibitAnyPolicy OBJECT IDENTIFIER ::= { id-ce 54 }
|
||||||
|
|
||||||
|
InhibitAnyPolicy ::= SkipCerts
|
||||||
|
|
||||||
|
-- freshest (delta)CRL extension OID and syntax
|
||||||
|
|
||||||
|
id-ce-freshestCRL OBJECT IDENTIFIER ::= { id-ce 46 }
|
||||||
|
|
||||||
|
FreshestCRL ::= CRLDistributionPoints
|
||||||
|
|
||||||
|
-- authority info access
|
||||||
|
|
||||||
|
id-pe-authorityInfoAccess OBJECT IDENTIFIER ::= { id-pe 1 }
|
||||||
|
|
||||||
|
AuthorityInfoAccessSyntax ::=
|
||||||
|
SEQUENCE SIZE (1..MAX) OF AccessDescription
|
||||||
|
|
||||||
|
AccessDescription ::= SEQUENCE {
|
||||||
|
accessMethod OBJECT IDENTIFIER,
|
||||||
|
accessLocation GeneralName }
|
||||||
|
|
||||||
|
-- subject info access
|
||||||
|
|
||||||
|
id-pe-subjectInfoAccess OBJECT IDENTIFIER ::= { id-pe 11 }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
SubjectInfoAccessSyntax ::=
|
||||||
|
SEQUENCE SIZE (1..MAX) OF AccessDescription
|
||||||
|
|
||||||
|
-- CRL number extension OID and syntax
|
||||||
|
|
||||||
|
id-ce-cRLNumber OBJECT IDENTIFIER ::= { id-ce 20 }
|
||||||
|
|
||||||
|
CRLNumber ::= INTEGER (0..MAX)
|
||||||
|
|
||||||
|
-- issuing distribution point extension OID and syntax
|
||||||
|
|
||||||
|
id-ce-issuingDistributionPoint OBJECT IDENTIFIER ::= { id-ce 28 }
|
||||||
|
|
||||||
|
IssuingDistributionPoint ::= SEQUENCE {
|
||||||
|
distributionPoint [0] DistributionPointName OPTIONAL,
|
||||||
|
onlyContainsUserCerts [1] BOOLEAN DEFAULT FALSE,
|
||||||
|
onlyContainsCACerts [2] BOOLEAN DEFAULT FALSE,
|
||||||
|
onlySomeReasons [3] ReasonFlags OPTIONAL,
|
||||||
|
indirectCRL [4] BOOLEAN DEFAULT FALSE,
|
||||||
|
onlyContainsAttributeCerts [5] BOOLEAN DEFAULT FALSE }
|
||||||
|
|
||||||
|
id-ce-deltaCRLIndicator OBJECT IDENTIFIER ::= { id-ce 27 }
|
||||||
|
|
||||||
|
BaseCRLNumber ::= CRLNumber
|
||||||
|
|
||||||
|
-- CRL reasons extension OID and syntax
|
||||||
|
|
||||||
|
id-ce-cRLReasons OBJECT IDENTIFIER ::= { id-ce 21 }
|
||||||
|
|
||||||
|
CRLReason ::= ENUMERATED {
|
||||||
|
unspecified (0),
|
||||||
|
keyCompromise (1),
|
||||||
|
cACompromise (2),
|
||||||
|
affiliationChanged (3),
|
||||||
|
superseded (4),
|
||||||
|
cessationOfOperation (5),
|
||||||
|
certificateHold (6),
|
||||||
|
removeFromCRL (8),
|
||||||
|
privilegeWithdrawn (9),
|
||||||
|
aACompromise (10) }
|
||||||
|
|
||||||
|
-- certificate issuer CRL entry extension OID and syntax
|
||||||
|
|
||||||
|
id-ce-certificateIssuer OBJECT IDENTIFIER ::= { id-ce 29 }
|
||||||
|
|
||||||
|
CertificateIssuer ::= GeneralNames
|
||||||
|
|
||||||
|
-- hold instruction extension OID and syntax
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
id-ce-holdInstructionCode OBJECT IDENTIFIER ::= { id-ce 23 }
|
||||||
|
|
||||||
|
HoldInstructionCode ::= OBJECT IDENTIFIER
|
||||||
|
|
||||||
|
-- ANSI x9 holdinstructions
|
||||||
|
|
||||||
|
-- ANSI x9 arc holdinstruction arc
|
||||||
|
|
||||||
|
holdInstruction OBJECT IDENTIFIER ::=
|
||||||
|
{joint-iso-itu-t(2) member-body(2) us(840) x9cm(10040) 2}
|
||||||
|
|
||||||
|
-- ANSI X9 holdinstructions referenced by this standard
|
||||||
|
|
||||||
|
id-holdinstruction-none OBJECT IDENTIFIER ::=
|
||||||
|
{holdInstruction 1} -- deprecated
|
||||||
|
|
||||||
|
id-holdinstruction-callissuer OBJECT IDENTIFIER ::=
|
||||||
|
{holdInstruction 2}
|
||||||
|
|
||||||
|
id-holdinstruction-reject OBJECT IDENTIFIER ::=
|
||||||
|
{holdInstruction 3}
|
||||||
|
|
||||||
|
-- invalidity date CRL entry extension OID and syntax
|
||||||
|
|
||||||
|
id-ce-invalidityDate OBJECT IDENTIFIER ::= { id-ce 24 }
|
||||||
|
|
||||||
|
InvalidityDate ::= GeneralizedTime
|
||||||
|
|
||||||
|
END
|
|
@ -0,0 +1,785 @@
|
||||||
|
RSPDefinitions {joint-iso-itu-t(2) international-organizations(23) gsma(146) rsp(1) spec-version(1) version-two(2)}
|
||||||
|
DEFINITIONS
|
||||||
|
AUTOMATIC TAGS
|
||||||
|
EXTENSIBILITY IMPLIED ::=
|
||||||
|
BEGIN
|
||||||
|
|
||||||
|
IMPORTS Certificate, CertificateList, Time FROM PKIX1Explicit88 {iso(1) identified-organization(3) dod(6) internet(1) security(5) mechanisms(5) pkix(7) id-mod(0) id-pkix1-explicit(18)}
|
||||||
|
SubjectKeyIdentifier FROM PKIX1Implicit88 {iso(1) identified-organization(3) dod(6) internet(1) security(5) mechanisms(5) pkix(7) id-mod(0) id-pkix1-implicit(19)};
|
||||||
|
|
||||||
|
id-rsp OBJECT IDENTIFIER ::= {joint-iso-itu-t(2) international-organizations(23) gsma(146) rsp(1)}
|
||||||
|
|
||||||
|
-- Basic types, for size constraints
|
||||||
|
Octet8 ::= OCTET STRING (SIZE(8))
|
||||||
|
Octet16 ::= OCTET STRING (SIZE(16))
|
||||||
|
OctetTo16 ::= OCTET STRING (SIZE(1..16))
|
||||||
|
Octet32 ::= OCTET STRING (SIZE(32))
|
||||||
|
Octet1 ::= OCTET STRING(SIZE(1))
|
||||||
|
Octet2 ::= OCTET STRING (SIZE(2))
|
||||||
|
VersionType ::= OCTET STRING(SIZE(3)) -- major/minor/revision version are coded as binary value on byte 1/2/3, e.g. '02 00 0C' for v2.0.12.
|
||||||
|
Iccid ::= [APPLICATION 26] OCTET STRING (SIZE(10)) -- ICCID as coded in EFiccid, corresponding tag is '5A'
|
||||||
|
RemoteOpId ::= [2] INTEGER {installBoundProfilePackage(1)}
|
||||||
|
TransactionId ::= OCTET STRING (SIZE(1..16))
|
||||||
|
|
||||||
|
-- Definition of EUICCInfo1 --------------------------
|
||||||
|
GetEuiccInfo1Request ::= [32] SEQUENCE { -- Tag 'BF20'
|
||||||
|
}
|
||||||
|
|
||||||
|
EUICCInfo1 ::= [32] SEQUENCE { -- Tag 'BF20'
|
||||||
|
svn [2] VersionType, -- GSMA SGP.22 version supported (SVN)
|
||||||
|
euiccCiPKIdListForVerification [9] SEQUENCE OF SubjectKeyIdentifier, -- List of CI Public Key Identifiers supported on the eUICC for signature verification
|
||||||
|
euiccCiPKIdListForSigning [10] SEQUENCE OF SubjectKeyIdentifier -- List of CI Public Key Identifier supported on the eUICC for signature creation
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Definition of EUICCInfo2 --------------------------
|
||||||
|
GetEuiccInfo2Request ::= [34] SEQUENCE { -- Tag 'BF22'
|
||||||
|
}
|
||||||
|
|
||||||
|
EUICCInfo2 ::= [34] SEQUENCE { -- Tag 'BF22'
|
||||||
|
profileVersion [1] VersionType, -- SIMAlliance Profile package version supported
|
||||||
|
svn [2] VersionType, -- GSMA SGP.22 version supported (SVN)
|
||||||
|
euiccFirmwareVer [3] VersionType, -- eUICC Firmware version
|
||||||
|
extCardResource [4] OCTET STRING, -- Extended Card Resource Information according to ETSI TS 102 226
|
||||||
|
uiccCapability [5] UICCCapability,
|
||||||
|
javacardVersion [6] VersionType OPTIONAL,
|
||||||
|
globalplatformVersion [7] VersionType OPTIONAL,
|
||||||
|
rspCapability [8] RspCapability,
|
||||||
|
euiccCiPKIdListForVerification [9] SEQUENCE OF SubjectKeyIdentifier, -- List of CI Public Key Identifiers supported on the eUICC for signature verification
|
||||||
|
euiccCiPKIdListForSigning [10] SEQUENCE OF SubjectKeyIdentifier, -- List of CI Public Key Identifier supported on the eUICC for signature creation
|
||||||
|
euiccCategory [11] INTEGER {
|
||||||
|
other(0),
|
||||||
|
basicEuicc(1),
|
||||||
|
mediumEuicc(2),
|
||||||
|
contactlessEuicc(3)
|
||||||
|
} OPTIONAL,
|
||||||
|
forbiddenProfilePolicyRules [25] PprIds OPTIONAL, -- Tag '99'
|
||||||
|
ppVersion VersionType, -- Protection Profile version
|
||||||
|
sasAcreditationNumber UTF8String (SIZE(0..64)),
|
||||||
|
certificationDataObject [12] CertificationDataObject OPTIONAL
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Definition of RspCapability
|
||||||
|
RspCapability ::= BIT STRING {
|
||||||
|
additionalProfile(0), -- at least one more Profile can be installed
|
||||||
|
crlSupport(1), -- CRL
|
||||||
|
rpmSupport(2), -- Remote Profile Management
|
||||||
|
testProfileSupport (3) -- support for test profile
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Definition of CertificationDataObject
|
||||||
|
CertificationDataObject ::= SEQUENCE {
|
||||||
|
platformLabel UTF8String, -- Platform_Label as defined in GlobalPlatform DLOA specification [57]
|
||||||
|
discoveryBaseURL UTF8String -- Discovery Base URL of the SE default DLOA Registrar as defined in GlobalPlatform DLOA specification [57]
|
||||||
|
}
|
||||||
|
|
||||||
|
CertificateInfo ::= BIT STRING {
|
||||||
|
|
||||||
|
reserved(0), -- eUICC has a CERT.EUICC.ECDSA in GlobalPlatform format. The use of this bit is deprecated.
|
||||||
|
certSigningX509(1), -- eUICC has a CERT.EUICC.ECDSA in X.509 format
|
||||||
|
rfu2(2),
|
||||||
|
rfu3(3),
|
||||||
|
reserved2(4), -- Handling of Certificate in GlobalPlatform format. The use of this bit is deprecated.
|
||||||
|
certVerificationX509(5)-- Handling of Certificate in X.509 format
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Definition of UICCCapability
|
||||||
|
UICCCapability ::= BIT STRING {
|
||||||
|
/* Sequence is derived from ServicesList[] defined in SIMalliance PEDefinitions*/
|
||||||
|
contactlessSupport(0), -- Contactless (SWP, HCI and associated APIs)
|
||||||
|
usimSupport(1), -- USIM as defined by 3GPP
|
||||||
|
isimSupport(2), -- ISIM as defined by 3GPP
|
||||||
|
csimSupport(3), -- CSIM as defined by 3GPP2
|
||||||
|
|
||||||
|
akaMilenage(4), -- Milenage as AKA algorithm
|
||||||
|
akaCave(5), -- CAVE as authentication algorithm
|
||||||
|
akaTuak128(6), -- TUAK as AKA algorithm with 128 bit key length
|
||||||
|
akaTuak256(7), -- TUAK as AKA algorithm with 256 bit key length
|
||||||
|
rfu1(8), -- reserved for further algorithms
|
||||||
|
rfu2(9), -- reserved for further algorithms
|
||||||
|
|
||||||
|
gbaAuthenUsim(10), -- GBA authentication in the context of USIM
|
||||||
|
gbaAuthenISim(11), -- GBA authentication in the context of ISIM
|
||||||
|
mbmsAuthenUsim(12), -- MBMS authentication in the context of USIM
|
||||||
|
eapClient(13), -- EAP client
|
||||||
|
|
||||||
|
javacard(14), -- Javacard support
|
||||||
|
multos(15), -- Multos support
|
||||||
|
|
||||||
|
multipleUsimSupport(16), -- Multiple USIM applications are supported within the same Profile
|
||||||
|
multipleIsimSupport(17), -- Multiple ISIM applications are supported within the same Profile
|
||||||
|
multipleCsimSupport(18) -- Multiple CSIM applications are supported within the same Profile
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Definition of DeviceInfo
|
||||||
|
DeviceInfo ::= SEQUENCE {
|
||||||
|
tac Octet8,
|
||||||
|
deviceCapabilities DeviceCapabilities,
|
||||||
|
imei Octet8 OPTIONAL
|
||||||
|
}
|
||||||
|
|
||||||
|
DeviceCapabilities ::= SEQUENCE { -- Highest fully supported release for each definition
|
||||||
|
-- The device SHALL set all the capabilities it supports
|
||||||
|
gsmSupportedRelease VersionType OPTIONAL,
|
||||||
|
utranSupportedRelease VersionType OPTIONAL,
|
||||||
|
cdma2000onexSupportedRelease VersionType OPTIONAL,
|
||||||
|
cdma2000hrpdSupportedRelease VersionType OPTIONAL,
|
||||||
|
cdma2000ehrpdSupportedRelease VersionType OPTIONAL,
|
||||||
|
eutranSupportedRelease VersionType OPTIONAL,
|
||||||
|
contactlessSupportedRelease VersionType OPTIONAL,
|
||||||
|
rspCrlSupportedVersion VersionType OPTIONAL,
|
||||||
|
rspRpmSupportedVersion VersionType OPTIONAL
|
||||||
|
}
|
||||||
|
|
||||||
|
ProfileInfoListRequest ::= [45] SEQUENCE { -- Tag 'BF2D'
|
||||||
|
searchCriteria [0] CHOICE {
|
||||||
|
isdpAid [APPLICATION 15] OctetTo16, -- AID of the ISD-P, tag '4F'
|
||||||
|
iccid Iccid, -- ICCID, tag '5A'
|
||||||
|
profileClass [21] ProfileClass -- Tag '95'
|
||||||
|
} OPTIONAL,
|
||||||
|
tagList [APPLICATION 28] OCTET STRING OPTIONAL -- tag '5C'
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Definition of ProfileInfoList
|
||||||
|
ProfileInfoListResponse ::= [45] CHOICE { -- Tag 'BF2D'
|
||||||
|
profileInfoListOk SEQUENCE OF ProfileInfo,
|
||||||
|
profileInfoListError ProfileInfoListError
|
||||||
|
}
|
||||||
|
|
||||||
|
ProfileInfo ::= [PRIVATE 3] SEQUENCE { -- Tag 'E3'
|
||||||
|
iccid Iccid OPTIONAL,
|
||||||
|
isdpAid [APPLICATION 15] OctetTo16 OPTIONAL, -- AID of the ISD-P containing the Profile, tag '4F'
|
||||||
|
profileState [112] ProfileState OPTIONAL, -- Tag '9F70'
|
||||||
|
profileNickname [16] UTF8String (SIZE(0..64)) OPTIONAL, -- Tag '90'
|
||||||
|
serviceProviderName [17] UTF8String (SIZE(0..32)) OPTIONAL, -- Tag '91'
|
||||||
|
profileName [18] UTF8String (SIZE(0..64)) OPTIONAL, -- Tag '92'
|
||||||
|
iconType [19] IconType OPTIONAL, -- Tag '93'
|
||||||
|
icon [20] OCTET STRING (SIZE(0..1024)) OPTIONAL, -- Tag '94', see condition in ES10c:GetProfilesInfo
|
||||||
|
profileClass [21] ProfileClass DEFAULT operational, -- Tag '95'
|
||||||
|
notificationConfigurationInfo [22] SEQUENCE OF NotificationConfigurationInformation OPTIONAL, -- Tag 'B6'
|
||||||
|
profileOwner [23] OperatorID OPTIONAL, -- Tag 'B7'
|
||||||
|
dpProprietaryData [24] DpProprietaryData OPTIONAL, -- Tag 'B8'
|
||||||
|
profilePolicyRules [25] PprIds OPTIONAL -- Tag '99'
|
||||||
|
}
|
||||||
|
|
||||||
|
PprIds ::= BIT STRING {-- Definition of Profile Policy Rules identifiers
|
||||||
|
pprUpdateControl(0), -- defines how to update PPRs via ES6
|
||||||
|
ppr1(1), -- Indicator for PPR1 'Disabling of this Profile is not allowed'
|
||||||
|
ppr2(2), -- Indicator for PPR2 'Deletion of this Profile is not allowed'
|
||||||
|
ppr3(3) -- Indicator for PPR3 'Deletion of this Profile is required upon its successful disabling'
|
||||||
|
}
|
||||||
|
|
||||||
|
OperatorID ::= SEQUENCE {
|
||||||
|
mccMnc OCTET STRING (SIZE(3)), -- MCC and MNC coded as defined in 3GPP TS 24.008 [32]
|
||||||
|
gid1 OCTET STRING OPTIONAL, -- referring to content of EF GID1 (file identifier '6F3E') as defined in 3GPP TS 31.102 [54]
|
||||||
|
gid2 OCTET STRING OPTIONAL -- referring to content of EF GID2 (file identifier '6F3F') as defined in 3GPP TS 31.102 [54]
|
||||||
|
}
|
||||||
|
|
||||||
|
ProfileInfoListError ::= INTEGER {incorrectInputValues(1), undefinedError(127)}
|
||||||
|
|
||||||
|
-- Definition of StoreMetadata request
|
||||||
|
|
||||||
|
StoreMetadataRequest ::= [37] SEQUENCE { -- Tag 'BF25'
|
||||||
|
iccid Iccid,
|
||||||
|
serviceProviderName [17] UTF8String (SIZE(0..32)), -- Tag '91'
|
||||||
|
profileName [18] UTF8String (SIZE(0..64)), -- Tag '92' (corresponds to 'Short Description' defined in SGP.21 [2])
|
||||||
|
iconType [19] IconType OPTIONAL, -- Tag '93' (JPG or PNG)
|
||||||
|
icon [20] OCTET STRING (SIZE(0..1024)) OPTIONAL, -- Tag '94'(Data of the icon. Size 64 x 64 pixel. This field SHALL only be present if iconType is present)
|
||||||
|
profileClass [21] ProfileClass OPTIONAL, -- Tag '95' (default if absent: 'operational')
|
||||||
|
notificationConfigurationInfo [22] SEQUENCE OF NotificationConfigurationInformation OPTIONAL,
|
||||||
|
profileOwner [23] OperatorID OPTIONAL, -- Tag 'B7'
|
||||||
|
profilePolicyRules [25] PprIds OPTIONAL -- Tag '99'
|
||||||
|
}
|
||||||
|
|
||||||
|
NotificationEvent ::= BIT STRING {
|
||||||
|
notificationInstall (0),
|
||||||
|
notificationEnable(1),
|
||||||
|
notificationDisable(2),
|
||||||
|
notificationDelete(3)
|
||||||
|
}
|
||||||
|
|
||||||
|
NotificationConfigurationInformation ::= SEQUENCE {
|
||||||
|
profileManagementOperation NotificationEvent,
|
||||||
|
notificationAddress UTF8String -- FQDN to forward the notification
|
||||||
|
}
|
||||||
|
|
||||||
|
IconType ::= INTEGER {jpg(0), png(1)}
|
||||||
|
ProfileState ::= INTEGER {disabled(0), enabled(1)}
|
||||||
|
ProfileClass ::= INTEGER {test(0), provisioning(1), operational(2)}
|
||||||
|
|
||||||
|
-- Definition of UpdateMetadata request
|
||||||
|
UpdateMetadataRequest ::= [42] SEQUENCE { -- Tag 'BF2A'
|
||||||
|
serviceProviderName [17] UTF8String (SIZE(0..32)) OPTIONAL, -- Tag '91'
|
||||||
|
profileName [18] UTF8String (SIZE(0..64)) OPTIONAL, -- Tag '92'
|
||||||
|
iconType [19] IconType OPTIONAL, -- Tag '93'
|
||||||
|
icon [20] OCTET STRING (SIZE(0..1024)) OPTIONAL, -- Tag '94'
|
||||||
|
profilePolicyRules [25] PprIds OPTIONAL -- Tag '99'
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Definition of data objects for command PrepareDownload -------------------------
|
||||||
|
PrepareDownloadRequest ::= [33] SEQUENCE { -- Tag 'BF21'
|
||||||
|
smdpSigned2 SmdpSigned2, -- Signed information
|
||||||
|
smdpSignature2 [APPLICATION 55] OCTET STRING, -- DP_Sign1, tag '5F37'
|
||||||
|
hashCc Octet32 OPTIONAL, -- Hash of confirmation code
|
||||||
|
smdpCertificate Certificate -- CERT.DPpb.ECDSA
|
||||||
|
}
|
||||||
|
|
||||||
|
SmdpSigned2 ::= SEQUENCE {
|
||||||
|
transactionId [0] TransactionId, -- The TransactionID generated by the SM DP+
|
||||||
|
ccRequiredFlag BOOLEAN, --Indicates if the Confirmation Code is required
|
||||||
|
bppEuiccOtpk [APPLICATION 73] OCTET STRING OPTIONAL -- otPK.EUICC.ECKA already used for binding the BPP, tag '5F49'
|
||||||
|
}
|
||||||
|
|
||||||
|
PrepareDownloadResponse ::= [33] CHOICE { -- Tag 'BF21'
|
||||||
|
downloadResponseOk PrepareDownloadResponseOk,
|
||||||
|
downloadResponseError PrepareDownloadResponseError
|
||||||
|
}
|
||||||
|
|
||||||
|
PrepareDownloadResponseOk ::= SEQUENCE {
|
||||||
|
euiccSigned2 EUICCSigned2, -- Signed information
|
||||||
|
euiccSignature2 [APPLICATION 55] OCTET STRING -- tag '5F37'
|
||||||
|
}
|
||||||
|
|
||||||
|
EUICCSigned2 ::= SEQUENCE {
|
||||||
|
transactionId [0] TransactionId,
|
||||||
|
euiccOtpk [APPLICATION 73] OCTET STRING, -- otPK.EUICC.ECKA, tag '5F49'
|
||||||
|
hashCc Octet32 OPTIONAL -- Hash of confirmation code
|
||||||
|
}
|
||||||
|
|
||||||
|
PrepareDownloadResponseError ::= SEQUENCE {
|
||||||
|
transactionId [0] TransactionId,
|
||||||
|
downloadErrorCode DownloadErrorCode
|
||||||
|
}
|
||||||
|
|
||||||
|
DownloadErrorCode ::= INTEGER {invalidCertificate(1), invalidSignature(2), unsupportedCurve(3), noSessionContext(4), invalidTransactionId(5), undefinedError(127)}
|
||||||
|
|
||||||
|
-- Definition of data objects for command AuthenticateServer--------------------
|
||||||
|
AuthenticateServerRequest ::= [56] SEQUENCE { -- Tag 'BF38'
|
||||||
|
serverSigned1 ServerSigned1, -- Signed information
|
||||||
|
serverSignature1 [APPLICATION 55] OCTET STRING, -- tag ?5F37?
|
||||||
|
euiccCiPKIdToBeUsed SubjectKeyIdentifier, -- CI Public Key Identifier to be used
|
||||||
|
serverCertificate Certificate, -- RSP Server Certificate CERT.XXauth.ECDSA
|
||||||
|
ctxParams1 CtxParams1
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerSigned1 ::= SEQUENCE {
|
||||||
|
transactionId [0] TransactionId, -- The Transaction ID generated by the RSP Server
|
||||||
|
euiccChallenge [1] Octet16, -- The eUICC Challenge
|
||||||
|
serverAddress [3] UTF8String, -- The RSP Server address
|
||||||
|
serverChallenge [4] Octet16 -- The RSP Server Challenge
|
||||||
|
}
|
||||||
|
|
||||||
|
CtxParams1 ::= CHOICE {
|
||||||
|
ctxParamsForCommonAuthentication CtxParamsForCommonAuthentication -- New contextual data objects may be defined for extensibility
|
||||||
|
}
|
||||||
|
|
||||||
|
CtxParamsForCommonAuthentication ::= SEQUENCE {
|
||||||
|
matchingId UTF8String OPTIONAL,-- The MatchingId could be the Activation code token or EventID or empty
|
||||||
|
deviceInfo DeviceInfo -- The Device information
|
||||||
|
}
|
||||||
|
|
||||||
|
AuthenticateServerResponse ::= [56] CHOICE { -- Tag 'BF38'
|
||||||
|
authenticateResponseOk AuthenticateResponseOk,
|
||||||
|
authenticateResponseError AuthenticateResponseError
|
||||||
|
}
|
||||||
|
|
||||||
|
AuthenticateResponseOk ::= SEQUENCE {
|
||||||
|
euiccSigned1 EuiccSigned1, -- Signed information
|
||||||
|
euiccSignature1 [APPLICATION 55] OCTET STRING, --EUICC_Sign1, tag 5F37
|
||||||
|
euiccCertificate Certificate, -- eUICC Certificate (CERT.EUICC.ECDSA) signed by the EUM
|
||||||
|
eumCertificate Certificate -- EUM Certificate (CERT.EUM.ECDSA) signed by the requested CI
|
||||||
|
}
|
||||||
|
|
||||||
|
EuiccSigned1 ::= SEQUENCE {
|
||||||
|
transactionId [0] TransactionId,
|
||||||
|
serverAddress [3] UTF8String,
|
||||||
|
serverChallenge [4] Octet16, -- The RSP Server Challenge
|
||||||
|
euiccInfo2 [34] EUICCInfo2,
|
||||||
|
ctxParams1 CtxParams1
|
||||||
|
}
|
||||||
|
|
||||||
|
AuthenticateResponseError ::= SEQUENCE {
|
||||||
|
transactionId [0] TransactionId,
|
||||||
|
authenticateErrorCode AuthenticateErrorCode
|
||||||
|
}
|
||||||
|
|
||||||
|
AuthenticateErrorCode ::= INTEGER {invalidCertificate(1), invalidSignature(2), unsupportedCurve(3), noSessionContext(4), invalidOid(5), euiccChallengeMismatch(6), ciPKUnknown(7), undefinedError(127)}
|
||||||
|
|
||||||
|
-- Definition of Cancel Session------------------------------
|
||||||
|
CancelSessionRequest ::= [65] SEQUENCE { -- Tag 'BF41'
|
||||||
|
transactionId TransactionId, -- The TransactionID generated by the RSP Server
|
||||||
|
reason CancelSessionReason
|
||||||
|
}
|
||||||
|
|
||||||
|
CancelSessionReason ::= INTEGER {endUserRejection(0), postponed(1), timeout(2), pprNotAllowed(3)}
|
||||||
|
|
||||||
|
CancelSessionResponse ::= [65] CHOICE { -- Tag 'BF41'
|
||||||
|
cancelSessionResponseOk CancelSessionResponseOk,
|
||||||
|
cancelSessionResponseError INTEGER {invalidTransactionId(5), undefinedError(127)}
|
||||||
|
}
|
||||||
|
|
||||||
|
CancelSessionResponseOk ::= SEQUENCE {
|
||||||
|
euiccCancelSessionSigned EuiccCancelSessionSigned, -- Signed information
|
||||||
|
euiccCancelSessionSignature [APPLICATION 55] OCTET STRING -- tag '5F37
|
||||||
|
}
|
||||||
|
|
||||||
|
EuiccCancelSessionSigned ::= SEQUENCE {
|
||||||
|
transactionId TransactionId,
|
||||||
|
smdpOid OBJECT IDENTIFIER, -- SM-DP+ OID as contained in CERT.DPauth.ECDSA
|
||||||
|
reason CancelSessionReason
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Definition of Bound Profile Package --------------------------
|
||||||
|
BoundProfilePackage ::= [54] SEQUENCE { -- Tag 'BF36'
|
||||||
|
initialiseSecureChannelRequest [35] InitialiseSecureChannelRequest, -- Tag 'BF23'
|
||||||
|
firstSequenceOf87 [0] SEQUENCE OF [7] OCTET STRING, -- sequence of '87' TLVs
|
||||||
|
sequenceOf88 [1] SEQUENCE OF [8] OCTET STRING, -- sequence of '88' TLVs
|
||||||
|
secondSequenceOf87 [2] SEQUENCE OF [7] OCTET STRING OPTIONAL, -- sequence of '87' TLVs
|
||||||
|
sequenceOf86 [3] SEQUENCE OF [6] OCTET STRING -- sequence of '86' TLVs
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Definition of Get eUICC Challenge --------------------------
|
||||||
|
GetEuiccChallengeRequest ::= [46] SEQUENCE { -- Tag 'BF2E'
|
||||||
|
}
|
||||||
|
|
||||||
|
GetEuiccChallengeResponse ::= [46] SEQUENCE { -- Tag 'BF2E'
|
||||||
|
euiccChallenge Octet16 -- random eUICC challenge
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Definition of Profile Installation Resulceipt
|
||||||
|
ProfileInstallationResult ::= [55] SEQUENCE { -- Tag 'BF37'
|
||||||
|
profileInstallationResultData [39] ProfileInstallationResultData,
|
||||||
|
euiccSignPIR EuiccSignPIR
|
||||||
|
}
|
||||||
|
|
||||||
|
ProfileInstallationResultData ::= [39] SEQUENCE { -- Tag 'BF27'
|
||||||
|
transactionId[0] TransactionId, -- The TransactionID generated by the SM-DP+
|
||||||
|
notificationMetadata[47] NotificationMetadata,
|
||||||
|
smdpOid OBJECT IDENTIFIER OPTIONAL, -- SM-DP+ OID (same value as in CERT.DPpb.ECDSA)
|
||||||
|
finalResult [2] CHOICE {
|
||||||
|
successResult SuccessResult,
|
||||||
|
errorResult ErrorResult
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EuiccSignPIR ::= [APPLICATION 55] OCTET STRING -- Tag '5F37', eUICC?s signature
|
||||||
|
|
||||||
|
SuccessResult ::= SEQUENCE {
|
||||||
|
aid [APPLICATION 15] OCTET STRING (SIZE (5..16)), -- AID of ISD-P
|
||||||
|
simaResponse OCTET STRING -- contains (multiple) 'EUICCResponse' as defined in [5]
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorResult ::= SEQUENCE {
|
||||||
|
bppCommandId BppCommandId,
|
||||||
|
errorReason ErrorReason,
|
||||||
|
simaResponse OCTET STRING OPTIONAL -- contains (multiple) 'EUICCResponse' as defined in [5]
|
||||||
|
}
|
||||||
|
|
||||||
|
BppCommandId ::= INTEGER {initialiseSecureChannel(0), configureISDP(1), storeMetadata(2), storeMetadata2(3), replaceSessionKeys(4), loadProfileElements(5)}
|
||||||
|
|
||||||
|
ErrorReason ::= INTEGER {
|
||||||
|
incorrectInputValues(1),
|
||||||
|
invalidSignature(2),
|
||||||
|
invalidTransactionId(3),
|
||||||
|
unsupportedCrtValues(4),
|
||||||
|
unsupportedRemoteOperationType(5),
|
||||||
|
unsupportedProfileClass(6),
|
||||||
|
scp03tStructureError(7),
|
||||||
|
scp03tSecurityError(8),
|
||||||
|
installFailedDueToIccidAlreadyExistsOnEuicc(9), installFailedDueToInsufficientMemoryForProfile(10),
|
||||||
|
installFailedDueToInterruption(11),
|
||||||
|
installFailedDueToPEProcessingError (12),
|
||||||
|
installFailedDueToIccidMismatch(13),
|
||||||
|
testProfileInstallFailedDueToInvalidNaaKey(14),
|
||||||
|
pprNotAllowed(15),
|
||||||
|
installFailedDueToUnknownError(127)
|
||||||
|
}
|
||||||
|
|
||||||
|
ListNotificationRequest ::= [40] SEQUENCE { -- Tag 'BF28'
|
||||||
|
profileManagementOperation [1] NotificationEvent OPTIONAL
|
||||||
|
}
|
||||||
|
|
||||||
|
ListNotificationResponse ::= [40] CHOICE { -- Tag 'BF28'
|
||||||
|
notificationMetadataList SEQUENCE OF NotificationMetadata,
|
||||||
|
listNotificationsResultError INTEGER {undefinedError(127)}
|
||||||
|
}
|
||||||
|
|
||||||
|
NotificationMetadata ::= [47] SEQUENCE { -- Tag 'BF2F'
|
||||||
|
seqNumber [0] INTEGER,
|
||||||
|
profileManagementOperation [1] NotificationEvent, --Only one bit set to 1
|
||||||
|
notificationAddress UTF8String, -- FQDN to forward the notification
|
||||||
|
iccid Iccid OPTIONAL
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Definition of Profile Nickname Information
|
||||||
|
SetNicknameRequest ::= [41] SEQUENCE { -- Tag 'BF29'
|
||||||
|
iccid Iccid,
|
||||||
|
profileNickname [16] UTF8String (SIZE(0..64))
|
||||||
|
}
|
||||||
|
|
||||||
|
SetNicknameResponse ::= [41] SEQUENCE { -- Tag 'BF29'
|
||||||
|
setNicknameResult INTEGER {ok(0), iccidNotFound (1), undefinedError(127)}
|
||||||
|
}
|
||||||
|
|
||||||
|
id-rsp-cert-objects OBJECT IDENTIFIER ::= { id-rsp cert-objects(2)}
|
||||||
|
|
||||||
|
id-rspExt OBJECT IDENTIFIER ::= {id-rsp-cert-objects 0}
|
||||||
|
|
||||||
|
id-rspRole OBJECT IDENTIFIER ::= {id-rsp-cert-objects 1}
|
||||||
|
|
||||||
|
-- Definition of OIDs for role identification
|
||||||
|
id-rspRole-ci OBJECT IDENTIFIER ::= {id-rspRole 0}
|
||||||
|
id-rspRole-euicc OBJECT IDENTIFIER ::= {id-rspRole 1}
|
||||||
|
id-rspRole-eum OBJECT IDENTIFIER ::= {id-rspRole 2}
|
||||||
|
id-rspRole-dp-tls OBJECT IDENTIFIER ::= {id-rspRole 3}
|
||||||
|
id-rspRole-dp-auth OBJECT IDENTIFIER ::= {id-rspRole 4}
|
||||||
|
id-rspRole-dp-pb OBJECT IDENTIFIER ::= {id-rspRole 5}
|
||||||
|
id-rspRole-ds-tls OBJECT IDENTIFIER ::= {id-rspRole 6}
|
||||||
|
id-rspRole-ds-auth OBJECT IDENTIFIER ::= {id-rspRole 7}
|
||||||
|
|
||||||
|
--Definition of data objects for InitialiseSecureChannel Request
|
||||||
|
InitialiseSecureChannelRequest ::= [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'
|
||||||
|
smdpSign [APPLICATION 55] OCTET STRING -- SM-DP's signature, tag '5F37'
|
||||||
|
}
|
||||||
|
|
||||||
|
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'
|
||||||
|
hostId[4] OctetTo16 -- Host ID value , Tag '84'
|
||||||
|
}
|
||||||
|
|
||||||
|
--Definition of data objects for ConfigureISDPRequest
|
||||||
|
ConfigureISDPRequest ::= [36] SEQUENCE { -- Tag 'BF24'
|
||||||
|
dpProprietaryData [24] DpProprietaryData OPTIONAL -- Tag 'B8'
|
||||||
|
}
|
||||||
|
|
||||||
|
DpProprietaryData ::= SEQUENCE { -- maximum size including tag and length field: 128 bytes
|
||||||
|
dpOid OBJECT IDENTIFIER -- OID in the tree of the SM-DP+ that created the Profile
|
||||||
|
-- additional data objects defined by the SM-DP+ MAY follow
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Definition of request message for command ReplaceSessionKeys
|
||||||
|
ReplaceSessionKeysRequest ::= [38] SEQUENCE { -- tag 'BF26'
|
||||||
|
/*The new initial MAC chaining value*/
|
||||||
|
initialMacChainingValue OCTET STRING,
|
||||||
|
/*New session key value for encryption/decryption (PPK-ENC)*/
|
||||||
|
ppkEnc OCTET STRING,
|
||||||
|
/*New session key value of the session key C-MAC computation/verification (PPK-MAC)*/
|
||||||
|
ppkCmac OCTET STRING
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Definition of data objects for RetrieveNotificationsList
|
||||||
|
RetrieveNotificationsListRequest ::= [43] SEQUENCE { -- Tag 'BF2B'
|
||||||
|
searchCriteria CHOICE {
|
||||||
|
seqNumber [0] INTEGER,
|
||||||
|
profileManagementOperation [1] NotificationEvent
|
||||||
|
} OPTIONAL
|
||||||
|
}
|
||||||
|
|
||||||
|
RetrieveNotificationsListResponse ::= [43] CHOICE { -- Tag 'BF2B'
|
||||||
|
notificationList SEQUENCE OF PendingNotification,
|
||||||
|
notificationsListResultError INTEGER {noResultAvailable(1), undefinedError(127)}
|
||||||
|
}
|
||||||
|
|
||||||
|
PendingNotification ::= CHOICE {
|
||||||
|
profileInstallationResult [55] ProfileInstallationResult, -- tag 'BF37'
|
||||||
|
otherSignedNotification OtherSignedNotification
|
||||||
|
}
|
||||||
|
|
||||||
|
OtherSignedNotification ::= SEQUENCE {
|
||||||
|
tbsOtherNotification NotificationMetadata,
|
||||||
|
euiccNotificationSignature [APPLICATION 55] OCTET STRING, -- eUICC signature of tbsOtherNotification, Tag '5F37'
|
||||||
|
euiccCertificate Certificate, -- eUICC Certificate (CERT.EUICC.ECDSA) signed by the EUM
|
||||||
|
eumCertificate Certificate -- EUM Certificate (CERT.EUM.ECDSA) signed by the requested CI
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Definition of notificationSent
|
||||||
|
NotificationSentRequest ::= [48] SEQUENCE { -- Tag 'BF30'
|
||||||
|
seqNumber [0] INTEGER
|
||||||
|
}
|
||||||
|
|
||||||
|
NotificationSentResponse ::= [48] SEQUENCE { -- Tag 'BF30'
|
||||||
|
deleteNotificationStatus INTEGER {ok(0), nothingToDelete(1), undefinedError(127)}
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Definition of Enable Profile --------------------------
|
||||||
|
EnableProfileRequest ::= [49] SEQUENCE { -- Tag 'BF31'
|
||||||
|
profileIdentifier CHOICE {
|
||||||
|
isdpAid [APPLICATION 15] OctetTo16, -- AID, tag '4F'
|
||||||
|
iccid Iccid -- ICCID, tag '5A'
|
||||||
|
},
|
||||||
|
refreshFlag BOOLEAN -- indicating whether REFRESH is required
|
||||||
|
}
|
||||||
|
|
||||||
|
EnableProfileResponse ::= [49] SEQUENCE { -- Tag 'BF31'
|
||||||
|
enableResult INTEGER {ok(0), iccidOrAidNotFound (1), profileNotInDisabledState(2), disallowedByPolicy(3), wrongProfileReenabling(4), undefinedError(127)}
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Definition of Disable Profile --------------------------
|
||||||
|
DisableProfileRequest ::= [50] SEQUENCE { -- Tag 'BF32'
|
||||||
|
profileIdentifier CHOICE {
|
||||||
|
isdpAid [APPLICATION 15] OctetTo16, -- AID, tag '4F'
|
||||||
|
iccid Iccid -- ICCID, tag '5A'
|
||||||
|
},
|
||||||
|
refreshFlag BOOLEAN -- indicating whether REFRESH is required
|
||||||
|
}
|
||||||
|
|
||||||
|
DisableProfileResponse ::= [50] SEQUENCE { -- Tag 'BF32'
|
||||||
|
disableResult INTEGER {ok(0), iccidOrAidNotFound (1), profileNotInEnabledState(2), disallowedByPolicy(3), undefinedError(127)}
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Definition of Delete Profile --------------------------
|
||||||
|
DeleteProfileRequest ::= [51] CHOICE { -- Tag 'BF33'
|
||||||
|
isdpAid [APPLICATION 15] OctetTo16, -- AID, tag '4F'
|
||||||
|
iccid Iccid -- ICCID, tag '5A'
|
||||||
|
}
|
||||||
|
|
||||||
|
DeleteProfileResponse ::= [51] SEQUENCE { -- Tag 'BF33'
|
||||||
|
deleteResult INTEGER {ok(0), iccidOrAidNotFound (1), profileNotInDisabledState(2), disallowedByPolicy(3), undefinedError(127)}
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Definition of Memory Reset --------------------------
|
||||||
|
EuiccMemoryResetRequest ::= [52] SEQUENCE { -- Tag 'BF34'
|
||||||
|
resetOptions [2] BIT STRING {
|
||||||
|
deleteOperationalProfiles(0),
|
||||||
|
deleteFieldLoadedTestProfiles(1),
|
||||||
|
resetDefaultSmdpAddress(2)}
|
||||||
|
}
|
||||||
|
|
||||||
|
EuiccMemoryResetResponse ::= [52] SEQUENCE { -- Tag 'BF34'
|
||||||
|
resetResult INTEGER {ok(0), nothingToDelete(1), undefinedError(127)}
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Definition of Get EID --------------------------
|
||||||
|
GetEuiccDataRequest ::= [62] SEQUENCE { -- Tag 'BF3E'
|
||||||
|
tagList [APPLICATION 28] Octet1 -- tag '5C', the value SHALL be set to '5A'
|
||||||
|
}
|
||||||
|
|
||||||
|
GetEuiccDataResponse ::= [62] SEQUENCE { -- Tag 'BF3E'
|
||||||
|
eidValue [APPLICATION 26] Octet16 -- tag '5A'
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Definition of Get Rat
|
||||||
|
|
||||||
|
GetRatRequest ::= [67] SEQUENCE { -- Tag ' BF43'
|
||||||
|
-- No input data
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GetRatResponse ::= [67] SEQUENCE { -- Tag 'BF43'
|
||||||
|
rat RulesAuthorisationTable
|
||||||
|
}
|
||||||
|
|
||||||
|
RulesAuthorisationTable ::= SEQUENCE OF ProfilePolicyAuthorisationRule
|
||||||
|
ProfilePolicyAuthorisationRule ::= SEQUENCE {
|
||||||
|
pprIds PprIds,
|
||||||
|
allowedOperators SEQUENCE OF OperatorID,
|
||||||
|
pprFlags BIT STRING {consentRequired(0)}
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Definition of data structure command for loading a CRL
|
||||||
|
LoadCRLRequest ::= [53] SEQUENCE { -- Tag 'BF35'
|
||||||
|
-- A CRL-A
|
||||||
|
crl CertificateList
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Definition of data structure response for loading a CRL
|
||||||
|
LoadCRLResponse ::= [53] CHOICE { -- Tag 'BF35'
|
||||||
|
loadCRLResponseOk LoadCRLResponseOk,
|
||||||
|
loadCRLResponseError LoadCRLResponseError
|
||||||
|
}
|
||||||
|
|
||||||
|
LoadCRLResponseOk ::= SEQUENCE {
|
||||||
|
missingParts SEQUENCE OF SEQUENCE {
|
||||||
|
number INTEGER (0..MAX)
|
||||||
|
} OPTIONAL
|
||||||
|
}
|
||||||
|
LoadCRLResponseError ::= INTEGER {invalidSignature(1), invalidCRLFormat(2), notEnoughMemorySpace(3), verificationKeyNotFound(4), undefinedError(127)}
|
||||||
|
|
||||||
|
-- Definition of the extension for Certificate Expiration Date
|
||||||
|
id-rsp-expDate OBJECT IDENTIFIER ::= {id-rspExt 1}
|
||||||
|
ExpirationDate ::= Time
|
||||||
|
|
||||||
|
-- Definition of the extension id for total partial-CRL number
|
||||||
|
id-rsp-totalPartialCrlNumber OBJECT IDENTIFIER ::= {id-rspExt 2}
|
||||||
|
TotalPartialCrlNumber ::= INTEGER
|
||||||
|
|
||||||
|
|
||||||
|
-- Definition of the extension id for the partial-CRL number
|
||||||
|
id-rsp-partialCrlNumber OBJECT IDENTIFIER ::= {id-rspExt 3}
|
||||||
|
PartialCrlNumber ::= INTEGER
|
||||||
|
|
||||||
|
-- Definition for ES9+ ASN.1 Binding --------------------------
|
||||||
|
RemoteProfileProvisioningRequest ::= [2] CHOICE { -- Tag 'A2'
|
||||||
|
initiateAuthenticationRequest [57] InitiateAuthenticationRequest, -- Tag 'BF39'
|
||||||
|
authenticateClientRequest [59] AuthenticateClientRequest, -- Tag 'BF3B'
|
||||||
|
getBoundProfilePackageRequest [58] GetBoundProfilePackageRequest, -- Tag 'BF3A'
|
||||||
|
cancelSessionRequestEs9 [65] CancelSessionRequestEs9, -- Tag 'BF41'
|
||||||
|
handleNotification [61] HandleNotification -- tag 'BF3D'
|
||||||
|
}
|
||||||
|
|
||||||
|
RemoteProfileProvisioningResponse ::= [2] CHOICE { -- Tag 'A2'
|
||||||
|
initiateAuthenticationResponse [57] InitiateAuthenticationResponse, -- Tag 'BF39'
|
||||||
|
authenticateClientResponseEs9 [59] AuthenticateClientResponseEs9, -- Tag 'BF3B'
|
||||||
|
getBoundProfilePackageResponse [58] GetBoundProfilePackageResponse, -- Tag 'BF3A'
|
||||||
|
cancelSessionResponseEs9 [65] CancelSessionResponseEs9, -- Tag 'BF41'
|
||||||
|
authenticateClientResponseEs11 [64] AuthenticateClientResponseEs11 -- Tag 'BF40'
|
||||||
|
}
|
||||||
|
|
||||||
|
InitiateAuthenticationRequest ::= [57] SEQUENCE { -- Tag 'BF39'
|
||||||
|
euiccChallenge [1] Octet16, -- random eUICC challenge
|
||||||
|
smdpAddress [3] UTF8String,
|
||||||
|
euiccInfo1 EUICCInfo1
|
||||||
|
}
|
||||||
|
|
||||||
|
InitiateAuthenticationResponse ::= [57] CHOICE { -- Tag 'BF39'
|
||||||
|
initiateAuthenticationOk InitiateAuthenticationOkEs9,
|
||||||
|
initiateAuthenticationError INTEGER {
|
||||||
|
invalidDpAddress(1),
|
||||||
|
euiccVersionNotSupportedByDp(2),
|
||||||
|
ciPKNotSupported(3)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
InitiateAuthenticationOkEs9 ::= SEQUENCE {
|
||||||
|
transactionId [0] TransactionId, -- The TransactionID generated by the SM-DP+
|
||||||
|
serverSigned1 ServerSigned1, -- Signed information
|
||||||
|
serverSignature1 [APPLICATION 55] OCTET STRING, -- Server_Sign1, tag '5F37'
|
||||||
|
euiccCiPKIdToBeUsed SubjectKeyIdentifier, -- The curve CI Public Key to be used as required by ES10b.AuthenticateServer
|
||||||
|
serverCertificate Certificate
|
||||||
|
}
|
||||||
|
|
||||||
|
AuthenticateClientRequest ::= [59] SEQUENCE { -- Tag 'BF3B'
|
||||||
|
transactionId [0] TransactionId,
|
||||||
|
authenticateServerResponse [56] AuthenticateServerResponse -- This is the response from ES10b.AuthenticateServer
|
||||||
|
}
|
||||||
|
|
||||||
|
AuthenticateClientResponseEs9 ::= [59] CHOICE { -- Tag 'BF3B'
|
||||||
|
authenticateClientOk AuthenticateClientOk,
|
||||||
|
authenticateClientError INTEGER {
|
||||||
|
eumCertificateInvalid(1),
|
||||||
|
eumCertificateExpired(2),
|
||||||
|
euiccCertificateInvalid(3),
|
||||||
|
euiccCertificateExpired(4),
|
||||||
|
euiccSignatureInvalid(5),
|
||||||
|
matchingIdRefused(6),
|
||||||
|
eidMismatch(7),
|
||||||
|
noEligibleProfile(8),
|
||||||
|
ciPKUnknown(9),
|
||||||
|
invalidTransactionId(10),
|
||||||
|
undefinedError(127)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AuthenticateClientOk ::= SEQUENCE {
|
||||||
|
transactionId [0] TransactionId,
|
||||||
|
profileMetaData [37] StoreMetadataRequest,
|
||||||
|
prepareDownloadRequest [33] PrepareDownloadRequest
|
||||||
|
}
|
||||||
|
|
||||||
|
GetBoundProfilePackageRequest ::= [58] SEQUENCE { -- Tag 'BF3A'
|
||||||
|
transactionId [0] TransactionId,
|
||||||
|
prepareDownloadResponse [33] PrepareDownloadResponse
|
||||||
|
}
|
||||||
|
|
||||||
|
GetBoundProfilePackageResponse ::= [58] CHOICE { -- Tag 'BF3A'
|
||||||
|
getBoundProfilePackageOk GetBoundProfilePackageOk,
|
||||||
|
getBoundProfilePackageError INTEGER {
|
||||||
|
euiccSignatureInvalid(1),
|
||||||
|
confirmationCodeMissing(2),
|
||||||
|
confirmationCodeRefused(3),
|
||||||
|
confirmationCodeRetriesExceeded(4),
|
||||||
|
invalidTransactionId(95),
|
||||||
|
undefinedError(127)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GetBoundProfilePackageOk ::= SEQUENCE {
|
||||||
|
transactionId [0] TransactionId,
|
||||||
|
boundProfilePackage [54] BoundProfilePackage
|
||||||
|
}
|
||||||
|
|
||||||
|
HandleNotification ::= [61] SEQUENCE { -- Tag 'BF3D'
|
||||||
|
pendingNotification PendingNotification
|
||||||
|
}
|
||||||
|
|
||||||
|
CancelSessionRequestEs9 ::= [65] SEQUENCE { -- Tag 'BF41'
|
||||||
|
transactionId TransactionId,
|
||||||
|
cancelSessionResponse CancelSessionResponse -- data structure defined for ES10b.CancelSession function
|
||||||
|
}
|
||||||
|
|
||||||
|
CancelSessionResponseEs9 ::= [65] CHOICE { -- Tag 'BF41'
|
||||||
|
cancelSessionOk CancelSessionOk,
|
||||||
|
cancelSessionError INTEGER {
|
||||||
|
invalidTransactionId(1),
|
||||||
|
euiccSignatureInvalid(2),
|
||||||
|
undefinedError(127)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CancelSessionOk ::= SEQUENCE { -- This function has no output data
|
||||||
|
}
|
||||||
|
|
||||||
|
EuiccConfiguredAddressesRequest ::= [60] SEQUENCE { -- Tag 'BF3C'
|
||||||
|
}
|
||||||
|
|
||||||
|
EuiccConfiguredAddressesResponse ::= [60] SEQUENCE { -- Tag 'BF3C'
|
||||||
|
defaultDpAddress UTF8String OPTIONAL, -- Default SM-DP+ address as an FQDN
|
||||||
|
rootDsAddress UTF8String -- Root SM-DS address as an FQDN
|
||||||
|
}
|
||||||
|
|
||||||
|
ISDRProprietaryApplicationTemplate ::= [PRIVATE 0] SEQUENCE { -- Tag 'E0'
|
||||||
|
svn [2] VersionType, -- GSMA SGP.22 version supported (SVN)
|
||||||
|
lpaeSupport BIT STRING {
|
||||||
|
lpaeUsingCat(0), -- LPA in the eUICC using Card Application Toolkit
|
||||||
|
lpaeUsingScws(1) -- LPA in the eUICC using Smartcard Web Server
|
||||||
|
} OPTIONAL
|
||||||
|
}
|
||||||
|
|
||||||
|
LpaeActivationRequest ::= [66] SEQUENCE { -- Tag 'BF42'
|
||||||
|
lpaeOption BIT STRING {
|
||||||
|
activateCatBasedLpae(0), -- LPAe with LUIe based on CAT
|
||||||
|
activateScwsBasedLpae(1) -- LPAe with LUIe based on SCWS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LpaeActivationResponse ::= [66] SEQUENCE { -- Tag 'BF42'
|
||||||
|
lpaeActivationResult INTEGER {ok(0), notSupported(1)}
|
||||||
|
}
|
||||||
|
|
||||||
|
SetDefaultDpAddressRequest ::= [63] SEQUENCE { -- Tag 'BF3F'
|
||||||
|
defaultDpAddress UTF8String -- Default SM-DP+ address as an FQDN
|
||||||
|
}
|
||||||
|
|
||||||
|
SetDefaultDpAddressResponse ::= [63] SEQUENCE { -- Tag 'BF3F'
|
||||||
|
setDefaultDpAddressResult INTEGER { ok (0), undefinedError (127)}
|
||||||
|
}
|
||||||
|
|
||||||
|
AuthenticateClientResponseEs11 ::= [64] CHOICE { -- Tag 'BF40'
|
||||||
|
authenticateClientOk AuthenticateClientOkEs11,
|
||||||
|
authenticateClientError INTEGER {
|
||||||
|
eumCertificateInvalid(1),
|
||||||
|
eumCertificateExpired(2),
|
||||||
|
euiccCertificateInvalid(3),
|
||||||
|
euiccCertificateExpired(4),
|
||||||
|
euiccSignatureInvalid(5),
|
||||||
|
eventIdUnknown(6),
|
||||||
|
invalidTransactionId(7),
|
||||||
|
undefinedError(127)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AuthenticateClientOkEs11 ::= SEQUENCE {
|
||||||
|
transactionId TransactionId,
|
||||||
|
eventEntries SEQUENCE OF EventEntries
|
||||||
|
}
|
||||||
|
|
||||||
|
EventEntries ::= SEQUENCE {
|
||||||
|
eventId UTF8String,
|
||||||
|
rspServerAddress UTF8String
|
||||||
|
}
|
||||||
|
|
||||||
|
END
|
|
@ -0,0 +1,122 @@
|
||||||
|
package com.truphone.lpad.worker;
|
||||||
|
|
||||||
|
|
||||||
|
import com.truphone.es9plus.AllocateProfileResponse;
|
||||||
|
import com.truphone.es9plus.Es9PlusImpl;
|
||||||
|
import com.truphone.lpad.progress.Progress;
|
||||||
|
import com.truphone.lpad.progress.ProgressStep;
|
||||||
|
import com.truphone.util.LogStub;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.mockito.Mockito.*;
|
||||||
|
import static org.mockito.internal.verification.VerificationModeFactory.times;
|
||||||
|
|
||||||
|
public class AllocateProfileWorkerTest {
|
||||||
|
|
||||||
|
// private AllocateProfileWorker allocateProfileWorker;
|
||||||
|
//
|
||||||
|
// @Mock
|
||||||
|
// private Progress mockProgress;
|
||||||
|
// @Mock
|
||||||
|
// private Es9PlusImpl mockEs9PlusImpl;
|
||||||
|
//
|
||||||
|
// @Before
|
||||||
|
// public void setUp() {
|
||||||
|
// MockitoAnnotations.initMocks(this);
|
||||||
|
// allocateProfileWorker = new AllocateProfileWorker(mockProgress, mockEs9PlusImpl);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Test(expected = IllegalArgumentException.class)
|
||||||
|
// public void shouldThrowIllegalArgumentExceptionProgressIsNull() {
|
||||||
|
// new AllocateProfileWorker(null, mockEs9PlusImpl);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Test(expected = IllegalArgumentException.class)
|
||||||
|
// public void shouldThrowIllegalArgumentExceptionWhenRsp29ModuleIsNull() {
|
||||||
|
// new AllocateProfileWorker(mockProgress, null);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Test
|
||||||
|
// public void shouldAllocateAProfileForAValidMcc() {
|
||||||
|
//
|
||||||
|
//// String mcc = "351";
|
||||||
|
//// String eid = "2";
|
||||||
|
//// String acToken = "token";
|
||||||
|
////
|
||||||
|
//// AllocateProfileResponse mockAllocateProfileResponse = mock(AllocateProfileResponse.class);
|
||||||
|
//// when(mockAllocateProfileResponse.getAcToken())
|
||||||
|
//// .thenReturn(acToken);
|
||||||
|
////
|
||||||
|
//// when(mockEs9PlusImpl.allocateProfile(eid, mcc))
|
||||||
|
//// .thenReturn(mockAllocateProfileResponse);
|
||||||
|
////
|
||||||
|
//// String run = allocateProfileWorker.run(buildLpadWorkerExchange(buildAllocateProfileInputParams(mcc, eid)));
|
||||||
|
////
|
||||||
|
//// assertEquals(acToken, run);
|
||||||
|
//// verify(mockProgress, times(1))
|
||||||
|
//// .setTotalSteps(2);
|
||||||
|
//// verify(mockProgress, times(1))
|
||||||
|
//// .stepExecuted(ProgressStep.ALLOCATE_PROFILE_ALLOCATING, "allocateProfile allocating...");
|
||||||
|
//// verify(mockProgress, times(1))
|
||||||
|
//// .stepExecuted(ProgressStep.ALLOCATE_PROFILE_ALLOCATED, "allocateProfile allocated!");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Test(expected = RuntimeException.class)
|
||||||
|
// public void shouldThrowRuntimeExceptionWhenRspEs29ModuleReturnsANullAllocateProfileResponse() {
|
||||||
|
// LogStub.getInstance().setLogLevel(Level.FINEST);
|
||||||
|
//
|
||||||
|
// String mcc = "351";
|
||||||
|
// String eid = "2";
|
||||||
|
//
|
||||||
|
// when(mockEs9PlusImpl.allocateProfile(eid, mcc))
|
||||||
|
// .thenReturn(null);
|
||||||
|
//
|
||||||
|
// allocateProfileWorker
|
||||||
|
// = new AllocateProfileWorker(mockProgress, mockEs9PlusImpl);
|
||||||
|
//
|
||||||
|
// allocateProfileWorker.run(buildLpadWorkerExchange(buildAllocateProfileInputParams(mcc, eid)));
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Test(expected = IllegalArgumentException.class)
|
||||||
|
// public void shouldThrowIllegalArgumentExceptionWhenAllocateProfileInputParamsIsNull() {
|
||||||
|
// allocateProfileWorker.run(null);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Test(expected = IllegalArgumentException.class)
|
||||||
|
// public void shouldThrowIllegalArgumentExceptionWhenMccIsNull() {
|
||||||
|
//
|
||||||
|
// allocateProfileWorker.run(buildLpadWorkerExchange(buildAllocateProfileInputParams(null, "eid")));
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Test(expected = IllegalArgumentException.class)
|
||||||
|
// public void shouldThrowIllegalArgumentExceptionWhenMccIsEmpty() {
|
||||||
|
//
|
||||||
|
// allocateProfileWorker.run(buildLpadWorkerExchange(buildAllocateProfileInputParams("", "eid")));
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Test(expected = IllegalArgumentException.class)
|
||||||
|
// public void shouldThrowIllegalArgumentExceptionWhenEidIsNull() {
|
||||||
|
//
|
||||||
|
// allocateProfileWorker.run(buildLpadWorkerExchange(buildAllocateProfileInputParams("mcc", null)));
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Test(expected = IllegalArgumentException.class)
|
||||||
|
// public void shouldThrowIllegalArgumentExceptionWhenEidIsEmpty() {
|
||||||
|
//
|
||||||
|
// allocateProfileWorker.run(buildLpadWorkerExchange(buildAllocateProfileInputParams("mcc", "")));
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// private AllocateProfileWorker.AllocateProfileInputParams buildAllocateProfileInputParams(final String mcc, final String eid) {
|
||||||
|
// return allocateProfileWorker. new AllocateProfileInputParams(mcc, eid);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// private LpadWorkerExchange<AllocateProfileWorker.AllocateProfileInputParams> buildLpadWorkerExchange(final AllocateProfileWorker.AllocateProfileInputParams allocateProfileInputParams) {
|
||||||
|
// return new LpadWorkerExchange<>(allocateProfileInputParams);
|
||||||
|
// }
|
||||||
|
}
|
|
@ -0,0 +1,213 @@
|
||||||
|
package com.truphone.lpad.worker;
|
||||||
|
|
||||||
|
import com.truphone.lpa.ApduChannel;
|
||||||
|
import com.truphone.lpad.progress.Progress;
|
||||||
|
import com.truphone.lpad.progress.ProgressStep;
|
||||||
|
import com.truphone.util.ToTLV;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
|
import static org.mockito.Matchers.any;
|
||||||
|
import static org.mockito.Matchers.anyString;
|
||||||
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
|
public class DeleteProfileWorkerTest {
|
||||||
|
|
||||||
|
private DeleteProfileWorker deleteProfileWorker;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private Progress mockProgress;
|
||||||
|
@Mock
|
||||||
|
private ApduChannel mockApduChannel;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
MockitoAnnotations.initMocks(this);
|
||||||
|
deleteProfileWorker = new DeleteProfileWorker(mockProgress, mockApduChannel);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void shouldThrowIllegalArgumentExceptionProgressIsNull() {
|
||||||
|
new DeleteProfileWorker(null, mockApduChannel);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void shouldThrowIllegalArgumentExceptionWhenApduChannelIsNull() {
|
||||||
|
new DeleteProfileWorker(mockProgress, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void shouldThrowIllegalArgumentExceptionWhenDeleteProfileInputParamsIsNull() {
|
||||||
|
deleteProfileWorker.run(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void shouldThrowIllegalArgumentExceptionWhenDeleteProfileInputParamsBodyIsNull() {
|
||||||
|
deleteProfileWorker.run(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void shouldThrowIllegalArgumentExceptionWhenICCIDIsNull() {
|
||||||
|
deleteProfileWorker.run(buildLpadWorkerExchange(buildDeleteProfileInputParams(null)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void shouldThrowIllegalArgumentExceptionWhenICCIDIsEmpty() {
|
||||||
|
deleteProfileWorker.run(buildLpadWorkerExchange(buildDeleteProfileInputParams("")));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = RuntimeException.class)
|
||||||
|
public void theTransmissionFailedResponseWrongContent(){
|
||||||
|
String iccid = "89445035401458888888";
|
||||||
|
String eResponse = "TEST";
|
||||||
|
when(mockApduChannel.transmitAPDU(anyString())).thenReturn(eResponse);
|
||||||
|
|
||||||
|
deleteProfileWorker.run(buildLpadWorkerExchange(buildDeleteProfileInputParams(iccid)));
|
||||||
|
|
||||||
|
verify(mockProgress, times(1)).setTotalSteps(3);
|
||||||
|
verify(mockProgress, times(1))
|
||||||
|
.stepExecuted(ProgressStep.DELETE_PROFILE_DELETING_PROFILE, iccid + " delete profile");
|
||||||
|
verify(mockProgress, times(1))
|
||||||
|
.stepExecuted(ProgressStep.DELETE_PROFILE_CONVERTING_RESPONSE, "Converting response");
|
||||||
|
verify(mockProgress, times(0))
|
||||||
|
.stepExecuted(ProgressStep.DELETE_PROFILE_DELETED, iccid + " deleted successfully");
|
||||||
|
verify(mockProgress, times(0))
|
||||||
|
.stepExecuted(ProgressStep.DELETE_PROFILE_NOT_DELETED, iccid + " profile not deleted");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = RuntimeException.class)
|
||||||
|
public void theTransmissionFailedResponseEmpty(){
|
||||||
|
String iccid = "89445035401458888888";
|
||||||
|
String eResponse = "";
|
||||||
|
|
||||||
|
when(mockApduChannel.transmitAPDU(any(String.class))).thenReturn(eResponse);
|
||||||
|
|
||||||
|
deleteProfileWorker.run(buildLpadWorkerExchange(buildDeleteProfileInputParams(iccid)));
|
||||||
|
|
||||||
|
verify(mockProgress, times(1)).setTotalSteps(3);
|
||||||
|
verify(mockProgress, times(1))
|
||||||
|
.stepExecuted(ProgressStep.DELETE_PROFILE_DELETING_PROFILE, iccid + " delete profile");
|
||||||
|
verify(mockProgress, times(1))
|
||||||
|
.stepExecuted(ProgressStep.DELETE_PROFILE_CONVERTING_RESPONSE, "Converting response");
|
||||||
|
verify(mockProgress, times(0))
|
||||||
|
.stepExecuted(ProgressStep.DELETE_PROFILE_DELETED, iccid + " deleted successfully");
|
||||||
|
verify(mockProgress, times(0))
|
||||||
|
.stepExecuted(ProgressStep.DELETE_PROFILE_NOT_DELETED, iccid + " profile not deleted");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void theTransmissionResponseOk(){
|
||||||
|
String iccid = "89445035401458888888";
|
||||||
|
String eResponse = ToTLV.toTLV("BF33", ToTLV.toTLV("80", "00"));
|
||||||
|
|
||||||
|
when(mockApduChannel.transmitAPDU(any(String.class))).thenReturn(eResponse);
|
||||||
|
deleteProfileWorker.run(buildLpadWorkerExchange(buildDeleteProfileInputParams(iccid)));
|
||||||
|
|
||||||
|
verify(mockProgress, times(1)).setTotalSteps(3);
|
||||||
|
verify(mockProgress, times(1))
|
||||||
|
.stepExecuted(ProgressStep.DELETE_PROFILE_DELETING_PROFILE, iccid + " delete profile");
|
||||||
|
verify(mockProgress, times(1))
|
||||||
|
.stepExecuted(ProgressStep.DELETE_PROFILE_CONVERTING_RESPONSE, "Converting response");
|
||||||
|
verify(mockApduChannel, times(1)).sendStatus();
|
||||||
|
|
||||||
|
verify(mockProgress, times(1))
|
||||||
|
.stepExecuted(ProgressStep.DELETE_PROFILE_DELETED, iccid + " deleted successfully");
|
||||||
|
verify(mockProgress, times(0))
|
||||||
|
.stepExecuted(ProgressStep.DELETE_PROFILE_NOT_DELETED, iccid + " profile not deleted");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void theTransmissionFailedIccidOrAidNotFound(){
|
||||||
|
String iccid = "89445035401458888888";
|
||||||
|
String eResponse = ToTLV.toTLV("BF33", ToTLV.toTLV("80", "01"));
|
||||||
|
|
||||||
|
when(mockApduChannel.transmitAPDU(any(String.class))).thenReturn(eResponse);
|
||||||
|
deleteProfileWorker.run(buildLpadWorkerExchange(buildDeleteProfileInputParams(iccid)));
|
||||||
|
|
||||||
|
verify(mockProgress, times(1)).setTotalSteps(3);
|
||||||
|
verify(mockProgress, times(1))
|
||||||
|
.stepExecuted(ProgressStep.DELETE_PROFILE_DELETING_PROFILE, iccid + " delete profile");
|
||||||
|
verify(mockProgress, times(1))
|
||||||
|
.stepExecuted(ProgressStep.DELETE_PROFILE_CONVERTING_RESPONSE, "Converting response");
|
||||||
|
verify(mockApduChannel, times(0)).sendStatus();
|
||||||
|
|
||||||
|
verify(mockProgress, times(0))
|
||||||
|
.stepExecuted(ProgressStep.DELETE_PROFILE_DELETED, iccid + " deleted successfully");
|
||||||
|
verify(mockProgress, times(1))
|
||||||
|
.stepExecuted(ProgressStep.DELETE_PROFILE_NOT_DELETED, iccid + " profile not deleted");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void theTransmissionFailedProfileNotInDisabledState(){
|
||||||
|
String iccid = "89445035401458888888";
|
||||||
|
String eResponse = ToTLV.toTLV("BF33", ToTLV.toTLV("80", "02"));
|
||||||
|
|
||||||
|
when(mockApduChannel.transmitAPDU(any(String.class))).thenReturn(eResponse);
|
||||||
|
deleteProfileWorker.run(buildLpadWorkerExchange(buildDeleteProfileInputParams(iccid)));
|
||||||
|
|
||||||
|
verify(mockProgress, times(1)).setTotalSteps(3);
|
||||||
|
verify(mockProgress, times(1))
|
||||||
|
.stepExecuted(ProgressStep.DELETE_PROFILE_DELETING_PROFILE, iccid + " delete profile");
|
||||||
|
verify(mockProgress, times(1))
|
||||||
|
.stepExecuted(ProgressStep.DELETE_PROFILE_CONVERTING_RESPONSE, "Converting response");
|
||||||
|
verify(mockApduChannel, times(0)).sendStatus();
|
||||||
|
|
||||||
|
verify(mockProgress, times(0))
|
||||||
|
.stepExecuted(ProgressStep.DELETE_PROFILE_DELETED, iccid + " deleted successfully");
|
||||||
|
verify(mockProgress, times(1))
|
||||||
|
.stepExecuted(ProgressStep.DELETE_PROFILE_NOT_DELETED, iccid + " profile not deleted");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void theTransmissionFailedDisallowedByPolicy(){
|
||||||
|
String iccid = "89445035401458888888";
|
||||||
|
String eResponse = ToTLV.toTLV("BF33", ToTLV.toTLV("80", "03"));
|
||||||
|
|
||||||
|
when(mockApduChannel.transmitAPDU(any(String.class))).thenReturn(eResponse);
|
||||||
|
deleteProfileWorker.run(buildLpadWorkerExchange(buildDeleteProfileInputParams(iccid)));
|
||||||
|
|
||||||
|
verify(mockProgress, times(1)).setTotalSteps(3);
|
||||||
|
verify(mockProgress, times(1))
|
||||||
|
.stepExecuted(ProgressStep.DELETE_PROFILE_DELETING_PROFILE, iccid + " delete profile");
|
||||||
|
verify(mockProgress, times(1))
|
||||||
|
.stepExecuted(ProgressStep.DELETE_PROFILE_CONVERTING_RESPONSE, "Converting response");
|
||||||
|
verify(mockApduChannel, times(0)).sendStatus();
|
||||||
|
|
||||||
|
verify(mockProgress, times(0))
|
||||||
|
.stepExecuted(ProgressStep.DELETE_PROFILE_DELETED, iccid + " deleted successfully");
|
||||||
|
verify(mockProgress, times(1))
|
||||||
|
.stepExecuted(ProgressStep.DELETE_PROFILE_NOT_DELETED, iccid + " profile not deleted");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void theTransmissionFailedUndefinedError(){
|
||||||
|
String iccid = "89445035401458888888";
|
||||||
|
String eResponse = ToTLV.toTLV("BF33", ToTLV.toTLV("80", "7F")); //7F
|
||||||
|
when(mockApduChannel.transmitAPDU(any(String.class))).thenReturn(eResponse);
|
||||||
|
deleteProfileWorker.run(buildLpadWorkerExchange(buildDeleteProfileInputParams(iccid)));
|
||||||
|
|
||||||
|
verify(mockProgress, times(1)).setTotalSteps(3);
|
||||||
|
verify(mockProgress, times(1))
|
||||||
|
.stepExecuted(ProgressStep.DELETE_PROFILE_DELETING_PROFILE, iccid + " delete profile");
|
||||||
|
verify(mockProgress, times(1))
|
||||||
|
.stepExecuted(ProgressStep.DELETE_PROFILE_CONVERTING_RESPONSE, "Converting response");
|
||||||
|
verify(mockApduChannel, times(0)).sendStatus();
|
||||||
|
|
||||||
|
verify(mockProgress, times(0))
|
||||||
|
.stepExecuted(ProgressStep.DELETE_PROFILE_DELETED, iccid + " deleted successfully");
|
||||||
|
verify(mockProgress, times(1))
|
||||||
|
.stepExecuted(ProgressStep.DELETE_PROFILE_NOT_DELETED, iccid + " profile not deleted");
|
||||||
|
}
|
||||||
|
|
||||||
|
private DeleteProfileWorker.DeleteProfileInputParams buildDeleteProfileInputParams(final String iccid) {
|
||||||
|
return deleteProfileWorker. new DeleteProfileInputParams(iccid);
|
||||||
|
}
|
||||||
|
|
||||||
|
private LpadWorkerExchange<DeleteProfileWorker.DeleteProfileInputParams> buildLpadWorkerExchange(final DeleteProfileWorker.DeleteProfileInputParams deleteProfileInputParams) {
|
||||||
|
return new LpadWorkerExchange<>(deleteProfileInputParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,111 @@
|
||||||
|
package com.truphone.lpad.worker;
|
||||||
|
|
||||||
|
|
||||||
|
import com.truphone.lpa.ApduChannel;
|
||||||
|
import com.truphone.lpa.apdu.ApduUtils;
|
||||||
|
import com.truphone.lpad.progress.Progress;
|
||||||
|
import com.truphone.lpad.progress.ProgressStep;
|
||||||
|
import com.truphone.util.LogStub;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.mockito.Matchers.any;
|
||||||
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
|
public class GetEidLpadWorkerTest {
|
||||||
|
|
||||||
|
private GetEidLpadWorker getIdWorker;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private Progress mockProgress;
|
||||||
|
@Mock
|
||||||
|
private ApduChannel mockApduChannel;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
MockitoAnnotations.initMocks(this);
|
||||||
|
|
||||||
|
getIdWorker = new GetEidLpadWorker(mockProgress, mockApduChannel);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void shouldThrowIllegalArgumentExceptionWhenProgressIsNull() {
|
||||||
|
new GetEidLpadWorker(null, mockApduChannel);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void shouldThrowIllegalArgumentExceptionWhenApduChannelIsNull() {
|
||||||
|
new GetEidLpadWorker(mockProgress, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void shouldThrowIllegalArgumentExceptionWhenTransmitAPDUReturnNull() {
|
||||||
|
when(mockApduChannel.transmitAPDU(any(String.class)))
|
||||||
|
.thenReturn(null);
|
||||||
|
|
||||||
|
getIdWorker.run(buildStringLpadWorkerExchange(ApduUtils.getEIDApdu()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void shouldThrowIllegalArgumentExceptionWhenTransmitAPDUReturnEmpty() {
|
||||||
|
when(mockApduChannel.transmitAPDU(any(String.class)))
|
||||||
|
.thenReturn("");
|
||||||
|
|
||||||
|
getIdWorker.run(buildStringLpadWorkerExchange(ApduUtils.getEIDApdu()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = RuntimeException.class)
|
||||||
|
public void shouldThrowRuntimeExceptionWhenIdentifierDoesNotMatch() {
|
||||||
|
when(mockApduChannel.transmitAPDU(any(String.class)))
|
||||||
|
.thenReturn("A0A40000027F");
|
||||||
|
|
||||||
|
getIdWorker.run(buildStringLpadWorkerExchange(ApduUtils.getEIDApdu()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = RuntimeException.class)
|
||||||
|
public void shouldThrowRuntimeExceptionWhenDecodeFails() {
|
||||||
|
LogStub.getInstance().setLogLevel(Level.FINEST);
|
||||||
|
when(mockApduChannel.transmitAPDU(any(String.class)))
|
||||||
|
.thenReturn("asdasdasd");
|
||||||
|
|
||||||
|
getIdWorker.run(buildStringLpadWorkerExchange(ApduUtils.getEIDApdu()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = RuntimeException.class)
|
||||||
|
public void shouldThrowRuntimeExceptionWhenEidApduIsNull() {
|
||||||
|
getIdWorker.run(buildStringLpadWorkerExchange(null));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = RuntimeException.class)
|
||||||
|
public void shouldThrowRuntimeExceptionWhenEidApduIsEmpty() {
|
||||||
|
getIdWorker.run(buildStringLpadWorkerExchange(""));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldGetEidData() {
|
||||||
|
when(mockApduChannel.transmitAPDU(any(String.class)))
|
||||||
|
.thenReturn("bf3e125a10890440500010006800000000000001709000");
|
||||||
|
|
||||||
|
String eidData = getIdWorker.run(buildStringLpadWorkerExchange(ApduUtils.getEIDApdu()));
|
||||||
|
|
||||||
|
assertEquals("89044050001000680000000000000170", eidData);
|
||||||
|
verify(mockProgress, times(1))
|
||||||
|
.setTotalSteps(3);
|
||||||
|
verify(mockProgress, times(1))
|
||||||
|
.stepExecuted(ProgressStep.GET_EID_RETRIEVING, "getEID retrieving...");
|
||||||
|
verify(mockProgress, times(1))
|
||||||
|
.stepExecuted(ProgressStep.GET_EID_CONVERTING, "getEID converting...");
|
||||||
|
verify(mockProgress, times(1))
|
||||||
|
.stepExecuted(ProgressStep.GET_EID_CONVERTED, "getEID converted...");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private LpadWorkerExchange<String> buildStringLpadWorkerExchange(final String eidApdu) {
|
||||||
|
return new LpadWorkerExchange<>(eidApdu);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,82 @@
|
||||||
|
package integration;
|
||||||
|
|
||||||
|
import com.github.tomakehurst.wiremock.common.ConsoleNotifier;
|
||||||
|
import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
|
||||||
|
import com.github.tomakehurst.wiremock.junit.WireMockRule;
|
||||||
|
import integration.utils.ReferenceData;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.ClassRule;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
import com.truphone.lpa.ApduChannel;
|
||||||
|
import com.truphone.lpa.LocalProfileAssistant;
|
||||||
|
import com.truphone.lpa.impl.LocalProfileAssistantImpl;
|
||||||
|
|
||||||
|
import static com.github.tomakehurst.wiremock.client.WireMock.*;
|
||||||
|
import static org.mockito.Matchers.anyString;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
public class AllocateProfileTest {
|
||||||
|
private LocalProfileAssistant localProfileAssistant;
|
||||||
|
|
||||||
|
// @Mock
|
||||||
|
// private ApduChannel mockApduChannel;
|
||||||
|
//
|
||||||
|
// @ClassRule
|
||||||
|
// public static WireMockRule wireMockRule = new WireMockRule(WireMockConfiguration.options().port(8090).httpsPort(8443).notifier(new ConsoleNotifier(true)));
|
||||||
|
//
|
||||||
|
// @Before
|
||||||
|
// public void setUp() {
|
||||||
|
// MockitoAnnotations.initMocks(this);
|
||||||
|
//
|
||||||
|
// localProfileAssistant = new LocalProfileAssistantImpl(this.mockApduChannel);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Test
|
||||||
|
// public void shouldReturnAcToken() {
|
||||||
|
// wireMockRule.stubFor(post(urlMatching("/custom/profile/"))
|
||||||
|
// .withHeader("Content-type", equalTo("application/x-www-form-urlencoded"))
|
||||||
|
// .withHeader("User-Agent", equalTo("gsma-rsp-com.truphone.lpad"))
|
||||||
|
// .withHeader("X-Admin-Protocol", equalTo("gsma/rsp/v2.2.0"))
|
||||||
|
// .withRequestBody(containing("eid=89044050001000680000000000000170&mcc=351"))
|
||||||
|
// .willReturn(aResponse().withStatus(200).withBody("$1$rsp.truphone.com$2")));
|
||||||
|
//
|
||||||
|
// when(mockApduChannel.transmitAPDU(anyString()))
|
||||||
|
// .thenReturn(ReferenceData.VALID_EID);
|
||||||
|
//
|
||||||
|
// Assert.assertEquals("2", localProfileAssistant.allocateProfile("351"));
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Test(expected = RuntimeException.class)
|
||||||
|
// public void shouldThrowRuntimeExceptionWhenRspServerRespondesWithEmpty() {
|
||||||
|
// wireMockRule.stubFor(post(urlMatching("/custom/profile/"))
|
||||||
|
// .withHeader("Content-type", equalTo("application/x-www-form-urlencoded"))
|
||||||
|
// .withHeader("User-Agent", equalTo("gsma-rsp-com.truphone.lpad"))
|
||||||
|
// .withHeader("X-Admin-Protocol", equalTo("gsma/rsp/v2.2.0"))
|
||||||
|
// .withRequestBody(containing("eid=89044050001000680000000000000170&mcc=351"))
|
||||||
|
// .willReturn(aResponse().withStatus(200).withBody("x")));
|
||||||
|
//
|
||||||
|
// when(mockApduChannel.transmitAPDU(anyString()))
|
||||||
|
// .thenReturn(ReferenceData.VALID_EID);
|
||||||
|
//
|
||||||
|
// localProfileAssistant.allocateProfile("351");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// @Test(expected = RuntimeException.class)
|
||||||
|
// public void shouldThrowRuntimeExceptionWhenRspServerRespondesWithStatusDifferentOf2xx() {
|
||||||
|
// wireMockRule.stubFor(post(urlMatching("/custom/profile/"))
|
||||||
|
// .withHeader("Content-type", equalTo("application/x-www-form-urlencoded"))
|
||||||
|
// .withHeader("User-Agent", equalTo("gsma-rsp-com.truphone.lpad"))
|
||||||
|
// .withHeader("X-Admin-Protocol", equalTo("gsma/rsp/v2.2.0"))
|
||||||
|
// .withRequestBody(containing("eid=89044050001000680000000000000170&mcc=351"))
|
||||||
|
// .willReturn(aResponse().withStatus(400).withBody("x")));
|
||||||
|
//
|
||||||
|
// when(mockApduChannel.transmitAPDU(anyString()))
|
||||||
|
// .thenReturn(ReferenceData.VALID_EID);
|
||||||
|
//
|
||||||
|
// localProfileAssistant.allocateProfile("351");
|
||||||
|
// }
|
||||||
|
}
|
|
@ -0,0 +1,104 @@
|
||||||
|
package integration;
|
||||||
|
|
||||||
|
|
||||||
|
import com.truphone.lpa.ApduChannel;
|
||||||
|
import com.truphone.lpa.LocalProfileAssistant;
|
||||||
|
import com.truphone.lpa.impl.LocalProfileAssistantImpl;
|
||||||
|
import com.truphone.lpad.progress.Progress;
|
||||||
|
import com.truphone.util.ToTLV;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.mockito.Matchers.any;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
public class DeleteProfileTest {
|
||||||
|
private LocalProfileAssistant localProfileAssistant;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private ApduChannel mockApduChannel;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private Progress mockProgress;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
MockitoAnnotations.initMocks(this);
|
||||||
|
|
||||||
|
localProfileAssistant = new LocalProfileAssistantImpl(this.mockApduChannel);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldResponseOk() {
|
||||||
|
String response = ToTLV.toTLV("BF33", ToTLV.toTLV("80", "00"));
|
||||||
|
when(mockApduChannel.transmitAPDU(any(String.class)))
|
||||||
|
.thenReturn(response);
|
||||||
|
|
||||||
|
assertEquals("0", this.localProfileAssistant.deleteProfile("89445035401458888888", mockProgress));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldFailedIccidOrAidNotFound() {
|
||||||
|
String response = ToTLV.toTLV("BF33", ToTLV.toTLV("80", "01"));
|
||||||
|
when(mockApduChannel.transmitAPDU(any(String.class)))
|
||||||
|
.thenReturn(response);
|
||||||
|
|
||||||
|
assertEquals("1", this.localProfileAssistant.deleteProfile("89445035401458888888", mockProgress));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldFailedProfileNotInDisabledState() {
|
||||||
|
String response = ToTLV.toTLV("BF33", ToTLV.toTLV("80", "02"));
|
||||||
|
when(mockApduChannel.transmitAPDU(any(String.class)))
|
||||||
|
.thenReturn(response);
|
||||||
|
|
||||||
|
assertEquals("2", this.localProfileAssistant.deleteProfile("89445035401458888888", mockProgress));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldFailedDisallowedByPolicy() {
|
||||||
|
String response = ToTLV.toTLV("BF33", ToTLV.toTLV("80", "03"));
|
||||||
|
when(mockApduChannel.transmitAPDU(any(String.class)))
|
||||||
|
.thenReturn(response);
|
||||||
|
|
||||||
|
assertEquals("3", this.localProfileAssistant.deleteProfile("89445035401458888888", mockProgress));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldFailedUndefinedError() {
|
||||||
|
String response = ToTLV.toTLV("BF33", ToTLV.toTLV("80", "7F"));
|
||||||
|
when(mockApduChannel.transmitAPDU(any(String.class)))
|
||||||
|
.thenReturn(response);
|
||||||
|
|
||||||
|
assertEquals("127", this.localProfileAssistant.deleteProfile("89445035401458888888", mockProgress));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = RuntimeException.class)
|
||||||
|
public void shouldFailedReturnStringWrong() {
|
||||||
|
when(mockApduChannel.transmitAPDU(any(String.class)))
|
||||||
|
.thenReturn("randomstring");
|
||||||
|
|
||||||
|
this.localProfileAssistant.deleteProfile("89445035401458888888", mockProgress);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = RuntimeException.class)
|
||||||
|
public void shouldFailedReturnEmptyString() {
|
||||||
|
when(mockApduChannel.transmitAPDU(any(String.class)))
|
||||||
|
.thenReturn("");
|
||||||
|
|
||||||
|
this.localProfileAssistant.deleteProfile("89445035401458888888", mockProgress);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test(expected = RuntimeException.class)
|
||||||
|
public void shouldFailedReturnNullString() {
|
||||||
|
when(mockApduChannel.transmitAPDU(any(String.class)))
|
||||||
|
.thenReturn(null);
|
||||||
|
|
||||||
|
this.localProfileAssistant.deleteProfile("89445035401458888888", mockProgress);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,72 @@
|
||||||
|
package integration;
|
||||||
|
|
||||||
|
|
||||||
|
import integration.utils.ReferenceData;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
import com.truphone.lpa.ApduChannel;
|
||||||
|
import com.truphone.lpa.LocalProfileAssistant;
|
||||||
|
import com.truphone.lpa.impl.LocalProfileAssistantImpl;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.mockito.Matchers.any;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
public class GetEidTest {
|
||||||
|
private LocalProfileAssistant localProfileAssistant;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private ApduChannel mockApduChannel;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
MockitoAnnotations.initMocks(this);
|
||||||
|
|
||||||
|
localProfileAssistant = new LocalProfileAssistantImpl(this.mockApduChannel);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldReturnEid() {
|
||||||
|
when(mockApduChannel.transmitAPDU(any(String.class)))
|
||||||
|
.thenReturn(ReferenceData.VALID_EID);
|
||||||
|
|
||||||
|
assertEquals("89044050001000680000000000000170", this.localProfileAssistant.getEID());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = RuntimeException.class)
|
||||||
|
public void shouldThrowRuntimeExceptionWhenApduChannelRespondsWithNonHexadecimalValue() {
|
||||||
|
when(mockApduChannel.transmitAPDU(any(String.class)))
|
||||||
|
.thenReturn("asdasd");
|
||||||
|
|
||||||
|
|
||||||
|
assertEquals("89044050001000680000000000000170", this.localProfileAssistant.getEID());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = RuntimeException.class)
|
||||||
|
public void shouldThrowRuntimeExceptionWhenApduChannelRespondsWithAnInvalidEID() {
|
||||||
|
when(mockApduChannel.transmitAPDU(any(String.class)))
|
||||||
|
.thenReturn("dfcd8f12a77c264a0ce4");
|
||||||
|
|
||||||
|
assertEquals("89044050001000680000000000000170", this.localProfileAssistant.getEID());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = RuntimeException.class)
|
||||||
|
public void shouldThrowRuntimeExceptionWhenApduChannelRespondsWithNull() {
|
||||||
|
when(mockApduChannel.transmitAPDU(any(String.class)))
|
||||||
|
.thenReturn(null);
|
||||||
|
|
||||||
|
|
||||||
|
assertEquals("89044050001000680000000000000170", this.localProfileAssistant.getEID());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = RuntimeException.class)
|
||||||
|
public void shouldThrowRuntimeExceptionWhenApduChannelRespondsWithEmpty() {
|
||||||
|
when(mockApduChannel.transmitAPDU(any(String.class)))
|
||||||
|
.thenReturn("");
|
||||||
|
|
||||||
|
|
||||||
|
assertEquals("89044050001000680000000000000170", this.localProfileAssistant.getEID());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
package integration.utils;
|
||||||
|
|
||||||
|
public interface ReferenceData {
|
||||||
|
|
||||||
|
String VALID_EID = "bf3e125a10890440500010006800000000000001709000";
|
||||||
|
}
|
|
@ -13,4 +13,4 @@ dependencyResolutionManagement {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rootProject.name = "OpenEUICC"
|
rootProject.name = "OpenEUICC"
|
||||||
include ':app'
|
include ':app', ':libs:lpad-sm-dp-plus-connector'
|
||||||
|
|
Loading…
Reference in New Issue