Sorry about the red box, but we really need you to update your browser. Read this excellent article if you're wondering why we are no longer supporting this browser version. Go to Browse Happy for browser suggestions and how to update.

Creating a cryptographic smart card driver

To create a cryptographic smart card driver for BlackBerry Device Software version 4.1 or later, you have to extend two classes. One class, CryptoSmartCard, represents a type of smart card. The other class, CryptoSmartCardSession, represents a communications session with a smart card of that type.

Create a smart card driver project

Smart card drivers are library applications. Follow these steps to create a library application project.

On the File menu, click New > Project.

Expand the BlackBerry® folder and select BlackBerry Project.

Click Next.

In the Project name field, type a name for the project.

Select Create new project in workspace.

Complete one of the following tasks:

  • To specify a specific JRE, select Use a project specific JRE.
  • To specify the default JRE in the workspace, select Use default JRE.

Click Next.

Click Finish.

In the Package Explorer view, right-click a BlackBerry application project and click Properties.

In the Properties for pane, click BlackBerry Project.

Click Application Descriptor.

Click the Application tab.

In the Application type field, select Library.

Check the Auto-run on startup check box.

In the Startup tier field, select 7.

On the Eclipse toolbar, click Save.

CryptoSmartCard methods you implement to create a driver

Table 1. Methods you must implement for a smart card driver

Method to implement

Description

SmartCard.openSessionImpl(SmartCardReaderSession)

Opens a cryptographic session with a smart card.

SmartCard.checkAnswerToResetImpl(AnswerToReset)

Verifies if a smart card is compatible with a specific Answer To Reset (ATR) sequence.

SmartCard.getCapabilitiesImpl()

Returns an instance of the SmartCardCapabilities class that enumerates the capabilities of the smart card.

SmartCard.displaySettingsImpl(Object)

Enables a smart card driver to display settings or properties.

SmartCard.isDisplaySettingsAvailableImpl(Object)

Enables a smart card driver to indicate support for display settings.

SmartCard.getCapabilitiesImpl()

Retrieves the capabilities of a smart card. The capabilites of a smart card include the protocols the card supports, the baud rate, and the clock adjustment factors.

SmartCard.getLabelImpl()

Retrieves the smart card type.

CryptoSmartCard.getAlgorithms()

Retrieves the names of the algorithms that the smart card supports, for example (“RSA”, “DSA”).

CryptoSmartCard.getCryptoToken(String)

Retrieves a CryptoToken object that supports the given algorithm.

SmartCard.getLabelImpl()

Returns a label associated with the kind of smart card.

Implement a class to represent a type of smart card

Import the required crypto and smartcard libraries.

Extend the CryptoSmartCard class.

Implement a libMain() method that calls SmartCardFactory.addSmartCard()

Implement the required CryptoSmartCard methods.

CryptoSmartCardSession methods you implement to create a driver

Table 2. Methods that you must implement for any smart card driver.

CryptoSmartCardSession methods

Description

SmartCardSession.closeImpl()

Closes a cryptographic smart card session.

SmartCardSession.getMaxLoginAttemptsImpl()

Retrieves the maximum number of login attempts.

SmartCardSession.getRemainingLoginAttemptsImpl()

Retrieves the remaining number of login attempts.

SmartCardSession.getSmartCardIDImpl()

Retrieves the ID for the smart card.

SmartCardSession.loginImpl(String)

Attempts to log in to the cryptographic session using a given password string.

CryptoSmartCardSession.getKeyStoreDataArrayImpl()

Retrieves certificates from the smart card.

CryptoSmartCardSession.getRandomBytesImpl(int maxNumBytes)

Retrieves random data from the internal random number generator of the smart card.

Table 3. Additional methods that you must implement for smart card drivers that support retrieving fingerprint data from smart cards.

Method to implement

Description

CryptoSmartCardSession.getFingerprintsImpl(int context)

Extend this method to provide support for extracting fingerprint sample data from a smart card. The data must be returned in a FingerprintBiometricData[]. The context parameter indicates why the fingerprints are being requested. In BlackBerry Java Development Environment 5.0, only FINGERPRINT_CONTEXT_AUTHENTICATION is used.

Implement a class to enable a communication session with a smart card

Import the required crypto and smartcard libraries.

Extend the abstract CryptoSmartCardSession class.

Implement CryptoSmartCardSession.getKeyStoreDataArrayImpl() according to the BlackBerry Device Software version of the target smartphone.

