* ==========================================================================
* Demo: Secure File Transfe
* Caution: no error check for the sake of briefness and understandability
* Tips:
* The ROCKEY dongle supports Secure File Transfer (SFT). The Remote Update Management (RUM) 
* function will verify the user's identity, but it cannot update the dongle algorithm because the 
* end user does not have access to the super password which is required to write to the dongle. 
* The SFT process allows the software developer to securely update dongle algorithms or data files 
* without compromising the super password.
* See the SFT operational overview described below:
* 1. The software developer generates the "cryptography file" by using with own dongle.
* 2. Transfer the file to the user;
* 3. The user transfers the cryptography file to dongle with the program provided by the software 
*    developer. The dongle converts the file to clear text file internally.
* We adopts the following security policies:
* 1. The algorithms of cryptography files and clear text files are completely confidential, not 
*    open to anyone;ĄŁ
* 2. The generation of cryptography files and clear text files is 100% performed inside dongle, 
*    no other external work is involved;ĄŁ
* 3. The encryption / decryption key is related to dongle super password and the management code. 
*    It is not necessary to worry that some one else could create a cryptography file valid in the 
*    end user's dongle
* 4. The content of the cryptography file can not be modified, the file ID, its attribute, and 
*    others are part of the cryptography file, and they are all protected by the file check 
*    mechanism.
* Attention::
* 1. The software developer can only generate the cryptography file after super password 
*    verification. The verified super password is part of the encryption key. That is to say, 
*    the super password of the end user should be the same with the super password which the 
*    software developer uses to generate the cryptography file.
* 2. During the cryptography file generation process, a temporary file with the same name will be 
*    created in the software developer's dongle, because the IC card can transfer at most data of 
*    250 bytes once, and many files are larger than that size. Therefore, dongle should have enough 
*    space for the temporary file generation. The file will not be deleted automatically after the 
*    "cryptography file" generation call and the return of the content; you need to delete it 
*    manually.
* ==========================================================================
* Here two security files will be created: an executable file and a data file. The function 
* of the executable file is to read and return the content of the data file. 

*
* Executable file readdata.c, input parameters are the internal file IDs of dongle to be accessed
* Output parameters are the contents of the internal file of dongle.
*void main(void)
*{
* word fileID;
* word fileSize;
* byte b_fileSize;
* byte xdata out[30];
* byte xdata result[100],ret;

* get_input(&fileID,0,1,1);
* open_file(&fileID, 0);
* get_file_infor(out, 1);
* fileSize = (out[5]<<8)|out[4];
* read_file(0,result,fileSize);
* b_fileSize=(unsigned char)fileSize;

*set_response(b_fileSize, result);
* exit();
*}
* ==========================================================================
#include "Dic32_Vfp.h"
clear 
DECLARE integer   DIC_Find IN Dic32u.dll
DECLARE integer   DIC_Open IN Dic32u.dll integer hic, string @  reader_name
DECLARE integer   DIC_Close  IN Dic32u.dll  integer   hic
DECLARE integer   DIC_Command  IN Dic32u.dll  integer  hic, integer cmd, string @  cmddata
DECLARE integer   DIC_Get  IN Dic32u.dll  string @xdata, integer  p1, integer   p2, string @buffer
DECLARE integer   DIC_Set  IN Dic32u.dll  string @xdata, integer  p1, integer  p2, integer   p3, string @buffer

store 0 to  errcode		   && error code 
store 0 to  num		   && number of founded card reader(s)
store 0 to  hic		   && handle of ROCKEY device.
store 0 to  i,j
store 0 to temp
store 0 to exesize, datasize, read_size

cmddata = space(512)
buffer = space(512)
c_exefile = space(512)
c_datafile = space(512)

