summaryrefslogblamecommitdiffstats
path: root/src/main/java/org/uic/barcode/Encoder.java
blob: f8dae029430aa9a0c9ca7fe0e4c8f950edc4dfa3 (plain) (tree)
1
2
3
4
5
6
7
8
9



                                 
                               
                                
                                          
 
                                                              
                                                                      
                                               
                                                           

                                                       
                                                     



                                                            

                                                            
                                          



                                                    
                                                                     


                                                       
                                           











                                          
                                                   



                                                


                                          






                                                                         


                                                                 








































                                                                                                                                                                  


                                                                                            



                                                    



                                                                                                            
                                 
                                                                     

                                                                                              
                                                                           





                                                                                                 

                                                                                                  

                                 




                                                                  


                  




































                                                                                                                                


















































                                                                                                                                       




                                 












                                                                  













                                                                                     








                                                                                  

                                                                                                            











                                                                                                       

                                                                                    
                          

                                                                                                         
                          

                                                                                                            
                                                 
                                                                                                                         



                          























                                                                                                                                                                 

                                                                                                

                                                                                    




                                                                 
                                                      
                                            

                                                                                    
                                         
                                                                                


                  
                                                                               
                                            

                                                                                    
                                         
                                                                                          


                  


                                                                                    



                             

                                                        
                                                                                    




                                                                 

         


                                                                    
                                                                                                                 






                                                                                                                          


                                                                                                                    


                                                                                                      


                                                                           


                                                                         

                                                                                           






                                                                                                                                 
                                                                        

                                                                           



                  










                                                                                                                                         



                                                                                                            






                                                                                                                         

                                                                           




                  
















                                                                             
                                                 
























                                                                           
                                                                       

                                                     

                                                  




                             








                                                                                           
 







                                                     




         
package org.uic.barcode;

import java.io.IOException;
import java.security.PrivateKey;
import java.security.Provider;
import java.security.PublicKey;
import java.util.zip.DataFormatException;

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.api.DynamicFrameCoder;
import org.uic.barcode.dynamicFrame.api.IData;
import org.uic.barcode.dynamicFrame.api.IDynamicFrame;
import org.uic.barcode.dynamicFrame.api.ILevel1Data;
import org.uic.barcode.dynamicFrame.api.SimpleData;
import org.uic.barcode.dynamicFrame.api.SimpleDynamicFrame;
import org.uic.barcode.dynamicFrame.api.SimpleLevel1Data;
import org.uic.barcode.dynamicFrame.api.SimpleLevel2Data;
import org.uic.barcode.dynamicFrame.v1.DynamicFrameCoderV1;
import org.uic.barcode.dynamicFrame.v2.DynamicFrameCoderV2;
import org.uic.barcode.ssbFrame.SsbFrame;
import org.uic.barcode.staticFrame.StaticFrame;
import org.uic.barcode.staticFrame.UFLEXDataRecord;
import org.uic.barcode.staticFrame.UHEADDataRecord;
import org.uic.barcode.staticFrame.UTLAYDataRecord;
import org.uic.barcode.staticFrame.ticketLayoutBarcode.TicketLayout;
import org.uic.barcode.ticket.EncodingFormatException;
import org.uic.barcode.ticket.UicRailTicketCoder;
import org.uic.barcode.ticket.api.spec.IUicRailTicket;
import org.uic.barcode.utils.ECKeyEncoder;


/**
 * The Class Encoder.
 * 
 * signing and encoding of UIC bar codes 
 * 
 * 
 */
public class Encoder {
	
	/** The dynamic frame. */
	private IDynamicFrame dynamicFrame = null;

	/** The static frame. */
	private StaticFrame staticFrame = null;
	
	/** The ssb frame. */
	private SsbFrame ssbFrame = null;
	

	/** The UIC bar code type classic. */
	public static String UIC_BARCODE_TYPE_CLASSIC = "UIC_CLASSIC";
	
	/** The UIC bar code type DOSIPAS. */
	public static String UIC_BARCODE_TYPE_DOSIPAS = "UIC_DOSIPAS";	
	
	/** The UIC bar code type SSB. */
	public static String UIC_BARCODE_TYPE_SSB = "UIC_SSB";	
	