To create a cryptographic smart card driver that is compatible with BlackBerry Device Software version 4.2 or later, implement CryptoSmartCardSession.getKeyStoreDataArrayImpl() as follows:

RSACryptoToken token = new MyRSACryptoToken(); 
RSACryptoSystem cryptoSystem = new RSACryptoSystem(token, 1024); 
RSAPrivateKey privateKey; 
PrivateKey privateKey = new RSAPrivateKey(cryptoSystem, new MyCryptoTokenData());

To create a cryptographic smart card driver that is compatible with BlackBerry Device Software version 4.1 and version 4.2 or later, and to include the cryptographic smart card driver in two-factor authentication, implement the getKeyStoreDataArrayImp method as follows:

PrivateKey privateKey = CryptoSmartCardUtilities2.createPrivateKey(token, 1024, new MyCryptoTokenData());

Implement CryptoSmartCardSession.getKeyStoreDataArrayImpl()

Implement the other required CryptoSmartCardSession methods.

Verify installation of a cryptographic smart card driver

On the BlackBerry smartphone, click Options > Security Options > Smart Card.

Ensure the cryptographic smart card appears in the Registered Card Drivers section.

Code sample: List smart card drivers

import net.rim.device.api.smartcard.SmartCardFactory;
import net.rim.device.api.smartcard.SmartCard;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.container.MainScreen;

public class ListSmartCards extends UiApplication
{
    public static void main(String args[])
    {
        ListSmartCards app = new ListSmartCards();
        app.enterEventDispatcher();
    }
    
    public ListSmartCards()
    {
        HomeScreen hs = new HomeScreen();
        pushScreen(hs);
    }
}

class HomeScreen extends MainScreen
{
    public HomeScreen()
    {
    	int numCards = SmartCardFactory.getNumSmartCards();
        SmartCard[] smartCards = SmartCardFactory.getSmartCards();
        int len = smartCards.length;
        StringBuffer sbCards = new StringBuffer();
        for(int i=0;i<len;i++)
        {
            sbCards.append(smartCards[i].getLabel() + '\n');
        }
        LabelField msg = new LabelField("There are " + Integer.toString(numCards)
        + " smart card drivers installed on this smartphone:\n");
        LabelField msgCards = new LabelField(sbCards.toString());
        add(msg);
        add(msgCards);
     }
}

Code sample: Sign data using private key on smart card and verify on the smartphone

import java.util.Enumeration;
import net.rim.device.api.crypto.Crypto;
import net.rim.device.api.crypto.CryptoException;
import net.rim.device.api.crypto.NoSuchAlgorithmException;
import net.rim.device.api.crypto.PrivateKey;
import net.rim.device.api.crypto.RandomSource;
import net.rim.device.api.crypto.certificate.*;
import net.rim.device.api.crypto.keystore.*;
import net.rim.device.api.system.Application;

public class SignDataPrivate extends Application 
{
  public static void main(String[] args)
  {
    SignDataPrivate app = new SignDataPrivate();
    KeyStore keyStore;
    try 
    {
      keyStore = DeviceKeyStore.getInstance();
      KeyStoreData ksData = null;
      AssociatedDataKeyStoreIndex index = new AssociatedDataKeyStoreIndex(
      AssociatedData.SMART_CARD_KEY);
						keyStore.addIndex(index);
      Enumeration enumeration = keyStore.elements( index.getID() );
      while( enumeration.hasMoreElements() ) 
      {
        ksData = (KeyStoreData) enumeration.nextElement();
        Certificate certificate = ksData.getCertificate();
        if( ( certificate == null ) || !ksData.isPrivateKeySet())
        {
          continue;
        }
        if( !( certificate.queryKeyUsage( 
               KeyUsage.DIGITAL_SIGNATURE ) != KeyUsageResult.NOT_ALLOWED ) ) 
        {
          continue;
        }
      }
      
      byte [] randomData = new byte[ 64 ];
      RandomSource.getBytes( randomData );
      PrivateKey privateKey = ksData.getPrivateKey( null );
      byte [] signature = Crypto.sign(randomData,0,randomData.length,
                                      privateKey,null,"X509" );

      if(!Crypto.verify(randomData, 0, randomData.length, 
                        keyStoreData.getPublicKey(), "X509", signature, 0 )) 
      {
         return false;
      }
    } 
    catch (KeyStoreRegisterException e) 
    {
    } 
    catch( NoSuchAlgorithmException e ) 
    {
    }
    catch( CryptoException e ) 
    {
    }
    catch( IllegalArgumentException e ) 
    {
    }
  }
}

