FileDocCategorySizeDatePackage
PhotoCardImpl.javaAPI DocJava Card6215Wed Mar 22 21:07:24 GMT 2006com.sun.javacard.samples.photocard

PhotoCardImpl.java

/*
 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
 * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */

/*
 * @(#)PhotoCardImpl.java	1.5 06/01/03
 */

package com.sun.javacard.samples.photocard;

import javacard.framework.*;
import javacard.framework.service.*;
import java.rmi.RemoteException;
import javacard.security.*;


public class PhotoCardImpl extends CardRemoteObject implements PhotoCard {

    // Internal fields    
    // Arrat containing photo objects
    private Object[] photos;
    
    private boolean[] photoReady;
    private byte[] buffer;
    
    PhotoCardImpl() {
        super();                     // export it
        // Initialize here
        photos = new Object[(short)MAX_PHOTO_COUNT];
        photoReady = new boolean[(short)MAX_PHOTO_COUNT];
        buffer = new byte[(short)MAX_BUFFER_BYTES];
        for (short i = (short)0; i < (short)MAX_PHOTO_COUNT; i++) {
            photoReady[i] = false;
        }        
    }

    // Implementation methods from Interface PhotoCard
    public short requestPhotoStorage(short size) 
        throws RemoteException, UserException {
        
        // 16-byte safety factor. For object header.
        if (JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_PERSISTENT) < 
            (short)(size + (short)16) ) {
            UserException.throwIt(NO_SPACE_AVAILABLE);
        }
        
        for (short i = (short)0; i < (short)MAX_PHOTO_COUNT;i++) {
            byte[] thePhoto = (byte[])photos[i];
            
            if (photos[i] == null) {
                photos[i] = new byte[size];
                return (short)(i + 1);
            }
        }
        UserException.throwIt(NO_SPACE_AVAILABLE);
        // Compiler requires this unreachable statement
        return (short)(-1);
    }
        
    public void loadPhoto(short photoID, byte[] data, 
        short size, short offset, boolean more) 
        throws RemoteException, UserException {
        
        if (photoID > (short)MAX_PHOTO_COUNT) {
            UserException.throwIt(PhotoCard.INVALID_PHOTO_ID);
        }
        
        byte[] selPhoto = (byte[])photos[(short)(photoID - (short)1)];
        
        if (selPhoto == null) {
            UserException.throwIt(PhotoCard.NO_PHOTO_STORED);
        }
        
        if (((short)(offset + size)) > selPhoto.length) {
            UserException.throwIt(PhotoCard.INVALID_ARGUMENT);
        }
        
        Util.arrayCopy(data, (short)0, selPhoto, offset, size);
        if (more == false) {
            photoReady[(short)(photoID - (short)1)] = true;
        }
    }
    
    public void deletePhoto(short photoID) 
        throws RemoteException, UserException {
                
        if (photoID > (short)MAX_PHOTO_COUNT) {
            UserException.throwIt(PhotoCard.INVALID_PHOTO_ID);
        }

        byte[] thePhoto = (byte[])photos[(short)(photoID - (short)1)];
        if (thePhoto != null) {
            thePhoto = null;
            JCSystem.requestObjectDeletion();
            photoReady[(short)(photoID - (short)1)] = false;
        } else {
            UserException.throwIt(PhotoCard.NO_PHOTO_STORED);
        }
    }

    public short getPhotoSize(short photoID) 
        throws RemoteException, UserException {

        if (photoID > (short)MAX_PHOTO_COUNT) {
            UserException.throwIt(PhotoCard.INVALID_PHOTO_ID);
        }

        byte[] thePhoto = (byte[])photos[(short)(photoID - (short)1)];
        if (thePhoto != null) {
             return (short)(thePhoto.length);
        } else {
             return (short)0;
        }
    }
    
    public byte[] getPhoto(short photoID, short offset, short size) 
        throws RemoteException, UserException {

        if (photoID > (short)MAX_PHOTO_COUNT) {
            UserException.throwIt(PhotoCard.INVALID_PHOTO_ID);
        }

        byte[] selPhoto = (byte[])photos[(short)(photoID - (short)1)];
                
        if ((selPhoto == null) || (photoReady[(short)(photoID - (short)1)] == false)) {
            UserException.throwIt(PhotoCard.NO_PHOTO_STORED);
        }

        if (((short)(offset + size)) > selPhoto.length) {
            UserException.throwIt(PhotoCard.INVALID_ARGUMENT);
        }
        Util.arrayCopy(selPhoto, offset, buffer, (short)0, size);
        return buffer;
    }
    
    public short verifyPhoto(short photoID, byte[] photoDigest, short photoOffset) 
        throws RemoteException, UserException {        
           
        MessageDigest md = null;  
		 short response;
        
        if(photoOffset > (short) photoDigest.length){
            UserException.throwIt(PhotoCard.INVALID_OFFSET);
        }

        if (photoID > (short)MAX_PHOTO_COUNT) {
            UserException.throwIt(PhotoCard.INVALID_PHOTO_ID);
        }

        byte[] selPhoto = (byte[])photos[(short)(photoID - (short)1)];
                
        if ((selPhoto == null) || (photoReady[(short)(photoID - (short)1)] == false)) {
            UserException.throwIt(PhotoCard.NO_PHOTO_STORED);
        }        
        
        try
        {
            md = MessageDigest.getInstance(MessageDigest.ALG_SHA_256,false);
        }catch(CryptoException e) {
            UserException.throwIt(PhotoCard.DOES_NOT_SUPPORT_PHOTO_VERIFICTAION);
        }
        
        short resultLength = md.doFinal(selPhoto,(short) 0, (short) selPhoto.length, 
                                        buffer,(short)0);
        response = compare(buffer,photoDigest,photoOffset,resultLength);        
		 return response;
    }
    
     private short compare(byte[] src, byte[] destination,
                          short photoOffset, short length){
        
        try {
		         if (length != (short)32){
                        ISOException.throwIt( FAIL4 );
                }          
                
                short comp = Util.arrayCompare(src, (short)0, 
                             destination, photoOffset, length);
                
                if(comp == 0){
                    return (short)0; 
				  }
               else{
                  return (short) FAIL1;
               }

	    } 
	    catch( CryptoException e ){
			return FAIL3;
	    }
    }
    

}