	/**
	 * Instantiates a new encoder.
	 *
	 * @param ticket the ticket
	 * @param layout the layout
	 * @param barcodeType the bar code type
	 * @param version the version of the bar code 
	 * @param fcbVersion the fcb version
	 * @throws IOException Signals that an I/O exception has occurred.
	 * @throws EncodingFormatException the encoding format exception
	 */
	public Encoder(IUicRailTicket ticket, TicketLayout layout, String barcodeType, int version, int fcbVersion) throws IOException, EncodingFormatException {
		
		if (barcodeType == UIC_BARCODE_TYPE_CLASSIC) {

			staticFrame = new StaticFrame();
			staticFrame.setVersion(version);
			
			if (layout != null) {
						
				UHEADDataRecord head = new UHEADDataRecord();
				head.setVersionId("01");
				staticFrame.setHeaderRecord(head);				
				
				UTLAYDataRecord tlay = new UTLAYDataRecord();
				tlay.setLayout(layout);
				tlay.setVersionId("01");
				staticFrame.setuTlay(tlay);
			}		
			
			if (ticket != null) {
				
				UFLEXDataRecord flex = new UFLEXDataRecord();
				flex.setTicket(ticket);
				flex.setVersionId(String.format("%02d",fcbVersion));
				staticFrame.setuFlex(flex);
			}
			
			
		} else if (barcodeType == UIC_BARCODE_TYPE_DOSIPAS) {
			
			dynamicFrame = new SimpleDynamicFrame();
			dynamicFrame.setLevel2Data(new SimpleLevel2Data());
			dynamicFrame.getLevel2Data().setLevel1Data(new SimpleLevel1Data());
			
			if (ticket != null) {
				
				if (version == 1) {
					dynamicFrame.setFormat(Constants.DYNAMIC_BARCODE_FORMAT_VERSION_1);
				} else if (version == 2) {
					dynamicFrame.setFormat(Constants.DYNAMIC_BARCODE_FORMAT_VERSION_2);
				} 
				
				IData ticketData = new SimpleData();
				
				UicRailTicketCoder uicTicketCoder = new UicRailTicketCoder();
				if (fcbVersion == 1 || fcbVersion == 13) {
					ticketData.setFormat(Constants.DATA_TYPE_FCB_VERSION_1);
				} else if (fcbVersion == 2) {
					ticketData.setFormat(Constants.DATA_TYPE_FCB_VERSION_2);
				} else if (fcbVersion == 3) {
					ticketData.setFormat(Constants.DATA_TYPE_FCB_VERSION_3);
				}
				ticketData.setData(uicTicketCoder.encode(ticket, fcbVersion));
				dynamicFrame.getLevel2Data().getLevel1Data().addData(ticketData);
				
			}
			
		} else if (barcodeType == UIC_BARCODE_TYPE_SSB) {
			
			ssbFrame = new SsbFrame();

		}
	}
	