Code sample: Implementing a class to enable a communication session with a smart card


package com.rim.samples.device.smartcard;
import net.rim.device.api.crypto.*;
import net.rim.device.api.crypto.certificate.*;
import net.rim.device.api.crypto.certificate.x509.*;
import net.rim.device.api.crypto.keystore.*;
import net.rim.device.api.smartcard.*;
import net.rim.device.api.util.*;

/*******************************************************************************
* This class represents a communication session with a physical smart card.
*
* Application Protocol Data Units (APDUs) can be sent to the smart card over a
* session to provide the desired functionality.
* 
* Do not keep sessions open when you are not using them. They should be
* short-lived. As a security precaution, only one open session is allowed 
* per SmartCardReader.Subsequent openSession() requests will block until the 
* current session is closed.
*/

     public class MyCryptoSmartCardSession extends CryptoSmartCardSession
     {
     
        // We assume that the smart card has three certificates identified 
        // by: ID_PKI, SIGNING_PKI and ENCRYPION_PKI. Your smart card may have a
        // different number of certificates or be identified differently. These
        // three certificates are just an example of what might be stored on a
        // smart card.
        
     public static final byte ID_PKI             = (byte)0x00;
     public static final byte SIGNING_PKI        = (byte)0x01;
     public static final byte ENCRYPTION_PKI     = (byte)0x02;
     private static final String WAITING_MSG     = "Please Wait";
     private static final String ID_STRING       = "Jason Hood";
     private static final String ID_CERT         = "ID Certificate";
     private static final String SIGNING_CERT    = "Signing Certificate";
     private static final String ENCRYPTION_CERT = "Encryption Certificate";
     

     /**************************************************************************
     * Provide a constructor for the session.
     *
     * The smartCard argument is the smart card associated with this session.
     * The readerSession argument holds the reader session commands sent to this
     * smart card.
     ***************************************************************************/
     
     protected MyCryptoSmartCardSession(SmartCard smartCard, SmartCardReaderSession readerSession)
     {
          super( smartCard, readerSession );
     }
     
     /**************************************************************************
     * Provide a method to close the session.
     *
     * Do not close the underlying SmartCardReaderSession.Use this method to
     * clean up the session prior to its closure.
     ***************************************************************************
     /
     protected void closeImpl()
     {
        // Do any session cleanup needed here.
     }
     
     /**************************************************************************
     * Provide a method that returns the maximum number of allowed login 
     * attempts. Return Integer.MAX_VALUE to allow an infinite number of login
     * attempts.
     ***************************************************************************/
     
     protected int getMaxLoginAttemptsImpl() throws SmartCardException
     {
          return 5;
     }
     
     /**************************************************************************
     * Provide a method that returns the number of allowed login attempts
     * remaining (before the smart card will lock). Return Integer.MAX_VALUE if
     * the smart card will never lock.
     ***************************************************************************
     /
     protected int getRemainingLoginAttemptsImpl() throws SmartCardException
     {
          return 4;
     }
     
     /**************************************************************************
     * Provide a method that logs into the smart card with a specified password.
     * This method should not implement UI.
     ***************************************************************************/
     
     protected boolean loginImpl( String password ) throws SmartCardException
     {
        // Create the APDU command for your smart card. Consult documentation 
        // from your smartcard vendor.
        
          CommandAPDU command = 
           new CommandAPDU( (byte)0x00, (byte)0x20, (byte)0x00, (byte)0x00 );
          command.setLcData( password.getBytes() );
          ResponseAPDU response = new ResponseAPDU();
          sendAPDU( command, response );
     
        // Check for response codes specific to your smart card.
          if ( response.checkStatusWords( (byte)0x90, (byte)0x00 ) ) 
          {
               return true;
          }
          else if ( response.checkStatusWords( (byte)0x64, (byte)0xF8 ) ) 
          {
               throw new SmartCardLockedException();
          }
          else 
          {
             // Authentication failed
               return false;
          }
     }
     
     /**************************************************************************
     * Provide a method that returns an ID for the smart card associated with
     * this session.
     ***************************************************************************/
     protected SmartCardID getSmartCardIDImpl() throws SmartCardException
     {
          // Retrieve a unique ID from the card
          
          byte [] uniqueCardData = new byte[] 
          { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b };
     
          // Convert the byte array to a long
          
          SHA1Digest digest = new SHA1Digest();
          digest.update( uniqueCardData );
          long idLong = byteArrayToLong(Arrays.copy(digest.getDigest(), 0, 8));
     
          return new SmartCardID( idLong , ID_STRING, getSmartCard() );
     }


     /**************************************************************************
     * Private method to convert a byte array into a long integer. Note that the
     * return value should be interpretted as an unsigned value.
     * 
     * The method throws an IllegalArgumentException if the byte array contains
     * a number larger than 64 bits.
     * 
     * Note: If your smart card driver is only designed to work with BlackBerry
     * Version 4.2 or later, you can replace this method with a call to
     * CryptoByteArrayArithmetic.valueOf( byte [] ).
     **************************************************************************/
     
     private long byteArrayToLong( byte[] array )
     {
          if ( array == null ) 
          {
               throw new IllegalArgumentException();
          }
          // Remove the leading zeros from the specified byte array and return
          // a new byte array without them.
          
          int zeros = 0;
          for ( int i = 0; i < array.length && array[i] == 0; i++ )
          {
               zeros++;
          }
     
          if ( zeros != 0 ) 
          {
               array = Arrays.copy( array, zeros, array.length - zeros );
          }
          int length = array.length;
          
          if( length > 8 ) 
          {
               throw new IllegalArgumentException();
          }
          long n = 0;
          
          for( int i=0; i<length; i++ ) 
          {
               n <<= 8;
               n += array[i] & 0xff;
          }
          return n;
     }
     
     
     /**************************************************************************
     * Provide a method that returns random data from the smart cards internal
     * random number generator.
     ***************************************************************************/
     protected byte [] getRandomBytesImpl( int maxBytes ) throws SmartCardException
     {
          // Create the appropriate CommandAPDU for your smart card. See your
          // smart card vendor's documentation.
          
          CommandAPDU command = 
           new CommandAPDU((byte)0x00,(byte)0x4C,(byte)0x00,(byte)0x00,maxBytes);
          ResponseAPDU response = new ResponseAPDU();
          sendAPDU( command, response );
          
          // Check for response codes specific to your smart card
          
          if( response.checkStatusWords( (byte)0x90, (byte)0x00 ) ) 
          {
          // return the response code containing the random data
               return response.getData();
          }
          return null;
     }
     
     /**************************************************************************
     * Provide a method that returns certificates from the smart card.
     * Return an array containing copies of certificates on the card.
     ***************************************************************************/
     protected CryptoSmartCardKeyStoreData[] getKeyStoreDataArrayImpl() 
      throws SmartCardException, CryptoTokenException
     {
          try 
          {
               // Display a progress dialog because this operation may take a long
               // time.
               
               displayProgressDialog( WAITING_MSG, 4 );
               
               // Associate the certificates with a particular card.
               
               SmartCardID smartCardID = getSmartCardID();
               RSACryptoToken token = new MyRSACryptoToken();
               RSACryptoSystem cryptoSystem = new RSACryptoSystem( token, 1024 );
               RSAPrivateKey privateKey;
               CryptoSmartCardKeyStoreData[] keyStoreDataArray = new
                CryptoSmartCardKeyStoreData[ 3 ];
          
               // This encoding would be extracted from the card using a series of
               // APDU commands.
          
               Certificate certificate = null;
               
               // Extract the certificate encoding from the card.
          
               byte [] certificateEncoding = new byte[0];
               try 
               {
                    certificate = new X509Certificate( certificateEncoding );
               }
               catch( CertificateParsingException e )
               { 
                    // invalid X509 certificate 
               }
               }
          
               stepProgressDialog( 1 );
               privateKey = new RSAPrivateKey(cryptoSystem, 
                 new MyCryptoTokenData( smartCardID, ID_PKI ) );
               keyStoreDataArray[ 0 ] = 
               new CryptoSmartCardKeyStoreData( null, ID_CERT, privateKey, null, 
                 KeyStore.SECURITY_LEVEL_HIGH, certificate, null, null, 0 );
               
               stepProgressDialog( 1 );
               privateKey = new RSAPrivateKey( cryptoSystem,
                 new MyCryptoTokenData( smartCardID, SIGNING_PKI ) );
               keyStoreDataArray[ 1 ] = 
               new CryptoSmartCardKeyStoreData( null, SIGNING_CERT, privateKey,
                 null, KeyStore.SECURITY_LEVEL_HIGH, certificate, null, null, 0 );
               
               stepProgressDialog( 1 );
               privateKey = new RSAPrivateKey( cryptoSystem,
                new MyCryptoTokenData( smartCardID, ENCRYPTION_PKI ) );
               keyStoreDataArray[ 2 ] = new CryptoSmartCardKeyStoreData( null, 
                 ENCRYPTION_CERT, privateKey, null, 
                 KeyStore.SECURITY_LEVEL_HIGH, certificate, null, null, 0 );
               
               stepProgressDialog( 1 );
               
               // Sleep so the user sees the last step of the progress dialog
               // as it moves to 100%
               
               try 
               {
                    Thread.sleep( 250 );
               } 
               catch ( InterruptedException e ) 
               {
               }
               dismissProgressDialog();
               return keyStoreDataArray;
          } 
          catch ( CryptoUnsupportedOperationException e ) 
          {
          } 
          catch ( UnsupportedCryptoSystemException e ) 
          {
          } 
          catch ( CryptoTokenException e ) 
          {
          }
          throw new SmartCardException();
     }
     
     /**************************************************************************
     * Send some data to the smart card for signing or decryption.
     ***************************************************************************/
     /*package*/ void signDecrypt( RSACryptoSystem cryptoSystem, 
       MyCryptoTokenData privateKeyData,byte[] input, int inputOffset,
       byte[] output, int outputOffset ) throws SmartCardException
     {
     // Check for nulls
     if ( cryptoSystem == null || privateKeyData == null || input == null || output == null) {
     throw new IllegalArgumentException();
     }
     // Validate the input parameters
     int modulusLength = cryptoSystem.getModulusLength();
     if ( ( input.length < inputOffset + modulusLength ) || ( output.length < outputOffset + 
     modulusLength ) ) {
     throw new IllegalArgumentException();
     }
     // Construct the response Application Protocol Data Unit
     ResponseAPDU response = new ResponseAPDU();
     // Construct the command and set its information
     // Create a CommandAPDU which your smart card will understand
     CommandAPDU signAPDU = new CommandAPDU( (byte)0x80, (byte)0x56, (byte)0x00, 
     (byte)0x00, modulusLength );
     signAPDU.setLcData( input, inputOffset, input.length - inputOffset );
     // Send the command to the smart card
     sendAPDU( signAPDU, response );
     // Validate the status words of the response
     // Check for response codes specific to your smart card
     if ( response.checkStatusWords( (byte)0x90, (byte)0x00 ) ) {
     byte [] responseData = response.getData();
     System.arraycopy( responseData, 0, output, outputOffset, responseData.length );
     }
     else {
     throw new SmartCardException( “Invalid response code, sw1=” + Integer.toHexString( 
     response.getSW1() & 0xff ) + “ sw2=” + Integer.toHexString( response.getSW2() & 0xff ) );
     }
     }
}

