summaryrefslogblamecommitdiffstats
path: root/src/main/java/org/uic/barcode/dynamicFrame/api/SimpleDynamicFrame.java
blob: ae1b4e2b7670d55bd3e524e4e85ccb90ece96689 (plain) (tree)
1
2
3
4
5
6
7
                                          




                                               
                               




                                                   
                       
 

                                                               
                                                                      


                                                            
                                                       
                                                    
                                            
 
 
 


                                    
    
                                                           
         


                                             




                                                   

                           
                                     
         
                                        
                         
                                       

         
                                               


                                          





                              
                  








                                        
                  



                                               




                                           
                  

                                             

          




                                                               
                  

                                                                  

          




                                         
                  
                                             


                                        




                                                            
                  
                                                                 


                                                        
 
         




                                                                                        
                           
                                            
                 


                                                                     







                                                                                        
                                                            
                                         
                                            
                 

                                                                                  
                 

                                          





                                                                                                      
                 
                                                                                         
                                                                                                  
 




                                                                          
                                                                              

                                                                         
                                         

                                          
                                                                                                                                         





                                                                                         
                 

                                      
                                                                                                     
                         
                                                


                                                                                                       
                                                  
                                                                                               




                                                                                                 


                                                                                         


                                                                                         
 
                                                                
                                          
                      
                                                                                                             


                                                                                    
                                          


                                                                                    
                                      
                      
                                                
                                                                         
                                 
                                                                                  
                          









                                                                                    
                                                                 
                                                 







                                                                                    
                                                    










                                                                                    




                                                                                                 
         
















                                                                                                                               


                                                                         
                 
                                                                              











                                                                                                                 
                                 

                                                                                        






                                                                                                           


                                                                
                                                                                                           








                                                                                    





                                                                         



                                                                                    
                                                                





                                                                                    
                         
                                                                                         
                         
                                                         
                         







                                                                                    

                                                    
                                                                       
                                 
                                                                          
                          
                                        
                                                                                    
                  
          
         
                  
                                                                  
                                       
          
 



                              
                                                        

                                           
                  
                                                                                 



                                                                          

                                                                

                                                                                                                                                 
 




                                                                
                                   
                                                                              
                                        
                                              


                 
         





                                                                         
                  
                                                                                                   
                                 
                                                            
                 
                                                                                                  
                         
                                                                                                                                     







                                                      
                  
                                                                                  
                                                                                         

          




                                       
                  

                                                        

                                                                               


                                             
                                                                                         


                         
 
            


                                                                                        
           



                              
            
                  
                                                                  
                 
                                       
                 




















                                                                                                  




                                                                          

                                                                
                                                                                                                       
                                      
 




                                                                 

                                   
                                                                    

                                                                 
          






















                                                                                            
                  















                                                                                           

 

         
package org.uic.barcode.dynamicFrame.api;

import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.Provider;
import java.security.PublicKey;
import java.security.Signature;
import java.security.SignatureException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;
import java.util.Date;

import org.uic.barcode.dynamicContent.api.DynamicContentCoder;
import org.uic.barcode.dynamicContent.api.IUicDynamicContent;
import org.uic.barcode.dynamicContent.fdc1.UicDynamicContentDataFDC1;
import org.uic.barcode.dynamicFrame.Constants;
import org.uic.barcode.dynamicFrame.v1.DynamicFrameCoderV1;
import org.uic.barcode.dynamicFrame.v2.DynamicFrameCoderV2;
import org.uic.barcode.ticket.EncodingFormatException;
import org.uic.barcode.utils.AlgorithmNameResolver;
import org.uic.barcode.utils.SecurityUtils;



/**
 * The DynamicHeader for bar codes 
 * 
 */
public class SimpleDynamicFrame implements IDynamicFrame {
	
	/**
	 * Instantiates a new dynamic frame.
	 */
	public SimpleDynamicFrame() {}
	
