FileDocCategorySizeDatePackage
MySecurityService.javaAPI DocJava Card7748Wed Mar 22 21:07:24 GMT 2006com.sun.javacard.samples.SecureRMIDemo

MySecurityService

public class MySecurityService extends BasicService implements SecurityService

Fields Summary
private static final byte[]
PRINCIPAL_APP_PROVIDER_ID
private static final byte[]
PRINCIPAL_CARDHOLDER_ID
static final byte
APDU_SM_MASK_TYPE4
private OwnerPIN
provider_pin
private OwnerPIN
cardholder_pin
private byte
commandProperties
private byte
authenticated
private static final byte
INS_SELECT
private static final byte
APDU_CMD_MASK
private static final byte
CLA_AUTH
private static final byte
INS_AUTH
Constructors Summary
public MySecurityService()

    
      
        provider_pin = new OwnerPIN((byte)2,(byte)2);
        cardholder_pin = new OwnerPIN((byte)2,(byte)2);
        provider_pin.update(PRINCIPAL_APP_PROVIDER_ID, (short)0, (byte)2);
        cardholder_pin.update(PRINCIPAL_CARDHOLDER_ID, (short)0, (byte)2);
    
Methods Summary
private booleancheckAndRemoveChecksum(APDU apdu)

        byte[] buffer = apdu.getBuffer();
        
        if(!apdu.isSecureMessagingCLA()) {
            return false;
        }
        
        // reset secure flag
        apdu.getBuffer()[0] &= ~APDU_SM_MASK_TYPE4;
        
        short Lc = buffer[4];
        
        if(Lc<2) return false;  // must have at least the checksum
        
        short csum1 = 0;
        buffer[4] -= 2;       // decrease Lc
        Lc = buffer[4];
        
        for(short n = 5; n<(short)(Lc+5); ++n) {
            csum1 += buffer[n];
        }
        
        final short csum2 = Util.getShort(buffer, (short)(Lc+5));
        
        
        return (csum1 == csum2);
    
private booleanisAuthenticate(APDU command)

    
        
        return
        (getCLA(command) == CLA_AUTH
        &&
        getINS(command) == INS_AUTH);
        
    
public booleanisAuthenticated(short principal)
Checks whether or not the specified principal is currently authenticated. The validity timeframe(selection or reset) and authentication method as well as the exact interpretation of the specified principal parameter needs to be detailed by the implementation class. The only generic guarantee is that the authentication has been performed in the current card session.

param
principal an identifier of the principal that needs to be authenticated
return
true if the expected principal is authenticated
throws
ServiceException with the following reason code:
  • ServiceException.ILLEGAL_PARAM if the specified principal is unknown.

        
        return (authenticated == principal);
    
public booleanisChannelSecure(byte prop)

        return false;
    
public booleanisCommandSecure(byte properties)
Checks whether a secure channel is in use between the card and the host for the ongoing command that guarantees the indicated properties. The result is only correct after pre-processing the command (for instance during the processing of the command). For properties on incoming data, the result is guaranteed to be correct; for outgoing data, the result reflects the expectations of the client software, with no other guarantee.

param
properties the required properties.
return
true if the required properties are true, false othewise
throws
ServiceException with the following reason code:
  • ServiceException.ILLEGAL_PARAM if the specified property is unknown.

        return (commandProperties & properties) != 0;
    
private booleanpreprocessCommandAPDU(APDU apdu)

        
        receiveInData(apdu);
        
        if(checkAndRemoveChecksum(apdu)) {
            commandProperties |= SecurityService.PROPERTY_INPUT_INTEGRITY;
        }
        else {
            commandProperties &= ~SecurityService.PROPERTY_INPUT_INTEGRITY;
        }
        
        return false;
    
public booleanprocessCommand(APDU apdu)

        if(isAuthenticate(apdu)) {
            receiveInData(apdu);
            if(apdu.getBuffer()[4] == 2) {
                authenticated = 0;
                
                //                short id = Util.getShort(apdu.getBuffer(), (short)5);
                
                if(provider_pin.check(apdu.getBuffer(), (short)5, (byte)2)) {
                    authenticated = PRINCIPAL_APP_PROVIDER;
                    setOutputLength(apdu,(short)0);
                    succeed(apdu);
                }
                else if(cardholder_pin.check(apdu.getBuffer(), (short)5, (byte)2)) {
                    authenticated = PRINCIPAL_CARDHOLDER;
                    setOutputLength(apdu,(short)0);
                    succeed(apdu);
                }
                else {
                    fail(apdu, (short)0x6666);
                }
            }
            else {
                fail(apdu, (short) 0x6565);
            }
            return true;
        }
        else {
            return false;
        }
    
public booleanprocessDataIn(APDU apdu)
Pre-processes the input data for the command in the APDU object. When invoked, the APDU object should either be in STATE_INITIAL with the APDU buffer in the Init format or in STATE_FULL_INCOMING with the APDU buffer in the Input Ready format defined in BasicService.

The method must return true if no more pre-processing should be performed, and false otherwise. In particular, it must return false if it has not performed any processing on the command.

After normal completion, the APDU object is usually in STATE_FULL_INCOMING with the APDU buffer in the Input Ready format defined in BasicService. However, in some cases if the Service processes the command entirely, the APDU object may be in STATE_OUTGOING with the APDU buffer in the Output Ready format defined in BasicService.

param
apdu the APDU object containing the command being processed.
return
true if input processing is finished, false otherwise.

        
        
        if(selectingApplet()) {
            commandProperties = 0;
            authenticated = 0;
            return false;   // in case some other service is interested
        }
        else {
            return preprocessCommandAPDU(apdu);
        }
    
public booleanprocessDataOut(APDU apdu)

        
        if(selectingApplet()) return false;
        
        // if not select...
        // compute and append checksum
        byte[] buffer = apdu.getBuffer();
        short Le = (short)(buffer[4] & 0x00FF);
        
        short csum = 0;
        
        for(short n = 5; n<(short)(Le+5); ++n) {
            csum += buffer[n];
        }
        
        javacard.framework.Util.setShort(buffer, (short)(Le+5), csum);
        buffer[4] += 2;
        return false;