	/**
	 * Instantiates a new encoder for a level 2 encoding.
	 *
	 * @param level1Data the level 1 data (binary as signed)
	 * @param signatureLevel1 the signature of the level 1 data 
	 * @param version the version of the bar code 
	 * @throws IOException Signals that an I/O exception has occurred.
	 * @throws EncodingFormatException the encoding format exception
	 */
	public Encoder(byte[] level1DataBin, byte[] signatureLevel1, int version) throws IOException, EncodingFormatException {
		
			
		dynamicFrame = new SimpleDynamicFrame();
		dynamicFrame.setLevel2Data(new SimpleLevel2Data());
			
		if (version == 1) {
			
			dynamicFrame.setFormat(Constants.DYNAMIC_BARCODE_FORMAT_VERSION_1);
			
			ILevel1Data l1 = DynamicFrameCoderV1.decodeLevel1(level1DataBin);
			
			dynamicFrame.getLevel2Data().setLevel1Data(l1);
			
			dynamicFrame.getLevel2Data().setLevel1Signature(signatureLevel1);
			
		} else if (version == 2) {
			
			dynamicFrame.setFormat(Constants.DYNAMIC_BARCODE_FORMAT_VERSION_2);
			
			ILevel1Data l1 = DynamicFrameCoderV2.decodeLevel1(level1DataBin);
			
			dynamicFrame.getLevel2Data().setLevel1Data(l1);
			
			dynamicFrame.getLevel2Data().setLevel1Signature(signatureLevel1);
			
		} else {
			throw new EncodingFormatException("Version of the dynamic header not supported");
		}
		
				
	}
	
	
	/**
	 * Instantiates a new encoder for a level 2 encoding with tan encoded dynamic frame containing the level 1 data and signature.
	 *
	 * @param level1Data the level 1 data (binary as signed)
	 * @param signatureLevel1 the signature of the level 1 data 
	 * @param version the version of the bar code 
	 * @throws IOException Signals that an I/O exception has occurred.
	 * @throws EncodingFormatException the encoding format exception
	 * @throws DataFormatException 
	 */
	public Encoder(byte[] encoded, int version) throws IOException, EncodingFormatException, DataFormatException {
		
		Decoder decoder = new Decoder(encoded);
		
		if (decoder.getDynamicFrame() == null) {
			throw new EncodingFormatException("No dynamic frame included");
		}
		
			
		dynamicFrame = decoder.getDynamicFrame();
		byte[] level1DataBin = decoder.getEncodedLevel1Data();
		byte[] signatureLevel1 = decoder.getLevel1Signature();
			
		if (version == 1) {
			
			dynamicFrame.setFormat(Constants.DYNAMIC_BARCODE_FORMAT_VERSION_1);
			
			ILevel1Data l1 = DynamicFrameCoderV1.decodeLevel1(level1DataBin);
			
			dynamicFrame.getLevel2Data().setLevel1Data(l1);
			
			dynamicFrame.getLevel2Data().setLevel1Signature(signatureLevel1);
			
		} else if (version == 2) {
			
			dynamicFrame.setFormat(Constants.DYNAMIC_BARCODE_FORMAT_VERSION_2);
			
			ILevel1Data l1 = DynamicFrameCoderV2.decodeLevel1(level1DataBin);
			
			dynamicFrame.getLevel2Data().setLevel1Data(l1);
			
			dynamicFrame.getLevel2Data().setLevel1Signature(signatureLevel1);
			
		} else {
			throw new EncodingFormatException("Version of the dynamic header not supported");
		}
		
				
	}
	
	
	
	/**
	 * Signing level 2 of a dynamic bar code
	 *     
	 * @param key the key
	 * @throws Exception the exception
	 */
	public void signLevel2(PrivateKey key) throws Exception {
		if (dynamicFrame != null) {
			dynamicFrame.signLevel2(key);
		} 
	}
	
	/**
	 * Signing level 2 of a dynamic bar code
	 *     
	 * @param key the key
	 * @param provider - provider of the java security implementation to be used
	 * @throws Exception the exception
	 */
	public void signLevel2(PrivateKey key, Provider prov) throws Exception {
		if (dynamicFrame != null) {
			dynamicFrame.signLevel2(key, prov);
		} 
	}


	/**
	 * Sets the level 1 algorithm Is.
	 *
	 * @param level1SigningAlg the level 1 signing algorithm (OID)
	 * @param level1KeyAlg the level 1 key algorithm (OID)
	 */
	public void setLevel1Algs(String level1SigningAlg, String level1KeyAlg) {
		if (dynamicFrame != null) {
			dynamicFrame.getLevel2Data().getLevel1Data().setLevel1SigningAlg(level1SigningAlg);
			dynamicFrame.getLevel2Data().getLevel1Data().setLevel1KeyAlg(level1KeyAlg);	
		}
	}
	
	/**
	 * Sets the level 2 algorithm Is.
	 *
	 * @param level2SigningAlg the level 2 signing algorithm (OID)
	 * @param level2KeyAlg the level 2 key algorithm (OID)
	 * @param publicKey the public key of the level 2 signature
	 */
	public void setLevel2Algs(String level2SigningAlg, String level2KeyAlg, PublicKey publicKey) {
		if (dynamicFrame != null) {
			if (dynamicFrame.getLevel2Data() == null) {
				dynamicFrame.setLevel2Data(new SimpleLevel2Data());
			}
			if (dynamicFrame.getLevel2Data().getLevel1Data() == null) {
				dynamicFrame.getLevel2Data().setLevel1Data(new SimpleLevel1Data());	
			}
			dynamicFrame.getLevel2Data().getLevel1Data().setLevel2SigningAlg(level2SigningAlg);
			dynamicFrame.getLevel2Data().getLevel1Data().setLevel2KeyAlg(level2KeyAlg);
			if (publicKey != null) {
				dynamicFrame.getLevel2Data().getLevel1Data().setLevel2publicKey(publicKey.getEncoded());
			}
		}
	}
	