	public SimpleDynamicFrame(String format) {
		this.format = format;
	}

	/** The format. */
	public String format = null;
	
	/** The level 2 signed data. */
	/*level 2 data*/
	public ILevel2Data level2Data;
	
	
	/**  The signature of level 2 data. */
	public byte[] level2Signature;
	
	public Date endOfValidity = null;
	
	/**
	 * Gets the format.
	 *
	 * @return the format
	 */
	@Override
	public String getFormat() {
		return format;
	}

	/**
	 * Sets the format.
	 *
	 * @param format the new format
	 */
	@Override
	public void setFormat(String format) {
		this.format = format;
	}
	
	/**
	 * Gets the level 2 signed data.
	 *
	 * @return the level 2 signed data
	 */
	@Override
	public ILevel2Data getLevel2Data() {
		return level2Data;
	}

	/**
	 * Sets the level 2 signed data.
	 *
	 * @param level2SignedData the new level 2 signed data
	 */
	@Override
	public void setLevel2Data(ILevel2Data level2SignedData) {
		this.level2Data = level2SignedData;
	}

	/**
	 * Gets the level 2 signature.
	 *
	 * @return the level 2 signature
	 */
	@Override
	public byte[] getLevel2Signature() {
		return level2Signature;
	}

	/**
	 * Sets the level 2 signature.
	 *
	 * @param level2Signature the new level 2 signature
	 */
	@Override
	public void setLevel2Signature(byte[] level2Signature) {
		this.level2Signature = level2Signature;
	}


	
	/**
	 * Verify the level 2 signature
	 * 
	 * Note:  an appropriate security provider (e.g. BC) must be registered before 
	 *
	 * @return the int
	 * @throws EncodingFormatException 
	 */	
	@Override
	public int validateLevel2() throws EncodingFormatException {
		return validateLevel2(null);
	
	}
	
