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
|
||||
.cxx
|
||||
local.properties
|
||||
/libs/**/build
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<bytecodeTargetLevel target="11" />
|
||||
<bytecodeTargetLevel target="1.8">
|
||||
<module name="OpenEUICC.app" target="11" />
|
||||
</bytecodeTargetLevel>
|
||||
</component>
|
||||
</project>
|
|
@ -1,5 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="GradleMigrationSettings" migrationVersion="1" />
|
||||
<component name="GradleSettings">
|
||||
<option name="linkedExternalProjectsSettings">
|
||||
<GradleProjectSettings>
|
||||
|
@ -11,6 +12,8 @@
|
|||
<set>
|
||||
<option value="$PROJECT_DIR$" />
|
||||
<option value="$PROJECT_DIR$/app" />
|
||||
<option value="$PROJECT_DIR$/libs" />
|
||||
<option value="$PROJECT_DIR$/libs/lpad-sm-dp-plus-connector" />
|
||||
</set>
|
||||
</option>
|
||||
<option name="resolveModulePerSourceSet" value="false" />
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<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" />
|
||||
</component>
|
||||
<component name="ProjectType">
|
||||
|
|
|
@ -32,7 +32,7 @@ android {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
implementation project(":libs:lpad-sm-dp-plus-connector")
|
||||
implementation 'androidx.core:core-ktx:1.7.0'
|
||||
implementation 'androidx.appcompat:appcompat:1.4.1'
|
||||
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"
|
||||
include ':app'
|
||||
include ':app', ':libs:lpad-sm-dp-plus-connector'
|
||||
|
|
Loading…
Reference in New Issue