Question

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.

Was it helpful?

Solution

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);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top