	/**
	 * Verify the level 2 signature
	 * 
	 * Note:  an appropriate security provider (e.g. BC) must be registered before 
	 *
	 * @param provider the registered security provider
	 * @return the return error code
	 * @throws EncodingFormatException 
	 */	
	@Override
	public int validateLevel2(Provider prov) throws EncodingFormatException {
		
		Provider provider = prov;
		
		if (getLevel2Data() == null
				|| getLevel2Data().getLevel1Data() == null 
				|| getLevel2Data().getLevel1Data().getLevel2KeyAlg() == null
				|| getLevel2Data().getLevel1Data().getLevel2KeyAlg().length() == 0) {
			return Constants.LEVEL2_VALIDATION_NO_KEY;
		}
		
		String level2KeyAlg = getLevel2Data().getLevel1Data().getLevel2KeyAlg();
		String level2SigAlg = this.getLevel2Data().getLevel1Data().getLevel2SigningAlg();

	 
		if (level2KeyAlg == null || level2KeyAlg.length() == 0) {
			return Constants.LEVEL2_VALIDATION_NO_KEY;
		}
		
		if (level2Signature == null || level2Signature.length == 0) {
			return Constants.LEVEL2_VALIDATION_NO_SIGNATURE;
		}
					
		String keyAlgName = null;
		try {
			keyAlgName = AlgorithmNameResolver.getName(AlgorithmNameResolver.TYPE_KEY_GENERATOR_ALG, level2KeyAlg,provider);
		} catch (Exception e1) {
			return Constants.LEVEL2_VALIDATION_KEY_ALG_NOT_IMPLEMENTED;	
		}
		if (keyAlgName == null || keyAlgName.length() == 0) {
			return Constants.LEVEL2_VALIDATION_KEY_ALG_NOT_IMPLEMENTED;	
		}
		
		PublicKey key = null;
		try {
			byte[] keyBytes = this.getLevel2Data().getLevel1Data().getLevel2publicKey();
			
			if (provider == null) {
				provider = SecurityUtils.findPublicKeyProvider(level2KeyAlg,keyBytes);
			} 
			KeyFactory keyFactory = KeyFactory.getInstance(keyAlgName,provider);
			if (keyFactory != null) {
				X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
				key = keyFactory.generatePublic(keySpec);
			} else {
				return Constants.LEVEL2_VALIDATION_KEY_ALG_NOT_IMPLEMENTED;	
			}
			
		} catch (InvalidKeySpecException e1) {
			return Constants.LEVEL2_VALIDATION_KEY_ALG_NOT_IMPLEMENTED;	
		} catch (NoSuchAlgorithmException e1) {
			return Constants.LEVEL2_VALIDATION_KEY_ALG_NOT_IMPLEMENTED;	
		}
		

		//find the algorithm name for the signature OID
		String sigAlgName = null;
		try {
			sigAlgName = AlgorithmNameResolver.getSignatureAlgorithmName(level2SigAlg,provider);
		} catch (Exception e1) {
			return Constants.LEVEL2_VALIDATION_SIG_ALG_NOT_IMPLEMENTED;
		}
		if (sigAlgName == null) {
			return Constants.LEVEL2_VALIDATION_SIG_ALG_NOT_IMPLEMENTED;
		}
		
		Signature sig = null;
		try {
			if (provider == null) {
				sig = Signature.getInstance(sigAlgName);
			} else {
				sig = Signature.getInstance(sigAlgName,provider);
			}
		} catch (NoSuchAlgorithmException e) {
			return Constants.LEVEL2_VALIDATION_SIG_ALG_NOT_IMPLEMENTED;
		}
		try {
			sig.initVerify(key);
		} catch (InvalidKeyException e) {
			return Constants.LEVEL2_VALIDATION_SIG_ALG_NOT_IMPLEMENTED;
		}
		
		try {
			byte[] signedData2 = getLevel2DataBin();
			sig.update(signedData2);
		} catch (SignatureException e) {
			return Constants.LEVEL2_VALIDATION_SIG_ALG_NOT_IMPLEMENTED;
		} catch (IllegalArgumentException e) {
			return Constants.LEVEL2_VALIDATION_ENCODING_ERROR;
		} catch (UnsupportedOperationException e) {
			return Constants.LEVEL2_VALIDATION_ENCODING_ERROR;
		}
		
		byte[] signature = level2Signature;
		try {
			if (sig.verify(signature)){
				return Constants.LEVEL2_VALIDATION_OK;
			} else {
				return Constants.LEVEL2_VALIDATION_FRAUD;
			}
		} catch (SignatureException e) {
			return Constants.LEVEL2_VALIDATION_SIG_ALG_NOT_IMPLEMENTED;
		}
  	}
	
	@Override
	public int validateLevel1(PublicKey key, Provider prov) throws EncodingFormatException {
		return validateLevel1(key, prov, null);

  	}
	
	@Override
	public int validateLevel1(PublicKey key) throws EncodingFormatException {
		return validateLevel1(key, null, null);
  	}
	
	@Override
	public int validateLevel1(PublicKey key, String signatureAlgorithmOid) throws EncodingFormatException {
		return validateLevel1(key, null, signatureAlgorithmOid);
	}

