/* * MyCryptoSmartCard.java * * Copyright � 1998-2011 Research In Motion Limited * * 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 * * http://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. * * Note: For the sake of simplicity, this sample application may not leverage * resource bundles and resource strings. However, it is STRONGLY recommended * that application developers make use of the localization features available * within the BlackBerry development platform to ensure a seamless application * experience across a variety of languages and geographies. For more information * on localizing your application, please refer to the BlackBerry Java Development * Environment Development Guide associated with this release. */ package com.rim.samples.device.smartcarddriverdemo; import net.rim.device.api.crypto.CryptoSmartCard; import net.rim.device.api.crypto.CryptoToken; import net.rim.device.api.crypto.CryptoTokenException; import net.rim.device.api.crypto.NoSuchAlgorithmException; import net.rim.device.api.smartcard.AnswerToReset; import net.rim.device.api.smartcard.SmartCardCapabilities; import net.rim.device.api.smartcard.SmartCardException; import net.rim.device.api.smartcard.SmartCardFactory; import net.rim.device.api.smartcard.SmartCardReaderSession; import net.rim.device.api.smartcard.SmartCardSession; import net.rim.device.api.system.ControlledAccessException; import net.rim.device.api.ui.component.Dialog; import net.rim.device.api.util.Persistable; /** * This class represents a kind (or model or family) of a physical smart card. * There should only be one instance of this class in the system at a time, * which is referenced 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 properties/settings now"; private static final String RSA = "RSA"; /** * Called on startup of the device. Register this driver with the smart card * factory. When you do this, your driver is automatically registered with * the user authenticator framework, which allows your smart card to be used * as a second factor of authentication when unlocking the BlackBerry. * * Under the "Application" tab in this project's properties, make sure the * project type is set to "Library" and "Auto-run on startup" is checked. * The demo is not intended to be run on the simulator or on a real device, * but rather it is just instructional code. */ public static void libMain(final String args[]) { try { SmartCardFactory.addSmartCard(new MyCryptoSmartCard()); } catch (final 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 was registered with the smart card API framework and // can still // be used for importing certificates and signing/decrypting // messages. } } /** * Returns the appropriate subclass of SmartCardSession. Implementations of * this method should not bring up UI. */ protected SmartCardSession openSessionImpl( final SmartCardReaderSession readerSession) throws SmartCardException { return new MyCryptoSmartCardSession(this, readerSession); } /** * Returns true if this SmartCard implementation should be used to * communicate with a physical smart card that has the given AnswerToReset. * This method is called when the system is trying to ascertain which * SmartCard implementation should be used to communicate with a physical * smart card found in a reader. */ protected boolean checkAnswerToResetImpl(final AnswerToReset atr) { // If you return false from this method your driver will never be called // to do additional // operations on that particular smart card. You should *only* return // true if you support // the particular ATR. Returning true when you do not support the card // corresponding to // the ATR may prevent other smart card drivers from functioning // correctly. // The AnswerToReset object passed in contains the full ATR from the // card. Your implementation // may check the entire ATR or just parts of the ATR, as long as you are // certain that // your driver supports the corresponding smart card. return _myATR.equals(atr); } /** * Returns a label associated with the kind of smart card. The string should * not include the words "smart card", as this method will be used to * generate strings such as: * * ( "Please insert your %s smart card", getLabel() ) */ protected String getLabelImpl() { return LABEL; } /** * Returns the <code>SmartCardCapabilities</code> of the smart card. * <p> * * @return The capabilities of the smart card. */ protected SmartCardCapabilities getCapabilitiesImpl() { return new SmartCardCapabilities(SmartCardCapabilities.PROTOCOL_T0); } /** * Allows the driver to indicate if they support displaying settings. */ protected boolean isDisplaySettingsAvailableImpl(final Object context) { return true; } /** * Allows the driver to display some settings or properties. 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. * * @param context * Reserved for future use. */ protected void displaySettingsImpl(final Object context) { Dialog.alert(DISPLAY_SETTINGS); } /** * Returns the names of all the algorithms supported by this token (e.g., * "RSA", "DSA"). * <p> * * @return A String that represents the names of the algorithms. */ public String[] getAlgorithms() { return new String[] { RSA }; } /** * Returns a crypto token that supports the given algorithm. * <p> * * @param algorithm * A String representing the name of the algorithm. * @return The crypto token. * @throws NoSuchAlgorithmException * Thrown if the specified algorithm is invalid. * @throws CryptoTokenException * Thrown if there is a token related problem. */ public CryptoToken getCryptoToken(final String algorithm) throws NoSuchAlgorithmException, CryptoTokenException { if (algorithm.equals(RSA)) { return new MyRSACryptoToken(); } throw new NoSuchAlgorithmException(); } }