Code sample: Implementing a class to represent a type of smart card

package com.rim.samples.device.smartcard;
import net.rim.device.api.smartcard.*;
import net.rim.device.api.util.*;
import net.rim.device.api.crypto.*;
import net.rim.device.api.ui.component.*;
import net.rim.device.api.system.*;

/*****************************************************************************
* This class represents a kind (or model or family) of physical smart card.
* There should only be one instance of this class in the system at a time. The
* instance is managed by the SmartCardFactory.
******************************************************************************/

public class MyCryptoSmartCard extends CryptoSmartCard implements Persistable
{
     private final static byte MY_ATR [] = { 
     (byte)0x3b, (byte)0x7d, (byte)0x11,
     (byte)0x00, (byte)0x00, (byte)0x00, 
     (byte)0x31, (byte)0x80, (byte)0x71, 
     (byte)0x8e, (byte)0x64, (byte)0x86, 
     (byte)0xd6, (byte)0x01, (byte)0x00,
     (byte)0x81, (byte)0x90, (byte)0x00 };

     private final static AnswerToReset _myATR    = new AnswerToReset( MY_ATR );
     private static final String LABEL            = "RIM Sample";
     private static final String DISPLAY_SETTINGS = "Show driver settings now";
     private static final String RSA              = "RSA";