	@Override
	public int validateLevel1(PublicKey key, Provider prov, String signatureAlgorithmOid) throws EncodingFormatException {

		if (getLevel2Data() == null
				|| getLevel2Data().getLevel1Signature() == null
				|| getLevel2Data().getLevel1Signature() == null
				|| getLevel2Data().getLevel1Signature().length == 0) {
			return Constants.LEVEL1_VALIDATION_NO_SIGNATURE;
		}
		
		
		byte[] signature = this.getLevel2Data().getLevel1Signature();

	
		//find the algorithm name for the signature OID		
		String signingAlgorithmOid = null;
		if (getLevel2Data() != null 
				&& getLevel2Data().getLevel1Data() != null 
				&& getLevel2Data().getLevel1Data().getLevel1SigningAlg() != null
				&& getLevel2Data().getLevel1Data().getLevel1SigningAlg().length() > 0) {
				signingAlgorithmOid = getLevel2Data().getLevel1Data().getLevel1SigningAlg();	
		} else {
			signingAlgorithmOid = signatureAlgorithmOid;
		}
				
		if (signingAlgorithmOid == null || signingAlgorithmOid.length() == 0) {
			return Constants.LEVEL1_VALIDATION_NO_SIGNATURE;
		}		
		
		if (prov == null) {
			prov = SecurityUtils.findSignatureProvider(key.getEncoded(), signingAlgorithmOid);
		}

		
		//find the algorithm name for the signature OID
		String algo = null;
		try {
			algo = AlgorithmNameResolver.getSignatureAlgorithmName(signingAlgorithmOid, prov);
		} catch (Exception e1) {
			return Constants.LEVEL1_VALIDATION_SIG_ALG_NOT_IMPLEMENTED;
		}	
		if (algo == null) {
			return Constants.LEVEL1_VALIDATION_SIG_ALG_NOT_IMPLEMENTED;
		}
		
		Signature sig;
		try {
			if (prov != null) {
				sig = Signature.getInstance(algo, prov);
			} else {
				sig = Signature.getInstance(algo);

			}
		} catch (NoSuchAlgorithmException e) {
			return Constants.LEVEL1_VALIDATION_SIG_ALG_NOT_IMPLEMENTED;
		}
		try {
			key = SecurityUtils.convert(key, prov);
			sig.initVerify(key);
		} catch (InvalidKeyException e) {
			return Constants.LEVEL1_VALIDATION_SIG_ALG_NOT_IMPLEMENTED;
		}
		
		try {
			
			byte[]  encodedData = getLevel1DataBin();			
			
			sig.update(encodedData);	
			
		} catch (SignatureException e) {
			return Constants.LEVEL1_VALIDATION_SIG_ALG_NOT_IMPLEMENTED;
		} catch (IllegalArgumentException e) {
			return Constants.LEVEL1_VALIDATION_ENCODING_ERROR;
		} catch (UnsupportedOperationException e) {
			return Constants.LEVEL1_VALIDATION_ENCODING_ERROR;
		}
		
		try {
			if (sig.verify(signature)){
				return Constants.LEVEL1_VALIDATION_OK;
			} else {
				return Constants.LEVEL1_VALIDATION_FRAUD;
			}
		} catch (Exception e) {
			return Constants.LEVEL1_VALIDATION_SIG_ALG_NOT_IMPLEMENTED;
		}
	}
	
	@Override
	public void signLevel2(PrivateKey key) throws Exception {
		signLevel2(key, null);
	}

	/**
	 * Sign level 2 data.
	 *
	 * @param key the key
	 * @param prov the registered security provider
	 * @throws Exception the exception
	 */
	@Override
	public void signLevel2(PrivateKey key, Provider prov) throws Exception {

		if (prov == null) {
			prov = SecurityUtils.findPrivateKeyProvider(key);
		}
		
		//find the algorithm name for the signature OID
		String algo = AlgorithmNameResolver.getSignatureAlgorithmName(this.getLevel2Data().getLevel1Data().getLevel2SigningAlg(), prov);
		Signature sig = null;

		if (prov != null) {
			sig = Signature.getInstance(algo,prov);
		} else {
			sig = Signature.getInstance(algo);
		}
		sig.initSign(key);
		byte[] signedData = DynamicFrameCoder.encodeLevel2Data(this);
		sig.update(signedData);
		level2Signature = sig.sign();
		
	}

	
	/**
	 * Adds the dynamic content and encodes it. (API level)
	 *
	 * @param content the dynamic content
	 * @throws EncodingFormatException the encoding format exception
	 */
	@Override
	public void addDynamicContent(IUicDynamicContent content) throws EncodingFormatException {
				
		level2Data.setLevel2Data(new SimpleData());
		
		level2Data.getLevel2Data().setFormat(DynamicContentCoder.dynamicContentDataFDC1);
			
		level2Data.getLevel2Data().setData(DynamicContentCoder.encode(content, DynamicContentCoder.dynamicContentDataFDC1));
		
	}
	
