From e670f1fdbc43f0d0854896a1afe2815f8a9f4c87 Mon Sep 17 00:00:00 2001 From: CGantert345 <57003061+CGantert345@users.noreply.github.com> Date: Mon, 11 Apr 2022 15:06:48 +0200 Subject: fixing DOSIPAS algorithm names and supported EC curves --- .../dynamicFrame/api/SimpleDynamicFrame.java | 43 ++++- .../uic/barcode/utils/AlgorithmNameResolver.java | 187 ++++++++++++++------- .../java/org/uic/barcode/utils/SecurityUtils.java | 129 ++++++++++++++ 3 files changed, 288 insertions(+), 71 deletions(-) create mode 100644 src/main/java/org/uic/barcode/utils/SecurityUtils.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/uic/barcode/dynamicFrame/api/SimpleDynamicFrame.java b/src/main/java/org/uic/barcode/dynamicFrame/api/SimpleDynamicFrame.java index a05a936..ef31166 100644 --- a/src/main/java/org/uic/barcode/dynamicFrame/api/SimpleDynamicFrame.java +++ b/src/main/java/org/uic/barcode/dynamicFrame/api/SimpleDynamicFrame.java @@ -20,6 +20,7 @@ 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; @@ -132,13 +133,15 @@ public class SimpleDynamicFrame implements IDynamicFrame { * * Note: an appropriate security provider (e.g. BC) must be registered before * - * @param prov the registered security provider + * @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 @@ -159,7 +162,7 @@ public class SimpleDynamicFrame implements IDynamicFrame { String keyAlgName = null; try { - keyAlgName = AlgorithmNameResolver.getName(AlgorithmNameResolver.TYPE_KEY_GENERATOR_ALG, level2KeyAlg,prov); + keyAlgName = AlgorithmNameResolver.getName(AlgorithmNameResolver.TYPE_KEY_GENERATOR_ALG, level2KeyAlg,provider); } catch (Exception e1) { return Constants.LEVEL2_VALIDATION_KEY_ALG_NOT_IMPLEMENTED; } @@ -171,7 +174,20 @@ public class SimpleDynamicFrame implements IDynamicFrame { try { byte[] keyBytes = this.getLevel2Data().getLevel1Data().getLevel2publicKey(); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); - key = KeyFactory.getInstance(keyAlgName).generatePublic(keySpec); + + KeyFactory keyFactory = null; + if (provider == null) { + keyFactory = SecurityUtils.findKeyFactory(level2KeyAlg, keyBytes); + provider = keyFactory.getProvider(); + } else { + keyFactory = KeyFactory.getInstance(keyAlgName,provider); + } + if (keyFactory != null) { + 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) { @@ -183,7 +199,7 @@ public class SimpleDynamicFrame implements IDynamicFrame { String sigAlgName = null; try { - sigAlgName = AlgorithmNameResolver.getName(AlgorithmNameResolver.TYPE_SIGNATURE_ALG,level2SigAlg,prov); + sigAlgName = AlgorithmNameResolver.getSignatureAlgorithmName(level2SigAlg,provider); } catch (Exception e1) { return Constants.LEVEL2_VALIDATION_SIG_ALG_NOT_IMPLEMENTED; } @@ -191,12 +207,12 @@ public class SimpleDynamicFrame implements IDynamicFrame { return Constants.LEVEL2_VALIDATION_SIG_ALG_NOT_IMPLEMENTED; } - Signature sig; + Signature sig = null; try { - if (prov == null) { + if (provider == null) { sig = Signature.getInstance(sigAlgName); } else { - sig = Signature.getInstance(sigAlgName, prov); + sig = Signature.getInstance(sigAlgName,provider); } } catch (NoSuchAlgorithmException e) { return Constants.LEVEL2_VALIDATION_SIG_ALG_NOT_IMPLEMENTED; @@ -321,7 +337,7 @@ public class SimpleDynamicFrame implements IDynamicFrame { } else { return Constants.LEVEL1_VALIDATION_FRAUD; } - } catch (SignatureException e) { + } catch (Exception e) { return Constants.LEVEL1_VALIDATION_SIG_ALG_NOT_IMPLEMENTED; } } @@ -344,6 +360,9 @@ public class SimpleDynamicFrame implements IDynamicFrame { //find the algorithm name for the signature OID String algo = AlgorithmNameResolver.getSignatureAlgorithmName(this.getLevel2Data().getLevel1Data().getLevel2SigningAlg(), prov); Signature sig = null; + if (prov == null) { + prov = SecurityUtils.findPrivateKeyProvider(key); + } if (prov != null) { sig = Signature.getInstance(algo,prov); } else { @@ -438,10 +457,16 @@ public class SimpleDynamicFrame implements IDynamicFrame { 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()); + String algo = AlgorithmNameResolver.getSignatureAlgorithmName(level1Data.getLevel1SigningAlg(), prov); Signature sig = null; + if (prov != null) { sig = Signature.getInstance(algo, prov); } else { diff --git a/src/main/java/org/uic/barcode/utils/AlgorithmNameResolver.java b/src/main/java/org/uic/barcode/utils/AlgorithmNameResolver.java index a3154f3..28f90e6 100644 --- a/src/main/java/org/uic/barcode/utils/AlgorithmNameResolver.java +++ b/src/main/java/org/uic/barcode/utils/AlgorithmNameResolver.java @@ -3,98 +3,161 @@ package org.uic.barcode.utils; import java.security.Provider; import java.security.Provider.Service; import java.security.Security; +import java.util.HashMap; +/** + * The Class AlgorithmNameResolver. + */ public class AlgorithmNameResolver { + /** The Constant TYPE_KEY_GENERATOR_ALG. */ public static final String TYPE_KEY_GENERATOR_ALG = "KeyPairGenerator"; + + /** The Constant TYPE_SIGNATURE_ALG. */ public static final String TYPE_SIGNATURE_ALG = "Signature"; + /** The map. */ + private static HashMap> map = new HashMap>(); + + /** + * Adds an entry for a mapping of algorithm type and oid to an algorithm name + * + * @param type the algorithm type + * @param oid the algorithm OID + * @param name the algorithm name + */ + public static void addMap (String type, String oid, String name) { + + if (map.get(type) == null) { + HashMap list = new HashMap(); + list.put(oid, name); + map.put(type, list); + } else { + map.get(type).put(oid, name); + } + } + + /** + * Gets the signature algorithm name. + * + * @param oid the oid + * @return the signature algorithm name + * @throws Exception the exception + */ public static String getSignatureAlgorithmName (String oid) throws Exception { - Provider[] provs = Security.getProviders(); - for (Provider prov : provs) { - Service service = prov.getService(AlgorithmNameResolver.TYPE_SIGNATURE_ALG,oid); - if (service != null) { - return service.getAlgorithm(); - } - } - return null; + return getSignatureAlgorithmName (oid, null); } + /** + * Gets the signature algorithm name. + * + * @param oid the oid + * @param provider the provider + * @return the signature algorithm name + * @throws Exception the exception + */ public static String getSignatureAlgorithmName (String oid, Provider provider) throws Exception { + return getAlgorithmName(AlgorithmNameResolver.TYPE_SIGNATURE_ALG,oid,provider); + + } + + /** + * Gets the name. + * + * @param type the type + * @param oid the oid + * @return the name + * @throws Exception the exception + */ + public static String getName (String type, String oid) throws Exception { + + return getAlgorithmName(type,oid,null); + + } + + + /** + * Gets the name. + * + * @param type the type + * @param oid the oid + * @param provider the provider + * @return the name + * @throws Exception the exception + */ + public static String getName(String type, String oid, Provider provider) throws Exception { + + return getAlgorithmName(type,oid,provider); + + } + + + + /** + * Gets the algorithm name. + * + * @param type the type + * @param oid the oid + * @param provider the provider + * @return the algorithm name + * @throws Exception the exception + */ + public static String getAlgorithmName (String type, String oid, Provider provider) throws Exception { + + String name = null; + if (provider != null) { - Service service = provider.getService(AlgorithmNameResolver.TYPE_SIGNATURE_ALG,oid); - return service.getAlgorithm(); + Service service = provider.getService(type,oid); + if (service != null) { + name = service.getAlgorithm(); + } + + if (name != null && name.length() > 0) { + return name; + } } Provider[] provs = Security.getProviders(); for (Provider prov : provs) { - Service service = prov.getService(AlgorithmNameResolver.TYPE_SIGNATURE_ALG,oid); + Service service = prov.getService(type,oid); if (service != null) { - return service.getAlgorithm(); + name = service.getAlgorithm(); + } + if (name != null && name.length() > 0) { + return name; } } - return null; - - } - - - public static String getName (String type, String oid) throws Exception { - - Provider[] provs = Security.getProviders(); - for (Provider prov : provs) { - Service service = prov.getService(type,oid); - if (service != null) { - return service.getAlgorithm(); - } - } - - if (oid.startsWith("1.2.840.10045")) { + + if (map.get(type) != null) { + if (map.get(type).get(oid) != null) { + return map.get(type).get(oid); + } + } + + + //fallback if the provider did not implement OIDs + if (oid.startsWith("1.2.840.10045.4")) { return "ECDSA"; - } else if (oid.startsWith("1.2.840.10040")) { - return "DSA"; - } - - return null; - - } - - - public static String getName(String type, String oid, Provider provider) throws Exception { - - Service service = null; - if (provider == null) { - - Provider[] provs = Security.getProviders(); - for (Provider prov : provs) { - service = prov.getService(type,oid); - } - - } else { - service = provider.getService(type,oid); - } - - - - if (service != null) { - return service.getAlgorithm(); - } - - if (oid.startsWith("1.2.840.10045")) { + } else if (oid.startsWith("1.2.840.10045.3")) { + return "EC"; + } else if (oid.startsWith("1.2.840.10045")) { return "ECDSA"; } else if (oid.startsWith("1.2.840.10040")) { return "DSA"; } - - return null; - - } + + return null; + + } + + diff --git a/src/main/java/org/uic/barcode/utils/SecurityUtils.java b/src/main/java/org/uic/barcode/utils/SecurityUtils.java new file mode 100644 index 0000000..542208b --- /dev/null +++ b/src/main/java/org/uic/barcode/utils/SecurityUtils.java @@ -0,0 +1,129 @@ +package org.uic.barcode.utils; + +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.Provider; +import java.security.PublicKey; +import java.security.Security; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; + +public class SecurityUtils { + + public static KeyFactory findKeyFactory(String oid, byte[] keyBytes) { + + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + + String name = null; + try { + name = AlgorithmNameResolver.getName(AlgorithmNameResolver.TYPE_KEY_GENERATOR_ALG, oid); + } catch (Exception e2) { + return null; + } + if (name == null || name.length() == 0) { + return null; + } + + KeyFactory keyFactory = null; + + Provider[] provs = Security.getProviders(); + for (Provider provider : provs) { + try { + keyFactory = KeyFactory.getInstance(name,provider); + } catch (NoSuchAlgorithmException e1) { + //try next + } + if (keyFactory != null) { + try { + keyFactory.generatePublic(keySpec); + return keyFactory; + } catch (Exception e) { + //try next + } + } + } + return null; + + } + + + public static Provider findPrivateKeyProvider(PrivateKey key) { + + String name = key.getAlgorithm(); + byte[] keyBytes = key.getEncoded(); + + + PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes); + + + KeyFactory keyFactory = null; + + Provider[] provs = Security.getProviders(); + for (Provider provider : provs) { + try { + keyFactory = KeyFactory.getInstance(name,provider); + } catch (NoSuchAlgorithmException e1) { + //try next + } + if (keyFactory != null) { + try { + keyFactory.generatePrivate(keySpec); + return provider; + } catch (Exception e) { + provider = null; + //try next + } + } + } + + return null; + } + + + + public static PublicKey convertPublicKey(PublicKey key) { + + + PublicKey publicKey; + try { + publicKey = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(key.getEncoded())); + } catch (InvalidKeySpecException | NoSuchAlgorithmException e) { + return key; + } + + return publicKey; + + } + + + public static PublicKey convert(PublicKey key, Provider provider) { + + PublicKey publicKey; + try { + publicKey = KeyFactory.getInstance("RSA", provider).generatePublic(new X509EncodedKeySpec(key.getEncoded())); + } catch (InvalidKeySpecException | NoSuchAlgorithmException e) { + return key; + } + + return publicKey; + + + } + + + public static PrivateKey convertPrivateKey(PrivateKey key) { + + + PrivateKey privateKey; + try { + privateKey = KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(key.getEncoded())); + } catch (InvalidKeySpecException | NoSuchAlgorithmException e) { + return key; + } + + return privateKey; + + } +} -- cgit v1.2.3