	/**
	 * Sets the level 2 algorithm Is.
	 *
	 * @param level2SigningAlg the level 2 signing algorithm (OID)
	 * @param level2KeyAlg the level 2 key algorithm (OID)
	 * @param publicKey the public key of the level 2 signature
	 * @param publicKeyEncodingFormat "X509", for elliptic curve keys only: "X962_UNCOMPRESSED", "X962_COMPRESSED" constants defined in class ECKeyEncoder.	
	 **/
	public void setLevel2Algs(String level2SigningAlg, String level2KeyAlg, PublicKey publicKey, String publicKeyEncodingFormat) {
		if (dynamicFrame != null) {
			if (dynamicFrame.getLevel2Data() == null) {
				dynamicFrame.setLevel2Data(new SimpleLevel2Data());
			}
			if (dynamicFrame.getLevel2Data().getLevel1Data() == null) {
				dynamicFrame.getLevel2Data().setLevel1Data(new SimpleLevel1Data());	
			}
			dynamicFrame.getLevel2Data().getLevel1Data().setLevel2SigningAlg(level2SigningAlg);
			dynamicFrame.getLevel2Data().getLevel1Data().setLevel2KeyAlg(level2KeyAlg);
			if (publicKey != null) {
				dynamicFrame.getLevel2Data().getLevel1Data().setLevel2publicKey(ECKeyEncoder.getEncoded(publicKey, publicKeyEncodingFormat));
			}
		}
	}
	
	public void setDynamicData(IUicDynamicContent content) throws EncodingFormatException {
		if (dynamicFrame != null) {
			if (dynamicFrame.getLevel2Data() == null) {
				dynamicFrame.setLevel2Data(new SimpleLevel2Data());
			}		
			dynamicFrame.addDynamicContent(content);
		}		
	}
	
	public void setLevel2Data(IData level2data) {
		if (dynamicFrame != null) {
			if (dynamicFrame.getLevel2Data() == null) {
				dynamicFrame.setLevel2Data(new SimpleLevel2Data());
			}		
			dynamicFrame.getLevel2Data().setLevel2Data(level2data);
		}
	}
	
	public void setDynamicContentDataUIC1(UicDynamicContentDataFDC1 dcd) {
		if (dynamicFrame != null) {
			if (dynamicFrame.getLevel2Data() == null) {
				dynamicFrame.setLevel2Data(new SimpleLevel2Data());
			}		
			dynamicFrame.getLevel2Data().setLevel2Data(dcd.getApiDataType());
		}
	}
		
	public IData getLevel2Data() {
		if (dynamicFrame != null && dynamicFrame.getLevel2Data() != null) {
			return dynamicFrame.getLevel2Data().getLevel2Data();
		}
		return null;
	}
	
	
	public IUicDynamicContent getDynamicContent() {
		if (dynamicFrame != null && dynamicFrame.getLevel2Data() != null) {
			return dynamicFrame.getDynamicContent();
		}
		return null;
	}
	

	
	/**
	 * Sign level 1 of a dynamic bar code or a static bar code.
	 *
	 * @param securityProvider the security provider (RICS code of the company responsible for the security)
	 * @param key the key
	 * @param signingAlg the signing algorithm (OID)
	 * @param keyId the key id
	 * @throws Exception the exception
	 */
	public void signLevel1(String securityProvider,PrivateKey key,String signingAlg, String keyId) throws Exception {
		if (dynamicFrame != null) {
			if (securityProvider != null && securityProvider.length() > 0) {
				dynamicFrame.getLevel2Data().getLevel1Data().setSecurityProvider(securityProvider);
			}
			dynamicFrame.getLevel2Data().getLevel1Data().setLevel1SigningAlg(signingAlg);
			dynamicFrame.getLevel2Data().getLevel1Data().setKeyId(Long.parseLong(keyId));
			dynamicFrame.signLevel1(key);
		} else if (staticFrame != null) {
			staticFrame.setSignatureKey(keyId);
			staticFrame.setSecurityProvider(securityProvider);
			if (securityProvider != null &&
				securityProvider.length() > 0 &&	
				staticFrame.getHeaderRecord()!= null) {
				staticFrame.getHeaderRecord().setIssuer(securityProvider);
			}
			if (securityProvider != null &&
				securityProvider.length() > 0 &&	
				staticFrame.getuFlex() != null && 
				staticFrame.getuFlex().getTicket() != null &&
				staticFrame.getuFlex().getTicket().getIssuerDetails() != null) {
				staticFrame.getuFlex().getTicket().getIssuerDetails().setSecurityProvider(securityProvider);	
			}
			staticFrame.signByAlgorithmOID(key,signingAlg);
		} else if (ssbFrame != null) {
			ssbFrame.signLevel1(key, null, keyId, signingAlg);
		}
	}
	