     /*************************************************************************
     * The libMain() method is invoked when the BlackBerry device starts and 
     * registers this smart card driver with the smart card factory.
     *
     * Registering this smart card driver with the smart card factory
     * automatically registers the driver with the user authenticator framework
     * which allows the smart card to be used as a second factor of 
     * authentication for unlocking a BlackBerry smartphone.
     *
     * In the BlackBerry development environment, in the settings for the smart
     * card driver project, set the project type to Library and select the 
     * auto-run on startup' setting.
     **************************************************************************/
     
     public static void libMain( String args[] )
     {
          try
          {
               SmartCardFactory.addSmartCard( new MyCryptoSmartCard() );
          }
          catch(ControlledAccessException cae)
          {
           // Application control may not allow your driver to be used with the 
           // user authenticator framework, in which case it will throw a 
           // ControlledAccessException.
           // Your driver is registered with the smart card API framework and 
           //can still
           // be used for importing certificates and signing/decrypting messages.
          }
    }

     /********************************************************
     * Retrieve the session handler for this smart card.
     * Implementations of this method should not include any UI.
     *********************************************************/
     protected SmartCardSession openSessionImpl( SmartCardReaderSession readerSession ) 
      throws SmartCardException 
     {
          return new MyCryptoSmartCardSession( this, readerSession );
     }

