Commit e3667545 authored by Josh Ji's avatar Josh Ji

Initial commit

parents
# Project exclude paths
/.gradle/
/build/
\ No newline at end of file
# Default ignored files
/shelf/
/workspace.xml
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="1.8" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleMigrationSettings" migrationVersion="1" />
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
</set>
</option>
</GradleProjectSettings>
</option>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central repository" />
<option name="url" value="https://repo1.maven.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
<remote-repository>
<option name="id" value="MavenRepo" />
<option name="name" value="MavenRepo" />
<option name="url" value="https://repo.maven.apache.org/maven2/" />
</remote-repository>
<remote-repository>
<option name="id" value="maven2" />
<option name="name" value="maven2" />
<option name="url" value="https://deadcode.me/mvm" />
</remote-repository>
<remote-repository>
<option name="id" value="maven" />
<option name="name" value="maven" />
<option name="url" value="https://javacard.pro/maven" />
</remote-repository>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>
\ No newline at end of file
buildscript{
repositories{
mavenCentral()
maven{url 'https://javacard.pro/maven'}
maven{url 'https://deadcode.me/mvm'}
}
dependencies{
classpath 'com.klinec:gradle-javacard:1.8.0'
}
}
plugins {
id 'java'
}
group 'josh'
version '1.0-SNAPSHOT'
apply plugin:'com.klinec.gradle.javacard'
apply plugin:'idea'
sourceCompatibility = 1.8
repositories {
mavenCentral()
maven{url 'https://javacard.pro/maven'}
maven{url 'https://deadcode.me/mvm'}
flatDir{
dirs 'libs'
}
}
dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.0'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine'
}
test {
useJUnitPlatform()
}
final def sdk_dir = 'sdks/jc304_kit'
javacard{
config{
jckit sdk_dir
debugGpPro true
cap{
packageName 'josh.passport'
version '0.1'
aid '0xA0:0x00:0x00:0x02:0x47:0x10'
output 'applet.cap'
targetsdk sdk_dir
applet{
className 'josh.passport.EvilPassportApplet'
aid '0xA0:0x00:0x00:0x02:0x47:0x10:0x01'
}
}
}
}
\ No newline at end of file
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
#!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=`expr $i + 1`
done
case $i in
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=`save "$@"`
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
exec "$JAVACMD" "$@"
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
Export file for package 'org.globalplatform' is generated with
AID: 0xA0:0x00:0x00:0x01:051:0x00
Version: 1.6
Backward Compatibility: Version 1.5
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=ISO-8859-1">
<meta http-equiv="Content-Style-Type" content="text/css">
<meta name="GENERATOR"
content="Adobe FrameMaker 7.0/HTML Export Filter">
<link rel="STYLESHEET" href="document.css" charset="ISO-8859-1"
type="text/css">
<title>Copyright</title>
</head>
<body style="background-color: rgb(255, 255, 255);">
<div><span style="font-weight: bold;">Copyright &copy; 1998, 2011,
Oracle and/or its affiliates. All rights reserved.</span><span
style="font-weight: bold;"><br>
</span>
<p>This software and related documentation are provided under a license
agreement containing restrictions on use and disclosure and are
protected by intellectual property laws. Except as expressly permitted
in your license agreement or allowed by law, you may not use, copy,
reproduce, translate, broadcast, modify, license, transmit, distribute,
exhibit, perform, publish, or display any part, in any form, or by any
means. Reverse engineering, disassembly, or decompilation of this
software, unless required by law for interoperability, is prohibited.</p>
<p>The information contained herein is subject to change without notice
and is not warranted to be error-free. If you find any errors, please
report them to us in writing.</p>
<p>If this is software or related software documentation that is
delivered to the U.S. Government or anyone licensing it on behalf of
the U.S. Government, the following notice is applicable:</p>
<p>U.S. GOVERNMENT RIGHTS Programs, software, databases, and related
documentation and technical data delivered to U.S. Government customers
are "commercial computer software" or "commercial technical data"
pursuant to the applicable Federal Acquisition Regulation and
agency-specific supplemental regulations. As such, the use,
duplication, disclosure, modification, and adaptation shall be subject
to the restrictions and license terms set forth in the applicable
Government contract, and, to the extent applicable by the terms of the
Government contract, the additional rights set forth in FAR 52.227-19,
Commercial Computer Software License (December 2007). Oracle USA, Inc.,
500 Oracle Parkway, Redwood City, CA 94065.</p>
<p>This software or hardware is developed for general use in a variety
of information management applications. It is not developed or intended
for use in any inherently dangerous applications, including
applications which may create a risk of personal injury. If you use
this software or hardware in dangerous applications, then you shall be
responsible to take all appropriate fail-safe, backup, redundancy, and
other measures to ensure the safe use. Oracle Corporation and its
affiliates disclaim any liability for any damages caused by use of this
software or hardware in dangerous applications.</p>
<p>Oracle and Java are registered trademarks of Oracle Corporation
and/or its
affiliates. Oracle and Java are registered trademarks of Oracle and/or
its affiliates. Other names may be trademarks of their respective
owners.</p>
<p>AMD, Opteron, the AMD logo, and the AMD Opteron logo are trademarks
or registered trademarks of Advanced Micro Devices. Intel and Intel
Xeon are trademarks or registered trademarks of Intel Corporation. All
SPARC trademarks are used under license and are trademarks or
registered trademarks of SPARC International, Inc. UNIX is a registered
trademark licensed through X/Open Company, Ltd.</p>
<p>This software or hardware and documentation may provide access to or
information on content, products, and services from third parties.
Oracle Corporation and its affiliates are not responsible for and
expressly disclaim all warranties of any kind with respect to
third-party content, products, and services. Oracle Corporation and its
affiliates will not be responsible for any loss, costs, or damages
incurred due to your access to or use of third-party content, products,
or services.<br>
</p>
<br>
<span style="font-weight: bold;">Copyright &copy; 1998, 2011, Oracle
et/ou ses affili&eacute;s.
Tous droits r&eacute;serv&eacute;s.
</span>
<p>Ce logiciel et la documentation qui l&#8217;accompagne sont
prot&eacute;g&eacute;s par les
lois sur la propri&eacute;t&eacute; intellectuelle. Ils sont
conc&eacute;d&eacute;s sous licence et soumis &agrave;
des restrictions d&#8217;utilisation et de divulgation. Sauf disposition de
votre contrat de licence ou
de la loi, vous ne pouvez pas copier, reproduire, traduire, diffuser,
modifier, breveter,
transmettre, distribuer, exposer, ex&eacute;cuter, publier ou afficher
le logiciel, m&ecirc;me partiellement, sous quelque forme
et par quelque proc&eacute;d&eacute; que ce soit. Par ailleurs, il est
interdit de
proc&eacute;der &agrave; toute ing&eacute;nierie inverse du logiciel,
de le d&eacute;sassembler ou de le d&eacute;compiler,
except&eacute; &agrave; des fins d&#8217;interop&eacute;rabilit&eacute; avec
des logiciels tiers ou tel que prescrit par
la loi.</p>
<p>Les informations fournies dans ce document sont susceptibles de
modification sans pr&eacute;avis.
Par ailleurs, Oracle Corporation ne garantit pas qu&#8217;elles soient
exemptes d&#8217;erreurs et vous invite,
le cas &eacute;ch&eacute;ant, &agrave; lui en faire part par
&eacute;crit.</p>
<p>Si ce logiciel, ou
la documentation qui l&#8217;accompagne, est conc&eacute;d&eacute; sous
licence au Gouvernement des Etats-Unis, ou &agrave;
toute entit&eacute; qui d&eacute;livre la licence de ce logiciel ou
l&#8217;utilise pour le
compte du Gouvernement des Etats-Unis, la notice suivante s&#8217;applique:</p>
<p>U.S. GOVERNMENT RIGHTS. Programs,
software, databases, and related documentation and technical data
delivered to U.S. Government customers are
"commercial computer software" or "commercial technical data" pursuant
to the applicable Federal Acquisition
Regulation and agency-specific supplemental regulations. As such, the
use, duplication, disclosure, modification, and
adaptation shall be subject to the restrictions and license terms set
forth in
the applicable Government contract, and, to the extent applicable by
the terms of the
Government contract, the additional rights set forth in FAR 52.227-19,
Commercial Computer Software
License (December 2007). Oracle America, Inc., 500 Oracle Parkway,
Redwood City, CA
94065.</p>
<p>Ce logiciel ou mat&eacute;riel a &eacute;t&eacute;
d&eacute;velopp&eacute; pour un usage g&eacute;n&eacute;ral dans le
cadre d&#8217;applications de gestion des informations. Ce logiciel ou
mat&eacute;riel n&#8217;est pas con&ccedil;u ni
n&#8217;est destin&eacute; &agrave; &ecirc;tre utilis&eacute; dans des
applications &agrave; risque, notamment dans des applications
pouvant causer des dommages corporels. Si vous utilisez ce logiciel ou
mat&eacute;riel dans
le cadre d&#8217;applications dangereuses, il est de votre
responsabilit&eacute; de prendre toutes les mesures
de secours, de sauvegarde, de redondance et autres mesures
n&eacute;cessaires &agrave; son utilisation
dans des conditions optimales de s&eacute;curit&eacute;. Oracle
Corporation et ses affili&eacute;s d&eacute;clinent toute
responsabilit&eacute;
quant aux dommages caus&eacute;s par l&#8217;utilisation de ce logiciel ou
mat&eacute;riel pour ce type
d&#8217;applications.</p>
<p>Oracle et Java sont des marques d&eacute;pos&eacute;es d&#8217;Oracle
Corporation et/ou de ses affili&eacute;s.Tout
autre nom mentionn&eacute; peut correspondre &agrave; des marques
appartenant &agrave; d&#8217;autres propri&eacute;taires qu&#8217;Oracle.</p>
<p>AMD, Opteron,
le logo AMD et le logo AMD Opteron sont des marques ou des
marques d&eacute;pos&eacute;es d&#8217;Advanced Micro Devices. Intel et Intel
Xeon sont des marques ou
des marques d&eacute;pos&eacute;es d&#8217;Intel Corporation. Toutes les
marques SPARC sont utilis&eacute;es sous licence et
sont des marques ou des marques d&eacute;pos&eacute;es de SPARC
International, Inc. UNIX est une
marque d&eacute;pos&eacute;e conc&eacute;d&eacute;e sous licence par
X/Open Company, Ltd.</p>
<p>Ce logiciel ou mat&eacute;riel et
la documentation qui l&#8217;accompagne peuvent fournir des informations ou
des liens donnant acc&egrave;s &agrave;
des contenus, des produits et des services &eacute;manant de tiers.
Oracle Corporation et
ses affili&eacute;s d&eacute;clinent toute responsabilit&eacute; ou
garantie expresse quant aux contenus, produits ou services
&eacute;manant de tiers. En aucun cas, Oracle Corporation et ses
affili&eacute;s ne sauraient
&ecirc;tre tenus pour responsables des pertes subies, des co&ucirc;ts
occasionn&eacute;s ou des dommages caus&eacute;s
par l&#8217;acc&egrave;s &agrave; des contenus, produits ou services tiers,
ou &agrave; leur utilisation.<br>
</p>
<p class="Paragraph-Credits"></p>
</div>
</body>
</html>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<meta http-equiv="CONTENT-TYPE"
content="text/html; charset=windows-1252">
<title>Release Notes - Classic Edition Development Kit, Java Card
Platform, Version 3.0.4</title>
<meta name="GENERATOR" content="OpenOffice.org 3.1 (Win32)">
<meta name="CREATED" content="0;0">
<meta name="CHANGEDBY" content="Saqib Ahmad">
<meta name="CHANGED" content="20110526;16055800">
<!-- Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. Use is subject to license terms. -->
<meta http-equiv="Content-Language" content="en-US">
<style type="text/css">
<!--
TD P { color: #000000; font-family: "Arial", "Helvetica", "FreeSans", "Luxi-sans", "Nimbus Sans L", sans-serif; font-size: 10pt }
P { color: #000000; font-family: "Arial", "Helvetica", "FreeSans", "Luxi-sans", "Nimbus Sans L", sans-serif; font-size: 10pt }
H4 { color: #000000 }
P.navtop { font-family: "Arial", "Helvetica", "FreeSans", "Luxi-sans", "Nimbus Sans L", sans-serif; font-size: 10pt }
H2 { color: #000000 }
H3 { color: #000000 }
H2.doctitle { color: #7f7f7f; font-family: "Univers LT Std", "Univers", "Arial", "Helvetica", sans-serif; text-align: left; text-decoration: none }
H3.subtitle { color: #7f7f7f; font-family: "Univers LT Std", "Univers", "Arial", "Helvetica", sans-serif; text-align: left; text-decoration: none }
H4.titledate { color: #7f7f7f; font-family: "Univers LT Std", "Univers", "Arial", "Helvetica", sans-serif; text-align: left; text-decoration: none }
BLOCKQUOTE { color: #000000; font-family: "Arial", "Helvetica", "FreeSans", "Luxi-sans", "Nimbus Sans L", sans-serif; font-size: 10pt }
TH P { color: #000000; font-family: "Arial", "Helvetica", "FreeSans", "Luxi-sans", "Nimbus Sans L", sans-serif; font-size: 10pt }
A:link { color: #666666; text-decoration: none }
CODE { color: #000000; font-family: "Monaco", "Courier", "Courier New" }
A:visited { color: #666666 }
-->
</style>
</head>
<body dir="LTR" vlink="#666666" bgcolor="#ffffff" lang="en-US"
link="#666666" text="#000000">
<table style="page-break-before: always;" width="100%" cellpadding="2"
cellspacing="2">
<tbody>
<tr>
<td>
<h2 class="doctitle"><a name="c1"></a><a name="c2"></a>Release
Notes</h2>
</td>
<th>
<div style="text-align: right;"> </div>
<p style="text-align: right;"><font color="#666666"><a
href="http://www.oracle.com/"><font color="#666666"><img
src="shared/smallOracleLogo.gif" name="graphics1" alt="Oracle logo"
width="133" align="BOTTOM" border="1" height="18"></font></a></font></p>
</th>
</tr>
</tbody>
</table>
<hr>
<table width="100%" cellpadding="2" cellspacing="2">
<tbody>
<tr valign="TOP">
<td>
<h2 class="doctitle"><a name="c5"></a><a name="c4"></a>Development
Kit
for
the
Java
Card
3
Platform</h2>
</td>
<th rowspan="3">
<p><a name="c3"></a><img src="shared/Java_clr_hori_interval.gif"
name="graphics2" alt="Java coffee cup logo" width="100" align="BOTTOM"
border="0" height="80"></p>
</th>
</tr>
<tr valign="TOP">
<td>
<h3 class="subtitle">Version 3.0.4, Classic Edition<br>
</h3>
</td>
</tr>
<tr valign="TOP">
<td>
<h4 class="titledate">September 2011</h4>
</td>
</tr>
</tbody>
</table>
<p class="navtop"><a name="top"></a><a href="#_maincontent">Skip
TOC&nbsp;</a><font color="#666666"><a href="#_maincontent"><font
color="#666666"><img src="shared/downicon.gif" name="graphics3"
alt="skip TOC" width="9" align="BOTTOM" border="1" height="9"></font></a></font></p>
<h2>Table of Contents</h2>
<p><a href="#Overview">1. Overview</a></p>
<p><a href="#Prerequisites">2. Prerequisites</a></p>
<p><a href="#Install">3. Installation Instructions</a></p>
<p><a href="#Using">4. Setting System Variables and Paths</a></p>
<p><a href="#config-jcre_samples">5. Configuring the Java Card RE for
the Samples</a></p>
<p><a href="#Netbeans">6. Development and Debugging with the NetBeans
IDE </a>
</p>
<p><a href="#Feedback">7. Product Information</a></p>
<h2><a name="top1"></a><a name="Overview"></a>1. Overview</h2>
<p>These release notes describe the development kit for the Java Card
3 Platform, Version 3.0.4, Classic Edition. This
version of the Classic Edition development kit is a maintenance
release and includes bug fixes. It also contains a string annotation
tool and string support as specified in Version 3.0.4 of the Java
Card API specification, Classic Edition. This release does not
include the Connected Edition.
</p>
<p>Java Card technology combines a subset of the Java programming
language with a runtime environment optimized for smart cards and
similar small-memory embedded devices. The goal of Java Card
technology is to bring many of the benefits of the Java programming
language to the resource-constrained world of smart cards. The Java
Card API is compatible with international standards such as ISO 7816,
and industry-specific standards such as Europay, Master Card, and
Visa (EMV).</p>
<p>Java Card 3 Platform, Version 3.0.4, Classic Edition is the latest
evolution of Java Card technology. This development kit is based on
version 3.0.4 of the Java Card specifications, Classic Edition, which
includes the errata sheets located at
<a
href="http://www.oracle.com/technetwork/java/javacard/jc-classic-spec-errata-140181.html">http://www.oracle.com/technetwork/java/javacard/jc-classic-spec-errata-140181.html</a>.
The
Java
Card
3
platform
consists
of
<font color="#000000">versions
3.0, 3.0.1 and 3.0.4 of the specifications and versions 3.0.1, 3.0.2,
3.0.3 and 3.0.4 of</font> the development kit.</p>
<p>The Java Card 3 Platform is available in two editions, both of which
are backward compatible with previous versions and share key security
features:</p>
<ul>
<li>
<p style="margin-bottom: 0in;">Classic Edition is based on an
evolution of the Java Card Platform, Version 2.2.2, architecture. This
edition targets more resource-constrained devices than the Connected
Edition. These release notes are for the Classic Edition development
kit, Version 3.0.4 only.</p>
</li>
<li>
<p>Connected Edition contains a new architecture compared to the
Java Card technology released in version 2.2.2, which is now known as
the "Classic Edition." The Connected Edition enables the integration of
smart cards within IP networks and web services architectures. To do
so, it features a significantly enhanced runtime environment and
virtual machine (VM), and it includes new network-oriented features,
such as support for Java Servlet APIs and Java Card applets with
extended and advanced capabilities.</p>
</li>
</ul>
<p class="navtop"><a href="#top">Top&nbsp;</a><font color="#666666"><a
href="#top"><font color="#666666"><img src="shared/topicon.gif"
name="graphics4" alt="go to TOC" width="9" align="BOTTOM" border="1"
height="9"></font></a></font></p>
<h2><a name="Prerequisites"></a>2. Prerequisites</h2>
<h3>Required Operating System</h3>
<ul>
<li>
<p>This release of the development kit for the Java Card 3
Platform, Version 3.0.4, Classic Edition is targeted for use on the
Microsoft Windows XP SP3 operating system.</p>
</li>
</ul>
<h3>Required Software</h3>
<p>The following software must be installed for the Java Card
development kit to work:</p>
<ul>
<li>
<p style="margin-bottom: 0in;"><b>Java Development Kit.</b> The
commercial version of Java Development Kit (JDK™) version 6, Update 10
or later is required. You can download the supported JDK software, JDK
6 Update 10 or later, from <a
href="http://www.oracle.com/technetwork/java/javase/downloads/index.html"
target="top">http://www.oracle.com/technetwork/java/javase/downloads/index.html</a>.
</p>
</li>
<li>
<p style="margin-bottom: 0in;"><b>GCC Compiler.</b> To build the
VM, this release requires Minimal GNU for Windows (MinGW) version 5.1.4
or later. MinGW can be obtained from <a
href="http://prdownloads.sourceforge.net/mingw" target="top">http://prdownloads.sourceforge.net/mingw</a>.
For
information
on
MinGW
go
to
<a href="http://www.mingw.org/" target="top">http://www.mingw.org</a>.
</p>
</li>
<li>
<p><b>Apache Ant.</b> Apache Ant version 1.6.5 or later is
required. Latest version of Apache Ant can be obtained <a
href="http://ant.apache.org/" target="top">http://ant.apache.org</a>. </p>
</li>
</ul>
<p><b>Note: </b>Do not install any software in a directory that
contains a space in its name. For example, do not install software in
any subdirectory of <code>c:\program files</code> because of the
space in the <code>program files</code> element</p>
<p><b>Note: </b>The bundle containing the specifications must be
downloaded separately.</p>
<h3>Contents of This Release</h3>
This release contains features required to support classic Java
Card applet applications on the card. Specifically, this release
includes the following:
<ul>
<li>
<p style="margin-bottom: 0in;">Java Card runtime environment (<code>cref.exe</code>)
</p>
</li>
<li>
<p style="margin-bottom: 0in;">Uninstaller tool</p>
</li>
<li>
<p style="margin-bottom: 0in;">Normalizer tool (<font
face="monospace">normalizer.bat</font>)</p>
</li>
<li>
<p style="margin-bottom: 0in;">APDU tool (<code>apdutool.bat</code>)
</p>
</li>
<li>
<p style="margin-bottom: 0in;">capdump tool</p>
</li>
<li>
<p style="margin-bottom: 0in;">capgen tool</p>
</li>
<li>
<p style="margin-bottom: 0in;">Converter tool (<code>converter.bat</code>)
</p>
</li>
<li>
<p style="margin-bottom: 0in;">exp2text tool</p>
</li>
<li>
<p style="margin-bottom: 0in;">on-card installer </p>
</li>
<li>
<p style="margin-bottom: 0in;">maskgen tool</p>
</li>
<li>
<p style="margin-bottom: 0in;">off-card verifier tool</p>
</li>
<li>
<p style="margin-bottom: 0in;">scriptgen tool </p>
</li>
<li>
<p style="margin-bottom: 0in;">String annotation processor</p>
</li>
<li>
<p style="margin-bottom: 0in;">optional Ant tasks</p>
</li>
<li>
<p style="margin-bottom: 0in;">Sample applications </p>
</li>
<li>
<p>Classic Edition simulator for classic applet development and
debugging </p>
</li>
</ul>
<ul>
<li>(<span style="font-family: monospace;">trimmer.bat</span>) batch
file for running the trimming tool with this development kit. The
trimming tool bundle is available
separately on the Java Licensee Engineering website <br>
</li>
</ul>
<ul>
<li><i>Development Kit User's Guide, Java Card 3 Platform, Version
3.0.4,
Classic Edition</i>.</li>
</ul>
<p class="navtop"><a href="#top">Top&nbsp;</a><font color="#666666"><a
href="#top"><font color="#666666"><img src="shared/topicon.gif"
name="graphics5" alt="go to TOC" width="9" align="BOTTOM" border="1"
height="9"></font></a></font></p>
<h2><a name="Install"></a>3. Installation Instructions</h2>
<p>For a more thorough description of the installation, contents and
use of the development kit, see <i>Development User's Guide, Java
Card 3 Platform, Version 3.0.4, Classic Edition</i>.</p>
<p>An automatic installer tool can be used to unpack the download
file containing this release. During download, you can choose to let
the installer tool unpack the download file into a directory of your
choice on your system or you can save the download file itself to
your system.</p>
<p><b>Note</b>: Do not install the development kit software in any
directory that has a space in its name. For example, on a Windows
platform, do not install software in the <code>c:\program files</code>
directory, or any subdirectory of <code>c:\program files</code>,
because the <code>program files</code> element contains a space.</p>
<p><b>Note</b>: Do not install this version of the Java Card
<font color="#000000">development kit into an existing directory </font>for
an
older
version.
You
must
first
uninstall
the
previously
installed
version of the Java Card development kit prior to
installing this version into the old directory. Installing into the
same directory without first uninstalling could result in
unpredictable behavior.</p>
<p>To install the Java Card development kit and associated software,
follow these steps:</p>
<ol>
<li>
<p style="margin-bottom: 0in;"><b>Install the JDK version 6, Update
10</b> or later. This JDK is available from: <a
href="http://www.oracle.com/technetwork/java/javase/downloads/index.html"
target="top">http://www.oracle.com/technetwork/java/javase/downloads/index.html</a>.
</p>
</li>
<li>
<p style="margin-bottom: 0in;"><b>Install Apache Ant version 1.6.5
or later</b>. The latest version is available at: <a
href="http://ant.apache.org/" target="top">http://ant.apache.org/</a>.
</p>
</li>
<li>
<p style="margin-bottom: 0in;"><b>Install the GCC compiler</b>. The
compiler Minimal GNU for Windows (MinGW), version 5.1.4 is
required.&nbsp; It is available at <a
href="http://sourceforge.net/projects/mingw">http://sourceforge.net/projects/mingw</a>,
while
its
installation
information
is
at
<a href="http://www.mingw.org/">http://www.mingw.org</a>. </p>
</li>
<li>
<p style="margin-bottom: 0in;"><b>Download the Java Card
development kit</b>. Download and store the development kit Java
Archive (JAR) file in a directory of your choice. </p>
</li>
<li>
<p><b>Run the development kit installer or use the command line</b>.
Double
click
the
JAR
file
on
your
system.
<font color="#000000">If the
JDK is installed correctly, the jar file is recognized as an executable
jar and t</font>he automatic installer will launch to step you through
the remainder of the installation process. </p>
</li>
</ol>
<p style="margin-left: 0.42in;">Alternatively, you can use the command
line to unpack the JAR file using the following command:</p>
<blockquote style="margin-left: 1.2in;"><code>java -jar</code> <i>Bundle-Filename</i></blockquote>
<blockquote>Where <i>Bundle-Filename</i> is the downloaded
development kit JAR file.
</blockquote>
<p>By default, the development kit is installed in
<code>C:\JCDK3.0.4_ClassicEdition</code> and its associated
sub-directories. You can specify a different directory if you wish.
</p>
<p>The directory <code>C:\JCDK3.0.4_ClassicEdition</code> (or
the alternate directory you specify during installation) is referred
to as <code><i>JC_CLASSIC_HOME</i></code>&nbsp; in these release
notes.
When the development kit installation is complete, <code><i>JC_CLASSIC_HOME</i></code>&nbsp;
contains
the
following:</p>
<p style="margin-bottom: 0in;"><br>
</p>
<table width="100%" border="0" cellpadding="3" cellspacing="2">
<tbody>
<tr>
<td width="15%">
<p><code><i>JC_CLASSIC_HOME</i></code> </p>
</td>
<td width="85%">
<p>These release notes. <br>
Copyright files.</p>
</td>
</tr>
<tr>
<td>
<p><code>docs</code></p>
</td>
<td>
<p><code>JCDevKitUG-Classic-3_0_4-RR.pdf</code> The <i>Development
Kit
User's
Guide
for
the
Java Card Platform, Version 3.0.4, Classic
Edition</i><font color="#000000">.</font></p>
</td>
</tr>
<tr>
<td style="vertical-align: top;">
<p><code>docs\html</code></p>
</td>
<td style="vertical-align: top;">HTML version of the user guide.<br>
</td>
</tr>
<tr>
<td>
<p><code>docs\apduiolib</code></p>
</td>
<td>
<p>Javadoc tool files for use with APDU I/O described in the
user's guide.<br>
</p>
</td>
</tr>
<tr>
<td>
<p><code>docs\rmiclientlib</code></p>
</td>
<td>
<p>Javadoc tool files for use with optional RMI implementation
described in the user's guide.<br>
</p>
</td>
</tr>
<tr>
<td>
<p><code>docs\api</code></p>
</td>
<td>
<p>Javadoc tool files for the API.</p>
</td>
</tr>
<tr>
<td>
<p><code>api_export_files</code></p>
</td>
<td>
<p>Contains <font face="monospace">java</font>, <font
face="monospace">javacard</font>, and <font face="monospace">javacardx
</font>directories of API export files.</p>
</td>
</tr>
<tr>
<td>
<p><code>bin</code> </p>
</td>
<td>
<p>Development kit executable files, including the <span
style="font-family: monospace;">trimmer.bat</span> batch file for
running the trimming tool with this development kit. </p>
</td>
</tr>
<tr>
<td>
<p><code>classic_simulator</code> </p>
</td>
<td>
<p>Contains files and directory structure required to create a
classic simulator platform in NetBeans for development and debugging of
classic applications.</p>
</td>
</tr>
<tr>
<td>
<p><code>lib</code> </p>
</td>
<td>
<p>Configuration and JAR files for the API, tools.<br>
Third-party libraries. </p>
</td>
</tr>
<tr>
<td style="vertical-align: top;">
<p><code>samples\classic_applets</code> </p>
</td>
<td style="vertical-align: top;">
<p>Samples of basic classic applets, such as HelloWorld.</p>
</td>
</tr>
<tr>
<td>
<p><code>samples\reference_apps</code></p>
</td>
<td>
<p>Samples of more robust classic applets.</p>
</td>
</tr>
<tr>
<td>
<p><code>src</code> </p>
</td>
<td>
<p>Development kit source files. AVAILABLE ONLY IF YOU HAVE A
SOURCE BUNDLE.</p>
</td>
</tr>
<tr>
<td>
<p><code>Uninstaller\uninstaller.jar</code></p>
</td>
<td>
<p>Uninstalls the development kit.</p>
</td>
</tr>
<tr>
<td>
<p><code>legal</code></p>
</td>
<td>
<p>Legal files.</p>
</td>
</tr>
</tbody>
</table>
<p><br>
</p>
<p class="navtop"><a href="#top">Top&nbsp;</a><font color="#666666"><a
href="#top"><font color="#666666"><img src="shared/topicon.gif"
name="graphics6" alt="go to TOC" width="9" align="BOTTOM" border="1"
height="9"></font></a></font></p>
<h2><a name="Using"></a>4. Setting System Variables and Paths</h2>
<p>System variables and paths must be set before running the
development kit. See the <i>Development Kit User's Guide</i> for more
details on how to set them. Note that if you choose to set the
variables and paths each time you run the development kit rather than
permanently in your system, you can place the appropriate commands in
a batch file.
</p>
<ul>
<li>
<p style="margin-bottom: 0in;"><code><b>JAVA_HOME</b></code>. You
must set the <code>JAVA_HOME</code> system variable to the JDK root
directory before running the development kit </p>
<ul>
<li>
<p style="margin-bottom: 0in;">To temporarily set <code>JAVA_HOME</code>
from the command line, enter the command: <code>set JAVA_HOME=c:\</code><code><i>path</i></code>&nbsp;
before
running
the
development
kit.
For
example,
if
the Java platform
software is stored in your <code>c:\jdk6</code> directory, enter <code>set
JAVA_HOME=c:\jdk6</code> before running the development kit. </p>
</li>
</ul>
</li>
<li>
<p style="margin-bottom: 0in;"><code><b>JC_CLASSIC_HOME</b></code>.&nbsp;<font
color="#000000">You must set the&nbsp; </font><code><font
color="#000000"><font face="monospace">JC_CLASSIC_HOME</font></font></code><font
color="#000000"> system variable to the directory in which the
development kit is installed before running the development kit.&nbsp;</font>&nbsp;
</p>
<ul>
<li>
<p>To temporarily set <code>JC_CLASSIC_HOME</code> from the
command line, enter the command: <code>set JC_CLASSIC_HOME=c:\</code><code><i>path</i></code>&nbsp;
before
running
the
development
kit.
For
example,
if the Java Card
development kit is stored in your <code>c:\JCDK3.0.4_ClassicEdition</code>
directory, enter <code>set JC_CLASSIC_HOME=c:\JCDK3.0.4_ClassicEdition</code>
before
running
the
development kit.&nbsp; </p>
</li>
</ul>
</li>
</ul>
<ul>
<li>
<p style="margin-bottom: 0in;"><b>Apache Ant. </b>You must set the
<font face="monospace">ANT_HOME</font> system variable to the
Apache Ant directory before running the samples.</p>
<ul>
<li>
<p>To temporarily set <code>ANT_HOME</code> from the command
line, enter the command: <code>set PATH=c:\</code><code><i>path</i></code>&nbsp;
before
running
the
development
kit.
For
example,
if
Apache Ant is
stored in your <code>c:\ant\apache-ant1.6.5</code> directory, enter <code>set
ANT_HOME=c:\ant\apache-ant1.6.5</code> before running the development
kit. </p>
</li>
</ul>
</li>
</ul>
<ul>
<li>
<p style="margin-bottom: 0in;"><b>MinGW</b>. You must set the path
to the location of <code>MinGW </code>before running the development
kit. Note that the path has to point to the <code>\bin</code>
subdirectory of the <code>MinGW </code>installation directory where
the <code>gcc.exe</code> file is located.&nbsp; </p>
<ul>
<li>
<p>To temporarily set the path to MinGW, enter the command <code>set
PATH=c:\</code><code><i>MinGW_path</i></code><code>;%PATH%</code>. For
example, if MinGW is installed in <code>c:\MinGW</code>, enter the
command <code>set PATH=c:\MinGW\bin;%PATH%</code> before running the
development kit. </p>
</li>
</ul>
</li>
</ul>
<h2><a name="config-jcre_samples"></a><b>5. Configuring the Java Card
RE for the Samples</b></h2>
<p>Note that the Java Card RE (<font face="monospace">cref</font>)
implementation is not optimized for memory or performance and,
therefore, requires more memory than an actual optimized
implementation on a card. To run the Java Card RE, you can use the
default executable, <font face="monospace">cref.bat</font>, using the
command line as follows:</p>
<p><code><font face="monospace"><i>JC_CLASSIC_HOME</i></font></code><code><font
face="monospace">\bin\</font></code><font face="monospace">cref.bat</font></p>
<p class="navtop"><a href="#top">Top&nbsp;</a><font color="#666666"><a
href="#top"><font color="#666666"><img src="shared/topicon.gif"
name="graphics7" alt="go to TOC" width="9" align="BOTTOM" border="1"
height="9"></font></a></font></p>
<h2><a name="Netbeans"></a><b>6. Development and Debugging with
the NetBeans IDE<br>
</b></h2>
<p style="font-weight: normal;">This release of Java Card Classic
Development Kit supports development of classic applications and
libraries using NetBeans. To develop and debug classic Java Card
applications with NetBeans Java Card plug-in, please follow the
following steps:</p>
<ol>
<li>
<p style="margin-bottom: 0in; font-weight: normal;">Download
the latest version NetBeans with Java Card
technology-specific plug-in. You will find the latest version in the
NetBeans Download Center.<br>
</p>
</li>
<li>
<p style="margin-bottom: 0in;"><font color="#000000"><span
style="font-weight: normal;">In the NetBeans Services window, under
Java Card Runtimes, add a new Java Card platform using </span></font><code><font
color="#000000"><i><span style="font-weight: normal;">JC_CLASSIC_HOME/classic_simulator
</span></i></font></code><font color="#000000"><span
style="font-weight: normal;">directory as the platform directory.</span></font></p>
</li>
</ol>
<p style="margin-bottom: 0in;"><br>
</p>
<h3 style="margin-top: 0in; margin-bottom: 0in;"><b>Known Issues With
NetBeans IDE Java Card Technology Plug-in</b></h3>
<p>Following is the
list of known issues and workarounds for the Java Card plug-in in
NetBeans. For issues related to the trimming tool, see its release
notes
in the separate trimming tool download bundle.</p>
<table width="706" border="0" cellpadding="2" cellspacing="0">
<col width="78"> <col width="620"> <thead> <tr>
<td sdval="12303491" sdnum="1033;" width="78">
<p style="text-align: left;"><b>Bug Id </b> </p>
</td>
<td width="620">
<p style="text-align: left;"><b>Description</b></p>
</td>
</tr>
</thead> <tbody>
<tr>
<td sdval="12302880" sdnum="1033;" width="78">200983 </td>
<td width="620">The classic simulator bundled in the Java Card
v3.0.4 BETA development kit does not work when the development kit is
installed in a relatively deeper directory layer </td>
</tr>
</tbody>
</table>
<p class="navtop"><a href="#top">Top&nbsp;</a><font color="#666666"><a
href="#top"><font color="#666666"><img src="shared/topicon.gif"
name="graphics8" alt="go to TOC" width="9" align="BOTTOM" border="1"
height="9"></font></a></font></p>
<h2><a name="Feedback"></a><b>7. Product Information</b></h2>
<p>The public Java Card technology web site is
<a href="http://www.oracle.com/technetwork/java/javacard">http://www.oracle.com/technetwork/java/javacard</a>.
The
developer
collaboration
web
site
also
contains
information
about
Java
Card technology at
<a href="http://kenai.com/projects/javacard/pages/HOME">http://kenai.com/projects/javacard/pages/HOME</a>.</p>
<p>If you are a Licensee, visit the product web site at
<a
href="https://java-partner.sun.com/portal/service/ent/platform/javacardgroup"
target="top">https://java-partner.sun.com/portal/service/ent/platform/javacardgroup</a>
This site has the most up-to-date information on the following:
</p>
<ul>
<li>
<p style="margin-bottom: 0in;">Product news and reviews </p>
</li>
<li>
<p style="margin-bottom: 0in;">Release notes and product
documentation </p>
</li>
<li>
<p>Technical support contact information </p>
</li>
</ul>
<p>We greatly appreciate your feedback on this reference
Implementation.&nbsp;</p>
<p class="navtop"><a href="#top">Top&nbsp;</a><font color="#666666"><a
href="#top"><font color="#666666"><img src="shared/topicon.gif"
name="graphics9" alt="go to TOC" width="9" align="BOTTOM" border="1"
height="9"></font></a></font></p>
<hr>
<p><a href="COPYRIGHT.html">Copyright</a> © 1998, 2011, Oracle
and/or its affiliates. All rights reserved.<br>
</p>
</body>
</html>
@echo off
setlocal
set JC_CLASSIC_HOME=%~dp0\..
rem Print warning if no JAVA_HOME set
if not defined JAVA_HOME goto nojavahome
rem set classpath to all jars
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\ant-contrib-1.0b3.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\api_classic_annotations.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\asm-all-3.1.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\bcel-5.2.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\commons-cli-1.0.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\commons-codec-1.3.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\commons-httpclient-3.0.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\commons-logging-1.1.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\jctasks.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\tools.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\api_classic.jar;%JC_CLASSPATH%
rem execute apdutool's Main class
"%JAVA_HOME%\bin\java" -Djc.home=%JC_CLASSIC_HOME% -classpath %JC_CLASSPATH% com.sun.javacard.apdutool.Main %*
goto done
:nojavahome
echo JAVA_HOME is not set - please set it to point to JDK 1.6
:done
endlocal
rem Send the error code to the command interpreter
cmd /c Exit /B %errorlevel%
\ No newline at end of file
@echo off
setlocal
set JC_CLASSIC_HOME=%~dp0\..
rem Print warning if no JAVA_HOME set
if not defined JAVA_HOME goto nojavahome
rem set classpath to all jars
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\ant-contrib-1.0b3.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\api_classic_annotations.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\asm-all-3.1.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\bcel-5.2.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\commons-cli-1.0.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\commons-codec-1.3.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\commons-httpclient-3.0.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\commons-logging-1.1.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\jctasks.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\tools.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\api_classic.jar;%JC_CLASSPATH%
rem execute capdump's Main class
"%JAVA_HOME%\bin\java" -Djc.home=%JC_CLASSIC_HOME% -classpath %JC_CLASSPATH% com.sun.javacard.capdump.CapDump %*
goto done
:nojavahome
echo JAVA_HOME is not set - please set it to point to JDK 1.6
:done
endlocal
rem Send the error code to the command interpreter
cmd /c Exit /B %errorlevel%
\ No newline at end of file
@echo off
setlocal
set JC_CLASSIC_HOME=%~dp0\..
rem Print warning if no JAVA_HOME set
if not defined JAVA_HOME goto nojavahome
rem set classpath to all jars
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\ant-contrib-1.0b3.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\api_classic_annotations.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\asm-all-3.1.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\bcel-5.2.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\commons-cli-1.0.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\commons-codec-1.3.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\commons-httpclient-3.0.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\commons-logging-1.1.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\jctasks.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\tools.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\api_classic.jar;%JC_CLASSPATH%
rem execute capgen's Main class
"%JAVA_HOME%\bin\java" -Djc.home=%JC_CLASSIC_HOME% -classpath %JC_CLASSPATH% com.sun.javacard.jcasm.cap.Main %*
goto done
:nojavahome
echo JAVA_HOME is not set - please set it to point to JDK 1.6
:done
endlocal
rem Send the error code to the command interpreter
cmd /c Exit /B %errorlevel%
\ No newline at end of file
@echo off
setlocal
set JC_CLASSIC_HOME=%~dp0\..
rem Print warning if no JAVA_HOME set
if not defined JAVA_HOME goto nojavahome
rem set classpath to all jars
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\ant-contrib-1.0b3.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\api_classic_annotations.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\asm-all-3.1.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\bcel-5.2.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\commons-cli-1.0.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\commons-codec-1.3.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\commons-httpclient-3.0.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\commons-logging-1.1.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\jctasks.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\tools.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\api_classic.jar;%JC_CLASSPATH%
rem execute converter's Main class
"%JAVA_HOME%\bin\java" -Djc.home=%JC_CLASSIC_HOME% -classpath %JC_CLASSPATH% com.sun.javacard.converter.Main %*
goto done
:nojavahome
echo JAVA_HOME is not set - please set it to point to JDK 1.6
:done
endlocal
rem Send the error code to the command interpreter
cmd /c Exit /B %errorlevel%
\ No newline at end of file
@echo off
rem
rem in Java Card 2 there was only cref.exe, but now we provide cref_t0.exe,
rem cref_t1.exe, and cref_tdual.exe.
rem
@echo off
setlocal
set JC_CLASSIC_HOME=%~dp0\..
rem this batch file is provided as a easy way to call the new .exe's.
rem
rem "cref.bat args" will call "cref_tdual.exe args"
rem
rem "cref.bat -t0 args" will call "cref_t0.exe args"
rem "cref.bat -t1 args" will call "cref_t1.exe args"
rem "cref.bat -tdual args" will call "cref_tdual.exe args"
rem
setlocal
set list=
set target=cref_tdual
:loop
if "%1"=="" goto done
if "%1"=="-t0" (
set target=cref_t0
shift
goto loop
)
if "%1"=="-t1" (
set target=cref_t1
shift
goto loop
)
if "%1"=="-tdual" (
set target=cref_tdual
shift
goto loop
)
set list=%list% %1
shift
goto loop
:done
call %JC_CLASSIC_HOME%\bin\%target%.exe %list%
endlocal
\ No newline at end of file
@echo off
setlocal
set JC_CLASSIC_HOME=%~dp0\..
rem Print warning if no JAVA_HOME set
if not defined JAVA_HOME goto nojavahome
rem set classpath to all jars
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\ant-contrib-1.0b3.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\api_classic_annotations.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\asm-all-3.1.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\bcel-5.2.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\commons-cli-1.0.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\commons-codec-1.3.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\commons-httpclient-3.0.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\commons-logging-1.1.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\jctasks.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\tools.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\api_classic.jar;%JC_CLASSPATH%
rem execute exp2text's Main class
"%JAVA_HOME%\bin\java" -Djc.home=%JC_CLASSIC_HOME% -classpath %JC_CLASSPATH% com.sun.javacard.converter.Exp2Text %*
goto done
:nojavahome
echo JAVA_HOME is not set - please set it to point to JDK 1.6
:done
endlocal
rem Send the error code to the command interpreter
cmd /c Exit /B %errorlevel%
\ No newline at end of file
@echo off
setlocal
set JC_CLASSIC_HOME=%~dp0\..
rem Print warning if no JAVA_HOME set
if not defined JAVA_HOME goto nojavahome
rem set classpath to all jars
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\ant-contrib-1.0b3.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\api_classic_annotations.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\asm-all-3.1.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\bcel-5.2.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\commons-cli-1.0.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\commons-codec-1.3.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\commons-httpclient-3.0.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\commons-logging-1.1.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\jctasks.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\tools.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\api_classic.jar;%JC_CLASSPATH%
rem execute normalizer's Main class
"%JAVA_HOME%\bin\java" -Djc.home=%JC_CLASSIC_HOME% -classpath %JC_CLASSPATH% com.sun.javacard.normalizer.Main %*
goto done
:nojavahome
echo JAVA_HOME is not set - please set it to point to JDK 1.6
:done
endlocal
rem Send the error code to the command interpreter
cmd /c Exit /B %errorlevel%
\ No newline at end of file
@echo off
setlocal
set JC_CLASSIC_HOME=%~dp0\..
rem Print warning if no JAVA_HOME set
if not defined JAVA_HOME goto nojavahome
rem set classpath to all jars
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\ant-contrib-1.0b3.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\api_classic_annotations.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\asm-all-3.1.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\bcel-5.2.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\commons-cli-1.0.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\commons-codec-1.3.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\commons-httpclient-3.0.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\commons-logging-1.1.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\jctasks.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\tools.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\api_classic.jar;%JC_CLASSPATH%
rem execute packager's Main class
"%JAVA_HOME%\bin\java" -Djc.home=%JC_CLASSIC_HOME% -classpath %JC_CLASSPATH% com.sun.javacard.packager.Main %*
goto done
:nojavahome
echo JAVA_HOME is not set - please set it to point to JDK 1.6
:done
endlocal
rem Send the error code to the command interpreter
cmd /c Exit /B %errorlevel%
\ No newline at end of file
@echo off
setlocal
set JC_CLASSIC_HOME=%~dp0\..
rem Print warning if no JAVA_HOME set
if not defined JAVA_HOME goto nojavahome
rem set classpath to all jars
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\ant-contrib-1.0b3.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\api_classic_annotations.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\asm-all-3.1.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\bcel-5.2.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\commons-cli-1.0.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\commons-codec-1.3.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\commons-httpclient-3.0.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\commons-logging-1.1.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\jctasks.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\tools.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\api_classic.jar;%JC_CLASSPATH%
rem execute scriptgen's Main class
"%JAVA_HOME%\bin\java" -Djc.home=%JC_CLASSIC_HOME% -classpath %JC_CLASSPATH% com.sun.javacard.scriptgen.Main %*
goto done
:nojavahome
echo JAVA_HOME is not set - please set it to point to JDK 1.6
:done
endlocal
rem Send the error code to the command interpreter
cmd /c Exit /B %errorlevel%
\ No newline at end of file
@echo off
setlocal
set JC_TRIMMER_HOME=%~dp0
set JC_TRIMMING_TOOL_CRYPTO_VERBOSE=false
rem Print warning if no JAVA_HOME set
if not defined JAVA_HOME goto nojavahome
rem Print warning if no JC_CLASSIC_HOME set
if not defined JC_CLASSIC_HOME goto nojcclassichome
rem Print warning if no ANT_HOME set
if not defined ANT_HOME goto noanthome
echo %JC_TRIMMER_HOME%
rem set classpath to all jars
set JCT_CLASSPATH=%JC_TRIMMER_HOME%\lib\Trimmer.jar;%JCT_CLASSPATH%
set JCT_CLASSPATH=%JC_TRIMMER_HOME%\lib\commons-cli-1.0.jar;%JCT_CLASSPATH%
set JCT_CLASSPATH=%JC_TRIMMER_HOME%\lib\commons-codec-1.3.jar;%JCT_CLASSPATH%
set JCT_CLASSPATH=%JC_TRIMMER_HOME%\lib\commons-httpclient-3.0.jar;%JCT_CLASSPATH%
set JCT_CLASSPATH=%JC_TRIMMER_HOME%\lib\commons-logging-1.1.jar;%JCT_CLASSPATH%
set JCT_CLASSPATH=%JC_TRIMMER_HOME%\lib\velocity-1.4.jar;%JCT_CLASSPATH%
set JCT_CLASSPATH=%JC_TRIMMER_HOME%\lib\velocity-dep-1.4.jar;%JCT_CLASSPATH%
set JCT_CLASSPATH=%JC_TRIMMER_HOME%\lib\bcel-5.2.jar;%JCT_CLASSPATH%
set JCT_CLASSPATH=%JC_TRIMMER_HOME%\lib\help.jar;%JCT_CLASSPATH%
set JCT_CLASSPATH=%JC_TRIMMER_HOME%\lib\jhall.jar;%JCT_CLASSPATH%
set JCT_CLASSPATH="%JC_CLASSIC_HOME%"\lib\tools.jar;%JCT_CLASSPATH%
set JCT_CLASSPATH="%ANT_HOME%"\lib\ant.jar;%JCT_CLASSPATH%
set JCT_CLASSPATH="%ANT_HOME%"\lib\ant-nodeps.jar;%JCT_CLASSPATH%
set JCT_CLASSPATH="%ANT_HOME%"\lib\ant-launcher.jar;%JCT_CLASSPATH%
set JCT_CLASSPATH="%JAVA_HOME%"\lib\tools.jar;%JCT_CLASSPATH%
set JCT_CLASSPATH=%JC_CLASSIC_HOME%\lib\JCBytecodeProfiler.jar;%JCT_CLASSPATH%
rem execute Timming Tool's Main class
"%JAVA_HOME%\bin\java" -Dtrimmer.home=%JC_TRIMMER_HOME% -classpath %JCT_CLASSPATH% com.sun.jctrimmer.ui.MainTree %*
goto done
:nojavahome
echo JAVA_HOME is not set - please set it to point to JDK 1.6
goto done
:nojcclassichome
echo JC_CLASSIC_HOME is not set - please set it to point to Java Card Classic Edition 3.0.3 SDK
goto done
:noanthome
echo ANT_HOME is not set - please set it to point to apache ant 1.6.5 or higher
goto done
:done
endlocal
@echo off
setlocal
set JC_CLASSIC_HOME=%~dp0\..
rem Print warning if no JAVA_HOME set
if not defined JAVA_HOME goto nojavahome
rem set classpath to all jars
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\ant-contrib-1.0b3.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\api_classic_annotations.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\asm-all-3.1.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\bcel-5.2.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\commons-cli-1.0.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\commons-codec-1.3.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\commons-httpclient-3.0.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\commons-logging-1.1.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\jctasks.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\tools.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\api_classic.jar;%JC_CLASSPATH%
rem execute verifycap's Main class
"%JAVA_HOME%\bin\java" -Djc.home=%JC_CLASSIC_HOME% -classpath %JC_CLASSPATH% com.sun.javacard.offcardverifier.Verifier %*
goto done
:nojavahome
echo JAVA_HOME is not set - please set it to point to JDK 1.6
:done
endlocal
rem Send the error code to the command interpreter
cmd /c Exit /B %errorlevel%
\ No newline at end of file
@echo off
setlocal
set JC_CLASSIC_HOME=%~dp0\..
rem Print warning if no JAVA_HOME set
if not defined JAVA_HOME goto nojavahome
rem set classpath to all jars
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\ant-contrib-1.0b3.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\api_classic_annotations.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\asm-all-3.1.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\bcel-5.2.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\commons-cli-1.0.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\commons-codec-1.3.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\commons-httpclient-3.0.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\commons-logging-1.1.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\jctasks.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\tools.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\api_classic.jar;%JC_CLASSPATH%
rem execute verifyexp's Main class
"%JAVA_HOME%\bin\java" -Djc.home=%JC_CLASSIC_HOME% -classpath %JC_CLASSPATH% com.sun.javacard.offcardverifier.VerifyExp %*
goto done
:nojavahome
echo JAVA_HOME is not set - please set it to point to JDK 1.6
:done
endlocal
rem Send the error code to the command interpreter
cmd /c Exit /B %errorlevel%
\ No newline at end of file
@echo off
setlocal
set JC_CLASSIC_HOME=%~dp0\..
rem Print warning if no JAVA_HOME set
if not defined JAVA_HOME goto nojavahome
rem set classpath to all jars
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\ant-contrib-1.0b3.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\api_classic_annotations.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\asm-all-3.1.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\bcel-5.2.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\commons-cli-1.0.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\commons-codec-1.3.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\commons-httpclient-3.0.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\commons-logging-1.1.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\jctasks.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\tools.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CLASSIC_HOME%\lib\api_classic.jar;%JC_CLASSPATH%
rem execute verifyrev's Main class
"%JAVA_HOME%\bin\java" -Djc.home=%JC_CLASSIC_HOME% -classpath %JC_CLASSPATH% com.sun.javacard.offcardverifier.VerifyRev %*
goto done
:nojavahome
echo JAVA_HOME is not set - please set it to point to JDK 1.6
:done
endlocal
rem Send the error code to the command interpreter
cmd /c Exit /B %errorlevel%
\ No newline at end of file
@echo off
setlocal
set JC_CONNECTED_HOME=%~dp0\..
rem Print warning if no JAVA_HOME set
if not defined JAVA_HOME goto nojavahome
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\ant-contrib-1.0b3.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\commons-cli-1.0.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\commons-codec-1.3.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\commons-httpclient-3.0.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\commons-logging-1.1.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\bcel-5.2.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\asm-all-3.1.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\tools.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\romizer.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\api.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\api_connected.jar;%JC_CLASSPATH%
rem execute apdutool's Main class
"%JAVA_HOME%\bin\java" -Djc.home=%JC_CONNECTED_HOME% -classpath %JC_CLASSPATH% com.sun.javacard.apdutool.Main %*
goto done
:nojavahome
echo JAVA_HOME is not set - please set it to point to JDK 1.6
:done
endlocal
rem Send the error code to the command interpreter
cmd /c Exit /B %errorlevel%
@echo off
setlocal
set JC_CONNECTED_HOME=%~dp0\..
rem Print warning if no JAVA_HOME set
if not defined JAVA_HOME goto nojavahome
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\ant-contrib-1.0b3.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\commons-cli-1.0.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\commons-codec-1.3.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\commons-httpclient-3.0.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\commons-logging-1.1.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\bcel-5.2.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\asm-all-3.1.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\tools.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\romizer.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\api.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\api_connected.jar;%JC_CLASSPATH%
rem execute converter's Main class
"%JAVA_HOME%\bin\java" -Djc.home=%JC_CONNECTED_HOME% -classpath %JC_CLASSPATH% com.sun.javacard.converter.Main %*
goto done
:nojavahome
echo JAVA_HOME is not set - please set it to point to JDK 1.6
:done
endlocal
rem Send the error code to the command interpreter
cmd /c Exit /B %errorlevel%
@echo off
setlocal
set JC_CONNECTED_HOME=%~dp0\..
rem Print warning if no JAVA_HOME set
if not defined JAVA_HOME goto nojavahome
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\ant-contrib-1.0b3.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\commons-cli-1.0.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\commons-codec-1.3.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\commons-httpclient-3.0.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\commons-logging-1.1.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\bcel-5.2.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\asm-all-3.1.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\tools.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\romizer.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\api.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\api_connected.jar;%JC_CLASSPATH%
rem execute debugproxy's Main class
"%JAVA_HOME%\bin\java" -Djc.home=%JC_CONNECTED_HOME% -classpath %JC_CLASSPATH% com.sun.javacard.debugproxy.Main %*
goto done
:nojavahome
echo JAVA_HOME is not set - please set it to point to JDK 1.6
:done
endlocal
rem Send the error code to the command interpreter
cmd /c Exit /B %errorlevel%
@echo off
setlocal
set JC_CONNECTED_HOME=%~dp0\..
rem Print warning if no JAVA_HOME set
if not defined JAVA_HOME goto nojavahome
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\ant-contrib-1.0b3.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\commons-cli-1.0.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\commons-codec-1.3.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\commons-httpclient-3.0.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\commons-logging-1.1.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\bcel-5.2.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\asm-all-3.1.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\tools.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\romizer.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\api.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\api_connected.jar;%JC_CLASSPATH%
rem execute installer's Main class
"%JAVA_HOME%\bin\java" -Djc.home=%JC_CONNECTED_HOME% -classpath %JC_CLASSPATH% com.sun.javacard.offcardinstaller.Main %*
goto done
:nojavahome
echo JAVA_HOME is not set - please set it to point to JDK 1.6
:done
endlocal
rem Send the error code to the command interpreter
cmd /c Exit /B %errorlevel%
@echo off
setlocal
echo Java Card 3.0.2 Compiler
set JC_CONNECTED_HOME=%~dp0\..
rem Print warning if no JAVA_HOME set
if not defined JAVA_HOME goto nojavahome
"%JAVA_HOME%\bin\javac" -processorpath %JC_CONNECTED_HOME%\lib\jcapt.jar -processor com.sun.javacard.apt.JCAnnotationProcessor -Amode=connected %*
goto done
:nojavahome
echo JAVA_HOME is not set - please set it to point to JDK 1.6
:done
endlocal
\ No newline at end of file
@echo off
setlocal
set JC_CONNECTED_HOME=%~dp0\..
rem Print warning if no JAVA_HOME set
if not defined JAVA_HOME goto nojavahome
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\ant-contrib-1.0b3.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\commons-cli-1.0.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\commons-codec-1.3.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\commons-httpclient-3.0.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\commons-logging-1.1.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\bcel-5.2.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\asm-all-3.1.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\tools.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\romizer.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\api.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\api_connected.jar;%JC_CLASSPATH%
rem execute normalizer's Main class
"%JAVA_HOME%\bin\java" -Djc.home=%JC_CONNECTED_HOME% -classpath %JC_CLASSPATH% com.sun.javacard.normalizer.Main %*
goto done
:nojavahome
echo JAVA_HOME is not set - please set it to point to JDK 1.6
:done
endlocal
rem Send the error code to the command interpreter
cmd /c Exit /B %errorlevel%
@echo off
setlocal
set JC_CONNECTED_HOME=%~dp0\..
rem Print warning if no JAVA_HOME set
if not defined JAVA_HOME goto nojavahome
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\ant-contrib-1.0b3.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\commons-cli-1.0.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\commons-codec-1.3.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\commons-httpclient-3.0.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\commons-logging-1.1.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\bcel-5.2.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\asm-all-3.1.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\tools.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\romizer.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\api.jar;%JC_CLASSPATH%
set JC_CLASSPATH=%JC_CONNECTED_HOME%\lib\api_connected.jar;%JC_CLASSPATH%
rem execute packager's Main class
"%JAVA_HOME%\bin\java" -Djc.home=%JC_CONNECTED_HOME% -classpath %JC_CLASSPATH% com.sun.javacard.packager.Main %*
goto done
:nojavahome
echo JAVA_HOME is not set - please set it to point to JDK 1.6
:done
endlocal
rem Send the error code to the command interpreter
cmd /c Exit /B %errorlevel%
#
# Copyright (c) 2009 Sun Microsystems, Inc.
# All rights reserved.
# Use is subject to license terms.
#
# RI Specific tunable parameters
# Visible from com.sun.javacard.Configuration.getProperty(key)
#
# Note: There must be a blank line at end of the file,
# or
# keep a comment line at the end.
# **** The last line is ignored. ****
#
# Index based properties starts with index 0. Properties are read from 0 until the sequence is broken.
# For example if the property names are like
# myproperty.0, mypropert.1, myproperty.3, then the myproperty.3 is not read because the sequence is broken at .2
#
# These Properties are visible from JCRuntime.getConfigProperty()
#
#
#----//// Some RI level properties \\\\----#
system.i18n.lang: en
system.i18n.encoding: ISO8859_1
javacard.io.socket.buffersize: 256
#com.sun.javacard.io.http.proxy: webcache:8080
#com.sun.javacard.io.http.force_non_persistent: false
#com.sun.javacard.io.http.persistent_connection_linger_time: 60000
#com.sun.javacard.io.http.inputBufferSize: 256
#com.sun.javacard.io.http.outputBufferSize: 2048
#com.sun.javacard.io.http.max_persistent_connections: 4
#----//// [End] Some RI level properties \\\\----#
#
#----//// Platform Policy Default Protection Domains Configuration \\\\----#
#format of each line
# <classname><space><each argument in double quotes seperated by , as if like calling a method>
# Example: MyPermission "arg1", "arg2", "arg3"
#
# Note: There is no error checking. If there is some problem while parsing the string,
# either it will be ignored or may have wrong values for the arguments.
#---- Web Domain ----
webDomain.include.0=javacardx.spi.framework.JCREPermission "callPermJCREEPO.EXTENDED"
webDomain.include.1=javacardx.spi.framework.JCREPermission "callPermJCREEPO.CLASSIC"
webDomain.include.2=javacardx.facilities.EventRegistryPermission "event:///~/*", "notify,register,unregister"
webDomain.include.3=javacardx.facilities.EventRegistryPermission "event:///platform/*", "register,unregister"
webDomain.include.4=javacardx.facilities.EventRegistryPermission "event:///standard/*", "register,unregister"
webDomain.include.5=javacardx.facilities.ServiceRegistryPermission "sio:///~/*", "lookup,register,unregister"
webDomain.include.6=javacardx.facilities.ServiceRegistryPermission "sio:///standard/auth/*", "lookup"
webDomain.include.7=javacardx.facilities.TaskRegistryPermission "task.*"
webDomain.include.8=javacardx.framework.ContextPermission "sio:///standard/auth/*", "switch,transfer"
webDomain.include.9=javacardx.framework.JCRuntimePermission "credentialManager.*"
webDomain.include.10=javacardx.framework.JCRuntimePermission "thread.*"
webDomain.include.11=javacardx.io.ConnectorPermission "file:///~/*", "read"
#webDomain.include.12=javacardx.io.ConnectorPermission file:///~/docroot/tmp write
#---- Extended Domain ----
extendedDomain.include.0=javacardx.spi.framework.JCREPermission "callPermJCREEPO.EXTENDED"
extendedDomain.include.1=javacardx.spi.framework.JCREPermission "callPermJCREEPO.CLASSIC"
extendedDomain.include.2=javacardx.spi.framework.JCREPermission "callTempJCREEPO.CLASSIC"
extendedDomain.include.3=javacardx.facilities.EventRegistryPermission "event://aid/~/*", "notify,register,unregister"
extendedDomain.include.4=javacardx.facilities.EventRegistryPermission "event:///platform/*", "register,unregister"
extendedDomain.include.5=javacardx.facilities.EventRegistryPermission "event:///standard/*", "register,unregister"
extendedDomain.include.6=javacardx.facilities.ServiceRegistryPermission "sio://aid/~/*", "lookup,register,unregister"
extendedDomain.include.7=javacardx.facilities.ServiceRegistryPermission "sio:///standard/auth/*", "lookup"
extendedDomain.include.8=javacardx.facilities.TaskRegistryPermission "task.*"
extendedDomain.include.9=javacardx.framework.ContextPermission "sio:///standard/auth/*", "switch,transfer"
extendedDomain.include.10=javacardx.framework.JCRuntimePermission "thread.*"
extendedDomain.include.11=javacardx.framework.JCRuntimePermission "credentialManager.*"
extendedDomain.include.12=javacardx.io.ConnectorPermission "file://aid/~/*", "read"
#---- Classic Domain ----
classicDomain.include.0=javacardx.spi.framework.JCREPermission "callPermJCREEPO.CLASSIC"
classicDomain.include.1=javacardx.spi.framework.JCREPermission "callTempJCREEPO.CLASSIC"
#---- CardManagement Domain ----
cmDomain.include.0=javacardx.spi.cardmgmt.CardManagementPermission "credentialManager.*"
cmDomain.include.1=javacardx.spi.framework.JCREPermission "callPermJCREEPO.EXTENDED"
cmDomain.include.2=javacardx.spi.framework.JCREPermission "callPermJCREEPO.CLASSIC"
cmDomain.include.3=javacardx.spi.framework.JCREPermission "callTempJCREEPO.CLASSIC"
cmDomain.include.4=javacardx.facilities.EventRegistryPermission "event://*/~/*", "notify,register,unregister"
cmDomain.include.5=javacardx.facilities.EventRegistryPermission "event://*/platform/*", "register,unregister"
cmDomain.include.6=javacardx.facilities.EventRegistryPermission "event://*/standard/*", "notify,register,unregister"
cmDomain.include.7=javacardx.facilities.ServiceRegistryPermission "sio://*/~/*", "lookup,register,unregister"
cmDomain.include.8=javacardx.facilities.ServiceRegistryPermission "sio://*/standard/auth/*", "register,unregister,lookup"
cmDomain.include.9=javacardx.facilities.TaskRegistryPermission "task.*"
cmDomain.include.10=javacardx.framework.ContextPermission "sio://*/standard/auth/*", "switch,transfer"
cmDomain.include.11=javacardx.framework.JCRuntimePermission "credentialManager.*"
cmDomain.include.12=javacardx.framework.JCRuntimePermission "thread.*"
cmDomain.include.13=javacardx.io.ConnectorPermission "file://*/~/", "read"
cmDomain.include.14=javacardx.spi.cardmgmt.CardManagementPermission "deploymentUnit.*"
cmDomain.include.15=javacardx.spi.cardmgmt.CardManagementPermission "application.*"
cmDomain.include.16=javacardx.spi.cardmgmt.CardManagementPermission "protectionDomain.*"
cmDomain.include.17=javacardx.spi.framework.JCREPermission "callPermJCREEPO.CARDMGMT"
#----//// [End] Platform Policy Default Protection Domains Configuration \\\\----#
#
#----//// Custom Protection Domains \\\\----#
# This is RI specific mechanism to assign a protection domain for an application.
# <JC_CONNECTED_HOME>/samples/keystore folder contains some keystore files. These protection domains are associated with
# each of those files. The BASE-64 encoded certificate is associated with each protection domain.
# Depending on the keystore file used to sign the application, corresponding protection domain is associated to that application.
# This is a way to add more permissions to default platform policy for application type by adding more include/exclude prmissions.
#
# <JC_CONNECTED_HOME>/samples/keystore/a.keystore
pd.0.certificate=MIIB8TCCAVqgAwIBAgIER+0X/zANBgkqhkiG9w0BAQUFADA9MQswCQYDVQQGEwJVUzELMAkGA1UEChMCUkkxFTATBgNVBAsTDEhvd1RvU2FtcGxlczEKMAgGA1UEAxMBQTAeFw0wODAzMjgxNjA4MzFaFw0wODA2MjYxNjA4MzFaMD0xCzAJBgNVBAYTAlVTMQswCQYDVQQKEwJSSTEVMBMGA1UECxMMSG93VG9TYW1wbGVzMQowCAYDVQQDEwFBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCTIYVeLV+oyViuf8WOPQeo9AaydiuO5tWzHarb3ol3tY1o0xuooC9MpJEYyDTFBJ9YH9oNtemDU0YxswNtVbJropvwO9lVChn3OvXNfoFEYw8aeVl3pFHrAf4T+EL61Ybgi8PqW0OO/fEf6gkvbJkxy5S421gOrK191pIRTmyr5QIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAD0ufB/7/hgx0Zp/T5kjuaWEc6hXB4wlRnXzfwjysvx8K2z2aSVGO5ZbJL8qCh3PQmZZZlpVTbxey/jijwylFiBT3rTonjdKFpv3pypt+3teXvvSfApnUrA7PlgPBgfkWR/UgzN9N6huOWNfJkkWuCsRhq47PpxYfdh1LeyLjuNR
pd.0.name=0
pd.0.include.0=javacardx.facilities.ServiceRegistryPermission "sio:///*", "register,unregister,lookup"
pd.0.include.1=javacardx.facilities.EventRegistryPermission "event:///*", "register,unregister,notify"
pd.0.include.2=javacardx.security.CryptoServicePermission "*"
pd.0.include.3=javacardx.framework.ContextPermission "/*", "transfer,switch"
pd.0.include.4=javacardx.facilities.EventRegistryPermission "event://aid/*", "notify,register,unregister"
pd.0.include.5=javacardx.facilities.ServiceRegistryPermission "sio://aid/*", "lookup,register,unregister"
pd.0.include.6=javacardx.framework.ContextPermission "pd:1", "transfer,switch"
#added for file system
pd.0.include.7=javacardx.io.ConnectorPermission "file:///~/*", "write"
pd.0.include.8=javacardx.io.ConnectorPermission "file://aid/~/*", "write"
pd.0.include.9=javacardx.io.ConnectorPermission "socket://*/*", "connect,listen,accept,read,write"
# <JC_CONNECTED_HOME>/samples/keystore/b.keystore
pd.1.certificate=MIIB8TCCAVqgAwIBAgIER+0v9jANBgkqhkiG9w0BAQUFADA9MQswCQYDVQQGEwJVUzELMAkGA1UEChMCUkkxFTATBgNVBAsTDEhvd1RvU2FtcGxlczEKMAgGA1UEAxMBQjAeFw0wODAzMjgxNzUwNDZaFw0wODA2MjYxNzUwNDZaMD0xCzAJBgNVBAYTAlVTMQswCQYDVQQKEwJSSTEVMBMGA1UECxMMSG93VG9TYW1wbGVzMQowCAYDVQQDEwFCMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCAwAK5KOHPZ9tPMW1fhI7ZMbf/8oKWPaXA4jysLBJZRujb9MHb4k8sXRryU+poaR2WfiWiEaf1e++Vg9WqiIZK/nWvkJM+RvLDjp/uXq771AreLeB6UCfCpyKuYkeNufSyBQb8y2Mw4ZaNimQuSou9N0z+cufwq32q4FklvezVZQIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAG95Tg9tOrrQSOvxENy1dbHDueUam9wZ19a3torZNng5RG77048lj4V4VA+lMjFcw8dzB3KnPjePhUj3w/tBTNzXH/0lZ8K9MSxlXOVxF7/KcBEV3DluHS986um5LIEwcFqVgFf+Vg3jBMV3SE77tNAFVSmzhHETqIyLVr8sBV9P
pd.1.name=1
pd.1.include.0=javacardx.facilities.ServiceRegistryPermission "sio:///standard/auth/holder/global/foo/pin", "register,unregister"
pd.1.include.1=javacardx.framework.ContextPermission "pd:2", "transfer,switch"
pd.1.include.2=javacardx.facilities.ServiceRegistryPermission "sio:///*", "register,unregister,lookup"
#added for file system
pd.1.include.3=javacardx.io.ConnectorPermission "file:///~/*", "write"
# <JC_CONNECTED_HOME>/samples/keystore/c.keystore
pd.2.certificate=MIIB8TCCAVqgAwIBAgIER+0pITANBgkqhkiG9w0BAQUFADA9MQswCQYDVQQGEwJVUzELMAkGA1UEChMCUkkxFTATBgNVBAsTDEhvd1RvU2FtcGxlczEKMAgGA1UEAxMBQzAeFw0wODAzMjgxNzIxMzdaFw0wODA2MjYxNzIxMzdaMD0xCzAJBgNVBAYTAlVTMQswCQYDVQQKEwJSSTEVMBMGA1UECxMMSG93VG9TYW1wbGVzMQowCAYDVQQDEwFDMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDOkTtscaWeOTYVNormIhM5cS2ky/6U1gqU6mhuje6YaRxdIi35XfJozK4ydmASw9YE61jHjauRthljr2rC84/fjOfgHawYK8CSIpyKQ9q4T60u+SWJHb6ekJths7/KRGfPFzRew4Wkk/fR79Y7MgxkHkWar3iEvWaNkEgjWeognwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFNEh6+6pfInBfozlHtK7TSuH1yEeDEcx/VKIHUNOmquobtckVLl6i1iMTT694w2pEeY7zMX4o53/TFJAWruyQFnil3XfS/Culz77gVJhT8w4xpdiVA/Grv8+zKMFqc45KsNjdYqk5sZW161Bate2sSQWzt4MGKqWMLGENmPWi5m
pd.2.name=2
pd.2.include.0=javacardx.facilities.TaskRegistryPermission "task.*"
pd.2.include.1=javacardx.framework.ContextPermission "pd:0", "transfer,switch"
pd.2.include.2=javacardx.io.ConnectorPermission "ssl://*/*", "connect,listen,accept,read,write"
pd.2.include.3=javacardx.io.ConnectorPermission "http://*/*", "connect,listen,accept,read,write"
pd.2.include.4=javacardx.io.ConnectorPermission "https://*/*", "connect,listen,accept,read,write"
pd.2.include.5=javacardx.io.ConnectorPermission "file://*/*", "connect,listen,accept,read,write"
pd.2.include.6=javacardx.io.ConnectorPermission "socket://*/*", "connect,listen,accept,read,write"
pd.2.include.7=javacardx.facilities.ServiceRegistryPermission "sio:///*", "register,unregister,lookup"
pd.2.include.8=javacardx.facilities.EventRegistryPermission "event:///*", "register,unregister,notify"
pd.2.include.9=javacardx.framework.JCRuntimePermission "credentialManager.*"
pd.2.include.10=javacardx.framework.JCRuntimePermission "thread.*"
pd.2.include.11=javacardx.security.CryptoServicePermission "*"
#----//// [End] Custom Protection Domains \\\\----#
#
#----//// Authenticators Configuration \\\\----#
# Configure authenticators used by RI
#
authenticator.0.uri: sio:///standard/auth/holder/session/admin/pin
authenticator.0.factory: com.sun.javacard.security.PINSessionAuthenticatorFactory
authenticator.0.pin: 1234
authenticator.0.digest: false
#
authenticator.1.uri: sio:///standard/auth/user/session/admin/pin
authenticator.1.factory: com.sun.javacard.security.PINSessionAuthenticatorFactory
authenticator.1.pin: 1234
authenticator.1.digest: false
#
authenticator.2.uri: sio:///standard/auth/holder/global/owner1/pin
authenticator.2.factory: com.sun.javacard.security.PINGlobalAuthenticatorFactory
authenticator.2.pin: 1234
authenticator.2.digest: false
#
authenticator.3.uri: sio:///standard/auth/holder/global/sunny/pin
authenticator.3.factory: com.sun.javacard.security.PINGlobalAuthenticatorFactory
authenticator.3.pin: 1234
authenticator.3.digest: false
#
authenticator.4.uri: sio:///standard/auth/user/session/boss/pin
authenticator.4.factory: com.sun.javacard.security.PINSessionAuthenticatorFactory
authenticator.4.pin: 5678
authenticator.4.digest: false
#
authenticator.5.uri: sio:///standard/auth/holder/global/admin/pin
authenticator.5.factory: com.sun.javacard.security.PINGlobalAuthenticatorFactory
authenticator.5.pin: 1234
authenticator.5.digest: false
# bio auth user
authenticator.6.uri: sio:///standard/auth/user/session/hk/bio-password
authenticator.6.factory: com.sun.javacard.security.BioSessionAuthenticatorFactory
authenticator.6.pin: testing
authenticator.6.digest: false
# transit app pos card holder
authenticator.7.uri: sio:///standard/auth/holder/session/transit/owner-pos/pin
authenticator.7.factory: com.sun.javacard.security.PINSessionAuthenticatorFactory
authenticator.7.pin: 8888
authenticator.7.digest: false
# transit app admin card holder
authenticator.8.uri: sio:///standard/auth/holder/global/transit/owner-admin/pin
authenticator.8.factory: com.sun.javacard.security.PINGlobalAuthenticatorFactory
authenticator.8.pin: 8888
authenticator.8.digest: false
# transit app admin remote user
authenticator.9.uri: sio:///standard/auth/user/session/transit/remote-admin/pin
authenticator.9.factory: com.sun.javacard.security.PINSessionAuthenticatorFactory
authenticator.9.pin: 8888
authenticator.9.digest: false
# transit app pos guest card holder
authenticator.10.uri: sio:///standard/auth/holder/session/transit/guest-pos/pin
authenticator.10.factory: com.sun.javacard.security.PINSessionAuthenticatorFactory
authenticator.10.pin: 8888
authenticator.10.digest: false
# authenticators for digest authentication
authenticator.11.uri: sio:///standard/auth/holder/session/digest-admin/pin
authenticator.11.factory: com.sun.javacard.security.PINSessionAuthenticatorFactory
authenticator.11.pin: 1234
authenticator.11.digest: true
#
authenticator.12.uri: sio:///standard/auth/user/session/digest-user/pin
authenticator.12.factory: com.sun.javacard.security.PINSessionAuthenticatorFactory
authenticator.12.pin: 1234
authenticator.12.digest: true
#
authenticator.13.uri: sio:///standard/auth/user/session/hk/password
authenticator.13.factory: com.sun.javacard.security.PasswordSessionAuthenticatorFactory
authenticator.13.pin: testing
authenticator.13.digest: false
#----//// [End] Authenticators Configuration \\\\----#
#
#----//// Credential Manager Defaults \\\\----#
# CAs used for trust determination in the normal SSL handshake
# VeriSign Class 3 Public Primary Certification Authority - G2
ssl.trusted.ca.0=MIIDAjCCAmsCEH3Z/gfPqB63EHln+6eJNMYwDQYJKoZIhvcNAQEFBQAwgcExCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMyBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMB4XDTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMyBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDMXtERXVxp0KvTuWpMmR9ZmDCOFoUgRm1HP9SFIIThbbP4pO0M8RcPO/mn+SXXwc+EY/J8Y8+iR/LGWzOOZEAEaMGAuWQcRXfH2G71lSk8UOg013gfqLptQ5GVj0VXXn7F+8qkBOvqlzdUMG+7AUcyM83cV5tkaWH4mx0ciU9cZwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFFNzb5cy5gZnBWyATl4Lk0PZ3BwmcYQWpSkU01UbSuvDV1Ai2TT1+7eVmGSX6bEHRBhNtMsJzzoKQm5EWR0zLVznxxIqbxhAe7iF6YM40AIOw7n60RzKprxaZLvcRTDOaxxp5EJb+RxBrO6WVcmeQD2+A2iMzAo1KpYoJ2daZH9
# our CA root
ssl.trusted.ca.1=MIIC+zCCAmSgAwIBAgIJANyV276phVfFMA0GCSqGSIb3DQEBBQUAMF0xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRlMRUwEwYDVQQKEwxIb3dUb1NhbXBsZXMxCzAJBgNVBAsTAlJJMRUwEwYDVQQDEwxIb3dUb1NhbXBsZXMwHhcNMDgwMzI3MjEwNTIyWhcNMTgwMzI1MjEwNTIyWjBdMQswCQYDVQQGEwJVUzETMBEGA1UECBMKU29tZS1TdGF0ZTEVMBMGA1UEChMMSG93VG9TYW1wbGVzMQswCQYDVQQLEwJSSTEVMBMGA1UEAxMMSG93VG9TYW1wbGVzMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDiEg6Q/1H7z6Flu4vX8G20cgIhKNJfhzKGy6fFnNNyFSfhjcxnseJ1m2s+zdjN8FutwmqpYR0+4+impMMufj3NAP945jGiXTI7BS4TB7a3xsv8ZCn5PJI8cv7hxU5/+jqOfHEnbatfI7KEt69Dhi0XCTE9TaLCUE0tuhJq0JV35wIDAQABo4HCMIG/MB0GA1UdDgQWBBQwHYyR3nNaJME5E3MDhOUQzEFJ0TCBjwYDVR0jBIGHMIGEgBQwHYyR3nNaJME5E3MDhOUQzEFJ0aFhpF8wXTELMAkGA1UEBhMCVVMxEzARBgNVBAgTClNvbWUtU3RhdGUxFTATBgNVBAoTDEhvd1RvU2FtcGxlczELMAkGA1UECxMCUkkxFTATBgNVBAMTDEhvd1RvU2FtcGxlc4IJANyV276phVfFMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAqjE2QvQT3CNRQic326c4tdEMl4+Ik4joCoutPD218n9O3RthgMXFGiKZ6gkVqqNaNZ47W+Wnam/QBLZMDK1MImVGIBPPOYtqP9XOnyGxQ8f6Eq0AgHby9Dal+158WwCyOgXwGet/FnfKhcjp4mhU2Xb1qEvPCaJX7KPuhSNhIs8=
# accepted certificate issuers (used in client authentication)
ssl.accepted.issuer.0=MIIC+zCCAmSgAwIBAgIJANyV276phVfFMA0GCSqGSIb3DQEBBQUAMF0xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRlMRUwEwYDVQQKEwxIb3dUb1NhbXBsZXMxCzAJBgNVBAsTAlJJMRUwEwYDVQQDEwxIb3dUb1NhbXBsZXMwHhcNMDgwMzI3MjEwNTIyWhcNMTgwMzI1MjEwNTIyWjBdMQswCQYDVQQGEwJVUzETMBEGA1UECBMKU29tZS1TdGF0ZTEVMBMGA1UEChMMSG93VG9TYW1wbGVzMQswCQYDVQQLEwJSSTEVMBMGA1UEAxMMSG93VG9TYW1wbGVzMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDiEg6Q/1H7z6Flu4vX8G20cgIhKNJfhzKGy6fFnNNyFSfhjcxnseJ1m2s+zdjN8FutwmqpYR0+4+impMMufj3NAP945jGiXTI7BS4TB7a3xsv8ZCn5PJI8cv7hxU5/+jqOfHEnbatfI7KEt69Dhi0XCTE9TaLCUE0tuhJq0JV35wIDAQABo4HCMIG/MB0GA1UdDgQWBBQwHYyR3nNaJME5E3MDhOUQzEFJ0TCBjwYDVR0jBIGHMIGEgBQwHYyR3nNaJME5E3MDhOUQzEFJ0aFhpF8wXTELMAkGA1UEBhMCVVMxEzARBgNVBAgTClNvbWUtU3RhdGUxFTATBgNVBAoTDEhvd1RvU2FtcGxlczELMAkGA1UECxMCUkkxFTATBgNVBAMTDEhvd1RvU2FtcGxlc4IJANyV276phVfFMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAqjE2QvQT3CNRQic326c4tdEMl4+Ik4joCoutPD218n9O3RthgMXFGiKZ6gkVqqNaNZ47W+Wnam/QBLZMDK1MImVGIBPPOYtqP9XOnyGxQ8f6Eq0AgHby9Dal+158WwCyOgXwGet/FnfKhcjp4mhU2Xb1qEvPCaJX7KPuhSNhIs8=
# Certificate sent by cjcre when acting as HTTPS server. (signed by our CA root)
ssl.selfIdentityAsServer=MIICJTCCAY4CAQkwDQYJKoZIhvcNAQEEBQAwXTELMAkGA1UEBhMCVVMxEzARBgNVBAgTClNvbWUtU3RhdGUxFTATBgNVBAoTDEhvd1RvU2FtcGxlczELMAkGA1UECxMCUkkxFTATBgNVBAMTDEhvd1RvU2FtcGxlczAeFw0xMDAzMjUyMDQ2MjhaFw0xMTAzMjUyMDQ2MjhaMFkxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxEjAQBgNVBAMTCWxvY2FsaG9zdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA8iU6cOGSsn75Pqh7gJu1CbMX6/LKKRoruEtS+ivq0+QzDQjjOo9lKfy3HbSWcLoEkZMfQbd1Xlr/aBtNu+p2Gc4O/ORrX4wK/7PikQRDxbWWUIEpRC8eXvg/wZG6sEVt+o0BCxmkXUAo89v/j0urGjA/fkSbe6s3etrPjkT55HcCAwEAATANBgkqhkiG9w0BAQQFAAOBgQCallptZqbrBfiC6azWRhZsd1d/zF3ODV4gTLvRZcvFhRUxMUAVU5eiieWPXHWrabJI/HyNg30aMtPuyIoNRVnH+oqqMubJVFR31D03UJlRs6Hjxi4VCUNeHfNgPWNFhToklNY+Laj0zgR9xeSHMG9ke3zzF0B1gV3HiUBsuECOcA==
# private key for ssl.selfIdentityAsServer
ssl.selfIdentitySSLPrivateKeyExp=sxNLI/3+clkq1Obe5x7ABRtYnpsgXMNI//NcuzzNXsTN6F7hRQaVJzcI6UQLWfSHum0WWZBmkVA0wHYox8c+bKjELIlCv2n9x/gZJ+FgF+Z3wQbWnlYts0ECrtJxFNVkugT2e80h2FFYRGClkesMLFMBfF9tMqJw9hD0iPLPJoE=
ssl.selfIdentitySSLPrivateKeyMod=8iU6cOGSsn75Pqh7gJu1CbMX6/LKKRoruEtS+ivq0+QzDQjjOo9lKfy3HbSWcLoEkZMfQbd1Xlr/aBtNu+p2Gc4O/ORrX4wK/7PikQRDxbWWUIEpRC8eXvg/wZG6sEVt+o0BCxmkXUAo89v/j0urGjA/fkSbe6s3etrPjkT55Hc=
# PSK Identity Hint
PSKIdentityHint=X509
#----//// [End] Credential Manager Defaults \\\\----#
#
#----//// Crypto Providers \\\\----#
# classes are expected to be ROMized.
# Only the listed CryptoProviders are registered.
# Note: The index sequence is important.
crypto.provider.0=com.sun.javacard.crypto.SunProvider
#cryptoProvider.1=my.romized.MyProvider
#
#End of configuration
\ No newline at end of file
# Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
# Properties file which configures the operation of the JDK
# logging facility.
# The system will look for this config file, first using
# a System property specified at startup:
#
# >java -Djava.util.logging.config.file=myLoggingConfigFilePath
#
# If this property is not specified, then the config file is
# retrieved from its default location at:
#
# JDK_HOME/jre/lib/logging.properties
# Global logging properties.
# ------------------------------------------
# The set of handlers to be loaded upon startup.
# Comma-separated list of class names.
# java.util.logging.ConsoleHandler
handlers=com.sun.javacard.tools.util.JCConsoleHandler, java.util.logging.FileHandler
# Default global logging level.
# Loggers and Handlers may override this level
.level=ALL
# Loggers
# ------------------------------------------
# Loggers are usually attached to packages.
# Here, the level for each package is specified.
# The global level is used by default, so levels
# specified here simply act as an override.
#com.sun.javacard.offcardinstaller=ALL
# Handlers
# -----------------------------------------
com.sun.javacard.tools.util.JCConsoleHandler.level=ALL
com.sun.javacard.tools.util.JCConsoleHandler.formatter=com.sun.javacard.tools.util.JCToolsFormatter
com.sun.javacard.tools.util.JCConsoleHandler.filter=com.sun.javacard.tools.util.ConsoleFilter
# --- FileHandler ---
# Override of global logging level
java.util.logging.FileHandler.level=ALL
# Naming style for the output file:
# (The output file is placed in the directory
# defined by the "user.home" System property.)
java.util.logging.FileHandler.pattern=%h/java%u.log
# Limiting size of output file in bytes:
java.util.logging.FileHandler.limit=50000
# Number of output files to cycle through, by appending an
# integer to the base file name:
java.util.logging.FileHandler.count=10
# Style of output (Simple or XML):
java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter
java.util.logging.FileHandler.append=true
#--------------print class method info
printCurrentClassAndMethod = false
#
# Copyright (c) 2009 Sun Microsystems, Inc.
# All rights reserved.
# Use is subject to license terms.
#
# Properties visible from System.getProperty()
# Note: There must be a blank line at end of the file
javacard.version: Java Card(tm) Platform v3.0 [Connected Edition]
#
javacard.connector.socket: true
javacard.connector.ssl: true
javacard.connector.http: true
javacard.connector.https: true
javacard.connector.file: false
javacard.connector.com: false
javacard.connector.datagram: false
#
javacard.encoding: ISO8859_1
# Irrespective of OS we are running, internally Java Card RI uses : as the path separator
path.separator: :
# Irrespective of OS we are running, internally Java Card RI uses / as the file separator
file.separator: /
# Irrespective of OS we are running, internally Java Card RI uses \n as the line separator
line.separator: \n
# I18N aliases for common character encodings
SHIFT_JIS_InternalEncodingName: SJIS
X_SJIS_InternalEncodingName: SJIS
# Trusted Clients on localhost
# A client is a trusted client if the HTTP field User-Agent contains
# the string value of trusted.useragent.includes and does not contain
# the string value of trusted.useragent.excludes.
# In the default configuration Firefox can be used as a trusted client and
# MSIE as a remote (not trusted) client.
trusted.useragent.includes=Firefox
trusted.useragent.excludes=MSIE
# Various properties used by Tools.
javacard.name=Java Card Platform
javacard.vendor=Oracle Corporation
javacard.version=3.0.4
javacard.java.majorVersion=1
javacard.java.minorVersion=6
javacard.edition=Classic
javacard.distribution.scope=@EXPORT_TYPE@
javacard.home=./
javacard.emulator=bin/cjcre.exe
javacard.bootclasspath=lib/api_connected.jar
javacard.classic.bootclasspath=lib/api_classic.jar
javacard.classpath=
javacard.javadocpath=docs/api/
javacard.sourcepath=src/api/
javacard.toolClassPath=lib/tools.jar:lib/ant-contrib-1.0b3.jar:lib/bcel-5.2.jar:lib/commons-cli-1.0.jar:lib/commons-codec-1.3.jar:lib/commons-httpclient-3.0.jar:lib/commons-logging-1.1.jar
javacard.nbtasksClassPath=lib/nbtasks.jar:lib/nbutils.jar
javacard.platform.kind=RI
javacard.device.file.extension=jcard
#
javacard.runtime.name=Java Card Runtime Environment
javacard.specification.version=3.0.1
javacard.specification.vendor=Sun Microsystems Inc.
javacard.referenceimplementation.version=3.0.4
javacard.referenceimplementation.vendor=Sun Microsystems Inc.
javacard.referenceimplementation.httpPort=yes
javacard.referenceimplementation.contactedPort=yes
javacard.referenceimplementation.contactlessPort=yes
#Supported app models
javacard.platform.supported.project.kinds=classic-applet,classic-lib
#tools/task class names
javacard.apdutoolClass=com.sun.javacard.apdutool.Main
javacard.tasks.packTaskClass=com.sun.javacard.nbtasks.PackTask
javacard.tasks.signTaskClass=com.sun.javacard.nbtasks.SignTask
javacard.tasks.proxyTaskClass=com.sun.javacard.nbtasks.ProxyTask
javacard.tasks.loadTaskClass=com.sun.javacard.nbtasks.LoadTask
javacard.tasks.createTaskClass=com.sun.javacard.nbtasks.CreateTask
javacard.tasks.deleteTaskClass=com.sun.javacard.nbtasks.DeleteTask
javacard.tasks.unloadTaskClass=com.sun.javacard.nbtasks.UnloadTask
javacard.tasks.browseTaskClass=com.sun.javacard.nbtasks.OpenBrowserTask
MIIB8TCCAVqgAwIBAgIER+0X/zANBgkqhkiG9w0BAQUFADA9MQswCQYDVQQGEwJVUzELMAkGA1UEChMCUkkxFTATBgNVBAsTDEhvd1RvU2FtcGxlczEKMAgGA1UEAxMBQTAeFw0wODAzMjgxNjA4MzFaFw0wODA2MjYxNjA4MzFaMD0xCzAJBgNVBAYTAlVTMQswCQYDVQQKEwJSSTEVMBMGA1UECxMMSG93VG9TYW1wbGVzMQowCAYDVQQDEwFBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCTIYVeLV+oyViuf8WOPQeo9AaydiuO5tWzHarb3ol3tY1o0xuooC9MpJEYyDTFBJ9YH9oNtemDU0YxswNtVbJropvwO9lVChn3OvXNfoFEYw8aeVl3pFHrAf4T+EL61Ybgi8PqW0OO/fEf6gkvbJkxy5S421gOrK191pIRTmyr5QIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAD0ufB/7/hgx0Zp/T5kjuaWEc6hXB4wlRnXzfwjysvx8K2z2aSVGO5ZbJL8qCh3PQmZZZlpVTbxey/jijwylFiBT3rTonjdKFpv3pypt+3teXvvSfApnUrA7PlgPBgfkWR/UgzN9N6huOWNfJkkWuCsRhq47PpxYfdh1LeyLjuNR
MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAJMhhV4tX6jJWK5/xY49B6j0BrJ2K47m1bMdqtveiXe1jWjTG6igL0ykkRjINMUEn1gf2g216YNTRjGzA21Vsmuim/A72VUKGfc69c1+gURjDxp5WXekUesB/hP4QvrVhuCLw+pbQ4798R/qCS9smTHLlLjbWA6srX3WkhFObKvlAgMBAAECgYBF+Os0nt+fpiJG2v1ZaCz8bRHCTfDpRV7ckH9xkaRPCkj2UXAWAhh8msdmwdBW4pvljUBmxN0JV9FKUZiPpvHzBHu7eHfNipFPa34Tw834sYRXz4jauHY10AD4d2blzBX59qtQY0oBYm5Ey4j76LFjAiA8Qp8s6lYabAurhBIIAQJBANzt9ooLQQLunIeg4v88jTGHs5iLMfoEL+RvZWRqpHWwPD6AzjtaL61F+vTqztYX03eP5Ix63wOTSsvPo8UegMkCQQCqfJAh4G1fOmKcnf1n3KmHw0BXVpk8TNM+wAZtNre60Ei7WJqwx22rN7N22GcDeNyXRxOgpIygJCXh+GDKghw9AkByUPNr1IzsLnlyOI6ckUFh6pzEhunyO25onjdxsTit6OYTVWThEzZuSzKivkkOQL/cMumIwx9YY0OlmChem/z5AkA3XXplNf/u1AQgPoKDzzpS94qWkm3zEjPsBepQX1utVGS6Spz52dn4p38lkkNp8j8Y9aEfIzDz9KlEyCeOvFA1AkBr982/4ktAy3TmtCzuSaIDjK5jqSkBahqM9kH8nz9dJY1EqY7GmFBOPj7CWoOo5BTA02XJvbb6kXVWF4kaUZVQ
MIIB8TCCAVqgAwIBAgIER+0v9jANBgkqhkiG9w0BAQUFADA9MQswCQYDVQQGEwJVUzELMAkGA1UEChMCUkkxFTATBgNVBAsTDEhvd1RvU2FtcGxlczEKMAgGA1UEAxMBQjAeFw0wODAzMjgxNzUwNDZaFw0wODA2MjYxNzUwNDZaMD0xCzAJBgNVBAYTAlVTMQswCQYDVQQKEwJSSTEVMBMGA1UECxMMSG93VG9TYW1wbGVzMQowCAYDVQQDEwFCMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCAwAK5KOHPZ9tPMW1fhI7ZMbf/8oKWPaXA4jysLBJZRujb9MHb4k8sXRryU+poaR2WfiWiEaf1e++Vg9WqiIZK/nWvkJM+RvLDjp/uXq771AreLeB6UCfCpyKuYkeNufSyBQb8y2Mw4ZaNimQuSou9N0z+cufwq32q4FklvezVZQIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAG95Tg9tOrrQSOvxENy1dbHDueUam9wZ19a3torZNng5RG77048lj4V4VA+lMjFcw8dzB3KnPjePhUj3w/tBTNzXH/0lZ8K9MSxlXOVxF7/KcBEV3DluHS986um5LIEwcFqVgFf+Vg3jBMV3SE77tNAFVSmzhHETqIyLVr8sBV9P
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAIDAArko4c9n208xbV+Ejtkxt//ygpY9pcDiPKwsEllG6Nv0wdviTyxdGvJT6mhpHZZ+JaIRp/V775WD1aqIhkr+da+Qkz5G8sOOn+5ervvUCt4t4HpQJ8KnIq5iR4259LIFBvzLYzDhlo2KZC5Ki703TP5y5/CrfargWSW97NVlAgMBAAECgYAUmKLW5Adbmo2m2Y1ZnmcLr7xzoWPqjOobNRXnpRU6WvGdXkY02rs3qZ1J7sqs8UPec0ep6ZEo4C6viGuB4F07H+YBlvwsqxaXyJYMfQvJzMlsq3Rpc1WhNEGLWXVGdaLM/Q+gQ5EShZuZ+fLX/wiBXetr9zIbbieMnkn5Tv0igQJBALqwq3v9a9ESsVqjdlnLfu5IbQqbETtNF951RE29pob5jPV/js7eWne3Di0yIjQqqQpsDwa0XXxG4zEHJ99gi1kCQQCwjJ9bD9LegC8iXEJrPigBhHtfNznQaHmCxjucxtpVO71u8LA6aSUrgYvtDBpNQk1aLfPzCWn1zrDh2fY6M/TtAkAZBPpGaKUdZOLt4cBHsnT1XDF43WVGzEMppg+cV5FMv377m7e406XOK3Mz7WcWFK2I3wh4fo2UzS8/b9URI7ApAkBDxzjGdOS3lu6BennlQg+JxZq3izQe1n0Pv5rTLWRUpIKtPKnrQsKKWUmmz6apUnLv1AR7oXmUbK1rh4oH/jphAkEAsSsmtbVpK850usdWmCIbcmwwWK8QaF77WOcE8YqymnL3zFFlWBQEZTYY1HGkqmaySrRdSo4e7PZe6pi08Wl7Qw==
MIIB8TCCAVqgAwIBAgIER+0pITANBgkqhkiG9w0BAQUFADA9MQswCQYDVQQGEwJVUzELMAkGA1UEChMCUkkxFTATBgNVBAsTDEhvd1RvU2FtcGxlczEKMAgGA1UEAxMBQzAeFw0wODAzMjgxNzIxMzdaFw0wODA2MjYxNzIxMzdaMD0xCzAJBgNVBAYTAlVTMQswCQYDVQQKEwJSSTEVMBMGA1UECxMMSG93VG9TYW1wbGVzMQowCAYDVQQDEwFDMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDOkTtscaWeOTYVNormIhM5cS2ky/6U1gqU6mhuje6YaRxdIi35XfJozK4ydmASw9YE61jHjauRthljr2rC84/fjOfgHawYK8CSIpyKQ9q4T60u+SWJHb6ekJths7/KRGfPFzRew4Wkk/fR79Y7MgxkHkWar3iEvWaNkEgjWeognwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFNEh6+6pfInBfozlHtK7TSuH1yEeDEcx/VKIHUNOmquobtckVLl6i1iMTT694w2pEeY7zMX4o53/TFJAWruyQFnil3XfS/Culz77gVJhT8w4xpdiVA/Grv8+zKMFqc45KsNjdYqk5sZW161Bate2sSQWzt4MGKqWMLGENmPWi5m
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAM6RO2xxpZ45NhU2iuYiEzlxLaTL/pTWCpTqaG6N7phpHF0iLfld8mjMrjJ2YBLD1gTrWMeNq5G2GWOvasLzj9+M5+AdrBgrwJIinIpD2rhPrS75JYkdvp6Qm2Gzv8pEZ88XNF7DhaST99Hv1jsyDGQeRZqveIS9Zo2QSCNZ6iCfAgMBAAECgYEAsvdJEK912hufK8nRlYk4NrBD51+F9dVr3ZEpYX8+lHWcyWPviPlIKFwNIFNG8XsSVbjBdkLbvqaSYLd+O+FhZ7J6knUwunCjKZkhK+qywyiqC92pq7azh1KMBW2rUAgH7OpbF8YINJIlKsM3tuFIEqwHYCSJ6nrRn3bfhPqRPoECQQDw4B4orfzooJMlmMXkLl7lnFX7uCbd7/or4GxkP8QRfl2T5joTJsGULK/KFeenLuD51Rpcf2DBfeoXMS8TgN4vAkEA24mjVeCxoLwlmVNQCJvJA7boNl+Ux8E7v3Jnzdi6dPRZm1z+gTp/1bYMBHLJVuT/Lu0jFgZ49ZigjJbthU44kQJAZETXKRXsLqYROthSoD7RUAF5JXSt8TshR7x/Qmfs5V9V8ugmiqxabqT/dD8UFFsGWdlkxNZdX45bsNXPg+3kDwJBAMP34AJ3uXe2m4V7VhTpIw2axzxKI+AQAIqL0FdyoDZoLFjAMTsgAh6+C4opAMr9TUERU2GE05K/9Iiq7UkyotECQGYXR4YOmTzdr4GlZBlA0f8xGMV//BSZeIYuRuI73DmIfFlTdtcobkskKHJpxoE3SGW/5tIjTMggTvghzW64NR8=
/*
* Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*
* SCCS: %W% %E%
*/
/* font tag overwrite */
font {
font-family:Arial, Helvetica, FreeSans, "Luxi-sans", "Nimbus Sans L", sans-serif;
font-size:14px;
}
/* font family */
body, input, select, textarea, button {
font-family:Arial, Helvetica, FreeSans, "Luxi-sans", "Nimbus Sans L", sans-serif;
font-size:100%;
}
code, kbd, tt, pre {
font-family:Monaco, Courier, "Courier New";
font-size:110%;
}
/* generic */
body {
color:#000;
}
a {
color:#666;
text-decoration:none
}
a.href {
color:#666;
text-decoration:none
}
a.hover {
color:#F00;
text-decoration:none
}
a.visited {
color:#999;
text-decoration:none
}
a.link {
color:#F00;
text-decoration:none
}
ol, ul {
margin:1ex;
padding-left:1ex;
}
li {
margin:1ex;
padding-left:0ex
}
dl {
margin:1.6ex;
padding-left:0ex;
}
dt {
margin:1ex;
padding-left:0ex
}
tr {vertical-align:top;}
table tr th {
background:#E5E5E6;
font-size:90%;
text-align:left;
vertical-align:top;
padding-left:1ex;
}
caption {
font-weight:bold;
font-size:85%;
}
/* hr */
hr.light {
background:#E3E3E3;
color:#E3E3E3;
height:2px;
padding:0;
border:0
}
hr.red {
background:#F00;
color:#F00;
height:2px;
padding:0;
border:0
}
div.MastheadPane {
height: 45px;
width: 100%;
top: 0;
right: 0;
bottom: auto;
left: 0;
overflow: hidden;
border-bottom: 3px #F00;
margin: 0;
text-decoration:none;
}
div.MastheadDateBuild {
height: 90px;
width: 100%;
top: 0;
right: 0;
bottom: auto;
left: 0;
overflow: visible;
border-bottom: 3px #F00;
text-decoration:none;
}
.MastheadPane tr td {
background:#fff;
background-color:#FFF;
padding: 0px;
margin: 0px;
}
.MastheadPane tr th {
background:#fff;
background-color:#FFF;
padding: 0px;
margin: 0px;
}
.MastheadDateBuild tr th {
background:#fff;
background-color:#FFF;
padding: 0px;
margin: 0px;
}
.MastheadDateBuild tr td {
background:#fff;
background-color:#FFF;
padding: 0px;
margin: 0px;
}
table.MastheadTable {
width: 100%;
border-collapse:collapse;
padding: 0px;
margin: 0px;
background:#FFF;
background-color:#FFF
}
table.MastheadDateBuild {
width: 100%;
border-collapse:collapse;
margin: 0px;
padding: 0px;
background:#FFF;
}
div.MastheadPane a {
color: rgb(127, 127, 127);
background:#FFF;
}
th.smallLogo {
width: 130px;
align: right;
}
td.smallLogo {
width: 130px;
align: right;
}
td.javaLogo {
width: 100px;
text-align: right;
}
.smallLogo img {
padding-right: 15px;
}
tr.breadcrumbbar {
margin: 0px;
height: 15px;
}
tr.titlebar {
height: 55px;
padding: 0px;
background-color:#FFF;
}
h4.contentpage-doctitle {
color: rgb(127, 127, 127);
font-family: "Univers LT Std", Univers, Arial, Helvetica, sans-serif;
font-size: 120%;
font-weight: bold;
text-align: left;
padding: 0px;
width: auto;
}
p.breadcrumb a {
color: rgb(255, 0, 0);
font-weight: bold;
}
p.breadcrumb {
margin-bottom: 20px
}
div.MainContent a:visited {
color: rgb(127, 127, 127)
}
div.MainContent a {
color: rgb(0, 0, 0);
text-decoration:none
}
div.embeddedtoc {
margin: 0ex;
}
.embeddedtoc a {
color:#666;
text-decoration:none
}
.embeddedtoc a.href {
color:#666;
text-decoration:none
}
.embeddedtoc a.hover {
color:#F00;
text-decoration:none
}
.embeddedtoc a.visited {
color:#999;
text-decoration:none
}
.embeddedtoc a.link {
color:#666;
text-decoration:none
}
.embeddedtoc p {
margin-top: -1ex;
}
.embeddedtoc p.level1 a {
color: (127,127,127);
font-size: 100%;
}
.embeddedtoc p.level2 a {
color: rgb(127,127,127);
font-size: 90%;
margin-left: 3ex;
}
.embeddedtoc p.level3 a {
color: rgb(127,127,127);
font-size: 85%;
margin-left: 6ex;
}
.embeddedtoc p.level4 a {
color: rgb(127,127,127);
font-size: 85%;
margin-left: 9ex;
}
.embeddedtoc p.level5 a {
color: rgb(70,70,70);
font-size: 85%;
margin-left: 12ex;
}
div.BodyStyle {
width: 100%;
top: 100px;
right: 0;
bottom: 20px;
left: 0px;
margin: 0px;
overflow: hidden;
font-family:Arial, Helvetica, FreeSans, "Luxi-sans", "Nimbus Sans L", sans-serif;
}
BodyStyle a.href {
text-decoration:none
}
BodyStyle a.hover {
color:#F00
}
BodyStyle a.visited {
color:#999
}
BodyStyle a.link {
color:#666
}
p.navtop, p.navtop a {
font-size:85%;
}
body {
padding: 1.5em;
margin: 0;
background-color: white;
font-size:14px;
}
h1+p, h2+p, h3+p, h4+p, h5+p {
margin-top: 0;
}
code, pre {
color: black;
}
pre {
background-color: #efefef;
border: 1px solid #ccc;
padding: 0.5em;
overflow: hidden;
font-size: 110%;
}
a img {
border-style: none;
}
div.TitleDiv {
margin-top: 30px;
}
h2.DocTitle {
color: rgb(127, 127, 127);
font-family: "Univers LT Std", Univers, Arial, Helvetica, sans-serif;
font-size: 115%;
font-weight: bold;
text-align: left;
text-decoration: none;
text-indent: 0px;
text-transform: none
}
h3.SubTitle {
color: rgb(127, 127, 127);
font-family: "Univers LT Std", Univers, Arial, Helvetica, sans-serif;
font-size: 90%;
font-weight: bold;
text-align: left;
text-decoration: none;
text-indent: 0px;
text-transform: none
}
h4.TitleDate {
color: rgb(127, 127, 127);
font-family: "Univers LT Std", Univers, Arial, Helvetica, sans-serif;
font-size: 80%;
font-weight: bold;
text-align: left;
text-decoration: none;
text-indent: 0px;
text-transform: none
}
.BodyStyle tr thead th {
text-align:left;
background-color:#fefefe;
}
.BodyStyle h1 {
margin-top: 1.25em;
margin-bottom: 0.5em;
color: rgb(127, 127, 127);
}
.BodyStyle h2 {
font-size: 125%;
font-family: "Univers LT Std", Univers, Arial, Helvetica, sans-serif;
margin-top: 1.25em;
margin-bottom: 0.5em;
color: rgb(127, 127, 127);
}
.BodyStyle h3 {
font-size: 115%;
font-family: "Univers LT Std", Univers, Arial, Helvetica, sans-serif;
margin-top: 1.25em;
color: rgb(127, 127, 127);
margin-bottom: 0.5em;
}
.BodyStyle h4 {
font-size: 105%;
font-family: "Univers LT Std", Univers, Arial, Helvetica, sans-serif;
margin-top: 1.25em;
margin-bottom: 0.5em;
color: rgb(127, 127, 127);
}
.BodyStyle h5 {
font-size: 95%;
font-family: "Univers LT Std", Univers, Arial, Helvetica, sans-serif;
margin-top: 1.25em;
margin-bottom: 0.5em;
color: rgb(127, 127, 127);
}
.BodyStyle h6 {
font-size: 85%;
font-family: "Univers LT Std", Univers, Arial, Helvetica, sans-serif;
margin-top: 1.25em;
margin-bottom: 0.5em;
color: rgb(127, 127, 127);
}
.BodyStyle table {
font-size:100%;
border-color:#CCC;
width:100%;
border:solid;
border-left:none;
border-right:none;
border-top:none;
border-bottom:medium;
border-width:medium;
}
DistributionREADME
DISTRIBUTION BY DEVELOPERS. Subject to the terms and conditions of the Software License Agreement and the obligations, restrictions, and exceptions set forth below, You may reproduce and distribute the portions of Software identified below ("Redistributable"), provided that:
(a) You distribute Redistributable complete and unmodified and only bundled as part of Your Programs,
(b) Your Programs add significant and primary functionality to the Redistributable,
(c) You do not distribute additional software intended to replace any
component(s) of the Redistributable,
(d) You do not remove or alter any proprietary legends or notices contained in or on the Redistributable.
(e) You only distribute the Redistributable subject to a license agreement that protects Oracle's interests consistent with the terms contained in this
Agreement, and
(f) You agree to defend and indemnify Oracle and its licensors from and against any damages, costs, liabilities, settlement amounts and/or expenses (including attorneys' fees) incurred in connection with any claim, lawsuit or action by any third party that arises or results from the use or distribution of any and all Programs and/or Redistributable.
The following files are Redistributables:
Java Card Development Kit 3.0.4
This source diff could not be displayed because it is too large. You can view the blob instead.
# Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
# Properties file which configures the operation of the JDK
# logging facility.
# The system will look for this config file, first using
# a System property specified at startup:
#
# >java -Djava.util.logging.config.file=myLoggingConfigFilePath
#
# If this property is not specified, then the config file is
# retrieved from its default location at:
#
# JDK_HOME/jre/lib/logging.properties
# Global logging properties.
# ------------------------------------------
# The set of handlers to be loaded upon startup.
# Comma-separated list of class names.
# java.util.logging.ConsoleHandler
handlers=com.sun.javacard.tools.util.JCConsoleHandler, java.util.logging.FileHandler
# Default global logging level.
# Loggers and Handlers may override this level
.level=ALL
# Loggers
# ------------------------------------------
# Loggers are usually attached to packages.
# Here, the level for each package is specified.
# The global level is used by default, so levels
# specified here simply act as an override.
#com.sun.javacard.offcardinstaller=ALL
# Handlers
# -----------------------------------------
com.sun.javacard.tools.util.JCConsoleHandler.level=ALL
com.sun.javacard.tools.util.JCConsoleHandler.formatter=com.sun.javacard.tools.util.JCToolsFormatter
com.sun.javacard.tools.util.JCConsoleHandler.filter=com.sun.javacard.tools.util.ConsoleFilter
# --- FileHandler ---
# Override of global logging level
java.util.logging.FileHandler.level=ALL
# Naming style for the output file:
# (The output file is placed in the directory
# defined by the "user.home" System property.)
java.util.logging.FileHandler.pattern=%h/java%u.log
# Limiting size of output file in bytes:
java.util.logging.FileHandler.limit=50000
# Number of output files to cycle through, by appending an
# integer to the base file name:
java.util.logging.FileHandler.count=10
# Style of output (Simple or XML):
java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter
java.util.logging.FileHandler.append=true
#--------------print class method info
printCurrentClassAndMethod = false
rootProject.name = 'passportApplet'
package josh.passport;
/* buffer for ATR Historical Bytes (ATS) must be a global */
public class ATRGlobal {
public static byte[] ATR_HIST= {(byte) 0x4a,(byte) 0x4d,(byte) 0x52, (byte) 0x54, (byte) 0x44}; // "JMRTD"
public static byte ATR_HIST_LEN= 0x05;
}
package josh.passport;
/**
* A very rough, zero extra memory use, TLV array scanner.
*
* @author Cees-Bart Breunesse <[email protected]>
* @author Wojciech Mostowski <[email protected]>
*
*/
public class BERTLVScanner {
/** Universal tag class. */
public static final short UNIVERSAL_CLASS = 0;
/** Application tag class. */
public static final short APPLICATION_CLASS = 1;
/** Context specific tag class. */
public static final short CONTEXT_SPECIFIC_CLASS = 2;
/** Private tag class. */
public static final short PRIVATE_CLASS = 3;
// Tag data
static short tag;
static short tagClass;
static boolean isPrimitive;
// Offset and length for the value
static short valueOffset;
static short valueLength;
private BERTLVScanner() { }
public static short readTag(byte[] in, short offset) {
short in_p = offset;
short b = (short) (in[in_p] & 0xff);
while (b == 0 || b == 0xff) {
in_p++;
b = in[in_p]; /* skip 00 and FF */
}
switch (b & 0xC0) {
case 0:
tagClass = UNIVERSAL_CLASS;
break;
case 0x40:
tagClass = APPLICATION_CLASS;
break;
case 0x80:
tagClass = CONTEXT_SPECIFIC_CLASS;
break;
case 0xC0:
tagClass = PRIVATE_CLASS;
break;
}
switch (b & 0x20) {
case 0:
isPrimitive = true;
break;
case 0x20:
isPrimitive = false;
break;
}
switch (b & 0x1F) {
case 0x1F:
tag = b;
in_p++;
b = in[in_p];
while ((b & 0x80) == 0x80) {
tag <<= 8;
tag |= (b & 0x7F);
in_p++;
b = in[in_p];
}
tag <<= 8;
tag |= (b & 0x7F);
break;
default:
tag = b;
break;
}
in_p++;
return in_p;
}
public static short readLength(byte[] in, short offset) {
short in_p = offset;
short b = (short) (in[offset] & 0xff);
if ((b & 0x80) == 0) {
/* short form */
valueLength = b;
} else {
/* long form */
short count = (short) (b & 0x7F);
valueLength = 0;
for (short i = 0; i < count; i++) {
in_p++;
b = (short) (in[in_p] & 0xff);
valueLength <<= 8;
valueLength += b;
}
}
valueOffset = (short) (in_p + 1);
return valueOffset;
}
public static short skipValue() {
return (short) (valueOffset + valueLength);
}
}
/*
* passportapplet - A reference implementation of the MRTD standards.
*
* Copyright (C) 2006 SoS group, Radboud University
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* $Id$
*/
package josh.passport;
import javacard.framework.ISO7816;
import javacard.framework.ISOException;
import javacard.framework.JCSystem;
import javacard.framework.Util;
import javacard.security.CryptoException;
import javacard.security.DESKey;
import javacard.security.Signature;
import javacardx.crypto.Cipher;
/**
* This class is a hack. It (probably) implements
* => encrypt/decrypt of ALG_DES_CBC_NOPAD using ALG_DES_CBC_ISO9797_M2
* This is because ALG_DES_CBC_NOPAD and ALG_DES_MAC8_ISO9797_1_M2_ALG3 do not
* exist on CREF.
*
* @author Cees-Bart Breunesse <[email protected]>
* @author Ronny Wichers Schreur <[email protected]>
*
* @version $Revision$
*/
public class CREFPassportCrypto extends JCOP41PassportCrypto implements ISO7816 {
private byte padding;
protected void init() {
ciph = Cipher.getInstance(Cipher.ALG_DES_CBC_ISO9797_M2, false);
sig = Signature.getInstance(Signature.ALG_DES_MAC8_ISO9797_M2,
false);
}
CREFPassportCrypto(KeyStore keyStore) {
super(keyStore);
tempSpace_decryptDES = JCSystem.makeTransientByteArray((short) 16,
JCSystem.CLEAR_ON_RESET);
tempSpace_doMacFinal = JCSystem.makeTransientByteArray((short) 24,
JCSystem.CLEAR_ON_RESET);
}
private short decryptDESusingDESCBCM2(DESKey key, byte[] in,
short in_offset, byte[] out, short out_offset, short length) {
if ((ciph.getAlgorithm() != Cipher.ALG_DES_CBC_ISO9797_M2)
|| ((short) (length + out_offset + 16) > (short) (out.length))
|| ((short) (length + in_offset) > (short) in.length))
ISOException.throwIt((short) 0x6d69);
ciph.init(key, Cipher.MODE_ENCRYPT);
ciph.doFinal(ZERO,
(short) 0,
(short) 8,
tempSpace_decryptDES,
(short) 0);
ciph.init(key, Cipher.MODE_DECRYPT);
short written = ciph.update(in, in_offset, length, out, out_offset);
written += ciph.doFinal(tempSpace_decryptDES,
(short) 0,
(short) (16),
out,
(short) (out_offset + written));
return (short)(written - 8); // FIXME: hack, compensate for padding
}
private static byte[] tempSpace_decryptDES;
private static final byte[] ZERO = { 0, 0, 0, 0, 0, 0, 0, 0 };
private DESKey k;
private byte[] tempSpace_doMacFinal;
private void decryptInit(DESKey k) {
this.k = k;
}
private void encryptInit(DESKey k) {
this.k = k;
}
public void decryptInit() {
k=keyStore.getCryptKey();
}
public short decrypt(byte[] ctext, short ctext_offset, short ctext_len,
byte[] ptext, short ptext_offset) {
CryptoException.throwIt((short)0x6d66);
return 0;
}
public short encrypt(byte[] ctext, short ctext_offset, short ctext_len,
byte[] ptext, short ptext_offset) {
CryptoException.throwIt((short)0x6d66);
return 0;
}
public short decryptFinal(byte[] ctext, short ctext_offset, short ctext_len,
byte[] ptext, short ptext_offset) {
return decryptDESusingDESCBCM2(k, ctext, ctext_offset, ptext, ptext_offset, ctext_len);
}
public short encryptInit(byte padding, byte[] plainText, short plaintextOffset, short plaintextLength) {
return encryptInit(keyStore.getCryptKey(), padding, plainText, plaintextOffset, plaintextLength);
}
private short encryptInit(DESKey k, byte padding, byte[] plainText, short plaintextOffset, short plaintextLength) {
this.k = k;
this.padding = padding;
return plaintextLength;
}
public short encryptFinal(byte[] ptext, short ptext_offset, short ptext_len,
byte[] ctext, short ctext_offset) {
ciph.init(k, Cipher.MODE_ENCRYPT);
short len = ciph.doFinal(ptext, ptext_offset, ptext_len, ctext, ctext_offset);
if(padding == PAD_INPUT) {
// ALG_DES_CBC_ISO9797_M2 does padding
return len;
}
else if (padding == DONT_PAD_INPUT) {
return (short)(len - 8); // FIXME: hack
}
return 0;
}
public void createMacFinal(byte[] msg, short msg_offset, short msg_len,
byte[] mac, short mac_offset) {
DESKey kA = keyStore.getMacKey(KeyStore.KEY_A);
DESKey kB = keyStore.getMacKey(KeyStore.KEY_B);
// updateMac(msg, msg_offset, msg_len);
sig.sign(msg, msg_offset, msg_len, mac, mac_offset);
decryptInit(kB);
short tempmac_offset = 0;
//macCiphECB.init(kB, Cipher.MODE_DECRYPT);
decryptFinal(mac, mac_offset, (short)8, tempSpace_doMacFinal, tempmac_offset );
//macCiphECB.doFinal(mac, mac_offset, (short)8, mac, mac_offset);
encryptInit(kA);
//macCiphECB.init(kA, Cipher.MODE_ENCRYPT);
encryptFinal(tempSpace_doMacFinal, tempmac_offset, (short)8, tempSpace_doMacFinal, tempmac_offset);
//macCiphECB.doFinal(mac, mac_offset, (short)8, mac, mac_offset);
Util.arrayCopyNonAtomic(tempSpace_doMacFinal, tempmac_offset, mac, mac_offset, (short)8);
}
}
package josh.passport;
import javacard.framework.ISO7816;
import javacard.framework.ISOException;
import javacard.framework.JCSystem;
import javacard.framework.Util;
import javacard.security.KeyBuilder;
import javacard.security.RSAPublicKey;
import javacard.security.Signature;
/**
* Encapsulation class for a card verifiable certificates according to EAC 1.11.
*
* @author Wojciech Mostowski <[email protected]>
*
*/
public class CVCertificate {
private static final byte ROLE_DV_DOMESTIC = (byte)0x80;
private static final byte ROLE_DV_FOREIGN = (byte)0x40;
private static final byte ACCESS_DG3 = 0x01;
private static final byte ACCESS_DG4 = 0x02;
private static final byte CAR_TAG = 0x42;
/**
* Offsets to where the particular data (offsets & lengths) of the current
* certificate is (temporarily) stored in the data array
*/
static final short OFFSET_PUB_KEY_MODULUS_OFFSET = 0;
static final short OFFSET_PUB_KEY_MODULUS_LENGTH = 1;
static final short OFFSET_PUB_KEY_EXPONENT_OFFSET = 2;
static final short OFFSET_PUB_KEY_EXPONENT_LENGTH = 3;
static final short OFFSET_SUB_ID_OFFSET = 4;
static final short OFFSET_SUB_ID_LENGTH = 5;
static final short OFFSET_AUTHORIZATION_OFFSET = 6;
static final short OFFSET_EFF_DATE_OFFSET = 7;
static final short OFFSET_EXP_DATE_OFFSET = 8;
static final short OFFSET_SIGNATURE_OFFSET = 9;
static final short OFFSET_SIGNATURE_LENGTH = 10;
static final short OFFSET_BODY_LENGTH = 11;
/** Different tags to parse */
private static final short TAG_CERT_BODY = 0x7F4E;
private static final short TAG_CERT_VERSION = 0x5F29;
private static final short TAG_AUTH_ID = 0x42;
private static final short TAG_PUB_KEY = 0x7F49;
private static final short TAG_OID = 0x06;
private static final short TAG_MODULUS = 0x81;
private static final short TAG_EXPONENT = 0x82;
private static final short TAG_SUBJECT_ID = 0x5F20;
private static final short TAG_SUBJECT_AUTH = 0x7F4C;
private static final short TAG_AUTHORIZATION = 0x53;
private static final short TAG_EFF_DATE = 0x5F25;
private static final short TAG_EXP_DATE = 0x5F24;
private static final short TAG_SIGNATURE = 0x5F37;
/** The ASN1 OID of the only algorithm our certificates support */
private static final byte[] RSA_SHA1_OID = { 0x04, 0x00,
0x7F, 0x00, 0x07, 0x02, 0x02, 0x02, 0x01, 0x01 };
/** The EAC OID, see EAC 1.11, D.2.1.3 */
private static final byte[] EAC_OID = { 0x04, 0x00,
0x7F, 0x00, 0x07, 0x03, 0x01, 0x02, 0x01 };
short[] data;
Object[] source;
RSAPublicKey currentCertPublicKey;
byte[] currentCertSubjectId;
byte[] effectiveCertAuthorization;
byte[] currentCertEffDate;
byte[] currentCertExpDate;
byte[] accessFlag;
byte[] currentDate = { 0x00, 0x09, 0x00, 0x01, 0x00, 0x01 }; // 2009-01-01
Signature signature;
byte[] currentCertNum;
byte[] cert1HolderReference;
byte[] cert1PublicKeyData;
byte cert1Authorization;
byte[] cert1EffDate;
byte[] cert1ExpDate;
byte[] cert2HolderReference;
byte[] cert2PublicKeyData;
byte cert2Authorization;
byte[] cert2EffDate;
byte[] cert2ExpDate;
byte[] cvcaFileReference;
CVCertificate() {
data = JCSystem.makeTransientShortArray(
(short) (OFFSET_BODY_LENGTH + 1), JCSystem.CLEAR_ON_DESELECT);
effectiveCertAuthorization = JCSystem.makeTransientByteArray((short)1,
JCSystem.CLEAR_ON_DESELECT);
currentCertNum = JCSystem.makeTransientByteArray((short)1,
JCSystem.CLEAR_ON_DESELECT);
accessFlag = JCSystem.makeTransientByteArray((short)1,
JCSystem.CLEAR_ON_DESELECT);
currentCertEffDate = JCSystem.makeTransientByteArray((short)6,
JCSystem.CLEAR_ON_DESELECT);
currentCertExpDate = JCSystem.makeTransientByteArray((short)6,
JCSystem.CLEAR_ON_DESELECT);
source = JCSystem.makeTransientObjectArray((short) 1,
JCSystem.CLEAR_ON_DESELECT);
currentCertSubjectId = JCSystem.makeTransientByteArray((short) 17,
JCSystem.CLEAR_ON_DESELECT);
currentCertPublicKey = (RSAPublicKey) KeyBuilder.buildKey(
KeyBuilder.TYPE_RSA_PUBLIC, KeyBuilder.LENGTH_RSA_1024, false);
signature = Signature.getInstance(Signature.ALG_RSA_SHA_PKCS1, false);
}
/**
* Checks if the provided subject id matches the current one, if any, or selects one of the root ones.
*
* @param data
* byte[] with the subject id
* @param offset
* offset to data
* @param length
* length of the data
* @return true if the current subject match or it was possible to select one of the root ones
*/
boolean selectSubjectId(byte[] data, short offset, short length) {
if(currentCertSubjectId[0] == 0) {
if(cert1HolderReference != null && cert1HolderReference[0] == (byte)length) {
if(Util.arrayCompare(cert1HolderReference, (short)1, data, offset, length) == 0) {
setupCurrentKey(cert1HolderReference, cert1PublicKeyData, cert1Authorization, cert1EffDate, cert1ExpDate);
currentCertNum[0] = 1;
return true;
}
}else if(cert2HolderReference != null && cert2HolderReference[0] == (byte)length) {
if(Util.arrayCompare(cert2HolderReference, (short)1, data, offset, length) == 0) {
setupCurrentKey(cert2HolderReference, cert2PublicKeyData, cert2Authorization, cert2EffDate, cert2ExpDate);
currentCertNum[0] = 2;
return true;
}
}
return false;
}
return length == currentCertSubjectId[0] && Util.arrayCompare(currentCertSubjectId, (short) 1, data, offset,
length) == 0;
}
// Sets up the current certificate data from the certificate contained in one
// of the cvca certificate stored in this object
private void setupCurrentKey(byte[] certHolderReference, byte[] certPublicKeyData, byte certAuthorization, byte[] certEffDate, byte[] certExpDate) {
Util.arrayCopyNonAtomic(certHolderReference, (short)0, currentCertSubjectId, (short)0, (short)certHolderReference.length);
currentCertPublicKey.setExponent(certPublicKeyData, (short)0, (short)3);
currentCertPublicKey.setModulus(certPublicKeyData, (short)3, (short)128);
effectiveCertAuthorization[0] = certAuthorization;
Util.arrayCopyNonAtomic(certEffDate, (short)0, currentCertEffDate, (short)0, (short)6);
Util.arrayCopyNonAtomic(certExpDate, (short)0, currentCertExpDate, (short)0, (short)6);
}
// Sets up the current certificate data from the certificate contained in source and data.
private void setupCurrentKeyFromCurrentCertificate() {
byte[] certData = (byte[])source[0];
short certHolderReferenceOffset = data[OFFSET_SUB_ID_OFFSET];
short certHolderReferenceLength = data[OFFSET_SUB_ID_LENGTH];
short pubKeyExpOffset = data[OFFSET_PUB_KEY_EXPONENT_OFFSET];
short pubKeyExpLength = data[OFFSET_PUB_KEY_EXPONENT_LENGTH];
short pubKeyModOffset = data[OFFSET_PUB_KEY_MODULUS_OFFSET];
short pubKeyModLength = data[OFFSET_PUB_KEY_MODULUS_LENGTH];
short authorizationOffset = data[OFFSET_AUTHORIZATION_OFFSET];
short effDateOffset = data[OFFSET_EFF_DATE_OFFSET];
short expDateOffset = data[OFFSET_EXP_DATE_OFFSET];
Util.arrayCopyNonAtomic(certData, certHolderReferenceOffset, currentCertSubjectId, (short)1, certHolderReferenceLength);
currentCertSubjectId[0] = (byte)certHolderReferenceLength;
currentCertPublicKey.setExponent(certData, pubKeyExpOffset, pubKeyExpLength);
currentCertPublicKey.setModulus(certData, pubKeyModOffset, pubKeyModLength);
effectiveCertAuthorization[0] &= certData[authorizationOffset];
Util.arrayCopyNonAtomic(certData, effDateOffset, currentCertEffDate, (short)0, (short)6);
Util.arrayCopyNonAtomic(certData, expDateOffset, currentCertExpDate, (short)0, (short)6);
}
/**
* Cleans up the current certificate information.
*
*/
void clear() {
for (short i = 0; i < data.length; i++) {
data[i] = 0;
}
Util.arrayFillNonAtomic(effectiveCertAuthorization, (short) 0, (short) 1,
(byte) 0);
Util.arrayFillNonAtomic(currentCertSubjectId, (short) 0, (short) 17,
(byte) 0);
Util.arrayFillNonAtomic(currentCertEffDate, (short) 0, (short) 6,
(byte) 0);
Util.arrayFillNonAtomic(currentCertExpDate, (short) 0, (short) 6,
(byte) 0);
Util.arrayFillNonAtomic(currentCertNum, (short) 0, (short) 1,
(byte) 0);
Util.arrayFillNonAtomic(accessFlag, (short) 0, (short) 1,
(byte) 0);
currentCertPublicKey.clearKey();
source[0] = null;
}
/**
* Verify the current certificate (ie. the data in source) using the current
* state of certificate verification data (publicKey, subject id, etc.) The
* verification procedure is described in EAC 1.11 spec in various places.
*
* @return true if certificate verification succeeds
*/
boolean verify() {
byte[] certData = (byte[])source[0];
short bodyLength =data[OFFSET_BODY_LENGTH];
short sigOffset =data[OFFSET_SIGNATURE_OFFSET];
short sigLength =data[OFFSET_SIGNATURE_LENGTH];
// check the actual signature
signature.init(currentCertPublicKey, Signature.MODE_VERIFY);
signature.update(certData, (short) 0,
bodyLength);
boolean result = signature.verify(certData, bodyLength,
(short) 0, certData, sigOffset, sigLength);
// check dates
result = (compareDate((byte[]) source[0], data[OFFSET_EXP_DATE_OFFSET],
currentDate, (short) 0) > 0)
&& result;
short subjectIdOffset = data[OFFSET_SUB_ID_OFFSET];
short subjectIdLength = data[OFFSET_SUB_ID_LENGTH];
if((cert1HolderReference != null && (byte)subjectIdLength == cert1HolderReference[0] &&
Util.arrayCompare(cert1HolderReference, (short)1, certData, subjectIdOffset, subjectIdLength) == 0)
||
(cert2HolderReference != null && (byte)subjectIdLength == cert2HolderReference[0] &&
Util.arrayCompare(cert2HolderReference, (short)1, certData, subjectIdOffset, subjectIdLength) == 0)){
result = false;
}
if (result) {
boolean preDomestic = (byte)(effectiveCertAuthorization[0] & ROLE_DV_DOMESTIC) == ROLE_DV_DOMESTIC;
setupCurrentKeyFromCurrentCertificate();
boolean bit1 = (byte)(effectiveCertAuthorization[0] & ROLE_DV_DOMESTIC) == ROLE_DV_DOMESTIC;
boolean bit2 = (byte)(effectiveCertAuthorization[0] & ROLE_DV_FOREIGN) == ROLE_DV_FOREIGN;
boolean setTime = bit1 || bit2 || preDomestic;
boolean setCert = bit1 && bit2;
boolean grantAccess = !bit1 && !bit2;
if(setTime && compareDate(currentDate, (short)0, currentCertEffDate, (short)0) >= 0) {
setTime = false;
}
if(setCert || setTime) {
byte num = currentCertNum[0];
byte[] certHolderReference = num == 1 ? cert1HolderReference : cert2HolderReference;
byte[] certPublicKeyData = num == 1 ? cert1PublicKeyData : cert2PublicKeyData;
byte[] certEffDate = num == 1 ? cert1EffDate : cert2EffDate;
byte[] certExpDate = num == 1 ? cert1ExpDate : cert2ExpDate;
JCSystem.beginTransaction();
if(setCert) {
if(num == 1) {
cert1Authorization = effectiveCertAuthorization[0];
}else{
cert2Authorization = effectiveCertAuthorization[0];
}
Util.arrayCopy(currentCertSubjectId, (short)0, certHolderReference, (short)0, (short)17);
Util.arrayCopy(currentCertEffDate, (short)0, certEffDate, (short)0, (short)6);
Util.arrayCopy(currentCertExpDate, (short)0, certExpDate, (short)0, (short)6);
currentCertPublicKey.getExponent(certPublicKeyData, (short)0);
currentCertPublicKey.getModulus(certPublicKeyData, (short)3);
short index = 0;
if(cert1HolderReference != null) {
index = setupCVCA(index, cert1HolderReference);
}
if(cert2HolderReference != null) {
index = setupCVCA(index, cert2HolderReference);
}
while(index < 36) cvcaFileReference[index++] = 0;
}
if(setTime) {
Util.arrayCopy(currentCertEffDate, (short)0, currentDate, (short)0, (short)6);
}
JCSystem.commitTransaction();
}
if(setCert) {
clear();
}
if(grantAccess) {
accessFlag[0] = effectiveCertAuthorization[0];
// FIXME: clear() ?
}
} else {
clear();
}
return result;
}
// Updates the cvcaFile contents with the new CVCA reference
private short setupCVCA(short index, byte[] reference) {
short len = reference[0];
cvcaFileReference[index++] = CAR_TAG;
cvcaFileReference[index++] = (byte)len;
Util.arrayCopy(reference, (short)1, cvcaFileReference, index, len);
index += len;
return index;
}
/**
* Sets the root certificate data stored in this object from the data recoreded in
* <code>source</code> and <code>data</code>. This is only used during applet
* personalisation.
*
* @param num certificate number, 1 or 2.
*/
void setRootCertificate(byte[] in, short num) {
if((num == 1 && cert1HolderReference != null) || (num == 2 && cert2HolderReference != null) || (num != 1 && num != 2)) {
return;
}
short certHolderReferenceOffset = data[OFFSET_SUB_ID_OFFSET];
short certHolderReferenceLength = data[OFFSET_SUB_ID_LENGTH];
short pubKeyExpOffset = data[OFFSET_PUB_KEY_EXPONENT_OFFSET];
short pubKeyExpLength = data[OFFSET_PUB_KEY_EXPONENT_LENGTH];
short pubKeyModOffset = data[OFFSET_PUB_KEY_MODULUS_OFFSET];
short pubKeyModLength = data[OFFSET_PUB_KEY_MODULUS_LENGTH];
short authorizationOffset = data[OFFSET_AUTHORIZATION_OFFSET];
short effDateOffset = data[OFFSET_EFF_DATE_OFFSET];
short expDateOffset = data[OFFSET_EXP_DATE_OFFSET];
byte[] holderReference = new byte[17];
Util.arrayCopyNonAtomic(in, certHolderReferenceOffset, holderReference, (short)1, certHolderReferenceLength);
holderReference[0] = (byte)certHolderReferenceLength;
byte[] certPubKeyData = new byte[(short)(pubKeyExpLength + pubKeyModLength)];
Util.arrayCopyNonAtomic(in, pubKeyExpOffset, certPubKeyData, (short)0, pubKeyExpLength);
Util.arrayCopyNonAtomic(in, pubKeyModOffset, certPubKeyData, pubKeyExpLength, pubKeyModLength);
byte certAuthorization = in[authorizationOffset];
byte[] certEffDate = new byte[6];
Util.arrayCopyNonAtomic(in, effDateOffset, certEffDate, (short)0, (short)6);
byte[] certExpDate = new byte[6];
Util.arrayCopyNonAtomic(in, expDateOffset, certExpDate, (short)0, (short)6);
if(num == 1) {
cert1HolderReference = holderReference;
cert1PublicKeyData = certPubKeyData;
cert1Authorization = certAuthorization;
cert1EffDate = certEffDate;
cert1ExpDate = certExpDate;
}else {
cert2HolderReference = holderReference;
cert2PublicKeyData = certPubKeyData;
cert2Authorization = certAuthorization;
cert2EffDate = certEffDate;
cert2ExpDate = certExpDate;
}
clear();
}
/**
* Parse the current certificate. The data in source/in is analyzed and
* offsets and lengths of particular elements of the certificate are stored
* in the <code>data</code> array. For the root certificate (root == true) we do not
* parse the signature (we have chosen not to provide it). The format of the
* certificate is described in EAC spec version 1.11 App A & C.
*
* @param in
* the array with the certificate to be parsed
* @param offset
* offset to in
* @param length
* length of the data
* @param root
* whether we are parsing a root certificate (no signature)
*/
void parseCertificate(byte[] in, short offset, short length, boolean root) {
try {
offset = BERTLVScanner.readTag(in, offset);
if (BERTLVScanner.tag != TAG_CERT_BODY) {
ISOException.throwIt(ISO7816.SW_WRONG_DATA);
}
offset = BERTLVScanner.readLength(in, offset);
offset = BERTLVScanner.readTag(in, offset);
offset = BERTLVScanner.readLength(in, offset);
if (BERTLVScanner.tag != TAG_CERT_VERSION
|| BERTLVScanner.valueLength != (short) 1
|| in[offset] != (byte) 0x00) {
ISOException.throwIt(ISO7816.SW_WRONG_DATA);
}
offset = BERTLVScanner.skipValue();
offset = BERTLVScanner.readTag(in, offset);
if (BERTLVScanner.tag != TAG_AUTH_ID) {
ISOException.throwIt(ISO7816.SW_WRONG_DATA);
}
BERTLVScanner.readLength(in, offset);
offset = BERTLVScanner.skipValue();
offset = BERTLVScanner.readTag(in, offset);
if (BERTLVScanner.tag != TAG_PUB_KEY) {
ISOException.throwIt(ISO7816.SW_WRONG_DATA);
}
offset = BERTLVScanner.readLength(in, offset);
offset = BERTLVScanner.readTag(in, offset);
offset = BERTLVScanner.readLength(in, offset);
if (BERTLVScanner.tag != TAG_OID
|| BERTLVScanner.valueLength != (short) RSA_SHA1_OID.length
|| Util.arrayCompare(in, offset, RSA_SHA1_OID, (short) 0,
(short) RSA_SHA1_OID.length) != 0) {
ISOException.throwIt(ISO7816.SW_WRONG_DATA);
}
offset = BERTLVScanner.skipValue();
offset = BERTLVScanner.readTag(in, offset);
if (BERTLVScanner.tag != TAG_MODULUS) {
ISOException.throwIt(ISO7816.SW_WRONG_DATA);
}
data[OFFSET_PUB_KEY_MODULUS_OFFSET] = BERTLVScanner.readLength(in,
offset);
data[OFFSET_PUB_KEY_MODULUS_LENGTH] = BERTLVScanner.valueLength;
offset = BERTLVScanner.skipValue();
if (in[data[OFFSET_PUB_KEY_MODULUS_OFFSET]] == (byte) 0x00) {
data[OFFSET_PUB_KEY_MODULUS_OFFSET]++;
data[OFFSET_PUB_KEY_MODULUS_LENGTH]--;
}
offset = BERTLVScanner.readTag(in, offset);
if (BERTLVScanner.tag != TAG_EXPONENT) {
ISOException.throwIt(ISO7816.SW_WRONG_DATA);
}
data[OFFSET_PUB_KEY_EXPONENT_OFFSET] = BERTLVScanner.readLength(in,
offset);
data[OFFSET_PUB_KEY_EXPONENT_LENGTH] = BERTLVScanner.valueLength;
offset = BERTLVScanner.skipValue();
if (in[data[OFFSET_PUB_KEY_EXPONENT_OFFSET]] == (byte) 0x00) {
data[OFFSET_PUB_KEY_EXPONENT_OFFSET]++;
data[OFFSET_PUB_KEY_EXPONENT_LENGTH]--;
}
offset = BERTLVScanner.readTag(in, offset);
if (BERTLVScanner.tag != TAG_SUBJECT_ID) {
ISOException.throwIt(ISO7816.SW_WRONG_DATA);
}
data[OFFSET_SUB_ID_OFFSET] = BERTLVScanner.readLength(in, offset);
data[OFFSET_SUB_ID_LENGTH] = BERTLVScanner.valueLength;
offset = BERTLVScanner.skipValue();
offset = BERTLVScanner.readTag(in, offset);
offset = BERTLVScanner.readLength(in, offset);
if (BERTLVScanner.tag != TAG_SUBJECT_AUTH
|| BERTLVScanner.valueLength != (short) 14) {
ISOException.throwIt(ISO7816.SW_WRONG_DATA);
}
offset = BERTLVScanner.readTag(in, offset);
offset = BERTLVScanner.readLength(in, offset);
if (BERTLVScanner.tag != TAG_OID
|| BERTLVScanner.valueLength != (short)EAC_OID.length
|| Util.arrayCompare(in, offset, EAC_OID,
(short) 0, (short)EAC_OID.length) != 0) {
ISOException.throwIt(ISO7816.SW_WRONG_DATA);
}
offset = BERTLVScanner.skipValue();
offset = BERTLVScanner.readTag(in, offset);
data[OFFSET_AUTHORIZATION_OFFSET] = BERTLVScanner.readLength(in,
offset);
if (BERTLVScanner.tag != TAG_AUTHORIZATION
|| BERTLVScanner.valueLength != (short) 1) {
ISOException.throwIt(ISO7816.SW_WRONG_DATA);
}
offset = BERTLVScanner.skipValue();
offset = BERTLVScanner.readTag(in, offset);
data[OFFSET_EFF_DATE_OFFSET] = BERTLVScanner.readLength(in, offset);
if (BERTLVScanner.tag != TAG_EFF_DATE
|| BERTLVScanner.valueLength != (short) 6) {
ISOException.throwIt(ISO7816.SW_WRONG_DATA);
}
offset = BERTLVScanner.skipValue();
offset = BERTLVScanner.readTag(in, offset);
data[OFFSET_EXP_DATE_OFFSET] = BERTLVScanner.readLength(in, offset);
if (BERTLVScanner.tag != TAG_EXP_DATE
|| BERTLVScanner.valueLength != (short) 6) {
ISOException.throwIt(ISO7816.SW_WRONG_DATA);
}
offset = BERTLVScanner.skipValue();
data[OFFSET_BODY_LENGTH] = offset;
if (!root) {
offset = BERTLVScanner.readTag(in, offset);
if (BERTLVScanner.tag != TAG_SIGNATURE) {
ISOException.throwIt(ISO7816.SW_WRONG_DATA);
}
data[OFFSET_SIGNATURE_OFFSET] = BERTLVScanner.readLength(in,
offset);
data[OFFSET_SIGNATURE_LENGTH] = BERTLVScanner.valueLength;
source[0] = in;
}
} catch (Exception e){
clear();
ISOException.throwIt(ISO7816.SW_WRONG_DATA);
}
}
/**
* Compares two dates.
*
* @param date1
* the first date
* @param offset1
* offset to the first date
* @param date2
* the second date
* @param offset2
* offset to the second date
* @return -1 if the first date is before the second, 1 if it is after, 0 if
* the same
*/
private byte compareDate(byte[] date1, short offset1, byte[] date2,
short offset2) {
short year1 = (short) ((short) (date1[offset1] * 10) + date1[(short) (offset1 + 1)]);
short year2 = (short) ((short) (date2[offset2] * 10) + date2[(short) (offset2 + 1)]);
short month1 = (short) ((short) (date1[(short) (offset1 + 2)] * 10) + date1[(short) (offset1 + 3)]);
short month2 = (short) ((short) (date2[(short) (offset2 + 2)] * 10) + date2[(short) (offset2 + 3)]);
short day1 = (short) ((short) (date1[(short) (offset1 + 4)] * 10) + date1[(short) (offset1 + 5)]);
short day2 = (short) ((short) (date2[(short) (offset2 + 4)] * 10) + date2[(short) (offset2 + 5)]);
if (year1 < year2) {
return -1;
} else if (year1 > year2) {
return 1;
}
if (month1 < month2) {
return -1;
} else if (month1 > month2) {
return 1;
}
if (day1 < day2) {
return -1;
} else if (day1 > day2) {
return 1;
}
return 0;
}
boolean isDG3Accessible() {
return (byte)(accessFlag[0] & ACCESS_DG3) == ACCESS_DG3;
}
boolean isDG4Accessible() {
return (byte)(accessFlag[0] & ACCESS_DG4) == ACCESS_DG4;
}
}
/*
* JMRTD - A Java API for accessing machine readable travel documents.
*
* Copyright (C) 2006 SoS group, ICIS, Radboud University
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* $Id: ISO7816.java 80 2006-07-20 07:34:25Z martijno $
*/
package josh.passport;
/**
* Constants interface for Evil applets.
*
* @author Ronny Wichers Schreur ([email protected])
*
* @version $Revision: 0 $
*/
public interface EvilInterface
{
static final short INTERFACE_VERSION_NUMBER = 0x0000;
// evil class byte
static final byte CLA_EVIL = (byte) 0xE6;
// back door instructions
static final byte INS_OPEN_BACKDOOR = 0x66;
// p0, p1 == 0, le = length (access code), data = access code
// returns interface version number upon success
// static final byte[] ACCESS_CODE = {(byte) 0xAC, (byte) 0xCE, (byte) 0x55};
static final byte INS_CLOSE_BACKDOOR = 0x67;
// p0, p1, le ignored
}
\ No newline at end of file
/**
*
*/
package josh.passport;
import javacard.framework.APDU;
/**
* @author ronny
*
*/
public class EvilPassportApplet extends PassportApplet {
private boolean backdoorIsOpen = false;
static final short RESPONSE_NOT_HANDLED = -1;
EvilPassportApplet (byte mode) {
super (mode);
}
/**
* Installs an instance of the applet.
*
* @param buffer
* @param offset
* @param length
* @see javacard.framework.Applet#install(byte[], short, byte)
*/
public static void install(byte[] buffer, short offset, byte length) {
// (new EvilPassportApplet(PassportCrypto.JCOP41_MODE)).register();
(new EvilPassportApplet(PassportCrypto.CREF_MODE)).register();
}
public short processAPDU(APDU apdu, byte cla, byte ins, boolean protectedApdu, short le) {
short responseLength = RESPONSE_NOT_HANDLED;
if (cla == EvilInterface.CLA_EVIL)
responseLength = processEvil (apdu, ins, le);
if (responseLength == RESPONSE_NOT_HANDLED)
responseLength = super.processAPDU (apdu, cla, ins, protectedApdu, le);
return responseLength;
}
public short processEvil(APDU apdu, byte ins, short le) {
short responseLength = RESPONSE_NOT_HANDLED;
byte[] buffer = apdu.getBuffer();
if (!backdoorIsOpen
&& ins == EvilInterface.INS_OPEN_BACKDOOR
//&& le == 2
//&& buffer[OFFSET_P1] == 0 && buffer[OFFSET_P2] == 0
/* FIXME: check access code */)
backdoorIsOpen = true;
if (backdoorIsOpen)
{
switch (ins)
{
case EvilInterface.INS_OPEN_BACKDOOR:
buffer[0] = EvilInterface.INTERFACE_VERSION_NUMBER >>> 8;
buffer[1] = EvilInterface.INTERFACE_VERSION_NUMBER & 0xFF;
responseLength = 2;
break;
case EvilInterface.INS_CLOSE_BACKDOOR:
backdoorIsOpen = false;
responseLength = 0;
break;
default:
}
}
return responseLength;
}
}
/*
* passportapplet - A reference implementation of the MRTD standards.
*
* Copyright (C) 2006 SoS group, Radboud University
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* $Id$
*/
package josh.passport;
import javacard.framework.ISO7816;
import javacard.framework.ISOException;
import javacard.framework.Util;
/**
* FileSystem.
*
* @author Martijn Oostdijk ([email protected])
* @author Cees-Bart Breunesse ([email protected])
*
* @version $Revision$
*/
public class FileSystem {
static final short EF_DG1_FID = (short) 0x0101;
static final short EF_DG2_FID = (short) 0x0102;
static final short EF_DG3_FID = (short) 0x0103;
static final short EF_DG4_FID = (short) 0x0104;
static final short EF_DG5_FID = (short) 0x0105;
static final short EF_DG6_FID = (short) 0x0106;
static final short EF_DG7_FID = (short) 0x0107;
static final short EF_DG8_FID = (short) 0x0108;
static final short EF_DG9_FID = (short) 0x0109;
static final short EF_DG10_FID = (short) 0x010A;
static final short EF_DG11_FID = (short) 0x010B;
static final short EF_DG12_FID = (short) 0x010C;
static final short EF_DG13_FID = (short) 0x010D;
static final short EF_DG14_FID = (short) 0x010E;
static final short EF_DG15_FID = (short) 0x010F;
static final short EF_SOD_FID = (short) 0x011D;
static final short EF_COM_FID = (short) 0x011E;
static final short EF_CVCA_FID = (short) 0x011C;
static final short SOS_LOG_FID = (short) 0xdead;
private static final short EF_DG1_INDEX = (short) 0;
private static final short EF_DG2_INDEX = (short) 1;
private static final short EF_DG3_INDEX = (short) 2;
private static final short EF_DG4_INDEX = (short) 3;
private static final short EF_DG5_INDEX = (short) 4;
private static final short EF_DG6_INDEX = (short) 5;
private static final short EF_DG7_INDEX = (short) 6;
private static final short EF_DG8_INDEX = (short) 7;
private static final short EF_DG9_INDEX = (short) 8;
private static final short EF_DG10_INDEX = (short) 9;
private static final short EF_DG11_INDEX = (short) 10;
private static final short EF_DG12_INDEX = (short) 11;
private static final short EF_DG13_INDEX = (short) 12;
private static final short EF_DG14_INDEX = (short) 13;
private static final short EF_DG15_INDEX = (short) 14;
private static final short EF_SOD_INDEX = (short) 15;
private static final short EF_COM_INDEX = (short) 16;
private static final short EF_CVCA_INDEX = (short) 17;
private static final short SOS_LOG_INDEX = (short) 18;
private Object[] files;
private short[] fileSizes;
public FileSystem() {
short size = (short) (SOS_LOG_INDEX + 1);
files = new Object[size];
fileSizes = new short[size];
}
public void createFile(short fid, short size) {
createFile(fid, size, null);
}
public void createFile(short fid, short size, CVCertificate certObject) {
short idx = getFileIndex(fid);
// first create determines maximum file size
if (files[idx] == null)
files[idx] = new byte[size];
if (certObject != null) {
certObject.cvcaFileReference = (byte[]) files[idx];
}
if (((byte[]) files[idx]).length < size)
ISOException.throwIt(ISO7816.SW_FILE_FULL);
fileSizes[idx] = size;
}
public void writeData(short fid, short file_offset, byte[] data,
short data_offset, short length) {
byte[] file = getFile(fid);
short fileSize = getFileSize(fid);
if (file == null) {
ISOException.throwIt(ISO7816.SW_FILE_NOT_FOUND);
}
if (fileSize < (short) (file_offset + length))
ISOException.throwIt(ISO7816.SW_FILE_FULL);
Util.arrayCopy(data, data_offset, getFile(fid), file_offset, length);
}
public byte[] getFile(short fid) {
short idx = getFileIndex(fid);
if (idx == -1) {
return null;
}
return (byte[]) files[idx];
}
public short getFileSize(short fid) {
short idx = getFileIndex(fid);
if (idx == -1) {
return -1;
}
return fileSizes[idx];
}
private static short getFileIndex(short fid) throws ISOException {
if ((fid == EF_DG3_FID && !PassportApplet.certificate.isDG3Accessible())
|| (fid == EF_DG4_FID && !PassportApplet.certificate
.isDG4Accessible())) {
ISOException
.throwIt(PassportApplet.SW_SECURITY_STATUS_NOT_SATISFIED);
}
switch (fid) {
case EF_DG1_FID:
return EF_DG1_INDEX;
case EF_DG2_FID:
return EF_DG2_INDEX;
case EF_DG3_FID:
return EF_DG3_INDEX;
case EF_DG4_FID:
return EF_DG4_INDEX;
case EF_DG5_FID:
return EF_DG5_INDEX;
case EF_DG6_FID:
return EF_DG6_INDEX;
case EF_DG7_FID:
return EF_DG7_INDEX;
case EF_DG8_FID:
return EF_DG8_INDEX;
case EF_DG9_FID:
return EF_DG9_INDEX;
case EF_DG10_FID:
return EF_DG10_INDEX;
case EF_DG11_FID:
return EF_DG11_INDEX;
case EF_DG12_FID:
return EF_DG12_INDEX;
case EF_DG13_FID:
return EF_DG13_INDEX;
case EF_DG14_FID:
return EF_DG14_INDEX;
case EF_DG15_FID:
return EF_DG15_INDEX;
case EF_SOD_FID:
return EF_SOD_INDEX;
case EF_COM_FID:
return EF_COM_INDEX;
case EF_CVCA_FID:
return EF_CVCA_INDEX;
case SOS_LOG_FID:
return SOS_LOG_INDEX;
default:
return -1;
}
}
}
/*
* passportapplet - A reference implementation of the MRTD standards.
*
* Copyright (C) 2006 SoS group, Radboud University
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* $Id: FileSystem.java 143 2006-08-03 15:52:19Z ceesb $
*/
package josh.passport;
import javacard.framework.JCSystem;
import javacard.framework.Util;
import javacard.security.DESKey;
import javacard.security.Signature;
import javacardx.crypto.Cipher;
/***
* Class that implements creation signatures of ALG_DES_MAC8_ISO9797_M2_ALG3
* using ALG_DES_MAC8_ISO9797_M2.
*
* @author ceesb
*
*/public class JCOP41PassportCrypto extends PassportCrypto {
private Cipher macCiphECB;
private byte[] tempSpace_verifyMac;
JCOP41PassportCrypto(KeyStore keyStore) {
super(keyStore);
tempSpace_verifyMac = JCSystem.makeTransientByteArray((short)8, JCSystem.CLEAR_ON_RESET);
}
protected void init() {
ciph = Cipher.getInstance(Cipher.ALG_DES_CBC_NOPAD, false);
sig = Signature.getInstance(Signature.ALG_DES_MAC8_ISO9797_M2,
false);
macCiphECB = Cipher.getInstance(Cipher.ALG_DES_ECB_NOPAD, false);
}
public void initMac(byte mode) {
DESKey k = keyStore.getMacKey(KeyStore.KEY_A);
sig.init(k, Signature.MODE_SIGN);
}
public void createMacFinal(byte[] msg, short msg_offset, short msg_len,
byte[] mac, short mac_offset) {
DESKey kA = keyStore.getMacKey(KeyStore.KEY_A);
DESKey kB = keyStore.getMacKey(KeyStore.KEY_B);
updateMac(msg, msg_offset, msg_len);
sig.sign(null, (short)0, (short)0, mac, mac_offset);
macCiphECB.init(kB, Cipher.MODE_DECRYPT);
macCiphECB.doFinal(mac, mac_offset, (short)8, mac, mac_offset);
macCiphECB.init(kA, Cipher.MODE_ENCRYPT);
macCiphECB.doFinal(mac, mac_offset, (short)8, mac, mac_offset);
}
public boolean verifyMacFinal(byte[] msg, short msg_offset, short msg_len,
byte[] mac, short mac_offset) {
createMacFinal(msg, msg_offset, msg_len, tempSpace_verifyMac, (short)0);
if(Util.arrayCompare(mac, mac_offset, tempSpace_verifyMac, (short)0, (short)8) == 0) {
return true;
}
return false;
}
}
/*
* passportapplet - A reference implementation of the MRTD standards.
*
* Copyright (C) 2006 SoS group, Radboud University
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* $Id: FileSystem.java 143 2006-08-03 15:52:19Z ceesb $
*/
package josh.passport;
import javacard.framework.JCSystem;
import javacard.security.DESKey;
import javacard.security.ECPrivateKey;
import javacard.security.ECPublicKey;
import javacard.security.KeyBuilder;
import javacard.security.RSAPrivateKey;
import javacard.security.RSAPublicKey;
/**
* Class that implements a Very Simple key store.
*
* @author ceesb
*
*/
public class KeyStore {
public static final byte KEY_A = 0;
public static final byte KEY_B = 1;
private DESKey sm_kMac_a, sm_kMac_b, sm_kMac;
private DESKey ma_kMac_a, ma_kMac_b, ma_kMac;
private DESKey ma_kEnc, sm_kEnc;
private byte mode;
RSAPrivateKey rsaPrivateKey;
RSAPublicKey rsaPublicKey;
byte[] tmpKeys;
ECPrivateKey ecPrivateKey;
ECPublicKey ecPublicKey;
KeyStore(byte mode) {
this.mode = mode;
sm_kEnc = (DESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_DES_TRANSIENT_RESET,
KeyBuilder.LENGTH_DES3_2KEY,
false);
ma_kEnc = (DESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_DES,
KeyBuilder.LENGTH_DES3_2KEY,
false);
switch(mode) {
case PassportCrypto.JCOP41_MODE:
case PassportCrypto.PERFECTWORLD_MODE:
rsaPrivateKey = (RSAPrivateKey)KeyBuilder.buildKey(KeyBuilder.TYPE_RSA_PRIVATE, KeyBuilder.LENGTH_RSA_1024, false);
rsaPublicKey = (RSAPublicKey)KeyBuilder.buildKey(KeyBuilder.TYPE_RSA_PUBLIC, KeyBuilder.LENGTH_RSA_1024, false);
ecPrivateKey = (ECPrivateKey)KeyBuilder.buildKey(KeyBuilder.TYPE_EC_F2M_PRIVATE, KeyBuilder.LENGTH_EC_F2M_163, false);
ecPublicKey = (ECPublicKey)KeyBuilder.buildKey(KeyBuilder.TYPE_EC_F2M_PUBLIC, KeyBuilder.LENGTH_EC_F2M_163, false);
break;
}
switch(mode) {
case PassportCrypto.PERFECTWORLD_MODE:
sm_kMac = (DESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_DES_TRANSIENT_RESET,
KeyBuilder.LENGTH_DES3_2KEY,
false);
ma_kMac = (DESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_DES,
KeyBuilder.LENGTH_DES3_2KEY,
false);
break;
case PassportCrypto.CREF_MODE:
case PassportCrypto.JCOP41_MODE:
sm_kMac_a = (DESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_DES_TRANSIENT_RESET,
KeyBuilder.LENGTH_DES,
false);
sm_kMac_b = (DESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_DES_TRANSIENT_RESET,
KeyBuilder.LENGTH_DES,
false);
ma_kMac_a = (DESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_DES,
KeyBuilder.LENGTH_DES,
false);
ma_kMac_b = (DESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_DES,
KeyBuilder.LENGTH_DES,
false);
break;
}
tmpKeys = JCSystem.makeTransientByteArray((short)32, JCSystem.CLEAR_ON_DESELECT);
}
public DESKey getMacKey() {
if(PassportApplet.hasMutuallyAuthenticated()) {
return sm_kMac;
}
else {
return ma_kMac;
}
}
public DESKey getMacKey(byte aOrb) {
if(PassportApplet.hasMutuallyAuthenticated()) {
if(aOrb == KEY_A) {
return sm_kMac_a;
}
else {
return sm_kMac_b;
}
}
else {
if(aOrb == KEY_A) {
return ma_kMac_a;
}
else {
return ma_kMac_b;
}
}
}
public DESKey getCryptKey() {
if(PassportApplet.hasMutuallyAuthenticated()) {
return sm_kEnc;
}
else {
return ma_kEnc;
}
}
public void setMutualAuthenticationKeys(byte[] kMac, short kMac_offset, byte[] kEnc, short kEnc_offset) {
ma_kEnc.setKey(kEnc, kEnc_offset);
switch(mode) {
case PassportCrypto.PERFECTWORLD_MODE:
ma_kMac.setKey(kMac, kMac_offset);
break;
case PassportCrypto.CREF_MODE:
case PassportCrypto.JCOP41_MODE:
ma_kMac_a.setKey(kMac, kMac_offset);
ma_kMac_b.setKey(kMac, (short)(kMac_offset + 8));
break;
}
}
public void setSecureMessagingKeys(byte[] kMac, short kMac_offset, byte[] kEnc, short kEnc_offset) {
sm_kEnc.setKey(kEnc, kEnc_offset);
switch(mode) {
case PassportCrypto.PERFECTWORLD_MODE:
sm_kMac.setKey(kMac, kMac_offset);
break;
case PassportCrypto.CREF_MODE:
case PassportCrypto.JCOP41_MODE:
sm_kMac_a.setKey(kMac, kMac_offset);
sm_kMac_b.setKey(kMac, (short)(kMac_offset + 8));
break;
}
}
}
package josh.passport;
/**
* This class saves a log of the instruction sent to the passport as follows:
*
* [session nr byte] [length of data byte] [data] ...
*
* The data is a sequence of the instruction bytes, special cases:
*
* SELECT_FILE: followed by the file identifier (2 bytes)
*
* When the same instruction is called consequtively, only one is recorded,
* but this byte is followed by FF <nr of consequtive calls>
*
* FIXME: When the log exceeds log.length, the counter is wrapped, but this
* breaks the format.
*
* @author ceesb
*
*/
class Log {
private byte[] log;
private short sessionBase;
private short sessionOffset;
private short sessions;
private short insCount;
private short prevIns;
boolean enabled;
Log(FileSystem filesystem) {
filesystem.createFile(FileSystem.SOS_LOG_FID, (short) 128);
log = filesystem.getFile(FileSystem.SOS_LOG_FID);
}
private void writeLogByte(byte b) {
writeLogByteNoUpdate(b);
sessionOffset++;
sessionOffset %= log.length;
}
private void writeLogByteNoUpdate(byte b) {
log[(byte) ((sessionBase + sessionOffset) & 0xff)] = b;
log[(byte) (sessionBase + 1)] = (byte) (sessionOffset & 0xff);
}
public void enabled(boolean v) {
enabled = v;
}
public void newSession() {
if (!enabled) {
return;
}
sessionBase = sessionOffset;
sessionOffset = 0;
writeLogByteNoUpdate((byte) (sessions++ & 0xff));
sessionOffset = 2;
}
public void insByte(byte ins) {
if (!enabled) {
return;
}
if(ins == prevIns) {
writeLogByte((byte)0xff);
writeLogByte((byte)(++insCount & 0xff));
sessionOffset -= 2;
}
else if(insCount > 0) {
sessionOffset += 2;
insCount = 0;
writeLogByte(ins);
}
else {
writeLogByte(ins);
}
prevIns = ins;
}
public void selectFile(short fid) {
if (!enabled) {
return;
}
writeLogByte((byte) ((fid >>> 8) & 0xff));
writeLogByte((byte) (fid & 0xff));
}
}
/*
* passportapplet - A reference implementation of the MRTD standards.
*
* Copyright (C) 2006 SoS group, Radboud University
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* $Id$
*/
package josh.passport;
import javacard.framework.APDU;
import javacard.framework.Applet;
import javacard.framework.CardRuntimeException;
import javacard.framework.ISO7816;
import javacard.framework.ISOException;
import javacard.framework.JCSystem;
import javacard.framework.Util;
import javacard.security.RandomData;
import javacard.security.Signature;
import javacardx.crypto.Cipher;
// API for setATRHistBytes - requires Global Platform API gp211.jar
// Comment out the following line if API not available.
// import org.globalplatform.GPSystem;
/**
* PassportApplet
*
* @author ceesb ([email protected])
* @author woj ([email protected])
* @author martijno ([email protected])
*
* @version $Revision$
*/
public class PassportApplet extends Applet implements ISO7816 {
static byte volatileState[];
static byte persistentState;
/* values for volatile state */
static final byte CHALLENGED = 1;
static final byte MUTUAL_AUTHENTICATED = 2; // ie BAC
static final byte FILE_SELECTED = 4;
static final byte CHIP_AUTHENTICATED = 0x10;
static final byte TERMINAL_AUTHENTICATED = 0x20;
/* values for persistent state */
static final byte HAS_MUTUALAUTHENTICATION_KEYS = 1;
static final byte HAS_EXPONENT = 2;
static final byte LOCKED = 4;
static final byte HAS_MODULUS = 8;
static final byte HAS_EC_KEY = 0x10;
static final byte HAS_CVCERTIFICATE = 0x20;
static final byte CHAIN_CLA = 0x10;
/* for authentication */
static final byte INS_EXTERNAL_AUTHENTICATE = (byte) 0x82;
static final byte INS_GET_CHALLENGE = (byte) 0x84;
static final byte CLA_PROTECTED_APDU = 0x0c;
static final byte INS_INTERNAL_AUTHENTICATE = (byte) 0x88;
/* for EAC */
static final byte INS_PSO = (byte) 0x2A;
static final byte INS_MSE = (byte) 0x22;
static final byte P2_VERIFYCERT = (byte) 0xBE;
static final byte P1_SETFORCOMPUTATION = (byte) 0x41;
static final byte P1_SETFORVERIFICATION = (byte) 0x81;
static final byte P2_KAT = (byte) 0xA6;
static final byte P2_DST = (byte) 0xB6;
static final byte P2_AT = (byte) 0xA4;
/* for reading */
static final byte INS_SELECT_FILE = (byte) 0xA4;
static final byte INS_READ_BINARY = (byte) 0xB0;
/* for writing */
static final byte INS_UPDATE_BINARY = (byte) 0xd6;
static final byte INS_CREATE_FILE = (byte) 0xe0;
static final byte INS_PUT_DATA = (byte) 0xda;
static final short KEY_LENGTH = 16;
static final short KEYMATERIAL_LENGTH = 16;
static final short RND_LENGTH = 8;
static final short MAC_LENGTH = 8;
private static final byte PRIVMODULUS_TAG = 0x60;
private static final byte PRIVEXPONENT_TAG = 0x61;
private static final byte MRZ_TAG = 0x62;
private static final byte ECPRIVATEKEY_TAG = 0x63;
private static final byte CVCERTIFICATE_TAG = 0x64;
/* status words */
private static final short SW_OK = (short) 0x9000;
private static final short SW_REFERENCE_DATA_NOT_FOUND = (short) 0x6A88;
static final short SW_INTERNAL_ERROR = (short) 0x6d66;
private byte[] rnd;
private byte[] ssc;
private byte[] documentNumber;
private FileSystem fileSystem;
private RandomData randomData;
private short selectedFile;
private PassportCrypto passportCrypto;
private PassportInit passportInit;
static CVCertificate certificate;
KeyStore keyStore;
private byte[] lastINS;
private short[] chainingOffset;
private byte[] chainingTmp;
// This is as long we suspect a card verifiable certifcate could be
private static final short CHAINING_BUFFER_LENGTH = 400;
// public ATRGlobal atrGlobal;
/**
* Creates a new passport applet.
*/
public PassportApplet(byte mode) {
fileSystem = new FileSystem();
randomData = RandomData.getInstance(RandomData.ALG_PSEUDO_RANDOM);
certificate = new CVCertificate();
////
keyStore = new KeyStore(mode);
// if(true)
// return;
switch (mode) {
case PassportCrypto.CREF_MODE:
passportCrypto = new CREFPassportCrypto(keyStore);
break;
case PassportCrypto.PERFECTWORLD_MODE:
passportCrypto = new PassportCrypto(keyStore);
break;
case PassportCrypto.JCOP41_MODE:
passportCrypto = new JCOP41PassportCrypto(keyStore);
break;
}
passportInit = new PassportInit(passportCrypto);
////
rnd = JCSystem.makeTransientByteArray(RND_LENGTH,
JCSystem.CLEAR_ON_RESET);
ssc = JCSystem
.makeTransientByteArray((byte) 8, JCSystem.CLEAR_ON_RESET);
volatileState = JCSystem.makeTransientByteArray((byte) 1,
JCSystem.CLEAR_ON_RESET);
lastINS = JCSystem.makeTransientByteArray((short) 1,
JCSystem.CLEAR_ON_DESELECT);
chainingOffset = JCSystem.makeTransientShortArray((short) 1,
JCSystem.CLEAR_ON_DESELECT);
chainingTmp = JCSystem.makeTransientByteArray(CHAINING_BUFFER_LENGTH,
JCSystem.CLEAR_ON_DESELECT);
}
/**
* Installs an instance of the applet. The default crypto mode is now
* PERFECTWORLD_MODE as the new JCOP41 cards support all required crypto.
*
* @param buffer
* @param offset
* @param length
* @see javacard.framework.Applet#install(byte[], short, byte)
*/
public static void install(byte[] buffer, short offset, byte length) {
// (new PassportApplet(PassportCrypto.JCOP41_MODE)).register();
// new PassportApplet(PassportCrypto.PERFECTWORLD_MODE).register();
new PassportApplet(PassportCrypto.CREF_MODE).register();
}
/**
* Processes incoming APDUs.
*
* @param apdu
* @see javacard.framework.Applet#process(javacard.framework.APDU)
*/
public void process(APDU apdu) {
byte[] buffer = apdu.getBuffer();
byte cla = buffer[OFFSET_CLA];
byte ins = buffer[OFFSET_INS];
short sw1sw2 = SW_OK;
boolean protectedApdu = (byte)(cla & CLA_PROTECTED_APDU) == CLA_PROTECTED_APDU;
short responseLength = 0;
short le = 0;
if (lastINS[0] != ins) {
chainingOffset[0] = 0;
}
lastINS[0] = ins;
/* Ignore APDU that selects this applet... */
if (selectingApplet()) {
// Set ATR Historical Bytes (ATS).
// Requires gp211 API. Comment out the following line if API not
// available.
// org.globalplatform.GPSystem.setATRHistBytes(ATRGlobal.ATR_HIST,
// (short) 0x00, ATRGlobal.ATR_HIST_LEN);
return;
}
if (protectedApdu & hasMutuallyAuthenticated()) {
try {
le = passportCrypto.unwrapCommandAPDU(ssc, apdu);
} catch (CardRuntimeException e) {
sw1sw2 = e.getReason();
}
} else if (protectedApdu) {
ISOException.throwIt(ISO7816.SW_SECURE_MESSAGING_NOT_SUPPORTED);
}
if (sw1sw2 == SW_OK) {
try {
responseLength = processAPDU(apdu, cla, ins, protectedApdu, le);
} catch (CardRuntimeException e) {
sw1sw2 = e.getReason();
}
}
if (protectedApdu && hasMutuallyAuthenticated()) {
responseLength = passportCrypto.wrapResponseAPDU(ssc, apdu, passportCrypto
.getApduBufferOffset(responseLength), responseLength,
sw1sw2);
}
if (responseLength > 0) {
if (apdu.getCurrentState() != APDU.STATE_OUTGOING)
apdu.setOutgoing();
if (apdu.getCurrentState() != APDU.STATE_OUTGOING_LENGTH_KNOWN)
apdu.setOutgoingLength(responseLength);
apdu.sendBytes((short) 0, responseLength);
}
if (sw1sw2 != SW_OK) {
ISOException.throwIt(sw1sw2);
}
}
/**
* Processes incoming APDUs, excluding Secure Messaging.
*
* This method assumes SM protection has been removed from the
* incoming APDU, and does not add SM protection to the response.
* Handling of Secure Messaging is done in process(APDU apdu)
*
* @param protectedApdu true if Secure Messaging is used
* @return length of the response APDU
*/
public short processAPDU(APDU apdu, byte cla, byte ins,
boolean protectedApdu, short le) {
short responseLength = 0;
switch (ins) {
case INS_GET_CHALLENGE:
responseLength = processGetChallenge(apdu, protectedApdu, le);
break;
case INS_EXTERNAL_AUTHENTICATE:
responseLength = processMutualAuthenticate(apdu, protectedApdu);
break;
case INS_PSO:
if (!protectedApdu) {
ISOException.throwIt(SW_SECURITY_STATUS_NOT_SATISFIED);
}
responseLength = processPSO(apdu);
break;
case INS_MSE:
if (!protectedApdu) {
ISOException.throwIt(SW_SECURITY_STATUS_NOT_SATISFIED);
}
responseLength = processMSE(apdu);
break;
case INS_INTERNAL_AUTHENTICATE:
responseLength = processInternalAuthenticate(apdu, protectedApdu);
break;
case INS_SELECT_FILE:
processSelectFile(apdu);
break;
case INS_READ_BINARY:
responseLength = processReadBinary(apdu, le, protectedApdu);
break;
case INS_UPDATE_BINARY:
processUpdateBinary(apdu);
break;
case INS_CREATE_FILE:
processCreateFile(apdu);
break;
case INS_PUT_DATA:
processPutData(apdu);
break;
default:
ISOException.throwIt(SW_INS_NOT_SUPPORTED);
break;
}
return responseLength;
}
private short processPSO(APDU apdu) {
byte[] buffer = apdu.getBuffer();
if (!hasChipAuthenticated() || hasTerminalAuthenticated()) {
ISOException.throwIt(SW_SECURITY_STATUS_NOT_SATISFIED);
}
if (buffer[OFFSET_P1] != (byte) 0x00
&& buffer[OFFSET_P2] != P2_VERIFYCERT) {
ISOException.throwIt(SW_INCORRECT_P1P2);
}
if (certificate.currentCertSubjectId[0] == 0) {
ISOException.throwIt(SW_CONDITIONS_NOT_SATISFIED);
}
short lc = (short) (buffer[OFFSET_LC] & 0xFF);
if (chainingOffset[0] > (short) (CHAINING_BUFFER_LENGTH - lc)) {
ISOException.throwIt(SW_WRONG_LENGTH);
}
chainingOffset[0] = Util.arrayCopyNonAtomic(buffer, OFFSET_CDATA,
chainingTmp, chainingOffset[0], lc);
if (((byte) (buffer[OFFSET_CLA] & CHAIN_CLA) == CHAIN_CLA)) {
return (short) 0;
}
short chainingTmpLength = chainingOffset[0];
chainingOffset[0] = (short) 0;
certificate.parseCertificate(chainingTmp, (short) 0, chainingTmpLength,
false);
if (!certificate.verify()) {
ISOException.throwIt((short) 0x6300);
}
return (short) 0;
}
private short processMSE(APDU apdu) {
byte[] buffer = apdu.getBuffer();
byte p1 = (byte) (buffer[OFFSET_P1] & 0xff);
byte p2 = (byte) (buffer[OFFSET_P2] & 0xff);
short lc = (short) (buffer[OFFSET_LC] & 0xff);
short buffer_p = OFFSET_CDATA;
if (!hasEACKey() || !hasEACCertificate()) {
ISOException.throwIt(SW_INS_NOT_SUPPORTED);
}
if (!hasMutuallyAuthenticated() || hasTerminalAuthenticated()) {
ISOException.throwIt(SW_SECURITY_STATUS_NOT_SATISFIED);
}
if (p1 == P1_SETFORCOMPUTATION && p2 == P2_KAT) {
short lastOffset = (short) (lc + OFFSET_CDATA);
if (buffer_p > (short) (lastOffset - 2)) {
ISOException.throwIt(SW_WRONG_LENGTH);
}
if (buffer[buffer_p++] != (byte) 0x91) {
ISOException.throwIt(SW_WRONG_DATA);
}
short pubKeyLen = (short) (buffer[buffer_p++] & 0xFF);
short pubKeyOffset = buffer_p;
if (pubKeyOffset > (short) (lastOffset - pubKeyLen)) {
ISOException.throwIt(SW_WRONG_LENGTH);
}
buffer_p += pubKeyLen;
short keyIdOffset = 0;
short keyIdLength = 0;
if (buffer_p != lastOffset) {
if (buffer_p > (short) (lastOffset - 2)) {
ISOException.throwIt(SW_WRONG_LENGTH);
}
if (buffer[buffer_p++] != (byte) 0x84) {
ISOException.throwIt(SW_WRONG_DATA);
}
keyIdLength = (short) (buffer[buffer_p++] & 0xFF);
keyIdOffset = buffer_p;
if (keyIdOffset != (short) (lastOffset - keyIdLength)) {
ISOException.throwIt(SW_WRONG_LENGTH);
}
// ignore the key id, we don't use it for now
}
if (!passportCrypto.authenticateChip(buffer, pubKeyOffset, pubKeyLen)) {
ISOException.throwIt(SW_CONDITIONS_NOT_SATISFIED);
}
volatileState[0] |= CHIP_AUTHENTICATED;
return 0;
} else if (p1 == P1_SETFORVERIFICATION && (p2 == P2_DST || p2 == P2_AT)) {
if (!hasChipAuthenticated() || hasTerminalAuthenticated()) {
ISOException.throwIt(SW_SECURITY_STATUS_NOT_SATISFIED);
}
short lastOffset = (short) (lc + OFFSET_CDATA);
if (buffer_p > (short) (lastOffset - 2)) {
ISOException.throwIt(SW_WRONG_LENGTH);
}
if (buffer[buffer_p++] != (byte) 0x83) {
ISOException.throwIt(SW_WRONG_DATA);
}
short subIdLen = (short) (buffer[buffer_p++] & 0xFF);
if (buffer_p != (short) (lastOffset - subIdLen)) {
ISOException.throwIt(SW_WRONG_LENGTH);
}
if (!certificate.selectSubjectId(buffer, buffer_p, subIdLen)) {
ISOException.throwIt(SW_REFERENCE_DATA_NOT_FOUND);
}
} else {
ISOException.throwIt(SW_INCORRECT_P1P2);
}
return 0;
}
private void processPutData(APDU apdu) {
if (isLocked()) {
ISOException.throwIt(SW_CONDITIONS_NOT_SATISFIED);
}
byte[] buffer = apdu.getBuffer();
short buffer_p = (short) (OFFSET_CDATA & 0xff);
short lc = (short) (buffer[OFFSET_LC] & 0xff);
short p1 = (short) (buffer[OFFSET_P1] & 0xff);
short p2 = (short) (buffer[OFFSET_P2] & 0xff);
// sanity check
if (buffer.length < (short) (buffer_p + lc)) {
ISOException.throwIt(SW_INTERNAL_ERROR);
}
if (p1 == 0xde && p2 == 0xad) {
persistentState |= LOCKED;
} else if (p1 == 0 && p2 == PRIVMODULUS_TAG) {
buffer_p = BERTLVScanner.readTag(buffer, buffer_p); // tag ==
// PRIVMODULUS_TAG
buffer_p = BERTLVScanner.readLength(buffer, buffer_p); // length ==
// 00
buffer_p = BERTLVScanner.skipValue();
buffer_p = BERTLVScanner.readTag(buffer, buffer_p); // tag == 04
short modOffset = BERTLVScanner.readLength(buffer, buffer_p);
short modLength = BERTLVScanner.valueLength;
if (buffer[modOffset] == 0) {
modLength--;
modOffset++;
}
keyStore.rsaPrivateKey.setModulus(buffer, modOffset, modLength);
persistentState |= HAS_MODULUS;
} else if (p1 == 0 && p2 == PRIVEXPONENT_TAG) {
buffer_p = BERTLVScanner.readTag(buffer, buffer_p); // tag ==
// PRIVEXP_TAG
buffer_p = BERTLVScanner.readLength(buffer, buffer_p); // length ==
// 00
buffer_p = BERTLVScanner.skipValue();
buffer_p = BERTLVScanner.readTag(buffer, buffer_p); // tag == 04
short expOffset = BERTLVScanner.readLength(buffer, buffer_p);
short expLength = BERTLVScanner.valueLength;
// leading zero
if (buffer[expOffset] == 0) {
expLength--;
expOffset++;
}
keyStore.rsaPrivateKey.setExponent(buffer, expOffset, expLength);
persistentState |= HAS_EXPONENT;
} else if (p1 == 0 && p2 == MRZ_TAG) {
// data is BERTLV object with three objects; docNr, dataOfBirth,
// dateOfExpiry
buffer_p = BERTLVScanner.readTag(buffer, buffer_p);
buffer_p = BERTLVScanner.readLength(buffer, buffer_p);
buffer_p = BERTLVScanner.readTag(buffer, buffer_p);
short docNrOffset = BERTLVScanner.readLength(buffer, buffer_p);
short docNrLength = BERTLVScanner.valueLength;
buffer_p = BERTLVScanner.skipValue();
buffer_p = BERTLVScanner.readTag(buffer, buffer_p);
short dobOffset = BERTLVScanner.readLength(buffer, buffer_p);
short dobLength = BERTLVScanner.valueLength;
buffer_p = BERTLVScanner.skipValue();
buffer_p = BERTLVScanner.readTag(buffer, buffer_p);
short doeOffset = BERTLVScanner.readLength(buffer, buffer_p);
short doeLength = BERTLVScanner.valueLength;
buffer_p = BERTLVScanner.skipValue();
documentNumber = new byte[(short)(docNrLength+1)];
Util.arrayCopyNonAtomic(buffer, docNrOffset, documentNumber,
(short) 0, docNrLength);
documentNumber[docNrLength] = PassportInit.checkDigit(documentNumber,(short)0, docNrLength);
short keySeed_offset = passportInit.computeKeySeed(buffer, docNrOffset,
docNrLength, dobOffset, dobLength, doeOffset, doeLength);
short macKey_p = (short) (keySeed_offset + KEYMATERIAL_LENGTH);
short encKey_p = (short) (keySeed_offset + KEYMATERIAL_LENGTH + KEY_LENGTH);
passportCrypto.deriveKey(buffer, keySeed_offset, KEYMATERIAL_LENGTH, PassportCrypto.MAC_MODE,
macKey_p);
passportCrypto.deriveKey(buffer, keySeed_offset, KEYMATERIAL_LENGTH, PassportCrypto.ENC_MODE,
encKey_p);
keyStore.setMutualAuthenticationKeys(buffer, macKey_p, buffer,
encKey_p);
persistentState |= HAS_MUTUALAUTHENTICATION_KEYS;
} else if (p1 == 0 && p2 == ECPRIVATEKEY_TAG) {
short finish = (short) (buffer_p + lc);
while (buffer_p < finish) {
buffer_p = BERTLVScanner.readTag(buffer, buffer_p);
buffer_p = BERTLVScanner.readLength(buffer, buffer_p);
short len = BERTLVScanner.valueLength;
switch (BERTLVScanner.tag) {
case (short) 0x81:
if (len == (short) 6) {
short e1 = Util.getShort(buffer, buffer_p);
short e2 = Util
.getShort(buffer, (short) (buffer_p + 2));
short e3 = Util
.getShort(buffer, (short) (buffer_p + 4));
keyStore.ecPrivateKey.setFieldF2M(e1, e2, e3);
keyStore.ecPublicKey.setFieldF2M(e1, e2, e3);
} else {
keyStore.ecPrivateKey.setFieldF2M(Util.getShort(buffer,
buffer_p));
keyStore.ecPublicKey.setFieldF2M(Util.getShort(buffer,
buffer_p));
}
break;
case (short) 0x82:
keyStore.ecPrivateKey.setA(buffer, buffer_p, len);
keyStore.ecPublicKey.setA(buffer, buffer_p, len);
break;
case (short) 0x83:
keyStore.ecPrivateKey.setB(buffer, buffer_p, len);
keyStore.ecPublicKey.setB(buffer, buffer_p, len);
break;
case (short) 0x84:
keyStore.ecPrivateKey.setG(buffer, buffer_p, len);
keyStore.ecPublicKey.setG(buffer, buffer_p, len);
break;
case (short) 0x85:
keyStore.ecPrivateKey.setR(buffer, buffer_p, len);
keyStore.ecPublicKey.setR(buffer, buffer_p, len);
break;
case (short) 0x86:
if (len == (short) 20) {
buffer_p--;
len++;
buffer[buffer_p] = 0x00;
}
keyStore.ecPrivateKey.setS(buffer, buffer_p, len);
break;
case (short) 0x87:
// This is the k, ignore it
// short k = Util.getShort(buffer, buffer_p);
break;
default:
ISOException.throwIt(SW_WRONG_DATA);
break;
}
buffer_p = BERTLVScanner.skipValue();
}
if (keyStore.ecPrivateKey.isInitialized()) {
persistentState |= HAS_EC_KEY;
} else {
ISOException.throwIt(SW_WRONG_DATA);
}
} else if (p2 == CVCERTIFICATE_TAG) {
if ((byte) (persistentState & HAS_CVCERTIFICATE) == HAS_CVCERTIFICATE) {
// We already have the certificate initialized
ISOException.throwIt(SW_CONDITIONS_NOT_SATISFIED);
}
certificate.parseCertificate(buffer, buffer_p, lc, true);
certificate.setRootCertificate(buffer, p1);
persistentState |= HAS_CVCERTIFICATE;
} else {
ISOException.throwIt(SW_INCORRECT_P1P2);
}
}
/**
* Processes INTERNAL_AUTHENTICATE apdus, ie Active Authentication (AA).
* Receives a random and signs it.
*
* @param apdu
* @param protectedApdu true if Secure Messaging was used
* @return
*/
private short processInternalAuthenticate(APDU apdu, boolean protectedApdu) {
if (!hasInternalAuthenticationKeys() || !hasMutuallyAuthenticated()) {
ISOException.throwIt(ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED);
}
short buffer_p = (short) (OFFSET_CDATA & 0xff);
short hdr_offset = 0;
if (protectedApdu) {
hdr_offset = passportCrypto.getApduBufferOffset((short) 128);
}
short hdr_len = 1;
short m1_len = 106; // whatever
short m1_offset = (short) (hdr_offset + hdr_len);
short m2_len = 8;
short m2_offset = (short) (m1_offset + m1_len);
// we will write the hash over m2
short m1m2hash_offset = (short) (m1_offset + m1_len);
short m1m2hash_len = 20;
short trailer_offset = (short) (m1m2hash_offset + m1m2hash_len);
short trailer_len = 1;
byte[] buffer = apdu.getBuffer();
short bytesLeft = (short) (buffer[OFFSET_LC] & 0x00FF);
if (bytesLeft != m2_len)
ISOException.throwIt(SW_WRONG_LENGTH);
// put m2 in place
Util.arrayCopyNonAtomic(buffer, buffer_p, buffer, m2_offset, m2_len);
// write some random data of m1_len
// randomData.generateData(buffer, m1_offset, m1_length);
for (short i = m1_offset; i < (short) (m1_offset + m1_len); i++) {
buffer[i] = 0;
}
// calculate SHA1 hash over m1 and m2
passportCrypto.shaDigest.doFinal(buffer, m1_offset, (short) (m1_len + m2_len), buffer,
m1m2hash_offset);
passportCrypto.shaDigest.reset();
// write trailer
buffer[trailer_offset] = (byte) 0xbc;
// write header
buffer[hdr_offset] = (byte) 0x6a;
// encrypt the whole buffer with our AA private key
short plaintext_len = (short) (hdr_len + m1_len + m1m2hash_len + trailer_len);
// sanity check
if (plaintext_len != 128) {
ISOException.throwIt(SW_INTERNAL_ERROR);
}
passportCrypto.rsaCiph.init(keyStore.rsaPrivateKey, Cipher.MODE_ENCRYPT);
short ciphertext_len = passportCrypto.rsaCiph.doFinal(buffer, hdr_offset,
plaintext_len, buffer, hdr_offset);
// sanity check
if (ciphertext_len != 128) {
ISOException.throwIt(SW_INTERNAL_ERROR);
}
return ciphertext_len;
}
/**
* Processes incoming GET_CHALLENGE APDUs, as part of BAC or EAC.
*
* Generates random 8 bytes, sends back result and stores result in rnd.
* A GET_CHALLENGE APDU can be sent as part of BAC, or as part of
* EAC (more specifically, Terminal Authentication (TA).
*
* @param apdu
* is used for sending (8 bytes) only
* @param protectedApdu true if Secure Messaging was used
*/
private short processGetChallenge(APDU apdu, boolean protectedApdu, short le) {
if (protectedApdu) {
// we're doing TA
if (!hasChipAuthenticated()
|| certificate.cert1HolderReference[0] == (byte)0
|| hasTerminalAuthenticated()) {
ISOException.throwIt(SW_SECURITY_STATUS_NOT_SATISFIED);
}
} else {
// we're doing BAC
if (!hasMutualAuthenticationKeys() || hasMutuallyAuthenticated()) {
ISOException.throwIt(SW_SECURITY_STATUS_NOT_SATISFIED);
}
}
byte[] buffer = apdu.getBuffer();
if (!protectedApdu) {
le = apdu.setOutgoing();
}
// For the BAP challenge the length should be 8, for the EAP challenge
// we guess other lenghts are fine too?
if (le != 8) {
ISOException.throwIt(SW_WRONG_LENGTH);
}
randomData.generateData(rnd, (short) 0, le);
short bufferOffset = protectedApdu ? passportCrypto.getApduBufferOffset(le)
: (short) 0;
Util.arrayCopyNonAtomic(rnd, (short) 0, buffer, bufferOffset, le);
volatileState[0] |= CHALLENGED;
return le;
}
/**
* Processes incoming EXTERNAL_AUTHENTICATE APDUs, as part of BAC or EAC.
*
* An EXTERNAL_AUTHENTICATE can be the last step of BAC, or the last
* step of Terminal Authentication (TA) when doing EAC.
*
* @param apdu
* the APDU
* @param protectedApdu true if Secure Messaging was used
* @return length of response APDU
*/
private short processMutualAuthenticate(APDU apdu, boolean protectedApdu) {
if (protectedApdu) {
// we're doing EAC
if (!hasChipAuthenticated() || !isChallenged()
|| certificate.currentCertSubjectId[0] == (byte)0
|| hasTerminalAuthenticated()) {
ISOException.throwIt(SW_SECURITY_STATUS_NOT_SATISFIED);
}
byte[] buffer = apdu.getBuffer();
short buffer_p = OFFSET_CDATA;
short lc = (short) (buffer[OFFSET_LC] & 0xFF);
setNoChallenged();
if (!passportCrypto.eacVerifySignature(certificate.currentCertPublicKey, rnd,
documentNumber, buffer, buffer_p, lc)) {
certificate.clear();
ISOException.throwIt((short) 0x6300);
}
certificate.clear();
volatileState[0] |= TERMINAL_AUTHENTICATED;
return 0;
} else {
// we're doing BAC
if (!isChallenged() || hasMutuallyAuthenticated()) {
ISOException.throwIt(SW_SECURITY_STATUS_NOT_SATISFIED);
}
byte[] buffer = apdu.getBuffer();
short bytesLeft = (short) (buffer[OFFSET_LC] & 0x00FF);
short e_ifd_length = RND_LENGTH + RND_LENGTH + KEYMATERIAL_LENGTH;
// incoming message is e_ifd || m_ifd
// where e_ifd == E_KENC(rnd_ifd || rnd_icc || k_ifd)
if (bytesLeft != (short) (e_ifd_length + MAC_LENGTH))
ISOException.throwIt(SW_WRONG_LENGTH);
short e_ifd_p = OFFSET_CDATA;
short m_ifd_p = (short) (e_ifd_p + e_ifd_length);
if (apdu.getCurrentState() == APDU.STATE_INITIAL) {
apdu.setIncomingAndReceive();
}
if (apdu.getCurrentState() != APDU.STATE_FULL_INCOMING) {
// need all data in one APDU.
ISOException.throwIt(SW_INTERNAL_ERROR);
}
// buffer[OFFSET_CDATA ... +40] consists of e_ifd || m_ifd
// verify checksum m_ifd of cryptogram e_ifd
passportCrypto.initMac(Signature.MODE_VERIFY);
if (!passportCrypto.verifyMacFinal(buffer, e_ifd_p, e_ifd_length, buffer,
m_ifd_p))
ISOException.throwIt(SW_SECURITY_STATUS_NOT_SATISFIED);
// decrypt e_ifd into buffer[0] where buffer = rnd.ifd || rnd.icc ||
// k.ifd
passportCrypto.decryptInit();
short plaintext_len = passportCrypto.decryptFinal(buffer, e_ifd_p,
e_ifd_length, buffer, (short) 0);
if (plaintext_len != e_ifd_length) // sanity check
ISOException.throwIt(SW_INTERNAL_ERROR);
short rnd_ifd_p = 0;
short rnd_icc_p = RND_LENGTH;
short k_ifd_p = (short) (rnd_icc_p + RND_LENGTH);
/*
* we use apdu buffer for writing intermediate data in buffer with
* following pointers
*/
short k_icc_p = (short) (k_ifd_p + KEYMATERIAL_LENGTH);
short keySeed_p = (short) (k_icc_p + KEYMATERIAL_LENGTH);
short keys_p = (short) (keySeed_p + KEYMATERIAL_LENGTH);
// verify that rnd.icc equals value generated in getChallenge
if (Util.arrayCompare(buffer, rnd_icc_p, rnd, (short) 0, RND_LENGTH) != 0)
ISOException.throwIt(SW_SECURITY_STATUS_NOT_SATISFIED);
// generate keying material k.icc
randomData.generateData(buffer, k_icc_p, KEYMATERIAL_LENGTH);
// calculate keySeed for session keys by xorring k_ifd and k_icc
PassportUtil.xor(buffer, k_ifd_p, buffer, k_icc_p, buffer, keySeed_p,
KEYMATERIAL_LENGTH);
// calculate session keys
passportCrypto.deriveKey(buffer, keySeed_p, KEYMATERIAL_LENGTH, PassportCrypto.MAC_MODE, keys_p);
short macKey_p = keys_p;
keys_p += KEY_LENGTH;
passportCrypto.deriveKey(buffer, keySeed_p, KEYMATERIAL_LENGTH, PassportCrypto.ENC_MODE, keys_p);
short encKey_p = keys_p;
keys_p += KEY_LENGTH;
keyStore.setSecureMessagingKeys(buffer, macKey_p, buffer, encKey_p);
// compute ssc
PassportCrypto.computeSSC(buffer, rnd_icc_p, buffer, rnd_ifd_p, ssc);
// create response in buffer where response = rnd.icc || rnd.ifd ||
// k.icc
PassportUtil.swap(buffer, rnd_icc_p, rnd_ifd_p, RND_LENGTH);
Util.arrayCopyNonAtomic(buffer, k_icc_p, buffer, (short) (2 * RND_LENGTH),
KEYMATERIAL_LENGTH);
// make buffer encrypted using k_enc
passportCrypto.encryptInit();
short ciphertext_len = passportCrypto.encryptFinal(buffer, (short) 0,
(short) (2 * RND_LENGTH + KEYMATERIAL_LENGTH), buffer,
(short) 0);
// create m_icc which is a checksum of response
passportCrypto.initMac(Signature.MODE_SIGN);
passportCrypto.createMacFinal(buffer, (short) 0, ciphertext_len, buffer,
ciphertext_len);
setNoChallenged();
volatileState[0] |= MUTUAL_AUTHENTICATED;
return (short) (ciphertext_len + MAC_LENGTH);
}
}
/**
* Processes incoming SELECT_FILE APDUs.
*
* @param apdu
* where the first 2 data bytes encode the file to select.
*/
private void processSelectFile(APDU apdu) {
if (isLocked() & !hasMutuallyAuthenticated()) {
ISOException.throwIt(ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED);
}
byte[] buffer = apdu.getBuffer();
short lc = (short) (buffer[OFFSET_LC] & 0x00FF);
if (lc != 2)
ISOException.throwIt(SW_WRONG_LENGTH);
if (apdu.getCurrentState() == APDU.STATE_INITIAL) {
apdu.setIncomingAndReceive();
}
if (apdu.getCurrentState() != APDU.STATE_FULL_INCOMING) {
// need all data in one APDU.
ISOException.throwIt(SW_INTERNAL_ERROR);
}
short fid = Util.getShort(buffer, OFFSET_CDATA);
if (fileSystem.getFile(fid) != null) {
selectedFile = fid;
volatileState[0] |= FILE_SELECTED;
return;
}
setNoFileSelected();
ISOException.throwIt(ISO7816.SW_FILE_NOT_FOUND);
}
/**
* Processes incoming READ_BINARY APDUs. Returns data of the currently
* selected file.
*
* @param apdu
* where the offset is carried in header bytes p1 and p2.
* @param le
* expected length by terminal
* @return length of the response APDU
*/
private short processReadBinary(APDU apdu, short le, boolean protectedApdu) {
if (!hasMutuallyAuthenticated()) {
ISOException.throwIt(SW_SECURITY_STATUS_NOT_SATISFIED);
}
if (!hasFileSelected()) {
ISOException.throwIt(SW_CONDITIONS_NOT_SATISFIED);
}
byte[] buffer = apdu.getBuffer();
byte p1 = buffer[OFFSET_P1];
byte p2 = buffer[OFFSET_P2];
short offset = Util.makeShort(p1, p2);
byte[] file = fileSystem.getFile(selectedFile);
if (file == null) {
ISOException.throwIt(ISO7816.SW_FILE_NOT_FOUND);
}
short len;
short fileSize = fileSystem.getFileSize(selectedFile);
len = PassportUtil.min((short) (buffer.length - 37),
(short) (fileSize - offset));
// FIXME: 37 magic
len = PassportUtil.min(len, (short) buffer.length);
len = PassportUtil.min(le, len);
short bufferOffset = 0;
if (protectedApdu) {
bufferOffset = passportCrypto.getApduBufferOffset(len);
}
Util.arrayCopyNonAtomic(file, offset, buffer, bufferOffset, len);
return len;
}
/**
* Processes and UPDATE_BINARY apdu. Writes data in the currently selected
* file.
*
* @param apdu
* carries the offset where to write date in header bytes p1 and
* p2.
*/
private void processUpdateBinary(APDU apdu) {
if (!hasFileSelected() || isLocked()) {
ISOException.throwIt(SW_CONDITIONS_NOT_SATISFIED);
}
byte[] buffer = apdu.getBuffer();
byte p1 = buffer[OFFSET_P1];
byte p2 = buffer[OFFSET_P2];
short offset = Util.makeShort(p1, p2);
short readCount = (short) (buffer[ISO7816.OFFSET_LC] & 0xff);
readCount = apdu.setIncomingAndReceive();
while (readCount > 0) {
fileSystem.writeData(selectedFile, offset, buffer, OFFSET_CDATA,
readCount);
offset += readCount;
readCount = apdu.receiveBytes(ISO7816.OFFSET_CDATA);
}
}
/**
* Processes and CREATE_FILE apdu.
*
* This functionality is only partly implemented. Only non-directories
* (files) can be created, all options for CREATE_FILE are ignored.
*
* @param apdu
* containing 6 bytes: 0x64 || (1 byte) || size (2) || fid (2)
*/
private void processCreateFile(APDU apdu) {
if (isLocked()) {
ISOException.throwIt(SW_CONDITIONS_NOT_SATISFIED);
}
byte[] buffer = apdu.getBuffer();
short lc = (short) (buffer[OFFSET_LC] & 0xff);
if (apdu.getCurrentState() == APDU.STATE_INITIAL) {
apdu.setIncomingAndReceive();
}
if (apdu.getCurrentState() != APDU.STATE_FULL_INCOMING) {
// need all data in one APDU.
ISOException.throwIt(SW_INTERNAL_ERROR);
}
if (lc < (short) 6 || (buffer[OFFSET_CDATA + 1] & 0xff) < 4)
ISOException.throwIt(SW_WRONG_LENGTH);
if (buffer[OFFSET_CDATA] != 0x63)
ISOException.throwIt(SW_DATA_INVALID);
short size = Util.makeShort(buffer[(short) (OFFSET_CDATA + 2)],
buffer[(short) (OFFSET_CDATA + 3)]);
short fid = Util.makeShort(buffer[(short) (OFFSET_CDATA + 4)],
buffer[(short) (OFFSET_CDATA + 5)]);
if(fid == FileSystem.EF_CVCA_FID) {
fileSystem.createFile(fid, size, certificate);
}else{
fileSystem.createFile(fid, size);
}
}
public static boolean hasInternalAuthenticationKeys() {
return (persistentState & (HAS_EXPONENT | HAS_MODULUS)) == (HAS_EXPONENT | HAS_MODULUS);
}
public static boolean hasMutualAuthenticationKeys() {
return (persistentState & HAS_MUTUALAUTHENTICATION_KEYS) == HAS_MUTUALAUTHENTICATION_KEYS;
}
public static boolean hasEACKey() {
return (persistentState & HAS_EC_KEY) == HAS_EC_KEY;
}
public static boolean hasEACCertificate() {
return (persistentState & HAS_CVCERTIFICATE) == HAS_CVCERTIFICATE;
}
public static void setNoFileSelected() {
if (hasFileSelected()) {
volatileState[0] ^= FILE_SELECTED;
}
}
public static void setNoChallenged() {
if ((volatileState[0] & CHALLENGED) == CHALLENGED) {
volatileState[0] ^= CHALLENGED;
}
}
public static boolean hasFileSelected() {
return (volatileState[0] & FILE_SELECTED) == FILE_SELECTED;
}
public static boolean isLocked() {
return (persistentState & LOCKED) == LOCKED;
}
public static boolean isChallenged() {
return (volatileState[0] & CHALLENGED) == CHALLENGED;
}
/** Has BAC been completed? */
public static boolean hasMutuallyAuthenticated() {
return (volatileState[0] & MUTUAL_AUTHENTICATED) == MUTUAL_AUTHENTICATED;
}
public static boolean hasChipAuthenticated() {
return (volatileState[0] & CHIP_AUTHENTICATED) == CHIP_AUTHENTICATED;
}
public static boolean hasTerminalAuthenticated() {
return (volatileState[0] & TERMINAL_AUTHENTICATED) == TERMINAL_AUTHENTICATED;
}
}
/*
* passportapplet - A reference implementation of the MRTD standards.
*
* Copyright (C) 2006 SoS group, Radboud University
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* $Id$
*/
package josh.passport;
import javacard.framework.APDU;
import javacard.framework.ISO7816;
import javacard.framework.ISOException;
import javacard.framework.JCSystem;
import javacard.framework.Util;
import javacard.security.CryptoException;
import javacard.security.DESKey;
import javacard.security.KeyAgreement;
import javacard.security.KeyBuilder;
import javacard.security.MessageDigest;
import javacard.security.RSAPublicKey;
import javacard.security.Signature;
import javacardx.crypto.Cipher;
public class PassportCrypto {
public static final byte ENC_MODE = 1;
public static final byte MAC_MODE = 2;
public static final byte CREF_MODE = 3;
public static final byte PERFECTWORLD_MODE = 4;
public static final byte JCOP41_MODE = 5;
public static final byte INPUT_IS_NOT_PADDED = 5;
public static final byte INPUT_IS_PADDED = 6;
public static final byte PAD_INPUT = 7;
public static final byte DONT_PAD_INPUT = 8;
MessageDigest shaDigest;
Signature sig;
Cipher ciph;
Cipher rsaCiph;
KeyStore keyStore;
Signature rsaSig;
KeyAgreement keyAgreement;
boolean[] eacChangeKeys;
// byte[] eacTerminalKeyHash;
private static final short EC_X_LENGTH = (short)((short)(KeyBuilder.LENGTH_EC_F2M_163 / 8)+1);
public static byte[] PAD_DATA = { (byte) 0x80, 0, 0, 0, 0, 0, 0, 0 };
protected void init() {
sig = Signature.getInstance(Signature.ALG_DES_MAC8_ISO9797_1_M2_ALG3,
false);
ciph = Cipher.getInstance(Cipher.ALG_DES_CBC_NOPAD, false);
}
public PassportCrypto(KeyStore keyStore) {
this.keyStore = keyStore;
init();
shaDigest = MessageDigest.getInstance(MessageDigest.ALG_SHA, false);
rsaSig = Signature.getInstance(Signature.ALG_RSA_SHA_PKCS1, false);
rsaCiph = Cipher.getInstance(Cipher.ALG_RSA_NOPAD, false);
keyAgreement = KeyAgreement.getInstance(KeyAgreement.ALG_EC_SVDP_DH,
false);
eacChangeKeys = JCSystem.makeTransientBooleanArray((short) 1,
JCSystem.CLEAR_ON_DESELECT);
}
public void createMacFinal(byte[] msg, short msg_offset, short msg_len,
byte[] mac, short mac_offset) {
sig.sign(msg, msg_offset, msg_len, mac, mac_offset);
}
public boolean verifyMacFinal(byte[] msg, short msg_offset, short msg_len,
byte[] mac, short mac_offset) {
return sig.verify(msg, msg_offset, msg_len, mac, mac_offset, (short) 8);
}
public void decryptInit() {
DESKey k = keyStore.getCryptKey();
ciph.init(k, Cipher.MODE_DECRYPT);
}
public short decrypt(byte[] ctext, short ctext_offset, short ctext_len,
byte[] ptext, short ptext_offset) {
return ciph.update(ctext, ctext_offset, ctext_len, ptext, ptext_offset);
}
public short decryptFinal(byte[] ctext, short ctext_offset, short ctext_len,
byte[] ptext, short ptext_offset) {
return ciph.doFinal(ctext, ctext_offset, ctext_len, ptext, ptext_offset);
}
public short encryptInit() {
return encryptInit(DONT_PAD_INPUT, null, (short)0, (short)0);
}
public short encryptInit(byte padding, byte[] ptext, short ptext_offset, short ptext_len) {
DESKey k = keyStore.getCryptKey();
short newlen=ptext_len;
if(padding == PAD_INPUT) {
// pad input
newlen = PassportUtil.pad(ptext, ptext_offset, ptext_len);
}
ciph.init(k, Cipher.MODE_ENCRYPT);
return newlen;
}
public short encrypt(byte[] ptext, short ptext_offset, short ptext_len,
byte[] ctext, short ctext_offset) {
return ciph.update(ptext, ptext_offset, ptext_len, ctext, ctext_offset);
}
public short encryptFinal(byte[] ptext, short ptext_offset, short ptext_len,
byte[] ctext, short ctext_offset) {
return ciph.doFinal(ptext, ptext_offset, ptext_len, ctext, ctext_offset);
}
public void updateMac(byte[] msg, short msg_offset, short msg_len) {
sig.update(msg, msg_offset, msg_len);
}
public void initMac(byte mode) {
DESKey k = keyStore.getMacKey();
sig.init(k, mode);
}
// public short unwrapCommandAPDU_werkt(byte[] ssc, APDU aapdu) {
// byte[] apdu = aapdu.getBuffer();
// short apdu_p = (short) (ISO7816.OFFSET_CDATA & 0xff);
// // offset
// short lc = (short) (apdu[ISO7816.OFFSET_LC] & 0xff);
// short le = 0;
// short do87DataLen = 0;
// short do87Data_p = 0;
// short do87LenBytes = 0;
// short hdrLen = 4;
// short hdrPadLen = (short) (8 - hdrLen);
// short apduLength = (short) (hdrLen + 1 + lc);
//
// aapdu.setIncomingAndReceive();
//
// // sanity check
// if (apdu.length < (short) (apduLength + hdrPadLen + ssc.length)) {
// ISOException.throwIt((short)0x6d66);
// }
//
// // pad the header, make room for ssc, so we don't have to
// // modify pointers to locations in the apdu later.
// Util.arrayCopy(apdu, (short) (hdrLen + 1), // toss away lc
// apdu, (short) (hdrLen + hdrPadLen), lc);
// Util.arrayCopy(PassportCrypto.PAD_DATA,
// (short) 0,
// apdu,
// hdrLen,
// hdrPadLen);
// apduLength--;
// apduLength += hdrPadLen;
//
// // add ssc in front (needed to calculate the mac) so we don't have to
// // modify pointers to locations in the apdu later.
// incrementSSC(ssc);
// Util.arrayCopy(apdu, (short) 0, apdu, (short) ssc.length, apduLength);
// Util.arrayCopy(ssc, (short) 0, apdu, (short) 0, (short) ssc.length);
//
// apdu_p = (short) (hdrLen + hdrPadLen);
// apdu_p += (short) ssc.length;
//
// if (apdu[apdu_p] == (byte) 0x87) {
// apdu_p++;
// // do87
// if ((apdu[apdu_p] & 0xff) > 0x80) {
// do87LenBytes = (short) (apdu[apdu_p] & 0x7f);
// apdu_p++;
// } else {
// do87LenBytes = 1;
// }
// if (do87LenBytes > 2) { // sanity check
// ISOException.throwIt((short) 0x6d66);
// }
// for (short i = 0; i < do87LenBytes; i++) {
// do87DataLen += (short) ((apdu[(short)(apdu_p + i)] & 0xff) << (short) ((do87LenBytes - 1 - i) * 8));
// }
// apdu_p += do87LenBytes;
//
// if (apdu[apdu_p] != 1) {
// ISOException.throwIt((short) (0x6d66));
// }
// // store pointer to data and defer decrypt to after mac check (do8e)
// do87Data_p = (short) (apdu_p + 1);
// apdu_p += do87DataLen;
// do87DataLen--; // compensate for 0x01 marker
// }
//
// if (apdu[apdu_p] == (byte) 0x97) {
// // do97
// if (apdu[++apdu_p] != 1)
// ISOException.throwIt((short) (0x6d66));
// le = (short) (apdu[++apdu_p] & 0xff);
// apdu_p++;
// }
//
// // do8e
// if (apdu[apdu_p] != (byte) 0x8e) {
// ISOException.throwIt((short) (0x6d66));
// }
// if (apdu[++apdu_p] != 8) {
// ISOException.throwIt(ISO7816.SW_DATA_INVALID);
// }
//
// initMac();
// if (!verifyMacFinal(apdu,
// (short) 0,
// (short) (apdu_p - 1),
// apdu,
// (short)(apdu_p + 1))) {
// ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
// }
//
// // construct unprotected apdu
// // copy back the hdr
// Util.arrayCopy(apdu, (short) ssc.length, apdu, (short) 0, hdrLen);
// apduLength -= 4;
//
// short plaintextLength = 0;
// short plaintextLc = 0;
// if (do87DataLen != 0) {
// // decrypt data, and leave room for lc
// decryptInit();
// plaintextLength = decryptFinal(apdu,
// do87Data_p,
// do87DataLen,
// apdu,
// (short) (hdrLen + 1));
//
// plaintextLc = PassportUtil.calcLcFromPaddedData(apdu,
// (short) (hdrLen + 1),
// do87DataLen);
// apdu[hdrLen] = (byte) (plaintextLc & 0xff);
// }
//
// apduLength = (short) (hdrLen + 1 + plaintextLength);
//
// // empty out the rest
// for (short i = apduLength; i < apdu.length; i++) {
// apdu[i] = 0;
// }
//
// return le;
// }
public short unwrapCommandAPDU(byte[] ssc, APDU apdu) {
byte[] buf = apdu.getBuffer();
short apdu_p = (short) (ISO7816.OFFSET_CDATA & 0xff);
short start_p = apdu_p;
short lc = (short) (buf[ISO7816.OFFSET_LC] & 0xff);
short le = 0;
short do87DataLen = 0;
short do87Data_p = 0;
short do87LenBytes = 0;
short hdrLen = 4;
short hdrPadLen = (short) (8 - hdrLen);
apdu.setIncomingAndReceive();
incrementSSC(ssc);
if (buf[apdu_p] == (byte) 0x87) {
apdu_p++;
// do87
if ((buf[apdu_p] & 0xff) > 0x80) {
do87LenBytes = (short) (buf[apdu_p] & 0x7f);
apdu_p++;
} else {
do87LenBytes = 1;
}
if (do87LenBytes > 2) { // sanity check
ISOException.throwIt(PassportApplet.SW_INTERNAL_ERROR);
}
for (short i = 0; i < do87LenBytes; i++) {
do87DataLen += (short) ((buf[(short)(apdu_p + i)] & 0xff) << (short) ((do87LenBytes - 1 - i) * 8));
}
apdu_p += do87LenBytes;
if (buf[apdu_p] != 1) {
ISOException.throwIt(PassportApplet.SW_INTERNAL_ERROR);
}
// store pointer to data and defer decrypt to after mac check (do8e)
do87Data_p = (short) (apdu_p + 1);
apdu_p += do87DataLen;
do87DataLen--; // compensate for 0x01 marker
}
if (buf[apdu_p] == (byte) 0x97) {
// do97
if (buf[++apdu_p] != 1)
ISOException.throwIt(PassportApplet.SW_INTERNAL_ERROR);
le = (short) (buf[++apdu_p] & 0xff);
apdu_p++;
}
// do8e
if (buf[apdu_p] != (byte) 0x8e) {
ISOException.throwIt(PassportApplet.SW_INTERNAL_ERROR);
}
if (buf[++apdu_p] != 8) {
ISOException.throwIt(ISO7816.SW_DATA_INVALID);
}
// verify mac
initMac(Signature.MODE_VERIFY);
updateMac(ssc, (short)0, (short)ssc.length);
updateMac(buf, (short)0, hdrLen);
updateMac(PAD_DATA, (short)0, hdrPadLen);
if (!verifyMacFinal(buf,
start_p,
(short) (apdu_p - 1 - start_p),
buf,
(short)(apdu_p + 1))) {
ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
}
short plaintextLength = 0;
short plaintextLc = 0;
if (do87DataLen != 0) {
// decrypt data, and leave room for lc
decryptInit();
plaintextLength = decryptFinal(buf,
do87Data_p,
do87DataLen,
buf,
(short) (hdrLen + 1));
plaintextLc = PassportUtil.calcLcFromPaddedData(buf,
(short) (hdrLen + 1),
do87DataLen);
buf[hdrLen] = (byte) (plaintextLc & 0xff);
}
return le;
}
/***
* Space to reserve in buffer when using secure messaging.
*
* @param plaintextLength length of plaintext in which this offset depends.
* @return
*/
public short getApduBufferOffset(short plaintextLength) {
short do87Bytes = 2; // 0x87 len data 0x01
// smallest multiple of 8 strictly larger than plaintextLen + 1
// byte is probably the length of the ciphertext (including do87 0x01)
short do87DataLen = (short) ((((short) (plaintextLength + 8) / 8) * 8) + 1);
if(do87DataLen < 0x80) {
do87Bytes++;
}
else if(do87DataLen <= 0xff) {
do87Bytes += 2;
}
else {
do87Bytes += (short)(plaintextLength > 0xff ? 2 : 1);
}
return do87Bytes;
}
public short wrapResponseAPDU(byte[] ssc, APDU aapdu, short plaintextOffset, short plaintextLen,
short sw1sw2) {
byte[] apdu = aapdu.getBuffer();
short apdu_p = 0;
// smallest multiple of 8 strictly larger than plaintextLen
short do87DataLen = PassportUtil.lengthWithPadding(plaintextLen);
// for 0x01 marker (indicating padding is used)
do87DataLen++;
short do87DataLenBytes = (short)(do87DataLen > 0xff? 2 : 1);
short do87HeaderBytes = getApduBufferOffset(plaintextLen);
short do87Bytes = (short)(do87HeaderBytes + do87DataLen - 1); // 0x01 is counted twice
boolean hasDo87 = plaintextLen > 0;
incrementSSC(ssc);
short ciphertextLength=0;
short possiblyPaddedPlaintextLength=0;
if(hasDo87) {
// put ciphertext in proper position.
possiblyPaddedPlaintextLength = encryptInit(PAD_INPUT, apdu, plaintextOffset, plaintextLen);
ciphertextLength = encryptFinal(
apdu,
plaintextOffset,
possiblyPaddedPlaintextLength,
apdu,
do87HeaderBytes);
}
//sanity check
//note that this check
// (possiblyPaddedPlaintextLength != (short)(do87DataLen -1))
//does not always hold because some algs do the padding in the final, some in the init.
if (hasDo87 && (((short) (do87DataLen - 1) != ciphertextLength)))
ISOException.throwIt((short) 0x6d66);
if (hasDo87) {
// build do87
apdu[apdu_p++] = (byte) 0x87;
if(do87DataLen < 0x80) {
apdu[apdu_p++] = (byte)do87DataLen;
} else {
apdu[apdu_p++] = (byte) (0x80 + do87DataLenBytes);
for(short i=(short)(do87DataLenBytes-1); i>=0; i--) {
apdu[apdu_p++] = (byte) ((do87DataLen >>> (i * 8)) & 0xff);
}
}
apdu[apdu_p++] = 0x01;
}
if(hasDo87) {
apdu_p = do87Bytes;
}
// build do99
apdu[apdu_p++] = (byte) 0x99;
apdu[apdu_p++] = 0x02;
Util.setShort(apdu, apdu_p, sw1sw2);
apdu_p += 2;
// calculate and write mac
initMac(Signature.MODE_SIGN);
updateMac(ssc, (short)0, (short)ssc.length);
createMacFinal(apdu,
(short) 0,
apdu_p,
apdu,
(short)(apdu_p+2));
// write do8e
apdu[apdu_p++] = (byte) 0x8e;
apdu[apdu_p++] = 0x08;
apdu_p += 8; // for mac written earlier
if (eacChangeKeys[0]) {
eacChangeKeys[0] = false;
keyStore.setSecureMessagingKeys(keyStore.tmpKeys, (short) 0,
keyStore.tmpKeys, (short) 16);
Util.arrayFillNonAtomic(keyStore.tmpKeys, (short) 0, (short) 32,
(byte) 0x00);
Util.arrayFillNonAtomic(ssc, (short) 0, (short) ssc.length,
(byte) 0x00);
}
return apdu_p;
}
/**
* Derives the ENC or MAC key from the keySeed.
*
* @param keySeed
* the key seed.
* @param mode
* either <code>ENC_MODE</code> or <code>MAC_MODE</code>.
*
* @return the key.
*/
static byte[] c = { 0x00, 0x00, 0x00, 0x00 };
public void deriveKey(byte[] buffer, short keySeed_offset, short keySeed_length, byte mode, short key_offset)
throws CryptoException {
// only key_offset is a write pointer
// sanity checks
if ((short)buffer.length < (short)((short)(key_offset + keySeed_length) + c.length)) {
ISOException.throwIt((short)0x6d66);
}
if(keySeed_offset > key_offset) {
ISOException.throwIt((short)0x6d66);
}
c[(short)(c.length-1)] = mode;
// copy seed || c to key_offset
Util.arrayCopyNonAtomic(buffer, keySeed_offset, buffer, key_offset, keySeed_length);
Util.arrayCopyNonAtomic(c, (short) 0, buffer, (short)(key_offset + keySeed_length), (short)c.length);
// compute hash on key_offset (+seed len +c len)
shaDigest.doFinal(buffer, key_offset, (short)(keySeed_length + c.length), buffer, key_offset);
shaDigest.reset();
// parity bits
for (short i = key_offset; i < (short)(key_offset + PassportApplet.KEY_LENGTH); i++) {
if (PassportUtil.evenBits(buffer[i]) == 0)
buffer[i] = (byte) (buffer[i] ^ 1);
}
}
public static void incrementSSC(byte[] ssc) {
if (ssc == null || ssc.length <= 0)
return;
for (short s = (short) (ssc.length - 1); s >= 0; s--) {
if ((short) ((ssc[s] & 0xff) + 1) > 0xff)
ssc[s] = 0;
else {
ssc[s]++;
break;
}
}
}
public static void computeSSC(byte[] rndICC, short rndICC_offset,
byte[] rndIFD, short rndIFD_offset, byte[] ssc) {
if (rndICC == null || (short) (rndICC.length - rndICC_offset) < 8
|| rndIFD == null
|| (short) (rndIFD.length - rndIFD_offset) < 8) {
ISOException.throwIt((short) 0x6d66);
}
Util.arrayCopyNonAtomic(rndICC,
(short) (rndICC_offset + 4),
ssc,
(short) 0,
(short) 4);
Util.arrayCopyNonAtomic(rndIFD,
(short) (rndIFD_offset + 4),
ssc,
(short) 4,
(short) 4);
}
public void createHash(byte[] msg, short msg_offset, short length,
byte[] dest, short dest_offset) throws CryptoException {
if ((dest.length < (short) (dest_offset + length))
|| (msg.length < (short) (msg_offset + length)))
ISOException.throwIt((short) 0x6d66);
try {
shaDigest.doFinal(msg, msg_offset, length, dest, dest_offset);
} finally {
shaDigest.reset();
}
}
/**
* Chip authentication part of EAP.
*
* @param pubData
* the other parties public key data
* @param offset
* offset to the public key data
* @param length
* public key data length
*
* @return true when authentication successful
*/
public boolean authenticateChip(byte[] pubData, short offset, short length) {
try {
// Verify public key first. i.e. see if the data is correct and
// makes up a valid
// EC public key.
keyStore.ecPublicKey.setW(pubData, offset, length);
if (!keyStore.ecPublicKey.isInitialized()) {
CryptoException.throwIt(CryptoException.ILLEGAL_VALUE);
}
// Do the key agreement and derive new session keys based on the
// outcome:
keyAgreement.init(keyStore.ecPrivateKey);
short secOffset = (short) (offset + length);
short secLength = keyAgreement.generateSecret(pubData, offset,
length, pubData, secOffset);
// use only first 16 bytes?
// secLength = 16;
short keysOffset = (short) (secOffset + secLength);
deriveKey(pubData, secOffset, secLength, MAC_MODE, keysOffset);
short macKeyOffset = keysOffset;
keysOffset += PassportApplet.KEY_LENGTH;
deriveKey(pubData, secOffset, secLength, ENC_MODE, keysOffset);
short encKeyOffset = keysOffset;
Util.arrayCopyNonAtomic(pubData, macKeyOffset, keyStore.tmpKeys,
(short) 0, PassportApplet.KEY_LENGTH);
Util.arrayCopyNonAtomic(pubData, encKeyOffset, keyStore.tmpKeys,
PassportApplet.KEY_LENGTH, PassportApplet.KEY_LENGTH);
// The secure messaging keys should be replaced with the freshly
// computed ones
// just after the current APDU is completely processed.
eacChangeKeys[0] = true;
return true;
} catch (Exception e) {
eacChangeKeys[0] = false;
return false;
}
}
boolean eacVerifySignature(RSAPublicKey key, byte[] rnd,
byte[] docNr, byte[] buffer, short offset, short length) {
short x_offset = (short)(offset+length);
keyStore.ecPublicKey.getW(buffer, x_offset++);
rsaSig.init(key, Signature.MODE_VERIFY);
rsaSig.update(docNr, (short) 0, (short) docNr.length);
rsaSig.update(rnd, (short) 0, PassportApplet.RND_LENGTH);
return rsaSig.verify(buffer, x_offset, EC_X_LENGTH, buffer, offset, length);
}
}
/*
* passportapplet - A reference implementation of the MRTD standards.
*
* Copyright (C) 2006 SoS group, Radboud University
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* $Id$
*/
package josh.passport;
import javacard.framework.ISOException;
import javacard.framework.Util;
/*******************************************************************************
* Contains methods to initialize a fresh passport.
*
* @author Cees-Bart Breunesse ([email protected])
* @author Engelbert Hubbers ([email protected])
* @author Martijn Oostdijk ([email protected])
*
*/
public class PassportInit {
private PassportCrypto crypto;
private static byte[] weights = { 7, 3, 1 };
PassportInit(PassportCrypto crypto) {
this.crypto = crypto;
}
/**
* Looks up the numerical value for MRZ characters. In order to be able to
* compute check digits.
*
* @param ch
* a character from the MRZ.
* @return the numerical value of the character.
*/
private static byte decodeMRZDigit(byte ch) {
switch (ch) {
case '<':
case '0':
return 0;
case '1':
return 1;
case '2':
return 2;
case '3':
return 3;
case '4':
return 4;
case '5':
return 5;
case '6':
return 6;
case '7':
return 7;
case '8':
return 8;
case '9':
return 9;
case 'a':
case 'A':
return 10;
case 'b':
case 'B':
return 11;
case 'c':
case 'C':
return 12;
case 'd':
case 'D':
return 13;
case 'e':
case 'E':
return 14;
case 'f':
case 'F':
return 15;
case 'g':
case 'G':
return 16;
case 'h':
case 'H':
return 17;
case 'i':
case 'I':
return 18;
case 'j':
case 'J':
return 19;
case 'k':
case 'K':
return 20;
case 'l':
case 'L':
return 21;
case 'm':
case 'M':
return 22;
case 'n':
case 'N':
return 23;
case 'o':
case 'O':
return 24;
case 'p':
case 'P':
return 25;
case 'q':
case 'Q':
return 26;
case 'r':
case 'R':
return 27;
case 's':
case 'S':
return 28;
case 't':
case 'T':
return 29;
case 'u':
case 'U':
return 30;
case 'v':
case 'V':
return 31;
case 'w':
case 'W':
return 32;
case 'x':
case 'X':
return 33;
case 'y':
case 'Y':
return 34;
case 'z':
case 'Z':
return 35;
default:
throw new ISOException((short) 0x6d04);
}
}
/**
* Computes the 7-3-1 check digit for part of the MRZ.
*
* @param chars
* a part of the MRZ.
* @return the resulting check digit.
*/
static byte checkDigit(byte[] chars, short offset, short length) {
byte result = 0;
for (short i = 0; i < length; i++) {
result = (byte) ((short) ((result + weights[i % 3]
* decodeMRZDigit(chars[(short) (offset + i)]))) % 10);
}
return (byte) (result + 0x30); // return as character
}
public static short DOCNR_LEN = 9;
public static short DOB_LEN = 6;
public static short DOE_LEN = 6;
/**
* Computes the static key seed, based on information from the MRZ.
*
* @param buffer
* containing docNr || dateOfBirth || dateOfExpiry
* @param offset
* pointing to docNr
* @returns offset in buffer pointing to keySeed.
*/
public short computeKeySeed(
byte[] buffer,
short docNr_p,
short docNr_length,
short dateOfBirth_p,
short dateOfBirth_length,
short dateOfExpiry_p,
short dateOfExpiry_length) {
// sanity check: data is ordered
if(!((docNr_p < dateOfBirth_p) & (dateOfBirth_p < dateOfExpiry_p))) {
ISOException.throwIt((short)0x6d66);
}
// sanity check: no overlap
if(((short)(docNr_p + docNr_length) > dateOfBirth_p) ||
((short)(dateOfBirth_p + dateOfBirth_length) > dateOfExpiry_p)) {
ISOException.throwIt((short)0x6d66);
}
short buffer_p = 0;
Util.arrayCopyNonAtomic(buffer, docNr_p, buffer, buffer_p, docNr_length);
short offset = buffer_p;
buffer_p += docNr_length;
buffer[buffer_p] = checkDigit(buffer, offset, docNr_length);
buffer_p++;
Util.arrayCopyNonAtomic(buffer, dateOfBirth_p, buffer, buffer_p, dateOfBirth_length);
offset = buffer_p;
buffer_p += dateOfBirth_length;
buffer[buffer_p] = checkDigit(buffer, offset, dateOfBirth_length);
buffer_p++;
Util.arrayCopyNonAtomic(buffer, dateOfExpiry_p, buffer, buffer_p, dateOfExpiry_length);
offset = buffer_p;
buffer_p += dateOfExpiry_length;
buffer[buffer_p] = checkDigit(buffer, offset, dateOfExpiry_length);
buffer_p++;
crypto.createHash(buffer,
(short)0,
buffer_p,
buffer,
(short)0);
return 0;
}
/**
* Computes the static key seed, based on information from the MRZ.
*
* @param buffer
* containing docNr || dateOfBirth || dateOfExpiry
* @param offset
* pointing to docNr
* @returns offset in buffer pointing to keySeed.
*/
public short computeKeySeed(byte[] buffer, short offset) {
// sanity checks (80 for hash, 3 for checkdigits)
if (buffer.length < (short) (offset + DOCNR_LEN + DOB_LEN + DOE_LEN
+ 80 + 3)) {
ISOException.throwIt((short) 0x6d66);
}
short start_offset = offset;
// offset must initially point to docNr
offset += DOCNR_LEN;
short len = (short) (DOB_LEN + DOE_LEN);
// make room for checkdigit after docNr
Util.arrayCopyNonAtomic(buffer, offset, buffer, (short) (offset + 1), len);
buffer[offset] = checkDigit(buffer,
(short) (offset - DOCNR_LEN),
DOCNR_LEN);
offset += (short) (1 + DOB_LEN);
len -= DOB_LEN;
// make room for checkdigit after dateOfBirth
Util.arrayCopyNonAtomic(buffer, offset, buffer, (short) (offset + 1), len);
buffer[offset] = checkDigit(buffer, (short) (offset - DOB_LEN), DOB_LEN);
offset += (short) (1 + DOE_LEN);
buffer[offset] = checkDigit(buffer, (short) (offset - DOE_LEN), DOE_LEN);
offset++;
crypto.createHash(buffer,
start_offset,
(short) (offset - start_offset),
buffer,
offset);
return offset;
}
}
/*
* passportapplet - A reference implementation of the MRTD standards.
*
* Copyright (C) 2006 SoS group, Radboud University
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* $Id$
*/
package josh.passport;
import javacard.framework.ISO7816;
/**
* Generic helpers for the Passport.
*
* Contains some commented debug code.
*
* @author Cees-Bart Breunese ([email protected])
*
*/
public class PassportUtil implements ISO7816 {
/**
* Counts the number of set bits in a byte
*
* @param b byte to be counted
* @return 0 when number of bits in b is even
*/
public static byte evenBits(byte b) {
short count = 0;
for (short i = 0; i < 8; i++) {
count += (b >>> i) & 0x1;
}
return (byte) (count % 2);
}
/**
* Calculates the xor of byte arrays in1 and in2 into out.
*
* Arrays may be the same, but regions may not overlap.
*
*
* @param in1 input array
* @param in1_o offset of input array
* @param in2 input array
* @param in2_o offset of inputarray
* @param out output array
* @param out_o offset of output array
* @param len length of xor
*/
public static void xor(byte[] in1, short in1_o, byte[] in2,
short in2_o, byte[] out, short out_o, short len) {
for(short s=0; s < len; s++) {
out[(short)(out_o + s)] = (byte)(in1[(short)(in1_o + s)] ^ in2[(short)(in2_o + s)]);
}
}
/**
* Swaps two non-overlapping segments of the same length in the same byte array
* in place.
*
* @param buffer a byte array
* @param offset1 offset to first byte array
* @param offset2 offset to the second byte array
* @param len length of the segments
*/
public static void swap(byte[] buffer, short offset1, short offset2, short len) {
byte byte1, byte2;
for(short i=0; i<len; i++) {
byte1 = buffer[(short)(offset1 + i)];
byte2 = buffer[(short)(offset2 + i)];
buffer[(short)(offset1 + i)] = byte2;
buffer[(short)(offset2 + i)] = byte1;
}
}
/**
* Returns the sign bit of a short as a short.
* @param a a short value
* @return the sign bit of a as a short
*/
public static short sign(short a) {
return (byte)((a >>> (short)15) & 1);
}
/**
* Returns the smallest unsigned short argument.
*
* @param a a short
* @param b another short
* @return smallest unsigned value a or b.
*/
public static short min(short a, short b) {
if(sign(a) == sign(b))
return (a < b ? a : b);
else if(sign(a) == 1)
return b;
else
return a;
}
// public static void throwShort(short s) {
// ISOException.throwIt((short)(0x6d00 | (s & 0xff)));
// }
//
// public static void returnDESKey(DESKey k, APDU apdu) {
// byte[] b = new byte[(short)(k.getSize()/8)];
//
// k.getKey(b, (short) 0);
// returnBuffer(b, apdu);
// }
/***
* Pads an input buffer with max 8 and min 1 byte padding (0x80 followed by optional zeros)
* relative to the offset and length given. Always pad with at least a 0x80 byte.
*
* See 6.2.3.1 in ISO7816-4
*
* @param buffer array to pad
* @param offset to data
* @param length of data
* @return new length, with padding, of data
*
*/
public static short pad(byte[] buffer, short offset, short len) {
short padbytes = (short)(lengthWithPadding(len) - len);
for(short i=0; i<padbytes; i++) {
buffer[(short)(offset+len+i)] = (i == 0 ? (byte)0x80 : 0x00);
}
return (short)(len + padbytes);
}
public static short lengthWithPadding(short inputLength) {
return (short)((((short)(inputLength + 8)) / 8) * 8);
}
// public static void pad(APDU aapdu, short pad_len) {
// byte[] apdu = aapdu.getBuffer();
// short apdu_len=0;
// short lc = (short)(apdu[ISO7816.OFFSET_LC] & 0xff);
// try {
// apdu_len = (short)(ISO7816.OFFSET_CDATA + lc);
// } catch(NullPointerException e) {
// ISOException.throwIt((short)0x6d66);
// }
//
// if(apdu_len < apdu.length)
// if(pad_len < CREFPassportCrypto.PAD_DATA.length)
// Util.arrayCopy(CREFPassportCrypto.PAD_DATA, (short)0, apdu,
// apdu_len,
// pad_len);
// }
// public static void returnBuffer(byte[] b, APDU apdu) {
// returnBuffer(b, (short)b.length, apdu);
// }
//
// public static void returnBuffer(byte[] b, short length, APDU apdu) {
// returnBuffer(b, (short)0, length, apdu);
// }
// public static void returnBuffer(byte[] b, short offset, short length, APDU aapdu) {
// byte[] apdu = aapdu.getBuffer();
// short le = aapdu.setOutgoing(); //(short)(apdu[(short)(apdu.length-2)] & 0xff);
//
// if (le >= b.length) {
// aapdu.setOutgoingLength(le);
// if(le > b.length) {
// pad(aapdu, (short)(le - (short)b.length));
// }
// }
// else
// {
// ISOException.throwIt(SW_WRONG_LENGTH);
// }
//
// aapdu.setOutgoingLength(length);
// Util.arrayCopy(b, offset, apdu, (short)0, (short) length);
// aapdu.sendBytes((short) 0,length);
//
// }
// public static void returnByte(byte b, APDU apdu) {
// byte[] buffer = apdu.getBuffer();
// short le = apdu.setOutgoing();
// if (le != 1) {
// ISOException.throwIt(SW_WRONG_LENGTH);
// }
//
// apdu.setOutgoingLength((short) 1);
// buffer[0] = b;
// apdu.sendBytes((short) 0, (short) 1);
// }
/***
* Computes the actual length of a data block as byte value, without the padding.
*
* @param apdu containing data
* @param offset to data
* @param length of data
* @return new length of data, without padding
*/
public static byte calcLcFromPaddedData(byte[] apdu, short offset, short length) {
for(short i=(short)(length - 1) ; i>=0; i--)
if(apdu[(short)(offset + i)] != 0)
if((apdu[(short)(offset + i)] & 0xff)!= 0x80)
// not padded
return (byte)(length & 0xff);
else
return (byte)(i & 0xff);
return 0;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment