Commit 7f1f2094 authored by berge's avatar berge
Browse files

Added ePassport_Altsteps.ttcn

parent c749b8d0
Loading
Loading
Loading
Loading
+411 −0
Original line number Diff line number Diff line
/**
 *	@author 	ETSI
 *  @version 	$URL: $
 *				$Id: $
 *	@desc		This module contains alsteps for processing IS messages.
 *			
 *
 */
 
 module ePassport_Altsteps {

	//LibCommon
	import from LibCommon_DataStrings all;

	//Ats
	import from ePassport_TestSystem all;
	import from ePassport_Types all;
	import from ePassport_Values all;
	import from ePassport_Functions all;
	import from ePassport_Templates all;
	import from ePassport_Pixits all;


	group defaults {
		
		altstep a_fileDefault() runs on MRTD {
			
			// if passport is unprotected, then any file is accessible
			[vc_simu.passportProtection == e_plain] a_readAnyFile();

			// DG3 only accessible if terminal is authenticated
			[vc_simu.securityStatus >= e_terminalAuthenticated] a_readFile(c_longFileIdDG3);
			[vc_simu.securityStatus < e_terminalAuthenticated] a_refuseFileAccess(c_longFileIdDG3);

			// DG4 only accessible if terminal is authenticated
			[vc_simu.securityStatus >= e_terminalAuthenticated] a_readFile(c_longFileIdDG4);
			[vc_simu.securityStatus < e_terminalAuthenticated] a_refuseFileAccess(c_longFileIdDG4);
			
			// any other file accessible if BAC performed
			[vc_simu.securityStatus >= e_basicAccessControl] a_readAnyFile();
			
			// Otherwise, refuse file access
        	[] a_refuseAnyFileAccess();
		}
		
		altstep a_default() runs on MRTD {
			[] t_guard.timeout {
				log("**** a_default: Error: Lifetime of testcase has expired. Sopping TC now. ****");
        		setverdict(inconc);
        		stop
        	}
        	[] any timer.timeout {
        		log("**** a_default: Error: Unexpected timeout occured. ****");
        		setverdict(inconc);
        		stop
        	}        	
		}

        altstep a_mgmt(in Oct2 p_failCode) runs on MRTD {
        	
        	[v_checkpoint] mgmt.receive(mw_report(p_failCode)) 
        		{
        		setverdict(pass);
        		}
        	[] mgmt.receive 
        		{
        		setverdict(fail);
        		stop
        		}
        	
        }
	} // end defaults
	
	group inspectionProcedures {
		
		// Start the MRTD Test sequence :  Standard Inspection Procedure (SIP)
    	altstep a_standardInspectionProcedure() runs on MRTD {
    	
    		[] a_waitApplication();
    		
    		[vc_simu.securityStatus > e_noApplication] a_bac();
    		
    		[vc_simu.securityStatus >= e_basicAccessControl] a_activeAuthentication();
    	
        } // end a_standardInspectionProcedure
        
        // Start the MRTD Test sequence : Advanced Inspection Procedure (AIP) including EAC
        altstep a_advancedInspectionProcedure() runs on MRTD {
        	
        	[] a_waitApplication();
    		
    		[vc_simu.securityStatus > e_noApplication] a_bac();

			[vc_simu.securityStatus >= e_basicAccessControl] a_chipAuthentication();

    		[vc_simu.securityStatus >= e_basicAccessControl] a_activeAuthentication();

			[vc_simu.securityStatus >= e_chipAuthenticated] a_terminalAuthentication();
	
        } // end a_standardInspectionProcedure
    			
	} // end inspectionProcedures        
	
	group authenticationProcedures {
		
    	altstep a_activeAuthentication () runs on MRTD {
    		
    		var Command v_command;
    		var octetstring v_rndIfd;
    		var octetstring v_response;
    
			[] mrtdport.receive(mw_intauthenticate) -> value v_command {
   				v_rndIfd := v_command.payload.plainText.commandData;
				v_response := f_activeAuthentication(v_rndIfd);
				mrtdport.send(m_response_read(v_response));
			}
    	} // end a_activeAuthentication
    	
    	altstep a_chipAuthentication () runs on MRTD {

    		//var EFfile v_file:=valueof(p_file);
    		var Command v_command;
    		var octetstring v_publicKeyPcd;

			[] mrtdport.receive(mw_mse_setKAT) -> value v_command {
				v_publicKeyPcd := v_command.payload.plainText.commandData;
				f_chipAuthentication(v_publicKeyPcd);
				mrtdport.send(m_responseOK);
				vc_simu.securityStatus := e_chipAuthenticated;
			}
    	} // end a_chipAuthentication
    	
    	// Terminal Authentication triggered by reading of EF.CVCA
    	altstep a_terminalAuthentication () runs on MRTD {

    		var Command v_command;
    		var octetstring v_rndIcc;
    		var octetstring v_dstCAR, v_atCAR;
    		var octetstring v_certificate, v_signature;

           	// reading of the certificate chain
			[] mrtdport.receive(mw_mse_setDST) -> value v_command {
				v_dstCAR := v_command.payload.plainText.commandData;
				// TODO: check CAR exists
				
				mrtdport.send(m_responseOK);
				repeat;					
			}

			// The MRTD is waiting for a PSO:Verify Certificate
			[] mrtdport.receive(mw_pso_verifyCertificate) -> value v_command {
						 
				// if the Certificate Body and the Signature are OK then the certificate was successfully validated
				// and the public key has been imported
				// see TR-03110 EAC spec B.2.2
					
				// the correct Certificate must be passed as parameter in the external function
				// in order to verify IS and DV and link CAVA certificates.
				v_certificate := f_getCertificate(v_command.payload.plainText.commandData); 
				v_signature := f_getSignature(v_command.payload.plainText.commandData);
				if (f_verifySignature(v_signature, v_dstCAR)) {
					//TODO store certificate and CAR						
		 			mrtdport.send(m_responseOK);
		 		}
		 		else {
					//TODO: error
		 		}
		 		repeat;
			}

			// The MRTD is waiting a MSE:SetAT message with a key reference
			[] mrtdport.receive(mw_mse_setAT) -> value v_command {
				v_atCAR := v_command.payload.plainText.commandData;
				mrtdport.send(m_responseOK);
			}

			// The MRTD is waiting a Get_Challenge message in order that the IS requests the RpIcc RND key
			[] mrtdport.receive(mw_getChallenge) -> value v_command {
				v_rndIcc := f_generateRandomOctetstring(c_atNonceSize); 
				mrtdport.send(m_response_read(v_rndIcc));		
			}

			// The MRTD is waiting an External Authenticate message including the signature of the IS
			[] mrtdport.receive(mw_extAuthenticate) -> value v_command { 
				v_signature := v_command.payload.plainText.commandData;
				if(f_verifySignature(v_signature, v_atCAR)) {
					mrtdport.send(m_responseOK);
				}
				else {
					//TODO
				}
				
				vc_simu.securityStatus := e_terminalAuthenticated;
			}
    		
    	} // end a_terminalAuthentication
    			
	} // end authenticationProcedures

	group commandProcessing {
		
		// First message to be received while reading the ePassport
        altstep a_waitApplication () runs on MRTD {
    
    		[] mrtdport.receive(mw_application) {
    			mrtdport.send(m_responseOK);
    				vc_simu.securityStatus := e_noSecurity;
    		}
    		
    	} //end a_waitApplication
    			
    			

    			
    	altstep a_bac() runs on MRTD {
	
        	var Command v_command;
        	var CommandData v_data;
        	var octetstring v_rndIcc;
        	var octetstring v_response;
        	var octetstring v_challengeResponse;
        	
        	[] mrtdport.receive(mw_getChallenge) {            		
        		// MRTD sends its random challenge to IS
        		v_rndIcc := f_generateRandomOctetstring(c_bacNonceSize);
    			mrtdport.send(m_response_read(v_rndIcc));				
        	}
        	
    		[] mrtdport.receive(mw_extAuthenticate) -> value v_command {        				
    			v_challengeResponse := v_command.payload.plainText.commandData;
        		
        		v_response := f_basicAccessControl(v_rndIcc, v_challengeResponse);
        		mrtdport.send(m_response_read(v_response));
        		vc_simu.securityStatus := e_basicAccessControl;
    		}
    			
        } // end a_bac
            	
		
		altstep a_readFile(in LongFileId p_fileId) runs on MRTD {
	
    		var Command v_command;
    		var integer v_logicalChannel;
    		var octetstring v_data := ''O;
    		var integer v_dataLength;
    		var integer v_offset;
    		var W1W2Status v_result;
    		
    		// SELECT Command
        	[] mrtdport.receive(mw_selectByFileID(p_fileId)) -> value v_command {
        		
        		// set current file for logical channel
        		v_logicalChannel := f_getLogicalChannel(v_command.class);
        		vc_simu.currentFiles[v_logicalChannel] := v_command.payload.plainText.commandData;
        				
        		mrtdport.send(m_responseOK);
        		repeat;
        	}
        		
        	// READ Command with short EF
    		[] mrtdport.receive(mw_readShortEF(f_longFileIdToShortFileId(p_fileId))) -> value v_command {
    
    			// set current file for logical channel
        		v_logicalChannel := f_getLogicalChannel(v_command.class);
        		vc_simu.currentFiles[v_logicalChannel] := v_command.payload.plainText.commandData;
        					
    			v_offset := bit2int(v_command.p2);
    			v_dataLength := v_command.payload.plainText.lengthE;
      		
        		v_result := f_readFileData(v_logicalChannel, v_offset, v_dataLength, v_data);
        		mrtdport.send(m_responseRead(v_data, v_result));

    			repeat;
    		}
    
    		// READ Command (using current EF)
    		[] mrtdport.receive(mw_readCurrentEF) -> value v_command {
    		
    			// Check current file
    			v_logicalChannel := f_getLogicalChannel(v_command.class);
    			if(vc_simu.currentFiles[v_logicalChannel] == c_longFileIdNoFile) {
    				log(""); //TODO
    				mrtdport.send(m_responseNOK(c_w1w2NoCurrentEF));
    				repeat;
    			}
    		
    			v_offset := bit2int(v_command.p1 & v_command.p2);
    			
    			v_result := f_readFileData(v_logicalChannel, v_offset, v_dataLength, v_data);
        		mrtdport.send(m_responseRead(v_data, v_result));
    			 
    			repeat;			
    		}
    				
    		// TODO: receive statements for B1					
    				
    	} // end of a_readFile
		
		
		//FIXME: duplicated code
		altstep a_readAnyFile() runs on MRTD {
	
    		var Command v_command;
    		var integer v_logicalChannel;
    		var octetstring v_data := ''O;
    		var integer v_dataLength;
    		var integer v_offset;
    		var W1W2Status v_result;
    		
    		// SELECT Command
        	[] mrtdport.receive(mw_selectAnyFile) -> value v_command {
        		
        		// set current file for logical channel
        		v_logicalChannel := f_getLogicalChannel(v_command.class);
        		vc_simu.currentFiles[v_logicalChannel] := v_command.payload.plainText.commandData;
        				
        		mrtdport.send(m_responseOK);
        		repeat;
        	}
        		
        	// READ Command with short EF
    		[] mrtdport.receive(mw_readAnyShortEF) -> value v_command {
    
    			// set current file for logical channel
        		v_logicalChannel := f_getLogicalChannel(v_command.class);
        		vc_simu.currentFiles[v_logicalChannel] := v_command.payload.plainText.commandData;
        					
    			v_offset := bit2int(v_command.p2);
    			v_dataLength := v_command.payload.plainText.lengthE;
      		
        		v_result := f_readFileData(v_logicalChannel, v_offset, v_dataLength, v_data);
        		mrtdport.send(m_responseRead(v_data, v_result));
    			
    			repeat;
    		}
    
    		// READ Command (using current EF)
    		[] mrtdport.receive(mw_readCurrentEF) -> value v_command {
    		
    			// Check current file
    			v_logicalChannel := f_getLogicalChannel(v_command.class);
    			if(vc_simu.currentFiles[v_logicalChannel] == c_longFileIdNoFile) {
    				log(""); //TODO
    				mrtdport.send(m_responseNOK(c_w1w2NoCurrentEF));
    				repeat;
    			}
    		
    			v_offset := bit2int(v_command.p1 & v_command.p2);
    			
    			v_result := f_readFileData(v_logicalChannel, v_offset, v_dataLength, v_data);
        		mrtdport.send(m_responseRead(v_data, v_result));
    			 
    			repeat;			
    		}
    				
    		// TODO: receive statements for B1					
    				
    	} // end of a_readAnyFile

		altstep a_refuseFileAccess(in LongFileId p_fileId) runs on MRTD {
		
			// SELECT Command
        	[] mrtdport.receive(mw_selectByFileID(p_fileId)) {
        		mrtdport.send(m_responseNOK(c_w1w2SecurityStatusNotSatisfied));
        		repeat;
        	}
        		
        	// READ Command with short EF
    		[] mrtdport.receive(mw_readShortEF(f_longFileIdToShortFileId(p_fileId))) {
        		mrtdport.send(m_responseNOK(c_w1w2SecurityStatusNotSatisfied));
        		repeat;
    		}
    
    		// READ Command (using current EF)
    		[] mrtdport.receive(mw_readCurrentEF) {
        		mrtdport.send(m_responseNOK(c_w1w2NoCurrentEF));
        		repeat;
    		}
    				
    		// TODO: receive statements for B1	
			
		} // end a_refuseFileAccess
		
		//FIXME: duplicated code
		altstep a_refuseAnyFileAccess() runs on MRTD {
		
			// SELECT Command
        	[] mrtdport.receive(mw_selectAnyFile) {
        		mrtdport.send(m_responseNOK(c_w1w2SecurityStatusNotSatisfied));
        		repeat;
        	}
        		
        	// READ Command with short EF
    		[] mrtdport.receive(mw_readAnyShortEF) {
        		mrtdport.send(m_responseNOK(c_w1w2SecurityStatusNotSatisfied));
        		repeat;
    		}
    
    		// READ Command (using current EF)
    		[] mrtdport.receive(mw_readCurrentEF) {
        		mrtdport.send(m_responseNOK(c_w1w2NoCurrentEF));
        		repeat;
    		}
    				
    		// TODO: receive statements for B1	
			
		} // end a_refuseAnyFileAccess
			
	} // end commandProcessing

 } // end ePassport_Altsteps
 No newline at end of file
+1 −391

File changed.

Preview size limit exceeded, changes collapsed.

+1 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@ module ePassport_Testcases {
	import from ePassport_Types all;
	import from ePassport_Templates all;    
    import from ePassport_Functions all;
    import from ePassport_Altsteps all;
    import from ePassport_Values all;
	import from ePassport_Pixits all;