Reputation: 23
I'm beginner in JCard programming (2 days experience ...) and I'm trying to deploy an app on a CREF emulated card that generates an RSA KeyPair and sends the public key over to the host RMI Client application, somehow when I launch the init method from the client app I get this exception:
Exception in thread "main" java.lang.UnsatisfiedLinkError:
com.sun.javacard.impl.NativeMethods.getCurrentContext()B
at com.sun.javacard.impl.NativeMethods.getCurrentContext(Native Method)
at com.sun.javacard.impl.PrivAccess.getCurrentAppID(PrivAccess.java:454)
at javacard.framework.CardRuntimeException.<init>(CardRuntimeException.java:46)
at javacard.security.CryptoException.<init>(DashoA10*..:25)
at com.sun.javacard.javax.smartcard.rmiclient.CardObjectFactory.throwIt(Unknown Source)
at com.sun.javacard.javax.smartcard.rmiclient.CardObjectFactory.throwException(Unknown Source)
at com.sun.javacard.javax.smartcard.rmiclient.CardObjectFactory.getObject(Unknown Source)
at com.sun.javacard.rmiclientlib.JCRemoteRefImpl.parseAPDU(Unknown Source)
at com.sun.javacard.rmiclientlib.JCRemoteRefImpl.invoke(Unknown Source)
at sid2.CompteurImpl_Stub.initialiser(Unknown Source)
at sid2.ClientRmi.main(ClientRmi.java:36)
and here is the code from my JCard applet being called:
package sid2;
import java.rmi.RemoteException;
import javacard.framework.UserException;
import javacard.framework.service.CardRemoteObject;
import javacard.security.*;
import javacardx.crypto.Cipher;
public class CompteurImpl extends CardRemoteObject implements ICompteur {
private byte compteur = 120;
RSAPrivateKey rsa_PrivateKey;
RSAPublicKey rsa_PublicKey;
KeyPair rsa_KeyPair;
Cipher cipherRSA;
public void setPub(byte[] expo, byte[] mod) {
rsa_PublicKey.setExponent(expo, (short) 0, (short) expo.length);
rsa_PublicKey.setModulus(mod, (short) 0, (short) mod.length);
}
public byte[] getPub() {
byte[] ret = null;
rsa_PublicKey.getModulus(ret, (short) 0);
rsa_PublicKey.getExponent(ret, (short) (ret.length + 1));
return ret;
}
public void initialiser(byte v) throws RemoteException, UserException {
rsa_KeyPair = new KeyPair(KeyPair.ALG_RSA, KeyBuilder.LENGTH_RSA_2048);
rsa_KeyPair.genKeyPair();
rsa_PublicKey = (RSAPublicKey) rsa_KeyPair.getPublic();
rsa_PrivateKey = (RSAPrivateKey) rsa_KeyPair.getPrivate();
compteur = v;
}
}
Can anyone point out what I'm doing wrong here?
PS: I already tried basic stuff and it worked just fine, like having a variable on a Jcard and incrementing it, getting it and setting it.
Upvotes: 0
Views: 847
Reputation: 40831
According to the JCDK User's Guide (for JC 2.2.2) the CREF (C-language RE) implementation supports the following alogirthms:
- 112-, 128-, 160-, 192-bit ECC
- 512-bit RSA
Therefore, the line
rsa_KeyPair = new KeyPair(KeyPair.ALG_RSA, KeyBuilder.LENGTH_RSA_2048);
should throw a CryptoException.NO_SUCH_ALGORITHM
when executed in CREF (as CREF does not support 2048-bit RSA).
Besides that error, that is likely the cause of the exception that you get, your code has at least one more issue:
byte[] ret = null;
rsa_PublicKey.getModulus(ret, (short) 0);
rsa_PublicKey.getExponent(ret, (short) (ret.length + 1));
Here you initialize the buffer ret
to null
but then you try to fill the modulus and exponent into the buffer. These two methods (getModulus()
and getExponent()
) don't create that buffer for you. Instead you need to create a buffer of appropriate size first:
byte[] buffer = new byte[expected_length]; // Note that you certainly do not want to allocate that buffer within your getPub method!
And then you can fill the modulus and exponent into that buffer:
byte modLen = rsa_PublicKey.getModulus(buffer, (short) 0);
byte expLen = rsa_PublicKey.getExponent(buffer, (short) modLen);
Upvotes: 2