blob: 9605a0da3245cff010c31ef76178206d3892b577 (
plain) (
tree)
|
|
package org.uic.barcode.dynamicFrame;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.SignatureException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;
import org.uic.barcode.asn1.datatypes.Asn1Optional;
import org.uic.barcode.asn1.datatypes.CharacterRestriction;
import org.uic.barcode.asn1.datatypes.FieldOrder;
import org.uic.barcode.asn1.datatypes.HasExtensionMarker;
import org.uic.barcode.asn1.datatypes.RestrictedString;
import org.uic.barcode.asn1.datatypes.Sequence;
import org.uic.barcode.asn1.datatypesimpl.OctetString;
import org.uic.barcode.asn1.uper.UperEncoder;
import org.uic.barcode.utils.AlgorithmNameResolver;
/**
* The DynamicHeader for bar codes
*
* Implementation of the Draft under discussion, not final.
*/
@Sequence
@HasExtensionMarker
public class DynamicFrame extends Object{
public DynamicFrame() {}
/** The format. */
@FieldOrder(order = 0)
@RestrictedString(CharacterRestriction.IA5String)
public String format;
/*level 2 data*/
@FieldOrder(order = 1)
Level2DataType level2SignedData;
/** The signature of level 2 data*/
@FieldOrder(order = 2)
@Asn1Optional public OctetString level2Signature;
/**
* Gets the format.
*
* @return the format
*/
public String getFormat() {
return format;
}
/**
* Sets the format.
*
* @param format the new format
*/
public void setFormat(String format) {
this.format = format;
}
public Level2DataType getLevel2SignedData() {
return level2SignedData;
}
public void setLevel2SignedData(Level2DataType level2SignedData) {
this.level2SignedData = level2SignedData;
}
public OctetString getLevel2Signature() {
return level2Signature;
}
public void setLevel2Signature(OctetString level2Signature) {
this.level2Signature = level2Signature;
}
/**
* Encode.
*
* Encode the header as ASN.1 PER UNALIGNED byte array
*
* @return the byte[]
*/
public byte[] encode() {
return UperEncoder.encode(this);
}
/**
* Decode.
*
* Decode the header from an ASN.1 PER UNALIGNED encoded byte array
*
* @param bytes the bytes
* @return the dynamic header
*/
public static DynamicFrame decode(byte[] bytes) {
return UperEncoder.decode(bytes, DynamicFrame.class);
}
/**
* Verify the level 2 signature
*
* Note: an appropriate security provider (e.g. BC) must be registered before
*
*/
public int validateLevel2() {
String level2KeyAlg = this.getLevel2SignedData().getLevel1Data().level2KeyAlg;
if (level2KeyAlg == null || level2KeyAlg.length() == 0) {
return Constants.LEVEL2_VALIDATION_NO_KEY;
}
if (this.level2Signature.toByteArray() == null || this.level2Signature.toByteArray().length == 0) {
return Constants.LEVEL2_VALIDATION_NO_SIGNATURE;
}
String keyAlgName = null;
try {
keyAlgName = AlgorithmNameResolver.getName(AlgorithmNameResolver.TYPE_KEY_GENERATOR_ALG, level2KeyAlg);
} 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 {
key = KeyFactory.getInstance(keyAlgName).generatePublic(new X509EncodedKeySpec(this.getLevel2SignedData().getLevel1Data().level2publicKey.toByteArray()));
} catch (InvalidKeySpecException | NoSuchAlgorithmException e1) {
return Constants.LEVEL2_VALIDATION_KEY_ALG_NOT_IMPLEMENTED;
}
//find the algorithm name for the signature OID
String algo = null;
try {
algo = AlgorithmNameResolver.getName(AlgorithmNameResolver.TYPE_SIGNATURE_ALG,this.getLevel2SignedData().getLevel1Data().level2SigningAlg);
} catch (Exception e1) {
return Constants.LEVEL2_VALIDATION_SIG_ALG_NOT_IMPLEMENTED;
}
if (algo == null) {
return Constants.LEVEL2_VALIDATION_SIG_ALG_NOT_IMPLEMENTED;
}
Signature sig;
try {
sig = Signature.getInstance(algo);
} 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 {
sig.update(UperEncoder.encode(level2SignedData));
} 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.toByteArray();
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;
}
}
/**
* Verify the level 1 signature
*
* Note: an appropriate security provider (e.g. BC) must be registered before
*
*/
public int validateLevel1(PublicKey key) {
if (this.level2SignedData == null) {
return Constants.LEVEL1_VALIDATION_NO_SIGNATURE;
}
if (this.level2SignedData.level1Signature == null || this.level2SignedData.level1Signature.toByteArray().length == 0) {
return Constants.LEVEL1_VALIDATION_NO_SIGNATURE;
}
byte[] signature = this.getLevel2SignedData().level1Signature.toByteArray();
//find the algorithm name for the signature OID
String algo = null;
try {
algo = AlgorithmNameResolver.getSignatureAlgorithmName(getLevel2SignedData().getLevel1Data().level1SigningAlg);
} 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 {
sig = Signature.getInstance(algo);
} catch (NoSuchAlgorithmException e) {
return Constants.LEVEL1_VALIDATION_SIG_ALG_NOT_IMPLEMENTED;
}
try {
sig.initVerify(key);
} catch (InvalidKeyException e) {
return Constants.LEVEL1_VALIDATION_SIG_ALG_NOT_IMPLEMENTED;
}
try {
sig.update(this.level2SignedData.level1Data.encode());
} 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.LEVEL2_VALIDATION_OK;
} else {
return Constants.LEVEL2_VALIDATION_FRAUD;
}
} catch (SignatureException e) {
return Constants.LEVEL2_VALIDATION_SIG_ALG_NOT_IMPLEMENTED;
}
}
public void signLevel2(PrivateKey key) throws Exception {
//find the algorithm name for the signature OID
String algo = AlgorithmNameResolver.getSignatureAlgorithmName(this.getLevel2SignedData().getLevel1Data().level2SigningAlg);
Signature sig = Signature.getInstance(algo);
sig.initSign(key);
byte[] data = level2SignedData.encode();
sig.update(data);
this.level2Signature = new OctetString(sig.sign());
}
}
|