From 6eebf3f29b9658a4e74ab1d1f90146c8e029c736 Mon Sep 17 00:00:00 2001 From: CGantert345 <57003061+CGantert345@users.noreply.github.com> Date: Mon, 28 Jun 2021 17:28:50 +0200 Subject: - option to use a dedicated security provider implementation --- src/main/java/org/uic/barcode/Decoder.java | 43 +++++++++++++ src/main/java/org/uic/barcode/Encoder.java | 44 ++++++++++++- .../org/uic/barcode/dynamicFrame/DynamicFrame.java | 32 ++++++++- .../uic/barcode/dynamicFrame/Level2DataType.java | 21 ++++++ .../org/uic/barcode/staticFrame/StaticFrame.java | 75 +++++++++++++++++++++- .../uic/barcode/utils/AlgorithmNameResolver.java | 48 +++++++++----- 6 files changed, 244 insertions(+), 19 deletions(-) (limited to 'src/main/java/org/uic') diff --git a/src/main/java/org/uic/barcode/Decoder.java b/src/main/java/org/uic/barcode/Decoder.java index fe53ed0..e9dd4b0 100644 --- a/src/main/java/org/uic/barcode/Decoder.java +++ b/src/main/java/org/uic/barcode/Decoder.java @@ -3,6 +3,7 @@ package org.uic.barcode; import java.io.IOException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; +import java.security.Provider; import java.security.PublicKey; import java.security.SignatureException; import java.util.zip.DataFormatException; @@ -89,6 +90,34 @@ public class Decoder { } } + + /** + * Validate level 1. + * + * @param key the public key + * @param signingAlg the signing algorithm OID + * @param security provider in case a dedicated provider must be used (otherwise null) + * @return the return code indicating errors + * @throws InvalidKeyException the invalid key exception + * @throws NoSuchAlgorithmException the no such algorithm exception + * @throws SignatureException the signature exception + * @throws IllegalArgumentException the illegal argument exception + * @throws UnsupportedOperationException the unsupported operation exception + * @throws IOException Signals that an I/O exception has occurred. + * @throws EncodingFormatException the encoding format exception + */ + public int validateLevel1(PublicKey key, String signingAlg, Provider provider) throws InvalidKeyException, NoSuchAlgorithmException, SignatureException, IllegalArgumentException, UnsupportedOperationException, IOException, EncodingFormatException { + if (!isStaticHeader(data)) { + return dynamicFrame.validateLevel1(key) ; + } else { + if (staticFrame.verifyByAlgorithmOid(key,signingAlg, provider)) { + return Constants.LEVEL1_VALIDATION_OK; + } else { + return Constants.LEVEL1_VALIDATION_FRAUD; + } + } + } + /** * Validate level 2. * @@ -101,6 +130,20 @@ public class Decoder { return Constants.LEVEL2_VALIDATION_NO_SIGNATURE; } } + + /* + * Validate level 2. + * @param prov - provider of the java security implementation in case a dedicated provider must be used + * @return the return code indicating errors + */ + public int validateLevel2(Provider prov) { + if (!isStaticHeader(data)) { + return dynamicFrame.validateLevel2(prov) ; + } else { + return Constants.LEVEL2_VALIDATION_NO_SIGNATURE; + } + } + /** * Decode. diff --git a/src/main/java/org/uic/barcode/Encoder.java b/src/main/java/org/uic/barcode/Encoder.java index d971214..e906881 100644 --- a/src/main/java/org/uic/barcode/Encoder.java +++ b/src/main/java/org/uic/barcode/Encoder.java @@ -2,6 +2,7 @@ package org.uic.barcode; import java.io.IOException; import java.security.PrivateKey; +import java.security.Provider; import java.security.PublicKey; import org.uic.barcode.asn1.datatypesimpl.OctetString; @@ -120,6 +121,20 @@ public class Encoder { 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. @@ -193,7 +208,7 @@ public class Encoder { /** * Sign level 1 of a dynamic bar code or a static bar code. * - * @param securityProvider the security provider + * @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 @@ -215,6 +230,33 @@ public class Encoder { } } + /** + * 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.getLevel2SignedData().getLevel1Data().setSecurityProvider(securityProvider); + dynamicFrame.getLevel2SignedData().getLevel1Data().setLevel1SigningAlg(signingAlg); + dynamicFrame.getLevel2SignedData().getLevel1Data().setKeyId(Long.parseLong(keyId)); + dynamicFrame.getLevel2SignedData().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); + } + } + + /** * Sets the static header parameter. * diff --git a/src/main/java/org/uic/barcode/dynamicFrame/DynamicFrame.java b/src/main/java/org/uic/barcode/dynamicFrame/DynamicFrame.java index 375e2c6..1d96d05 100644 --- a/src/main/java/org/uic/barcode/dynamicFrame/DynamicFrame.java +++ b/src/main/java/org/uic/barcode/dynamicFrame/DynamicFrame.java @@ -4,6 +4,7 @@ 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; @@ -111,6 +112,18 @@ public class DynamicFrame extends Object{ * */ public int validateLevel2() { + + return validateLevel2(null); + + } + + /** + * Verify the level 2 signature + * + * Note: an appropriate security provider (e.g. BC) must be registered before + * + */ + public int validateLevel2(Provider prov) { String level2KeyAlg = this.getLevel2SignedData().getLevel1Data().level2KeyAlg; @@ -155,7 +168,11 @@ public class DynamicFrame extends Object{ Signature sig; try { - sig = Signature.getInstance(algo); + if (prov == null) { + sig = Signature.getInstance(algo); + } else { + sig = Signature.getInstance(algo, prov); + } } catch (NoSuchAlgorithmException e) { return Constants.LEVEL2_VALIDATION_SIG_ALG_NOT_IMPLEMENTED; } @@ -262,6 +279,19 @@ public class DynamicFrame extends Object{ this.level2Signature = new OctetString(sig.sign()); } + + public void signLevel2(PrivateKey key, Provider prov) throws Exception { + + //find the algorithm name for the signature OID + String algo = AlgorithmNameResolver.getSignatureAlgorithmName(this.getLevel2SignedData().getLevel1Data().level2SigningAlg); + Signature sig = Signature.getInstance(algo,prov); + sig.initSign(key); + byte[] data = level2SignedData.encode(); + sig.update(data); + this.level2Signature = new OctetString(sig.sign()); + + } + public void addLevel2DynamicData(UicDynamicContentDataFDC1 dynamicData) { this.getLevel2SignedData().setLevel2Data( dynamicData.getDataType()); diff --git a/src/main/java/org/uic/barcode/dynamicFrame/Level2DataType.java b/src/main/java/org/uic/barcode/dynamicFrame/Level2DataType.java index dbd25ce..8c3cd60 100644 --- a/src/main/java/org/uic/barcode/dynamicFrame/Level2DataType.java +++ b/src/main/java/org/uic/barcode/dynamicFrame/Level2DataType.java @@ -1,6 +1,7 @@ package org.uic.barcode.dynamicFrame; import java.security.PrivateKey; +import java.security.Provider; import java.security.Signature; import org.uic.barcode.asn1.datatypes.Asn1Optional; @@ -95,6 +96,26 @@ public class Level2DataType { this.level1Signature = new OctetString(sig.sign()); } + /** + * 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 + */ + public void signLevel1(PrivateKey key, Provider prov) throws Exception { + //find the algorithm name for the signature OID + String algo = AlgorithmNameResolver.getSignatureAlgorithmName(getLevel1Data().level1SigningAlg); + Signature sig = Signature.getInstance(algo, prov); + sig.initSign(key); + byte[] data = level1Data.encode(); + sig.update(data); + this.level1Signature = new OctetString(sig.sign()); + } } diff --git a/src/main/java/org/uic/barcode/staticFrame/StaticFrame.java b/src/main/java/org/uic/barcode/staticFrame/StaticFrame.java index 2759bf0..8dc1adb 100644 --- a/src/main/java/org/uic/barcode/staticFrame/StaticFrame.java +++ b/src/main/java/org/uic/barcode/staticFrame/StaticFrame.java @@ -677,6 +677,39 @@ public class StaticFrame { sig.update(getDataForSignature()); return sig.verify(this.getSignature()); } + + /** + * Verify the signature + * + * Note: an appropriate security provider (e.g. BC) must be registered before + * + * @param key the key + * @param singningAlg the Object ID of the signing algorithm + * @param a dedicated security provider to validate the signature + * @return true, if successful + * @throws InvalidKeyException the invalid key exception + * @throws NoSuchAlgorithmException the no such algorithm exception + * @throws SignatureException the signature exception + * @throws IllegalArgumentException the illegal argument exception + * @throws UnsupportedOperationException the unsupported operating exception + * @throws EncodingFormatException + * @throws IOException + */ + public boolean verifyByAlgorithmOid(PublicKey key, String signingAlg, Provider prov) throws InvalidKeyException, NoSuchAlgorithmException, SignatureException, IllegalArgumentException, UnsupportedOperationException, IOException, EncodingFormatException { + //find the algorithm name for the signature OID + String algo = null; + Service service = prov.getService("Signature",signingAlg); + if (service != null) { + algo = service.getAlgorithm(); + } + if (algo == null) { + throw new NoSuchAlgorithmException("No service for algorithm found: " + signingAlg); + } + Signature sig = Signature.getInstance(algo); + sig.initVerify(key); + sig.update(getDataForSignature()); + return sig.verify(this.getSignature()); + } /** * Sign the contained data block. @@ -695,14 +728,51 @@ public class StaticFrame { public void signByAlgorithmOID(PrivateKey key,String signingAlg) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException, IOException, EncodingFormatException { //find the algorithm name for the signature OID String algo = null; + algo = getAlgo(signingAlg); + if (algo == null) { + throw new NoSuchAlgorithmException("No service for algorthm found: " + signingAlg); + } + Signature sig = Signature.getInstance(algo); + sig.initSign(key); + signedData = getDataForSignature(); + sig.update(signedData); + signature = sig.sign(); + } + + private String getAlgo(String signingAlg) { Provider[] provs = Security.getProviders(); for (Provider prov : provs) { Service service = prov.getService("Signature",signingAlg); if (service != null) { - algo = service.getAlgorithm(); - break; + return service.getAlgorithm(); } } + return null; + } + + + + /** + * Sign the contained data block. + * + * Note: an appropriate security provider (e.g. BC) must be registered before + * + * @param key the key + * @param singningAlg the Object ID of the signing algorithm + * @return + * @throws NoSuchAlgorithmException the no such algorithm exception + * @throws InvalidKeyException the invalid key exception + * @throws SignatureException the signature exception + * @throws EncodingFormatException + * @throws IOException + */ + public void signByAlgorithmOID(PrivateKey key,String signingAlg, Provider prov) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException, IOException, EncodingFormatException { + //find the algorithm name for the signature OID + String algo = null; + Service service = prov.getService("Signature",signingAlg); + if (service != null) { + algo = service.getAlgorithm(); + } if (algo == null) { throw new NoSuchAlgorithmException("No service for algorthm found: " + signingAlg); } @@ -713,6 +783,7 @@ public class StaticFrame { signature = sig.sign(); } + /** * Sign the contained data block. * diff --git a/src/main/java/org/uic/barcode/utils/AlgorithmNameResolver.java b/src/main/java/org/uic/barcode/utils/AlgorithmNameResolver.java index e3918b0..1671ba9 100644 --- a/src/main/java/org/uic/barcode/utils/AlgorithmNameResolver.java +++ b/src/main/java/org/uic/barcode/utils/AlgorithmNameResolver.java @@ -39,24 +39,40 @@ public class AlgorithmNameResolver { Provider[] provs = Security.getProviders(); for (Provider prov : provs) { + + String name = getName(type, oid, prov); + if (name != null) return name; - SortedSet typeAndOID = getTypeAndOIDStrings(prov); - - for (String entry : typeAndOID) { - String[] typeAndOIDArray = entry.split("-"); - String ptype = typeAndOIDArray[0]; - if (ptype.equalsIgnoreCase(type)) { - String poid = typeAndOIDArray[1]; - Service pservice = prov.getService(ptype, poid); - String palgo = pservice.getAlgorithm(); - - if (poid != null && ptype.equalsIgnoreCase(type) && poid.equals(oid)) { - return palgo; - } - } - } } + if (oid.startsWith("1.2.840.10045")) { + return "ECDSA"; + } else if (oid.startsWith("1.2.840.10040")) { + return "DSA"; + } + + return null; + + } + + public static String getName(String type, String oid, Provider prov) throws Exception { + + SortedSet typeAndOID = getTypeAndOIDStrings(prov); + + for (String entry : typeAndOID) { + String[] typeAndOIDArray = entry.split("-"); + String ptype = typeAndOIDArray[0]; + if (ptype.equalsIgnoreCase(type)) { + String poid = typeAndOIDArray[1]; + Service pservice = prov.getService(ptype, poid); + String palgo = pservice.getAlgorithm(); + + if (poid != null && ptype.equalsIgnoreCase(type) && poid.equals(oid)) { + return palgo; + } + } + } + if (oid.startsWith("1.2.840.10045")) { return "ECDSA"; @@ -104,6 +120,8 @@ public class AlgorithmNameResolver { return null; } + + private static SortedSet getTypeAndOIDStrings(Provider prov) { -- cgit v1.2.3