From 3fad9a61aac40b37d0c1554aad890925f78f5690 Mon Sep 17 00:00:00 2001 From: Waldemar Dick Date: Thu, 9 Jan 2014 18:20:09 +0100 Subject: moved methods from BCStyle and RFC4519Style to an abstract super class, which have _exactly_ the same implementation --- .../asn1/x500/style/AbstractX500NameStyle.java | 127 +++++++++++++++++++++ .../org/bouncycastle/asn1/x500/style/BCStyle.java | 114 +----------------- .../bouncycastle/asn1/x500/style/RFC4519Style.java | 116 +------------------ 3 files changed, 130 insertions(+), 227 deletions(-) create mode 100644 core/src/main/java/org/bouncycastle/asn1/x500/style/AbstractX500NameStyle.java (limited to 'core/src/main/java/org') diff --git a/core/src/main/java/org/bouncycastle/asn1/x500/style/AbstractX500NameStyle.java b/core/src/main/java/org/bouncycastle/asn1/x500/style/AbstractX500NameStyle.java new file mode 100644 index 00000000..86311072 --- /dev/null +++ b/core/src/main/java/org/bouncycastle/asn1/x500/style/AbstractX500NameStyle.java @@ -0,0 +1,127 @@ +package org.bouncycastle.asn1.x500.style; + +import java.util.Enumeration; +import java.util.Hashtable; + +import org.bouncycastle.asn1.ASN1Encodable; +import org.bouncycastle.asn1.x500.AttributeTypeAndValue; +import org.bouncycastle.asn1.x500.RDN; +import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.asn1.x500.X500NameStyle; + +/** + * This class provides some default behavior and common implementation for a + * X500NameStyle. It should be easily extendible to support implementing the + * desired X500NameStyle. + * + */ +public abstract class AbstractX500NameStyle implements X500NameStyle { + + /** + * Tool function to shallow copy a Hashtable. + * + * @param paramsMap table to copy + * @return the copy of the table + */ + public static Hashtable copyHashTable(Hashtable paramsMap) { + Hashtable newTable = new Hashtable(); + + Enumeration keys = paramsMap.keys(); + while (keys.hasMoreElements()) { + Object key = keys.nextElement(); + newTable.put(key, paramsMap.get(key)); + } + + return newTable; + } + + private int calcHashCode(ASN1Encodable enc) { + String value = IETFUtils.valueToString(enc); + value = IETFUtils.canonicalize(value); + return value.hashCode(); + } + + public int calculateHashCode(X500Name name) { + int hashCodeValue = 0; + RDN[] rdns = name.getRDNs(); + + // this needs to be order independent, like equals + for (int i = 0; i != rdns.length; i++) { + if (rdns[i].isMultiValued()) { + AttributeTypeAndValue[] atv = rdns[i].getTypesAndValues(); + + for (int j = 0; j != atv.length; j++) { + hashCodeValue ^= atv[j].getType().hashCode(); + hashCodeValue ^= calcHashCode(atv[j].getValue()); + } + } else { + hashCodeValue ^= rdns[i].getFirst().getType().hashCode(); + hashCodeValue ^= calcHashCode(rdns[i].getFirst().getValue()); + } + } + + return hashCodeValue; + } + + public boolean areEqual(X500Name name1, X500Name name2) + { + RDN[] rdns1 = name1.getRDNs(); + RDN[] rdns2 = name2.getRDNs(); + + if (rdns1.length != rdns2.length) + { + return false; + } + + boolean reverse = false; + + if (rdns1[0].getFirst() != null && rdns2[0].getFirst() != null) + { + reverse = !rdns1[0].getFirst().getType().equals(rdns2[0].getFirst().getType()); // guess forward + } + + for (int i = 0; i != rdns1.length; i++) + { + if (!foundMatch(reverse, rdns1[i], rdns2)) + { + return false; + } + } + + return true; + } + + private boolean foundMatch(boolean reverse, RDN rdn, RDN[] possRDNs) + { + if (reverse) + { + for (int i = possRDNs.length - 1; i >= 0; i--) + { + if (possRDNs[i] != null && rdnAreEqual(rdn, possRDNs[i])) + { + possRDNs[i] = null; + return true; + } + } + } + else + { + for (int i = 0; i != possRDNs.length; i++) + { + if (possRDNs[i] != null && rdnAreEqual(rdn, possRDNs[i])) + { + possRDNs[i] = null; + return true; + } + } + } + + return false; + } + + protected boolean rdnAreEqual(RDN rdn1, RDN rdn2) + { + return IETFUtils.rDNAreEqual(rdn1, rdn2); + } + +} diff --git a/core/src/main/java/org/bouncycastle/asn1/x500/style/BCStyle.java b/core/src/main/java/org/bouncycastle/asn1/x500/style/BCStyle.java index 68421821..c6a8b0be 100644 --- a/core/src/main/java/org/bouncycastle/asn1/x500/style/BCStyle.java +++ b/core/src/main/java/org/bouncycastle/asn1/x500/style/BCStyle.java @@ -1,7 +1,6 @@ package org.bouncycastle.asn1.x500.style; import java.io.IOException; -import java.util.Enumeration; import java.util.Hashtable; import org.bouncycastle.asn1.ASN1Encodable; @@ -11,14 +10,13 @@ import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.DERPrintableString; import org.bouncycastle.asn1.DERUTF8String; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; -import org.bouncycastle.asn1.x500.AttributeTypeAndValue; import org.bouncycastle.asn1.x500.RDN; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x500.X500NameStyle; import org.bouncycastle.asn1.x509.X509ObjectIdentifiers; public class BCStyle - implements X500NameStyle + extends AbstractX500NameStyle { /** * country code - StringType(SIZE(2)) @@ -338,109 +336,11 @@ public class BCStyle return IETFUtils.decodeAttrName(attrName, defaultLookUp); } - public boolean areEqual(X500Name name1, X500Name name2) - { - RDN[] rdns1 = name1.getRDNs(); - RDN[] rdns2 = name2.getRDNs(); - - if (rdns1.length != rdns2.length) - { - return false; - } - - boolean reverse = false; - - if (rdns1[0].getFirst() != null && rdns2[0].getFirst() != null) - { - reverse = !rdns1[0].getFirst().getType().equals(rdns2[0].getFirst().getType()); // guess forward - } - - for (int i = 0; i != rdns1.length; i++) - { - if (!foundMatch(reverse, rdns1[i], rdns2)) - { - return false; - } - } - - return true; - } - - private boolean foundMatch(boolean reverse, RDN rdn, RDN[] possRDNs) - { - if (reverse) - { - for (int i = possRDNs.length - 1; i >= 0; i--) - { - if (possRDNs[i] != null && rdnAreEqual(rdn, possRDNs[i])) - { - possRDNs[i] = null; - return true; - } - } - } - else - { - for (int i = 0; i != possRDNs.length; i++) - { - if (possRDNs[i] != null && rdnAreEqual(rdn, possRDNs[i])) - { - possRDNs[i] = null; - return true; - } - } - } - - return false; - } - - protected boolean rdnAreEqual(RDN rdn1, RDN rdn2) - { - return IETFUtils.rDNAreEqual(rdn1, rdn2); - } - public RDN[] fromString(String dirName) { return IETFUtils.rDNsFromString(dirName, this); } - public int calculateHashCode(X500Name name) - { - int hashCodeValue = 0; - RDN[] rdns = name.getRDNs(); - - // this needs to be order independent, like equals - for (int i = 0; i != rdns.length; i++) - { - if (rdns[i].isMultiValued()) - { - AttributeTypeAndValue[] atv = rdns[i].getTypesAndValues(); - - for (int j = 0; j != atv.length; j++) - { - hashCodeValue ^= atv[j].getType().hashCode(); - hashCodeValue ^= calcHashCode(atv[j].getValue()); - } - } - else - { - hashCodeValue ^= rdns[i].getFirst().getType().hashCode(); - hashCodeValue ^= calcHashCode(rdns[i].getFirst().getValue()); - } - } - - return hashCodeValue; - } - - private int calcHashCode(ASN1Encodable enc) - { - String value = IETFUtils.valueToString(enc); - - value = IETFUtils.canonicalize(value); - - return value.hashCode(); - } - public String toString(X500Name name) { StringBuffer buf = new StringBuffer(); @@ -465,17 +365,5 @@ public class BCStyle return buf.toString(); } - private static Hashtable copyHashTable(Hashtable paramsMap) - { - Hashtable newTable = new Hashtable(); - Enumeration keys = paramsMap.keys(); - while (keys.hasMoreElements()) - { - Object key = keys.nextElement(); - newTable.put(key, paramsMap.get(key)); - } - - return newTable; - } } diff --git a/core/src/main/java/org/bouncycastle/asn1/x500/style/RFC4519Style.java b/core/src/main/java/org/bouncycastle/asn1/x500/style/RFC4519Style.java index 8c92257e..0574b6b0 100644 --- a/core/src/main/java/org/bouncycastle/asn1/x500/style/RFC4519Style.java +++ b/core/src/main/java/org/bouncycastle/asn1/x500/style/RFC4519Style.java @@ -1,7 +1,6 @@ package org.bouncycastle.asn1.x500.style; import java.io.IOException; -import java.util.Enumeration; import java.util.Hashtable; import org.bouncycastle.asn1.ASN1Encodable; @@ -9,13 +8,12 @@ import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.DERPrintableString; import org.bouncycastle.asn1.DERUTF8String; -import org.bouncycastle.asn1.x500.AttributeTypeAndValue; import org.bouncycastle.asn1.x500.RDN; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x500.X500NameStyle; public class RFC4519Style - implements X500NameStyle + extends AbstractX500NameStyle { public static final ASN1ObjectIdentifier businessCategory = new ASN1ObjectIdentifier("2.5.4.15"); public static final ASN1ObjectIdentifier c = new ASN1ObjectIdentifier("2.5.4.6"); @@ -227,67 +225,6 @@ public class RFC4519Style return IETFUtils.decodeAttrName(attrName, defaultLookUp); } - public boolean areEqual(X500Name name1, X500Name name2) - { - RDN[] rdns1 = name1.getRDNs(); - RDN[] rdns2 = name2.getRDNs(); - - if (rdns1.length != rdns2.length) - { - return false; - } - - boolean reverse = false; - - if (rdns1[0].getFirst() != null && rdns2[0].getFirst() != null) - { - reverse = !rdns1[0].getFirst().getType().equals(rdns2[0].getFirst().getType()); // guess forward - } - - for (int i = 0; i != rdns1.length; i++) - { - if (!foundMatch(reverse, rdns1[i], rdns2)) - { - return false; - } - } - - return true; - } - - private boolean foundMatch(boolean reverse, RDN rdn, RDN[] possRDNs) - { - if (reverse) - { - for (int i = possRDNs.length - 1; i >= 0; i--) - { - if (possRDNs[i] != null && rdnAreEqual(rdn, possRDNs[i])) - { - possRDNs[i] = null; - return true; - } - } - } - else - { - for (int i = 0; i != possRDNs.length; i++) - { - if (possRDNs[i] != null && rdnAreEqual(rdn, possRDNs[i])) - { - possRDNs[i] = null; - return true; - } - } - } - - return false; - } - - protected boolean rdnAreEqual(RDN rdn1, RDN rdn2) - { - return IETFUtils.rDNAreEqual(rdn1, rdn2); - } - // parse backwards public RDN[] fromString(String dirName) { @@ -302,43 +239,6 @@ public class RFC4519Style return res; } - public int calculateHashCode(X500Name name) - { - int hashCodeValue = 0; - RDN[] rdns = name.getRDNs(); - - // this needs to be order independent, like equals - for (int i = 0; i != rdns.length; i++) - { - if (rdns[i].isMultiValued()) - { - AttributeTypeAndValue[] atv = rdns[i].getTypesAndValues(); - - for (int j = 0; j != atv.length; j++) - { - hashCodeValue ^= atv[j].getType().hashCode(); - hashCodeValue ^= calcHashCode(atv[j].getValue()); - } - } - else - { - hashCodeValue ^= rdns[i].getFirst().getType().hashCode(); - hashCodeValue ^= calcHashCode(rdns[i].getFirst().getValue()); - } - } - - return hashCodeValue; - } - - private int calcHashCode(ASN1Encodable enc) - { - String value = IETFUtils.valueToString(enc); - - value = IETFUtils.canonicalize(value); - - return value.hashCode(); - } - // convert in reverse public String toString(X500Name name) { @@ -364,17 +264,5 @@ public class RFC4519Style return buf.toString(); } - private static Hashtable copyHashTable(Hashtable paramsMap) - { - Hashtable newTable = new Hashtable(); - - Enumeration keys = paramsMap.keys(); - while (keys.hasMoreElements()) - { - Object key = keys.nextElement(); - newTable.put(key, paramsMap.get(key)); - } - - return newTable; - } + } -- cgit v1.2.3 From c053c39682b3ad2b79817bb4db165a17cd8310a2 Mon Sep 17 00:00:00 2001 From: Waldemar Dick Date: Thu, 9 Jan 2014 19:00:44 +0100 Subject: move method stringToValue to super class and keep only the special cases in BCStyle and RFC4519Style --- .../asn1/x500/style/AbstractX500NameStyle.java | 55 ++++++++++++++++++++++ .../org/bouncycastle/asn1/x500/style/BCStyle.java | 48 ++++++------------- .../bouncycastle/asn1/x500/style/RFC4519Style.java | 37 ++++----------- 3 files changed, 79 insertions(+), 61 deletions(-) (limited to 'core/src/main/java/org') diff --git a/core/src/main/java/org/bouncycastle/asn1/x500/style/AbstractX500NameStyle.java b/core/src/main/java/org/bouncycastle/asn1/x500/style/AbstractX500NameStyle.java index 86311072..092e3d77 100644 --- a/core/src/main/java/org/bouncycastle/asn1/x500/style/AbstractX500NameStyle.java +++ b/core/src/main/java/org/bouncycastle/asn1/x500/style/AbstractX500NameStyle.java @@ -1,9 +1,15 @@ package org.bouncycastle.asn1.x500.style; +import java.io.IOException; import java.util.Enumeration; import java.util.Hashtable; import org.bouncycastle.asn1.ASN1Encodable; +import org.bouncycastle.asn1.ASN1GeneralizedTime; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.DERIA5String; +import org.bouncycastle.asn1.DERPrintableString; +import org.bouncycastle.asn1.DERUTF8String; import org.bouncycastle.asn1.x500.AttributeTypeAndValue; import org.bouncycastle.asn1.x500.RDN; import org.bouncycastle.asn1.x500.X500Name; @@ -63,6 +69,55 @@ public abstract class AbstractX500NameStyle implements X500NameStyle { return hashCodeValue; } + + /** + * For all string values starting with '#' is assumed, that these are + * already valid ASN.1 objects encoded in hex. + * + * All other string values are send to + * {@link AbstractX500NameStyle#encodeStringValue(ASN1ObjectIdentifier, String)}. + * + * Subclasses should overwrite + * {@link AbstractX500NameStyle#encodeStringValue(ASN1ObjectIdentifier, String)} + * to change the encoding of specific types. + * + */ + public ASN1Encodable stringToValue(ASN1ObjectIdentifier oid, String value) + { + if (value.length() != 0 && value.charAt(0) == '#') + { + try + { + return IETFUtils.valueFromHexString(value, 1); + } + catch (IOException e) + { + throw new RuntimeException("can't recode value for oid " + oid.getId()); + } + } + + if (value.length() != 0 && value.charAt(0) == '\\') + { + value = value.substring(1); + } + + return encodeStringValue(oid, value); + } + + /** + * Encoded every value into a UTF8String. + * + * Subclasses should overwrite + * this method to change the encoding of specific types. + * + * @param oid of the value + * @param value to encode + * @return a the value encoded into a ASN.1 object. Never returns null. + */ + protected ASN1Encodable encodeStringValue(ASN1ObjectIdentifier oid, String value) { + return new DERUTF8String(value); + } + public boolean areEqual(X500Name name1, X500Name name2) { RDN[] rdns1 = name1.getRDNs(); diff --git a/core/src/main/java/org/bouncycastle/asn1/x500/style/BCStyle.java b/core/src/main/java/org/bouncycastle/asn1/x500/style/BCStyle.java index c6a8b0be..dc1cc366 100644 --- a/core/src/main/java/org/bouncycastle/asn1/x500/style/BCStyle.java +++ b/core/src/main/java/org/bouncycastle/asn1/x500/style/BCStyle.java @@ -1,6 +1,5 @@ package org.bouncycastle.asn1.x500.style; -import java.io.IOException; import java.util.Hashtable; import org.bouncycastle.asn1.ASN1Encodable; @@ -8,7 +7,6 @@ import org.bouncycastle.asn1.ASN1GeneralizedTime; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.DERPrintableString; -import org.bouncycastle.asn1.DERUTF8String; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x500.RDN; import org.bouncycastle.asn1.x500.X500Name; @@ -284,41 +282,25 @@ public class BCStyle defaultLookUp = copyHashTable(DefaultLookUp); } - public ASN1Encodable stringToValue(ASN1ObjectIdentifier oid, String value) - { - if (value.length() != 0 && value.charAt(0) == '#') + + @Override + protected ASN1Encodable encodeStringValue(ASN1ObjectIdentifier oid, + String value) { + if (oid.equals(EmailAddress) || oid.equals(DC)) { - try - { - return IETFUtils.valueFromHexString(value, 1); - } - catch (IOException e) - { - throw new RuntimeException("can't recode value for oid " + oid.getId()); - } + return new DERIA5String(value); } - else + else if (oid.equals(DATE_OF_BIRTH)) // accept time string as well as # (for compatibility) { - if (value.length() != 0 && value.charAt(0) == '\\') - { - value = value.substring(1); - } - if (oid.equals(EmailAddress) || oid.equals(DC)) - { - return new DERIA5String(value); - } - else if (oid.equals(DATE_OF_BIRTH)) // accept time string as well as # (for compatibility) - { - return new ASN1GeneralizedTime(value); - } - else if (oid.equals(C) || oid.equals(SN) || oid.equals(DN_QUALIFIER) - || oid.equals(TELEPHONE_NUMBER)) - { - return new DERPrintableString(value); - } + return new ASN1GeneralizedTime(value); } - - return new DERUTF8String(value); + else if (oid.equals(C) || oid.equals(SN) || oid.equals(DN_QUALIFIER) + || oid.equals(TELEPHONE_NUMBER)) + { + return new DERPrintableString(value); + } + + return super.encodeStringValue(oid, value); } public String oidToDisplayName(ASN1ObjectIdentifier oid) diff --git a/core/src/main/java/org/bouncycastle/asn1/x500/style/RFC4519Style.java b/core/src/main/java/org/bouncycastle/asn1/x500/style/RFC4519Style.java index 0574b6b0..cc6a4281 100644 --- a/core/src/main/java/org/bouncycastle/asn1/x500/style/RFC4519Style.java +++ b/core/src/main/java/org/bouncycastle/asn1/x500/style/RFC4519Style.java @@ -1,13 +1,11 @@ package org.bouncycastle.asn1.x500.style; -import java.io.IOException; import java.util.Hashtable; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.DERPrintableString; -import org.bouncycastle.asn1.DERUTF8String; import org.bouncycastle.asn1.x500.RDN; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x500.X500NameStyle; @@ -177,37 +175,20 @@ public class RFC4519Style defaultLookUp = copyHashTable(DefaultLookUp); } - public ASN1Encodable stringToValue(ASN1ObjectIdentifier oid, String value) - { - if (value.length() != 0 && value.charAt(0) == '#') + @Override + protected ASN1Encodable encodeStringValue(ASN1ObjectIdentifier oid, + String value) { + if (oid.equals(dc)) { - try - { - return IETFUtils.valueFromHexString(value, 1); - } - catch (IOException e) - { - throw new RuntimeException("can't recode value for oid " + oid.getId()); - } + return new DERIA5String(value); } - else + else if (oid.equals(c) || oid.equals(serialNumber) || oid.equals(dnQualifier) + || oid.equals(telephoneNumber)) { - if (value.length() != 0 && value.charAt(0) == '\\') - { - value = value.substring(1); - } - if (oid.equals(dc)) - { - return new DERIA5String(value); - } - else if (oid.equals(c) || oid.equals(serialNumber) || oid.equals(dnQualifier) - || oid.equals(telephoneNumber)) - { - return new DERPrintableString(value); - } + return new DERPrintableString(value); } - return new DERUTF8String(value); + return super.encodeStringValue(oid, value); } public String oidToDisplayName(ASN1ObjectIdentifier oid) -- cgit v1.2.3