#define READDATA_SIZE  276
dimension g_progReadData[4]
store '002001004117012000117013000117014008228245015117016001117017001018000160117012000117013000117014008228245015018000191117012001117013000117014000117015001018000237144000004224254163224253238245010237245011228' to g_progReadData[1]
store '245012245013117014001117015000117016012133010017133011018018000125211229011148255229010148000064004127255128002175011143012117013001117014000117015012018000214002001016018255000229012036000229013036001229014' to g_progReadData[2]
store '036002229015036003229016036004229017036005229018036006018255003034018255000229012036000229013036001229014036002229015036003229016036004229017036005018255011034018255000229012036000229013036001229014036002229' to g_progReadData[3]
store '015036003018255002034018255000229013036000229014036001229015036002229012036003018255010034018255000229012036000229013036001229014036002229015036003018255006034120127228246216253117129018002000003018255013034' to g_progReadData[4]

	num = DIC_Find()
	for i=0 to num-1
		hic = DIC_Open(i, NULL)
		if (hic >= 0) 
		  exit  	&& Stop searching once one is found.
  	  endif
	endfor
	if (i == num) 
	     return
    endif
    
    * a. Change to super user status (Only super users are allowed to create executable files)
    * Super password is 8 FFs for demo ROCKEY
	for i=0 to 7
	    DIC_Set(@cmddata,i,1,0xff,NULL)
    endfor
	errcode = DIC_Command(hic, CHECK_SUPER_PASS, @cmddata) 
	

	* b. Format ROCKEY, all files and directorys will be cleared.
    *    You can set ATR and VOLUME here.
	DIC_Set(@cmddata, DIC_VOLUME, BY_ARRAY, 0, "DICSYSTEM") 
	DIC_Set(@cmddata, ATR, BY_ARRAY, 0, "DIC Co.") 
	errcode = DIC_Command(hic, FORMAT_CARD, @cmddata) 

	* c. Create the cryptography file of the executable file
	*    Difference between creating cryptography file and common file is that after setting the
	*    relevant file attributes FILE_DATA call is needed to transfer the file content.
    DIC_Set(@cmddata, FILL, 512, 0, NULL)	&& Clear buffer
	DIC_Set(@cmddata, FILE_ID, BY_VALUE, 0x0023, NULL) 				&& File ID
	DIC_Set(@cmddata, FILE_CLASS, BY_VALUE, 0xff, NULL) 				&& File class
	DIC_Set(@cmddata, FILE_ATTRIBUTE, BY_VALUE, FILEATTR_EXEC, NULL) 		&& File attr
	DIC_Set(@cmddata, FILE_SIZE, BY_VALUE, READDATA_SIZE, NULL) 			&& File size
	DIC_Set(@cmddata, FILE_NAME, BY_ARRAY, 0, "6088") 				&& File name
	for i = 1 to 4 
	   for j = 0 to READDATA_SIZE/4-1
	      temp = substr(g_progReadData[i],j*3+1,3)
	      DIC_Set(@buffer,(i-1)*READDATA_SIZE/4+j,bitor(BY_STRING,1),0 ,@temp)
	   endfor
	endfor
	DIC_Set(@cmddata, FILE_DATA, bitor(BY_ARRAY , READDATA_SIZE), 0, @buffer) 	&& File content
	errcode = DIC_Command(hic, CRYPTOTEXT_FILE, @cmddata) 
	exesize = DIC_Get(@cmddata, FILE_DATA, BY_ARRAY, @c_exefile) 

	* d. Create the cryptography file of the data file, data content is 0-9 repeated 8 times.
    for i = 0 to 7 
	   for j = 0 to 9
	      DIC_Set(@buffer,i*10+j,1,0x30+j ,NULL)
	   endfor
	endfor
    DIC_Set(@cmddata, FILL, 512, 0, NULL)	&& Clear buffer
	DIC_Set(@cmddata, FILE_ID, BY_VALUE, 0x0057, NULL) 		&& File ID
	DIC_Set(@cmddata, FILE_CLASS, BY_VALUE, 0xff, NULL) 		&& File class
	DIC_Set(@cmddata, FILE_ATTRIBUTE, BY_VALUE, FILEATTR_NORMAL, NULL) 	&& File attr
	DIC_Set(@cmddata, FILE_SIZE, BY_VALUE, 80, NULL) 		&& File size
	DIC_Set(@cmddata, FILE_NAME, BY_ARRAY, 0, "File1") 		&& File name
	DIC_Set(@cmddata, FILE_DATA, bitor(BY_ARRAY, 80), 0, @buffer) 	&& File content
	errcode = DIC_Command(hic, CRYPTOTEXT_FILE, @cmddata) 
	datasize = DIC_Get(@cmddata, FILE_DATA, BY_ARRAY, @c_datafile) 

	* e. Select the temporary file of the executable cryptography file(0x0023)
	DIC_Set(@cmddata, FILE_ID, BY_VALUE, 0x0023, NULL) 
	errcode = DIC_Command(hic, SET_CURRENT_FILE, @cmddata) 

	* f. Delete temporary file of the executable cryptography file(0x0023)
	errcode = DIC_Command(hic, REMOVE_FILE, @cmddata) 

	* g. Select the temporary file of the data cryptography file(0x0057)
	DIC_Set(@cmddata, FILE_ID, BY_VALUE, 0x0057, NULL) 
	errcode = DIC_Command(hic, SET_CURRENT_FILE, @cmddata) 

	* h. Delete the temporary file of the data cryptography file(0x0057)
	errcode = DIC_Command(hic, REMOVE_FILE, @cmddata) 

	* i. Lower the super password verified status to common user status, as it is unnecessary
	*    for super user to create the clear text file.
	errcode = DIC_Close(hic) 
	errcode = DIC_Open(hic, NULL) 

	* j. Create the clear text file of the executable file
	errcode = DIC_Command(hic, PLAINTEXT_FILE, @c_exefile) 

 
	* k. Create the clear text file of the data file
	errcode = DIC_Command(hic, PLAINTEXT_FILE, @c_datafile) 

	* l. Run the executable file(0x0023), to get the content of the data file(0x0057)
	*    and return
	DIC_Set(@buffer, 0, 2, 0x0057, NULL) 			&& Input the file ID
	DIC_Set(@cmddata, RUN_DATA, 2, 0x6088, @buffer) 	&& Set the run data
	errcode = DIC_Command(hic, RUN, @cmddata) 
	DIC_Set(@buffer, FILL, 256, 0, NULL)	&& Clear buffer
	read_size = DIC_Get(@cmddata, RUN_DATA, BY_ARRAY, @buffer) 	&& Fetch data after execution
	for i = 0 to 7
	    temp = substr(buffer , i*10+1,10)
	    ?temp
	endfor

	* m. Close dongle
	errcode = DIC_Close(hic) 
clear dlls
return 	