2323import javacard .framework .ISO7816 ;
2424import javacard .framework .ISOException ;
2525import javacard .framework .APDU ;
26+ import javacard .framework .SystemException ;
27+ import javacard .framework .TransactionException ;
2628import javacard .framework .JCSystem ;
2729import javacard .framework .Util ;
2830import javacard .framework .OwnerPIN ;
@@ -61,6 +63,11 @@ public class IsoApplet extends Applet implements ExtendedLength {
6163 /* Card-specific configuration */
6264 public static final boolean DEF_PRIVATE_KEY_IMPORT_ALLOWED = false ;
6365
66+ /* Certain cards (J3H081) break in unexpected ways testing these at
67+ * runtime. Allow them to be forced off so no test is run. */
68+ public static final boolean DEF_TEST_RSA_4096 = true ;
69+ public static final boolean DEF_TEST_RSA_PSS = true ;
70+
6471 /* ISO constants not in the "ISO7816" interface */
6572 // File system related INS:
6673 public static final byte INS_CREATE_FILE = (byte ) 0xE0 ;
@@ -138,12 +145,6 @@ public class IsoApplet extends Applet implements ExtendedLength {
138145 private Key [] keys = null ;
139146 private byte [] ram_buf = null ;
140147 private Cipher rsaPkcs1Cipher = null ;
141- private Signature ecdsaSignature = null ;
142- private Signature rsaSha1PssSignature = null ;
143- private Signature rsaSha224PssSignature = null ;
144- private Signature rsaSha256PssSignature = null ;
145- private Signature rsaSha384PssSignature = null ;
146- private Signature rsaSha512PssSignature = null ;
147148 private RandomData randomData = null ;
148149 private byte api_features ;
149150
@@ -179,54 +180,60 @@ protected IsoApplet() {
179180
180181 // API features: probe card support for ECDSA
181182 try {
182- ecdsaSignature = Signature .getInstance (MessageDigest .ALG_NULL , Signature .SIG_CIPHER_ECDSA , Cipher .PAD_NULL , false );
183+ Signature .getInstance (MessageDigest .ALG_NULL , Signature .SIG_CIPHER_ECDSA , Cipher .PAD_NULL , false );
183184 api_features |= API_FEATURE_ECC ;
184185 } catch (CryptoException e ) {
185186 if (e .getReason () == CryptoException .NO_SUCH_ALGORITHM ) {
186187 /* Few Java Cards do not support ECDSA at all.
187188 * We should not throw an exception in this cases
188189 * as this would prevent installation. */
189- ecdsaSignature = null ;
190190 api_features &= ~API_FEATURE_ECC ;
191191 } else {
192192 throw e ;
193193 }
194194 }
195195
196196 // API features: probe card support for 4096 bit RSA keys
197- try {
198- RSAPrivateCrtKey testKey = (RSAPrivateCrtKey )KeyBuilder .buildKey (KeyBuilder .TYPE_RSA_CRT_PRIVATE , KeyBuilder .LENGTH_RSA_4096 , false );
199- api_features |= API_FEATURE_RSA_4096 ;
200- } catch (CryptoException e ) {
201- if (e .getReason () == CryptoException .NO_SUCH_ALGORITHM ) {
202- api_features &= ~API_FEATURE_RSA_4096 ;
203- } else {
204- throw e ;
197+ if (DEF_TEST_RSA_4096 ) {
198+ try {
199+ RSAPrivateCrtKey testKey = (RSAPrivateCrtKey )KeyBuilder .buildKey (KeyBuilder .TYPE_RSA_CRT_PRIVATE , KeyBuilder .LENGTH_RSA_4096 , false );
200+ api_features |= API_FEATURE_RSA_4096 ;
201+ } catch (CryptoException e ) {
202+ if (e .getReason () == CryptoException .NO_SUCH_ALGORITHM ) {
203+ api_features &= ~API_FEATURE_RSA_4096 ;
204+ } else {
205+ throw e ;
206+ }
207+ } catch (TransactionException e ) {
208+ // J3H081 from javacardsdk.com (FUTAKO) raises this exception instead.
209+ if (e .getReason () == TransactionException .INTERNAL_FAILURE ) {
210+ api_features &= ~API_FEATURE_RSA_4096 ;
211+ } else {
212+ throw e ;
213+ }
205214 }
206215 }
207216
217+
208218 /* API features: probe card support for RSA and PSS padding with SHA-1 and all SHA-2 algorithms
209219 * to be used with Signature.signPreComputedHash() */
210- try {
211- rsaSha1PssSignature = Signature .getInstance (Signature .ALG_RSA_SHA_PKCS1_PSS , false );
212- rsaSha224PssSignature = Signature .getInstance (Signature .ALG_RSA_SHA_224_PKCS1_PSS , false );
213- rsaSha256PssSignature = Signature .getInstance (Signature .ALG_RSA_SHA_256_PKCS1_PSS , false );
214- rsaSha384PssSignature = Signature .getInstance (Signature .ALG_RSA_SHA_384_PKCS1_PSS , false );
215- rsaSha512PssSignature = Signature .getInstance (Signature .ALG_RSA_SHA_512_PKCS1_PSS , false );
216- api_features |= API_FEATURE_RSA_PSS ;
217- } catch (CryptoException e ) {
218- if (e .getReason () == CryptoException .NO_SUCH_ALGORITHM ) {
219- /* Certain Java Cards do not support this algorithm.
220- * We should not throw an exception in this cases
221- * as this would prevent installation. */
222- rsaSha1PssSignature = null ;
223- rsaSha224PssSignature = null ;
224- rsaSha384PssSignature = null ;
225- rsaSha256PssSignature = null ;
226- rsaSha512PssSignature = null ;
227- api_features &= ~API_FEATURE_RSA_PSS ;
228- } else {
229- throw e ;
220+ if (DEF_TEST_RSA_PSS ) {
221+ try {
222+ Signature .getInstance (Signature .ALG_RSA_SHA_PKCS1_PSS , false );
223+ Signature .getInstance (Signature .ALG_RSA_SHA_224_PKCS1_PSS , false );
224+ Signature .getInstance (Signature .ALG_RSA_SHA_256_PKCS1_PSS , false );
225+ Signature .getInstance (Signature .ALG_RSA_SHA_384_PKCS1_PSS , false );
226+ Signature .getInstance (Signature .ALG_RSA_SHA_512_PKCS1_PSS , false );
227+ api_features |= API_FEATURE_RSA_PSS ;
228+ } catch (CryptoException e ) {
229+ if (e .getReason () == CryptoException .NO_SUCH_ALGORITHM ) {
230+ /* Certain Java Cards do not support this algorithm.
231+ * We should not throw an exception in this cases
232+ * as this would prevent installation. */
233+ api_features &= ~API_FEATURE_RSA_PSS ;
234+ } else {
235+ throw e ;
236+ }
230237 }
231238 }
232239
@@ -1101,7 +1108,7 @@ public void processManageSecurityEnvironment(APDU apdu) throws ISOException {
11011108 if (privKeyRef < 0 ) {
11021109 ISOException .throwIt (ISO7816 .SW_DATA_INVALID );
11031110 }
1104- if (algRef == ALG_GEN_EC && ecdsaSignature == null ) {
1111+ if (algRef == ALG_GEN_EC && ( api_features & API_FEATURE_ECC ) == 0 ) {
11051112 // There are cards that do not support ECDSA at all.
11061113 ISOException .throwIt (ISO7816 .SW_FUNC_NOT_SUPPORTED );
11071114 }
@@ -1129,7 +1136,7 @@ public void processManageSecurityEnvironment(APDU apdu) throws ISOException {
11291136 if (keys [privKeyRef ].getType () != KeyBuilder .TYPE_EC_FP_PRIVATE ) {
11301137 ISOException .throwIt (ISO7816 .SW_DATA_INVALID );
11311138 }
1132- if (ecdsaSignature == null ) {
1139+ if (( api_features & API_FEATURE_ECC ) == 0 ) {
11331140 ISOException .throwIt (ISO7816 .SW_FUNC_NOT_SUPPORTED );
11341141 }
11351142
@@ -1297,24 +1304,27 @@ private void computeDigitalSignature(APDU apdu) throws ISOException {
12971304 } else if (currentAlgorithmRef [0 ] == ALG_RSA_PAD_PSS ) {
12981305 // ALG_RSA_PAD_PSS with pre-computed hash.
12991306 // Determine Signature object by hash length.
1307+ Signature obj = null ;
13001308 if (lc == (short ) 20 ) {
1301- rsaSha1PssSignature .init (rsaKey , Signature .MODE_SIGN );
1302- sigLen = rsaSha1PssSignature .signPreComputedHash (ram_buf , (short )0 , lc , ram_buf , lc );
1309+ obj = Signature .getInstance (Signature .ALG_RSA_SHA_PKCS1_PSS , false );
13031310 } else if (lc == (short ) 28 ) {
1304- rsaSha224PssSignature .init (rsaKey , Signature .MODE_SIGN );
1305- sigLen = rsaSha224PssSignature .signPreComputedHash (ram_buf , (short )0 , lc , ram_buf , lc );
1311+ obj = Signature .getInstance (Signature .ALG_RSA_SHA_224_PKCS1_PSS , false );
13061312 } else if (lc == (short ) 32 ) {
1307- rsaSha256PssSignature .init (rsaKey , Signature .MODE_SIGN );
1308- sigLen = rsaSha256PssSignature .signPreComputedHash (ram_buf , (short )0 , lc , ram_buf , lc );
1313+ obj = Signature .getInstance (Signature .ALG_RSA_SHA_256_PKCS1_PSS , false );
13091314 } else if (lc == (short ) 48 ) {
1310- rsaSha384PssSignature .init (rsaKey , Signature .MODE_SIGN );
1311- sigLen = rsaSha384PssSignature .signPreComputedHash (ram_buf , (short )0 , lc , ram_buf , lc );
1315+ obj = Signature .getInstance (Signature .ALG_RSA_SHA_384_PKCS1_PSS , false );
13121316 } else if (lc == (short ) 64 ) {
1313- rsaSha512PssSignature .init (rsaKey , Signature .MODE_SIGN );
1314- sigLen = rsaSha512PssSignature .signPreComputedHash (ram_buf , (short )0 , lc , ram_buf , lc );
1317+ obj = Signature .getInstance (Signature .ALG_RSA_SHA_512_PKCS1_PSS , false );
13151318 } else {
13161319 ISOException .throwIt (ISO7816 .SW_WRONG_LENGTH );
13171320 }
1321+
1322+ obj .init (rsaKey , Signature .MODE_SIGN );
1323+ sigLen = obj .signPreComputedHash (ram_buf , (short )0 , lc , ram_buf , lc );
1324+
1325+ if (JCSystem .isObjectDeletionSupported ()) {
1326+ JCSystem .requestObjectDeletion ();
1327+ }
13181328 } else {
13191329 ISOException .throwIt (ISO7816 .SW_FUNC_NOT_SUPPORTED );
13201330 }
@@ -1331,8 +1341,12 @@ private void computeDigitalSignature(APDU apdu) throws ISOException {
13311341 // Get the key - it must be a EC private key,
13321342 // checks have been done in MANAGE SECURITY ENVIRONMENT.
13331343 ECPrivateKey ecKey = (ECPrivateKey ) keys [currentPrivateKeyRef [0 ]];
1344+ Signature ecdsaSignature = Signature .getInstance (MessageDigest .ALG_NULL , Signature .SIG_CIPHER_ECDSA , Cipher .PAD_NULL , false );
13341345 ecdsaSignature .init (ecKey , Signature .MODE_SIGN );
13351346 sigLen = ecdsaSignature .sign (ram_buf , (short )0 , lc , apdu .getBuffer (), (short )0 );
1347+ if (JCSystem .isObjectDeletionSupported ()) {
1348+ JCSystem .requestObjectDeletion ();
1349+ }
13361350 apdu .setOutgoingAndSend ((short ) 0 , sigLen );
13371351 break ;
13381352
0 commit comments