diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2023-10-23 20:24:28 +0700 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2023-10-23 20:24:28 +0700 |
commit | d1a9f294e82c74fd4d5bb2fa80016f2b7fffb75c (patch) | |
tree | 7cd49dbe4c57083745bfe5e395830d9756428d18 /crypto/src/asn1/x500/style/IetfUtilities.cs | |
parent | Clean up warnings (diff) | |
download | BouncyCastle.NET-ed25519-d1a9f294e82c74fd4d5bb2fa80016f2b7fffb75c.tar.xz |
Refactoring around X509Name
Diffstat (limited to 'crypto/src/asn1/x500/style/IetfUtilities.cs')
-rw-r--r-- | crypto/src/asn1/x500/style/IetfUtilities.cs | 112 |
1 files changed, 110 insertions, 2 deletions
diff --git a/crypto/src/asn1/x500/style/IetfUtilities.cs b/crypto/src/asn1/x500/style/IetfUtilities.cs index 72ed08dd3..acc1ed72e 100644 --- a/crypto/src/asn1/x500/style/IetfUtilities.cs +++ b/crypto/src/asn1/x500/style/IetfUtilities.cs @@ -7,15 +7,123 @@ using Org.BouncyCastle.Utilities.Encoders; namespace Org.BouncyCastle.Asn1.X500.Style { + // TODO[api] static public abstract class IetfUtilities { + internal static string Unescape(string elt) + { + if (elt.Length < 1) + return elt; + + if (elt.IndexOf('\\') < 0 && elt.IndexOf('"') < 0) + return elt.Trim(); + + bool escaped = false; + bool quoted = false; + StringBuilder buf = new StringBuilder(elt.Length); + int start = 0; + + // if it's an escaped hash string and not an actual encoding in string form + // we need to leave it escaped. + if (elt[0] == '\\') + { + if (elt[1] == '#') + { + start = 2; + buf.Append("\\#"); + } + } + + bool nonWhiteSpaceEncountered = false; + int lastEscaped = 0; + char hex1 = Convert.ToChar(0); + + for (int i = start; i != elt.Length; i++) + { + char c = elt[i]; + + if (c != ' ') + { + nonWhiteSpaceEncountered = true; + } + + if (c == '"') + { + if (!escaped) + { + quoted = !quoted; + } + else + { + buf.Append(c); + escaped = false; + } + } + else if (c == '\\' && !(escaped || quoted)) + { + escaped = true; + lastEscaped = buf.Length; + } + else + { + if (c == ' ' && !escaped && !nonWhiteSpaceEncountered) + { + continue; + } + if (escaped && IsHexDigit(c)) + { + if (hex1 != 0) + { + buf.Append(Convert.ToChar(ConvertHex(hex1) * 16 + ConvertHex(c))); + escaped = false; + hex1 = Convert.ToChar(0); + continue; + } + hex1 = c; + continue; + } + buf.Append(c); + escaped = false; + } + } + + if (buf.Length > 0) + { + int last = buf.Length - 1; + while (buf[last] == ' ' && lastEscaped != last) + { + buf.Length = last; + } + } + + return buf.ToString(); + } + + private static bool IsHexDigit(char c) + { + return ('0' <= c && c <= '9') || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F'); + } + + private static int ConvertHex(char c) + { + if ('0' <= c && c <= '9') + { + return c - '0'; + } + if ('a' <= c && c <= 'f') + { + return c - 'a' + 10; + } + return c - 'A' + 10; + } + public static string ValueToString(Asn1Encodable value) { StringBuilder vBuf = new StringBuilder(); - if (value is IAsn1String && !(value is DerUniversalString)) + if (value is IAsn1String str && !(value is DerUniversalString)) { - string v = ((IAsn1String)value).GetString(); + string v = str.GetString(); if (v.Length > 0 && v[0] == '#') { vBuf.Append('\\'); |