diff options
Diffstat (limited to 'crypto/src/asn1/x500/style/IetfUtilities.cs')
-rw-r--r-- | crypto/src/asn1/x500/style/IetfUtilities.cs | 214 |
1 files changed, 214 insertions, 0 deletions
diff --git a/crypto/src/asn1/x500/style/IetfUtilities.cs b/crypto/src/asn1/x500/style/IetfUtilities.cs new file mode 100644 index 000000000..e3236aaec --- /dev/null +++ b/crypto/src/asn1/x500/style/IetfUtilities.cs @@ -0,0 +1,214 @@ +using System; +using System.Collections; +using System.IO; +using System.Text; + +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Asn1.X500.Style +{ + public abstract class IetfUtilities + { + public static string ValueToString(Asn1Encodable value) + { + StringBuilder vBuf = new StringBuilder(); + + if (value is IAsn1String && !(value is DerUniversalString)) + { + string v = ((IAsn1String)value).GetString(); + if (v.Length > 0 && v[0] == '#') + { + vBuf.Append('\\'); + } + + vBuf.Append(v); + } + else + { + try + { + vBuf.Append('#'); + vBuf.Append(Hex.ToHexString(value.ToAsn1Object().GetEncoded(Asn1Encodable.Der))); + } + catch (IOException e) + { + throw new ArgumentException("Other value has no encoded form", "value", e); + } + } + + int end = vBuf.Length; + int index = 0; + + if (vBuf.Length >= 2 && vBuf[0] == '\\' && vBuf[1] == '#') + { + index += 2; + } + + while (index != end) + { + switch (vBuf[index]) + { + case ',': + case '"': + case '\\': + case '+': + case '=': + case '<': + case '>': + case ';': + { + vBuf.Insert(index, "\\"); + index += 2; + ++end; + break; + } + default: + { + ++index; + break; + } + } + } + + int start = 0; + if (vBuf.Length > 0) + { + while (vBuf.Length > start && vBuf[start] == ' ') + { + vBuf.Insert(start, "\\"); + start += 2; + } + } + + int endBuf = vBuf.Length - 1; + + while (endBuf >= 0 && vBuf[endBuf] == ' ') + { + vBuf.Insert(endBuf, '\\'); + endBuf--; + } + + return vBuf.ToString(); + } + + public static string Canonicalize(string s) + { + string value = Platform.ToLowerInvariant(s); + + if (value.Length > 0 && value[0] == '#') + { + Asn1Object obj = DecodeObject(value); + + if (obj is IAsn1String) + { + value = Platform.ToLowerInvariant(((IAsn1String)obj).GetString()); + } + } + + if (value.Length > 1) + { + int start = 0; + while (start + 1 < value.Length && value[start] == '\\' && value[start + 1] == ' ') + { + start += 2; + } + + int end = value.Length - 1; + while (end - 1 > 0 && value[end - 1] == '\\' && value[end] == ' ') + { + end -= 2; + } + + if (start > 0 || end < value.Length - 1) + { + value = value.Substring(start, end + 1 - start); + } + } + + return StripInternalSpaces(value); + } + + public static string CanonicalString(Asn1Encodable value) + { + return Canonicalize(ValueToString(value)); + } + + private static Asn1Object DecodeObject(string oValue) + { + try + { + return Asn1Object.FromByteArray(Hex.Decode(oValue.Substring(1))); + } + catch (IOException e) + { + throw new InvalidOperationException("unknown encoding in name: " + e); + } + } + + public static string StripInternalSpaces(string str) + { + if (str.IndexOf(" ") < 0) + return str; + + StringBuilder res = new StringBuilder(); + + char c1 = str[0]; + res.Append(c1); + + for (int k = 1; k < str.Length; k++) + { + char c2 = str[k]; + if (!(' ' == c1 && ' ' == c2)) + { + res.Append(c2); + c1 = c2; + } + } + + return res.ToString(); + } + + public static bool RdnAreEqual(Rdn rdn1, Rdn rdn2) + { + if (rdn1.Count != rdn2.Count) + return false; + + AttributeTypeAndValue[] atvs1 = rdn1.GetTypesAndValues(); + AttributeTypeAndValue[] atvs2 = rdn2.GetTypesAndValues(); + + if (atvs1.Length != atvs2.Length) + return false; + + for (int i = 0; i != atvs1.Length; i++) + { + if (!AtvAreEqual(atvs1[i], atvs2[i])) + return false; + } + + return true; + } + + private static bool AtvAreEqual(AttributeTypeAndValue atv1, AttributeTypeAndValue atv2) + { + if (atv1 == atv2) + return true; + if (null == atv1 || null == atv2) + return false; + + DerObjectIdentifier o1 = atv1.Type; + DerObjectIdentifier o2 = atv2.Type; + + if (!o1.Equals(o2)) + return false; + + string v1 = CanonicalString(atv1.Value); + string v2 = CanonicalString(atv2.Value); + + if (!v1.Equals(v2)) + return false; + + return true; + } + } +} |