	/**
	 * Adds the level 2 dynamic data. (ASN level)
	 *
	 * @param dynamicData the dynamic data
	 */
	@Override
	public void addLevel2DynamicData(UicDynamicContentDataFDC1 dynamicData) {
		this.getLevel2Data().setLevel2Data(dynamicData.getApiDataType());	
	}
	
	/**
	 * Gets the dynamic content.
	 *
	 * @return the dynamic content
	 */
	@Override
	public IUicDynamicContent getDynamicContent() {
		
		if (this.getLevel2Data() == null || 
				this.getLevel2Data().getLevel2Data() == null){
				return null;
		}
		
		return DynamicContentCoder.decode(level2Data.getLevel2Data().getData());
			
	}
	

	/**
	 * Sign the contained data block.
	 * 
	 * Note:  an appropriate security provider (e.g. BC) must be registered before 
	 *
	 * @param key the key
	 * @return 
	 * @return the byte[]
	 * @throws Exception 
	 */
	@Override
	public void signLevel1(PrivateKey key) throws Exception {
		
		signLevel1(key, null);
		
	}

	/**
	 * Sign the contained data block.
	 * 
	 * Note:  an appropriate security provider (e.g. BC) must be registered before 
	 *
	 * @param key the key
	 * @param security provider - security provider that must be sued to create the signature
	 * @return 
	 * @return the byte[]
	 * @throws Exception 
	 */
	@Override
	public void signLevel1(PrivateKey key, Provider prov) throws Exception {
		
		if (level2Data == null) return;
		
		ILevel1Data level1Data = level2Data.getLevel1Data();
		
		if (level1Data == null) return;

		if (prov == null) {
			//check for a provider supporting the key
			prov = SecurityUtils.findPrivateKeyProvider(key);
		}
		
		//find the algorithm name for the signature OID
		String algo = AlgorithmNameResolver.getSignatureAlgorithmName(level1Data.getLevel1SigningAlg(), prov);
		Signature sig = null;

		if (prov != null) {
			sig = Signature.getInstance(algo, prov);
		} else {
			sig = Signature.getInstance(algo);
		}
		sig.initSign(key);
				
		byte[] data = DynamicFrameCoder.encodeLevel1(this);
		sig.update(data);
		level2Data.setLevel1Signature(sig.sign());	
	}

	@Override
	public byte[] getLevel1Signature() {
		return getLevel2Data().getLevel1Signature();
	}

	@Override
	public byte[] getLevel1DataBin() throws EncodingFormatException {
		
		if (Constants.DYNAMIC_BARCODE_FORMAT_VERSION_1.equals(format)) {
			
			return DynamicFrameCoderV1.encode(getLevel2Data().getLevel1Data());
			
		} else if (Constants.DYNAMIC_BARCODE_FORMAT_VERSION_2.equals(format)) {
			
			return DynamicFrameCoderV2.encode(getLevel2Data().getLevel1Data());
			
		}
		
		throw new EncodingFormatException("Dynamic Header Version not supported");

	}
	
	@Override
	public byte[] getLevel2DataBin() throws EncodingFormatException {
		
		if (Constants.DYNAMIC_BARCODE_FORMAT_VERSION_1.equals(format)) {
			
			return DynamicFrameCoderV1.encodeLevel2Data(getLevel2Data());
			
		} else if (Constants.DYNAMIC_BARCODE_FORMAT_VERSION_2.equals(format)) {
			
			return DynamicFrameCoderV2.encodeLevel2Data(getLevel2Data());
			
		}
		
		throw new EncodingFormatException("Dynamic Header Version not supported");

	}



	
}