     /**************************************************************************
     * Determine if the system should use this smart card object
     * to communicate with a physical smart card that has the given AnswerToReset.
     * The system invokes this method to determine which smart card driver 
     * implementation it should use to communicate with a physical smart card 
     * found in a BlackBerry Smart Card Reader.
     **************************************************************************/
     protected boolean checkAnswerToResetImpl( AnswerToReset atr )
     {
        /***********************************************************************
        * If this method returns false, the cryptographic smart card driver will
        * not be used to perform additional operations on a particular smart card.
        * This method should only return true if you support the specified ATR.
        * 
        * If this method returns true, but there is no support for the smart card
        * that corresponds to the ATR,other smart card drivers may stop working 
        * properly.
        *
        * The AnswerToReset argument contains the full ATR from the smart card.
        * Your implementation of this method may check the entire ATR or just 
        * parts of the ATR, as long as the driver supports the corresponding 
        * smart card.
        ************************************************************************/
        
          return _myATR.equals( atr );
     }

     /**************************************************************************
     * Retrieve the label associated with this smart card.
     * The string you return should not include the words "smart card", as the 
     * system uses this method to generate strings such as 
     * "Please insert your 'label' smart card".
     **************************************************************************/
     protected String getLabelImpl()
     {
         return LABEL;
     }

     /*******************************************
     * Retrieves this smart card’s capabilities
     *******************************************/
     protected SmartCardCapabilities getCapabilitiesImpl()
     {
          return new SmartCardCapabilities( SmartCardCapabilities.PROTOCOL_T0 );
     }

     /**********************************************************
     * Indicate whether this smart card can display its settings.
     **********************************************************/
     protected boolean isDisplaySettingsAvailableImpl( Object context )
     {
          return true;
     }

     /**************************************************************************
     * Display this smart card’s settings.
     * This method will be invoked from the smart card options screen when
     * the user selects the driver and chooses to view the settings of that 
     * driver.
     *
     * This method could be called from the event thread. The driver should not
     * block the event thread for long periods of time.
     *
     * The context parameter is reserved for possible future use.
     **************************************************************************/
     protected void displaySettingsImpl( Object context )
     {
          Dialog.alert( DISPLAY_SETTINGS );
     }

     /**********************************************************
     * Retrieve the algorithms supported by this smart card.
     * You must return one or more of “RSA”, “DSA”, or “ECC”.
     **********************************************************/
     public String[] getAlgorithms()
     {
          return new String [] { "RSA" };
     }

     /*********************************************************************
     * Retrieve a crypto token that supports the given algorithm.
     * The argument algorithm is the name of the algorithm.
     * Return the Crypto token supporting the named algorithm.
     *
     * Throw NoSuchAlgorithmException if the specified algorithm is invalid.
     * Throw CryptoTokenException if there is a token-related problem.
      **********************************************************************/
    public CryptoToken getCryptoToken( String algorithm ) 
      throws NoSuchAlgorithmException, CryptoTokenException
     {
          if ( algorithm.equals( RSA ) ) 
          {
               return new MyRSACryptoToken();
          }
          throw new NoSuchAlgorithmException();
     }
}

Display cryptographic smart card driver options

If your implementation of isDisplaySettingsAvailableImpl() returns true.

On the BlackBerry smartphone, click Options > Security Options > Smart Card.

In the Registered Card Drivers section select the cryptographic smart card driver you are testing.

Click Driver Settings.