	/**
	 * Sign level 1 of a dynamic bar code or a static bar code.
	 *
	 * @param securityProvider the security provider (RICS code of the company responsible for the security)
	 * @param key the key
	 * @param signingAlg the signing algorithm (OID)
	 * @param keyId the key id
	 * @param provider - the provider of the java security implementation
	 * @throws Exception the exception
	 */
	public void signLevel1(String securityProvider,PrivateKey key,String signingAlg, String keyId, Provider prov) throws Exception {
		if (dynamicFrame != null) {
			dynamicFrame.getLevel2Data().getLevel1Data().setSecurityProvider(securityProvider);
			dynamicFrame.getLevel2Data().getLevel1Data().setLevel1SigningAlg(signingAlg);
			dynamicFrame.getLevel2Data().getLevel1Data().setKeyId(Long.parseLong(keyId));
			dynamicFrame.signLevel1(key,prov);
		} else if (staticFrame != null) {
			staticFrame.setSignatureKey(keyId);
			staticFrame.setSecurityProvider(securityProvider);
			if (staticFrame.getHeaderRecord()!= null && staticFrame.getHeaderRecord().getIssuer() == null) {
				staticFrame.getHeaderRecord().setIssuer(securityProvider);
			}
			staticFrame.signByAlgorithmOID(key,signingAlg,prov);
		} else if (ssbFrame != null) {
			ssbFrame.signLevel1(key, prov, keyId, signingAlg);
		}
	}
	
	
	/**
	 * Sets the static header parameter.
	 *
	 * @param ticketId the ticket id
	 * @param language the language
	 */
	public void setStaticHeaderParams(String ticketId,String language) {
	  if (staticFrame != null && staticFrame.getHeaderRecord()!= null) {
		staticFrame.getHeaderRecord().setIdentifier(ticketId);
		staticFrame.getHeaderRecord().setLanguage(language);
	  }
	}

	/**
	 * Gets the dynamic frame.
	 *
	 * @return the dynamic frame
	 */
	public IDynamicFrame getDynamicFrame() {
		return dynamicFrame;
	}
	
	
	
	/**
	 * Gets the static frame.
	 *
	 * @return the static frame
	 */
	public StaticFrame getStaticFrame() {
		return staticFrame;
	}



	/**
	 * Encodes the signed bar code data 
	 *
	 * @return the byte[]
	 * @throws IOException Signals that an I/O exception has occurred.
	 * @throws Exception the exception
	 */
	public byte[] encode() throws IOException, Exception {
		if (dynamicFrame != null) {
			return DynamicFrameCoder.encode(dynamicFrame);
		} else if (staticFrame != null) {
			return staticFrame.encode();
		} else if (ssbFrame != null) {
			return ssbFrame.encode();
		}
		return null;
	}


	public byte[] getEncodedLevel1Data() throws IOException, EncodingFormatException {
		if (dynamicFrame != null) {
			return DynamicFrameCoder.encodeLevel1(dynamicFrame);
		} else if (staticFrame != null) {
			return staticFrame.getDataForSignature();
		} else {
			throw new EncodingFormatException("Unknown Header");
		}		
	}

	public SsbFrame getSsbFrame() {
		return ssbFrame;
	}

	public void setSsbFrame(SsbFrame ssbFrame) {
		this.ssbFrame = ssbFrame;
	}

	
	
	

}