public unsafe string Decode(X500DistinguishedNameFlags flag) { uint dwStrType = 3 | MapNameToStrFlag(flag); byte[] rawData = base.m_rawData; fixed (byte* numRef = rawData) { CAPIBase.CRYPTOAPI_BLOB cryptoapi_blob; IntPtr pName = new IntPtr((void*) &cryptoapi_blob); cryptoapi_blob.cbData = (uint) rawData.Length; cryptoapi_blob.pbData = new IntPtr((void*) numRef); uint csz = CAPISafe.CertNameToStrW(0x10001, pName, dwStrType, SafeLocalAllocHandle.InvalidHandle, 0); if (csz == 0) { throw new CryptographicException(-2146762476); } using (SafeLocalAllocHandle handle = CAPI.LocalAlloc(0x40, new IntPtr((long) (2 * csz)))) { if (CAPISafe.CertNameToStrW(0x10001, pName, dwStrType, handle, csz) == 0) { throw new CryptographicException(-2146762476); } return Marshal.PtrToStringUni(handle.DangerousGetHandle()); } } }
public unsafe string X500DistinguishedNameDecode(byte[] encodedDistinguishedName, X500DistinguishedNameFlags flag) { using (SafeX509NameHandle x509Name = Interop.libcrypto.OpenSslD2I(Interop.libcrypto.d2i_X509_NAME, encodedDistinguishedName)) { Interop.libcrypto.CheckValidOpenSslHandle(x509Name); using (SafeBioHandle bioHandle = Interop.libcrypto.BIO_new(Interop.libcrypto.BIO_s_mem())) { Interop.libcrypto.CheckValidOpenSslHandle(bioHandle); OpenSslX09NameFormatFlags nativeFlags = ConvertFormatFlags(flag); int written = Interop.libcrypto.X509_NAME_print_ex( bioHandle, x509Name, 0, new UIntPtr((uint)nativeFlags)); // X509_NAME_print_ex returns how many bytes were written into the buffer. // BIO_gets wants to ensure that the response is NULL-terminated. // So add one to leave space for the NULL. StringBuilder builder = new StringBuilder(written + 1); int read = Interop.libcrypto.BIO_gets(bioHandle, builder, builder.Capacity); if (read < 0) { throw Interop.libcrypto.CreateOpenSslCryptographicException(); } return builder.ToString(); } } }
public X500DistinguishedName (string distinguishedName, X500DistinguishedNameFlags flag) { if (distinguishedName == null) throw new ArgumentNullException ("distinguishedName"); if ((flag != 0) && ((flag & AllFlags) == 0)) throw new ArgumentException ("flag"); Oid = new Oid (); if (distinguishedName.Length == 0) { // empty (0x00) ASN.1 sequence (0x30) RawData = new byte [2] { 0x30, 0x00 }; DecodeRawData (); } else { ASN1 dn = MX.X501.FromString (distinguishedName); if ((flag & X500DistinguishedNameFlags.Reversed) != 0) { ASN1 rdn = new ASN1 (0x30); for (int i = dn.Count - 1; i >= 0; i--) rdn.Add (dn [i]); dn = rdn; } RawData = dn.GetBytes (); if (flag == X500DistinguishedNameFlags.None) name = distinguishedName; else name = Decode (flag); } }
// // Public methods. // public string Decode (X500DistinguishedNameFlags flag) { uint dwStrType = CAPI.CERT_X500_NAME_STR | MapNameToStrFlag(flag); unsafe { byte[] encodedDistinguishedName = this.m_rawData; fixed (byte * pbEncoded = encodedDistinguishedName) { CAPI.CRYPTOAPI_BLOB nameBlob; IntPtr pNameBlob = new IntPtr(&nameBlob); nameBlob.cbData = (uint) encodedDistinguishedName.Length; nameBlob.pbData = new IntPtr(pbEncoded); uint cchDecoded = CAPI.CertNameToStrW(CAPI.X509_ASN_ENCODING | CAPI.PKCS_7_ASN_ENCODING, pNameBlob, dwStrType, SafeLocalAllocHandle.InvalidHandle, 0); if (cchDecoded == 0) throw new CryptographicException(CAPI.CERT_E_INVALID_NAME); using (SafeLocalAllocHandle pwszDecodeName = CAPI.LocalAlloc(CAPI.LPTR, new IntPtr(2 * cchDecoded))) { if (CAPI.CertNameToStrW(CAPI.X509_ASN_ENCODING | CAPI.PKCS_7_ASN_ENCODING, pNameBlob, dwStrType, pwszDecodeName, cchDecoded) == 0) throw new CryptographicException(CAPI.CERT_E_INVALID_NAME); return Marshal.PtrToStringUni(pwszDecodeName.DangerousGetHandle()); } } } }
public static void TestDecodeFormats(X500DistinguishedNameFlags format) { // The Issuer field from the Microsoft.com test cert. byte[] encoding = ( "3077310B3009060355040613025553311D301B060355040A131453796D616E74" + "656320436F72706F726174696F6E311F301D060355040B131653796D616E7465" + "63205472757374204E6574776F726B312830260603550403131F53796D616E74" + "656320436C61737320332045562053534C204341202D204733").HexToByteArray(); X500DistinguishedName name = new X500DistinguishedName(encoding); string delimiter; switch (format) { case X500DistinguishedNameFlags.UseCommas: delimiter = ", "; break; case X500DistinguishedNameFlags.UseSemicolons: delimiter = "; "; break; case X500DistinguishedNameFlags.UseNewLines: delimiter = Environment.NewLine; break; default: throw new InvalidOperationException("No handler for format: " + format); } string expected = string.Format( "C=US{0}O=Symantec Corporation{0}OU=Symantec Trust Network{0}CN=Symantec Class 3 EV SSL CA - G3", delimiter); string actual = name.Decode(format); Assert.Equal(expected, actual); }
private static void ThrowIfInvalid(X500DistinguishedNameFlags flags) { // All values or'ed together. Change this if you add values to the enumeration. uint allFlags = 0x71F1; uint dwFlags = (uint)flags; if ((dwFlags & ~allFlags) != 0) throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, SR.Arg_EnumIllegalVal, "flag")); }
private static byte[] Encode(string distinguishedName, X500DistinguishedNameFlags flags) { if (distinguishedName == null) throw new ArgumentNullException("distinguishedName"); ThrowIfInvalid(flags); return X509Pal.Instance.X500DistinguishedNameEncode(distinguishedName, flags); }
public byte[] X500DistinguishedNameEncode(string distinguishedName, X500DistinguishedNameFlags flag) { Debug.Assert(distinguishedName != null); Interop.Crypt32.CertNameStrTypeAndFlags dwStrType = Interop.Crypt32.CertNameStrTypeAndFlags.CERT_X500_NAME_STR | MapNameToStrFlag(flag); int cbEncoded = 0; if (!Interop.Crypt32.CertStrToName(Interop.Crypt32.CertEncodingType.All, distinguishedName, dwStrType, IntPtr.Zero, null, ref cbEncoded, IntPtr.Zero)) throw Marshal.GetLastWin32Error().ToCryptographicException(); byte[] encodedName = new byte[cbEncoded]; if (!Interop.Crypt32.CertStrToName(Interop.Crypt32.CertEncodingType.All, distinguishedName, dwStrType, IntPtr.Zero, encodedName, ref cbEncoded, IntPtr.Zero)) throw Marshal.GetLastWin32Error().ToCryptographicException(); return encodedName; }
public byte[] X500DistinguishedNameEncode(string distinguishedName, X500DistinguishedNameFlags flag) { Debug.Assert(distinguishedName != null); CertNameStrTypeAndFlags dwStrType = CertNameStrTypeAndFlags.CERT_X500_NAME_STR | MapNameToStrFlag(flag); int cbEncoded = 0; if (!Interop.crypt32.CertStrToName(CertEncodingType.All, distinguishedName, dwStrType, IntPtr.Zero, null, ref cbEncoded, IntPtr.Zero)) throw Marshal.GetLastWin32Error().ToCryptographicException(); byte[] encodedName = new byte[cbEncoded]; if (!Interop.crypt32.CertStrToName(CertEncodingType.All, distinguishedName, dwStrType, IntPtr.Zero, encodedName, ref cbEncoded, IntPtr.Zero)) throw Marshal.GetLastWin32Error().ToCryptographicException(); return encodedName; }
// private stuff private static string GetSeparator(X500DistinguishedNameFlags flag) { if ((flag & X500DistinguishedNameFlags.UseSemicolons) != 0) { return("; "); } if ((flag & X500DistinguishedNameFlags.UseCommas) != 0) { return(", "); } if ((flag & X500DistinguishedNameFlags.UseNewLines) != 0) { return(Environment.NewLine); } return(", "); //default }
// of all X500DistinguishedNameFlags flags nothing can do a "correct" comparison :| internal static bool AreEqual(X500DistinguishedName name1, X500DistinguishedName name2) { if (name1 == null) { return(name2 == null); } if (name2 == null) { return(false); } if (name1.canonEncoding != null && name2.canonEncoding != null) { if (name1.canonEncoding.Length != name2.canonEncoding.Length) { return(false); } for (int i = 0; i < name1.canonEncoding.Length; i++) { if (name1.canonEncoding[i] != name2.canonEncoding[2]) { return(false); } } return(true); } X500DistinguishedNameFlags flags = X500DistinguishedNameFlags.UseNewLines | X500DistinguishedNameFlags.DoNotUseQuotes; string[] split = new string[] { Environment.NewLine }; string[] parts1 = name1.Decode(flags).Split(split, StringSplitOptions.RemoveEmptyEntries); string[] parts2 = name2.Decode(flags).Split(split, StringSplitOptions.RemoveEmptyEntries); if (parts1.Length != parts2.Length) { return(false); } for (int i = 0; i < parts1.Length; i++) { if (Canonize(parts1[i]) != Canonize(parts2[i])) { return(false); } } return(true); }
internal static string X500DistinguishedNameDecode( byte[] encodedName, bool printOid, X500DistinguishedNameFlags flags, bool addTrailingDelimiter = false) { bool reverse = (flags & X500DistinguishedNameFlags.Reversed) == X500DistinguishedNameFlags.Reversed; bool quoteIfNeeded = (flags & X500DistinguishedNameFlags.DoNotUseQuotes) != X500DistinguishedNameFlags.DoNotUseQuotes; bool useMultiSeparator = (flags & X500DistinguishedNameFlags.DoNotUsePlusSign) != X500DistinguishedNameFlags.DoNotUsePlusSign; string dnSeparator; if ((flags & X500DistinguishedNameFlags.UseSemicolons) == X500DistinguishedNameFlags.UseSemicolons) { dnSeparator = "; "; } // Explicit UseCommas has preference over explicit UseNewLines. else if ((flags & (X500DistinguishedNameFlags.UseNewLines | X500DistinguishedNameFlags.UseCommas)) == X500DistinguishedNameFlags.UseNewLines) { dnSeparator = Environment.NewLine; } else { // This is matching Windows (native) behavior, UseCommas does not need to be asserted, // it is just what happens if neither UseSemicolons nor UseNewLines is specified. dnSeparator = ", "; } string multiValueSparator = useMultiSeparator ? " + " : " "; try { return(X500DistinguishedNameDecode( encodedName, printOid, reverse, quoteIfNeeded, dnSeparator, multiValueSparator, addTrailingDelimiter)); } catch (CryptographicException) { // Windows compat: return(""); } }
/// <summary>Decodes a distinguished name using the characteristics specified by the <paramref name="flag" /> parameter.</summary> /// <returns>The decoded distinguished name.</returns> /// <param name="flag">A flag that specifies the characteristics of the <see cref="T:System.Security.Cryptography.X509Certificates.X500DistinguishedName" /> object.</param> /// <exception cref="T:System.Security.Cryptography.CryptographicException">The certificate has an invalid name.</exception> public string Decode(X500DistinguishedNameFlags flag) { if (flag != X500DistinguishedNameFlags.None && (flag & (X500DistinguishedNameFlags.Reversed | X500DistinguishedNameFlags.UseSemicolons | X500DistinguishedNameFlags.DoNotUsePlusSign | X500DistinguishedNameFlags.DoNotUseQuotes | X500DistinguishedNameFlags.UseCommas | X500DistinguishedNameFlags.UseNewLines | X500DistinguishedNameFlags.UseUTF8Encoding | X500DistinguishedNameFlags.UseT61Encoding | X500DistinguishedNameFlags.ForceUTF8Encoding)) == X500DistinguishedNameFlags.None) { throw new ArgumentException("flag"); } if (base.RawData.Length == 0) { return(string.Empty); } bool reversed = (flag & X500DistinguishedNameFlags.Reversed) != X500DistinguishedNameFlags.None; bool quotes = (flag & X500DistinguishedNameFlags.DoNotUseQuotes) == X500DistinguishedNameFlags.None; string separator = X500DistinguishedName.GetSeparator(flag); ASN1 seq = new ASN1(base.RawData); return(X501.ToString(seq, reversed, separator, quotes)); }
public X500DistinguishedName(string distinguishedName, X500DistinguishedNameFlags flag) { if (distinguishedName == null) { throw new ArgumentNullException("distinguishedName"); } if ((flag != 0) && ((flag & AllFlags) == 0)) { throw new ArgumentException("flag"); } Oid = new Oid(); if (distinguishedName.Length == 0) { // empty (0x00) ASN.1 sequence (0x30) RawData = new byte [2] { 0x30, 0x00 }; DecodeRawData(); } else { ASN1 dn = MX.X501.FromString(distinguishedName); if ((flag & X500DistinguishedNameFlags.Reversed) != 0) { ASN1 rdn = new ASN1(0x30); for (int i = dn.Count - 1; i >= 0; i--) { rdn.Add(dn [i]); } dn = rdn; } RawData = dn.GetBytes(); if (flag == X500DistinguishedNameFlags.None) { name = distinguishedName; } else { name = Decode(flag); } } }
private static OpenSslX09NameFormatFlags ConvertFormatFlags(X500DistinguishedNameFlags inFlags) { OpenSslX09NameFormatFlags outFlags = 0; if (inFlags.HasFlag(X500DistinguishedNameFlags.Reversed)) { outFlags |= OpenSslX09NameFormatFlags.XN_FLAG_DN_REV; } if (inFlags.HasFlag(X500DistinguishedNameFlags.UseSemicolons)) { outFlags |= OpenSslX09NameFormatFlags.XN_FLAG_SEP_SPLUS_SPC; } else if (inFlags.HasFlag(X500DistinguishedNameFlags.UseNewLines)) { outFlags |= OpenSslX09NameFormatFlags.XN_FLAG_SEP_MULTILINE; } else { outFlags |= OpenSslX09NameFormatFlags.XN_FLAG_SEP_CPLUS_SPC; } if (inFlags.HasFlag(X500DistinguishedNameFlags.DoNotUseQuotes)) { // TODO: Handle this. } if (inFlags.HasFlag(X500DistinguishedNameFlags.ForceUTF8Encoding)) { // TODO: Handle this. } if (inFlags.HasFlag(X500DistinguishedNameFlags.UseUTF8Encoding)) { // TODO: Handle this. } else if (inFlags.HasFlag(X500DistinguishedNameFlags.UseT61Encoding)) { // TODO: Handle this. } return(outFlags); }
public static string FormatName(MonoBtlsX509Name name, X500DistinguishedNameFlags flag) { if ((flag != 0) && ((flag & AllFlags) == 0)) { throw new ArgumentException("flag"); } if (name.GetEntryCount() == 0) { return(String.Empty); } // Mono.Security reversed isn't the same as fx 2.0 (which is the reverse of 1.x) bool reversed = ((flag & X500DistinguishedNameFlags.Reversed) != 0); bool quotes = ((flag & X500DistinguishedNameFlags.DoNotUseQuotes) == 0); string separator = GetSeparator(flag); return(FormatName(name, reversed, separator, quotes)); }
internal static byte[] X500DistinguishedNameEncode( string stringForm, X500DistinguishedNameFlags flags) { bool reverse = (flags & X500DistinguishedNameFlags.Reversed) == X500DistinguishedNameFlags.Reversed; bool noQuotes = (flags & X500DistinguishedNameFlags.DoNotUseQuotes) == X500DistinguishedNameFlags.DoNotUseQuotes; List <char> dnSeparators; // This rank ordering is based off of testing against the Windows implementation. if ((flags & X500DistinguishedNameFlags.UseSemicolons) == X500DistinguishedNameFlags.UseSemicolons) { // Just semicolon. dnSeparators = s_useSemicolonSeparators; } else if ((flags & X500DistinguishedNameFlags.UseCommas) == X500DistinguishedNameFlags.UseCommas) { // Just comma dnSeparators = s_useCommaSeparators; } else if ((flags & X500DistinguishedNameFlags.UseNewLines) == X500DistinguishedNameFlags.UseNewLines) { // CR or LF. Not "and". Whichever is first was the separator, the later one is trimmed as whitespace. dnSeparators = s_useNewlineSeparators; } else { // Comma or semicolon, but not CR or LF. dnSeparators = s_defaultSeparators; } Debug.Assert(dnSeparators.Count != 0); List <byte[][]> encodedSets = ParseDistinguishedName(stringForm, dnSeparators, noQuotes); if (reverse) { encodedSets.Reverse(); } return(DerEncoder.ConstructSequence(encodedSets)); }
/// <summary>Initializes a new instance of the <see cref="T:System.Security.Cryptography.X509Certificates.X500DistinguishedName" /> class using the specified string and <see cref="T:System.Security.Cryptography.X509Certificates.X500DistinguishedNameFlags" /> flag.</summary> /// <param name="distinguishedName">A string that represents the distinguished name.</param> /// <param name="flag">An <see cref="T:System.Security.Cryptography.X509Certificates.X500DistinguishedName" /> object that specifies the characteristics of the distinguished name.</param> public X500DistinguishedName(string distinguishedName, X500DistinguishedNameFlags flag) { if (distinguishedName == null) { throw new ArgumentNullException("distinguishedName"); } if (flag != X500DistinguishedNameFlags.None && (flag & (X500DistinguishedNameFlags.Reversed | X500DistinguishedNameFlags.UseSemicolons | X500DistinguishedNameFlags.DoNotUsePlusSign | X500DistinguishedNameFlags.DoNotUseQuotes | X500DistinguishedNameFlags.UseCommas | X500DistinguishedNameFlags.UseNewLines | X500DistinguishedNameFlags.UseUTF8Encoding | X500DistinguishedNameFlags.UseT61Encoding | X500DistinguishedNameFlags.ForceUTF8Encoding)) == X500DistinguishedNameFlags.None) { throw new ArgumentException("flag"); } base.Oid = new Oid(); if (distinguishedName.Length == 0) { byte[] array = new byte[2]; array[0] = 48; base.RawData = array; this.DecodeRawData(); } else { ASN1 asn = X501.FromString(distinguishedName); if ((flag & X500DistinguishedNameFlags.Reversed) != X500DistinguishedNameFlags.None) { ASN1 asn2 = new ASN1(48); for (int i = asn.Count - 1; i >= 0; i--) { asn2.Add(asn[i]); } asn = asn2; } base.RawData = asn.GetBytes(); if (flag == X500DistinguishedNameFlags.None) { this.name = distinguishedName; } else { this.name = this.Decode(flag); } } }
public string Decode(X500DistinguishedNameFlags flag) { if ((flag != 0) && ((flag & AllFlags) == 0)) { throw new ArgumentException("flag"); } if (RawData.Length == 0) { return(String.Empty); } // Mono.Security reversed isn't the same as fx 2.0 (which is the reverse of 1.x) bool reversed = ((flag & X500DistinguishedNameFlags.Reversed) != 0); bool quotes = ((flag & X500DistinguishedNameFlags.DoNotUseQuotes) == 0); string separator = GetSeparator(flag); ASN1 rdn = new ASN1(RawData); return(MX.X501.ToString(rdn, reversed, separator, quotes)); }
private static void VerifySeparatorProcessing(X500DistinguishedNameFlags flags) { const string input = "CN=a, O=b; OU=c\r L=d\n S=e"; // No separator flags: , and ; => CN, O, OU const string withNoFlags = "CN=a, O=b, OU=\"c\r L=d\n S=e\""; // UseNewlines: \r and \n => CN, L, S const string withNewlines = "CN=\"a, O=b; OU=c\", L=d, S=e"; // UseCommas: , => CN, O const string withCommas = "CN=a, O=\"b; OU=c\r L=d\n S=e\""; // UseSemicolons: ; => CN, OU const string withSemicolons = "CN=\"a, O=b\", OU=\"c\r L=d\n S=e\""; string expected; // Semicolons, if specified, always wins. // then commas, if specified, wins. // then newlines, if specified is valid. // Specifying nothing at all is (for some reason) both commas and semicolons. if ((flags & X500DistinguishedNameFlags.UseSemicolons) != 0) { expected = withSemicolons; } else if ((flags & X500DistinguishedNameFlags.UseCommas) != 0) { expected = withCommas; } else if ((flags & X500DistinguishedNameFlags.UseNewLines) != 0) { expected = withNewlines; } else { expected = withNoFlags; } X500DistinguishedName dn = new X500DistinguishedName(input, flags); Assert.Equal(expected, dn.Format(false)); }
public string Decode(X500DistinguishedNameFlags flag) { uint dwStrType = CAPI.CERT_X500_NAME_STR | MapNameToStrFlag(flag); unsafe { byte[] encodedDistinguishedName = this.m_rawData; fixed(byte *pbEncoded = encodedDistinguishedName) { CAPI.CRYPTOAPI_BLOB nameBlob; IntPtr pNameBlob = new IntPtr(&nameBlob); nameBlob.cbData = (uint)encodedDistinguishedName.Length; nameBlob.pbData = new IntPtr(pbEncoded); uint cchDecoded = CAPI.CertNameToStrW(CAPI.X509_ASN_ENCODING | CAPI.PKCS_7_ASN_ENCODING, pNameBlob, dwStrType, SafeLocalAllocHandle.InvalidHandle, 0); if (cchDecoded == 0) { throw new CryptographicException(CAPI.CERT_E_INVALID_NAME); } using (SafeLocalAllocHandle pwszDecodeName = CAPI.LocalAlloc(CAPI.LPTR, new IntPtr(2 * cchDecoded))) { if (CAPI.CertNameToStrW(CAPI.X509_ASN_ENCODING | CAPI.PKCS_7_ASN_ENCODING, pNameBlob, dwStrType, pwszDecodeName, cchDecoded) == 0) { throw new CryptographicException(CAPI.CERT_E_INVALID_NAME); } return(Marshal.PtrToStringUni(pwszDecodeName.DangerousGetHandle())); } } } }
private static unsafe byte[] Encode(string distinguishedName, X500DistinguishedNameFlags flag) { if (distinguishedName == null) { throw new ArgumentNullException("distinguishedName"); } uint pcbEncoded = 0; uint dwStrType = 3 | MapNameToStrFlag(flag); if (!CAPISafe.CertStrToNameW(0x10001, distinguishedName, dwStrType, IntPtr.Zero, IntPtr.Zero, ref pcbEncoded, IntPtr.Zero)) { throw new CryptographicException(Marshal.GetLastWin32Error()); } byte[] buffer = new byte[pcbEncoded]; fixed (byte* numRef = buffer) { if (!CAPISafe.CertStrToNameW(0x10001, distinguishedName, dwStrType, IntPtr.Zero, new IntPtr((void*) numRef), ref pcbEncoded, IntPtr.Zero)) { throw new CryptographicException(Marshal.GetLastWin32Error()); } } return buffer; }
private unsafe static byte[] Encode(string distinguishedName, X500DistinguishedNameFlags flag) { if (distinguishedName == null) { throw new ArgumentNullException("distinguishedName"); } uint cbEncoded = 0; uint dwStrType = CAPI.CERT_X500_NAME_STR | MapNameToStrFlag(flag); if (!CAPI.CertStrToNameW(CAPI.X509_ASN_ENCODING | CAPI.PKCS_7_ASN_ENCODING, distinguishedName, dwStrType, IntPtr.Zero, IntPtr.Zero, ref cbEncoded, IntPtr.Zero)) { throw new CryptographicException(Marshal.GetLastWin32Error()); } byte[] encodedName = new byte[cbEncoded]; fixed(byte *pbEncoded = encodedName) { if (!CAPI.CertStrToNameW(CAPI.X509_ASN_ENCODING | CAPI.PKCS_7_ASN_ENCODING, distinguishedName, dwStrType, IntPtr.Zero, new IntPtr(pbEncoded), ref cbEncoded, IntPtr.Zero)) { throw new CryptographicException(Marshal.GetLastWin32Error()); } } return(encodedName); }
public static void TestDecodeFormats(X500DistinguishedNameFlags format) { // The Issuer field from the Microsoft.com test cert. byte[] encoding = ( "3077310B3009060355040613025553311D301B060355040A131453796D616E74" + "656320436F72706F726174696F6E311F301D060355040B131653796D616E7465" + "63205472757374204E6574776F726B312830260603550403131F53796D616E74" + "656320436C61737320332045562053534C204341202D204733").HexToByteArray(); X500DistinguishedName name = new X500DistinguishedName(encoding); string delimiter; switch (format) { case X500DistinguishedNameFlags.UseCommas: delimiter = ", "; break; case X500DistinguishedNameFlags.UseSemicolons: delimiter = "; "; break; case X500DistinguishedNameFlags.UseNewLines: delimiter = Environment.NewLine; break; default: throw new InvalidOperationException("No handler for format: " + format); } string expected = string.Format( "C=US{0}O=Symantec Corporation{0}OU=Symantec Trust Network{0}CN=Symantec Class 3 EV SSL CA - G3", delimiter); string actual = name.Decode(format); Assert.Equal(expected, actual); }
public string X500DistinguishedNameDecode(byte[] encodedDistinguishedName, X500DistinguishedNameFlags flag) { CertNameStrTypeAndFlags dwStrType = CertNameStrTypeAndFlags.CERT_X500_NAME_STR | MapNameToStrFlag(flag); unsafe { fixed (byte* pbEncoded = encodedDistinguishedName) { CRYPTOAPI_BLOB nameBlob; nameBlob.cbData = encodedDistinguishedName.Length; nameBlob.pbData = pbEncoded; int cchDecoded = Interop.crypt32.CertNameToStr(CertEncodingType.All, ref nameBlob, dwStrType, null, 0); if (cchDecoded == 0) throw ErrorCode.CERT_E_INVALID_NAME.ToCryptographicException(); StringBuilder sb = new StringBuilder(cchDecoded); if (Interop.crypt32.CertNameToStr(CertEncodingType.All, ref nameBlob, dwStrType, sb, cchDecoded) == 0) throw ErrorCode.CERT_E_INVALID_NAME.ToCryptographicException(); return sb.ToString(); } } }
/// <summary> /// Generate the <see cref="X500DistinguishedName"/> /// </summary> /// <param name="flags">Controls the delimiter</param> /// <returns></returns> public X500DistinguishedName Build(X500DistinguishedNameFlags flags = X500DistinguishedNameFlags.UseNewLines) { var delimiter = '\n'; if (flags.HasFlag(X500DistinguishedNameFlags.UseNewLines)) { delimiter = '\n'; } else if (flags.HasFlag(X500DistinguishedNameFlags.UseCommas)) { delimiter = ','; } else if (flags.HasFlag(X500DistinguishedNameFlags.UseSemicolons)) { delimiter = ';'; } #if NETCOREAPP22 var name = string.Join(delimiter, Subject.Select(x => $"{x.Key}={x.Value}").ToArray()); #else var name = string.Join(delimiter.ToString(), Subject.Select(x => $"{x.Key}={x.Value}").ToArray()); #endif return(new X500DistinguishedName(name, flags)); }
public string X500DistinguishedNameDecode(byte[] encodedDistinguishedName, X500DistinguishedNameFlags flag) { const int sizeof_wchar_t = 4; int dwStrType = (int)(CertNameStrTypeAndFlags.CERT_X500_NAME_STR | MapNameToStrFlag(flag)); unsafe { fixed(byte *pbEncoded = encodedDistinguishedName) { CRYPTOAPI_BLOB nameBlob; nameBlob.cbData = encodedDistinguishedName.Length; nameBlob.pbData = pbEncoded; int cchDecoded = Interop.Crypt32.CertNameToStr((int)CertEncodingType.All, &nameBlob, dwStrType, null, 0); if (cchDecoded == 0) { throw ErrorCode.CERT_E_INVALID_NAME.ToCryptographicException(); } Span <byte> buffer = cchDecoded <= 256 ? stackalloc byte[cchDecoded * sizeof_wchar_t] : new byte[cchDecoded * sizeof_wchar_t]; fixed(byte *ptr = buffer) { int ret = Interop.Crypt32.CertNameToStr((int)CertEncodingType.All, &nameBlob, dwStrType, (char *)ptr, cchDecoded); if (ret == 0) { throw ErrorCode.CERT_E_INVALID_NAME.ToCryptographicException(); } } return(System.Text.Encoding.UTF32.GetString(buffer.Slice(0, (cchDecoded - 1) * sizeof_wchar_t).ToArray())); } } }
private static unsafe byte[] Encode(string distinguishedName, X500DistinguishedNameFlags flag) { if (distinguishedName == null) { throw new ArgumentNullException("distinguishedName"); } uint pcbEncoded = 0; uint dwStrType = 3 | MapNameToStrFlag(flag); if (!CAPISafe.CertStrToNameW(0x10001, distinguishedName, dwStrType, IntPtr.Zero, IntPtr.Zero, ref pcbEncoded, IntPtr.Zero)) { throw new CryptographicException(Marshal.GetLastWin32Error()); } byte[] buffer = new byte[pcbEncoded]; fixed(byte *numRef = buffer) { if (!CAPISafe.CertStrToNameW(0x10001, distinguishedName, dwStrType, IntPtr.Zero, new IntPtr((void *)numRef), ref pcbEncoded, IntPtr.Zero)) { throw new CryptographicException(Marshal.GetLastWin32Error()); } } return(buffer); }
internal static string X500DistinguishedNameDecode(byte[] encodedDistinguishedName, X500DistinguishedNameFlags flags, bool useFindFormat) { using (SafeX509NameHandle x509Name = Interop.Crypto.DecodeX509Name(encodedDistinguishedName, encodedDistinguishedName.Length)) { Interop.Crypto.CheckValidOpenSslHandle(x509Name); using (SafeBioHandle bioHandle = Interop.Crypto.CreateMemoryBio()) { Interop.Crypto.CheckValidOpenSslHandle(bioHandle); int written; if (useFindFormat) { written = Interop.Crypto.X509NamePrintForFind(bioHandle, x509Name); } else { written = Interop.Crypto.X509NamePrintEx(bioHandle, x509Name, flags); } // X509_NAME_print_ex returns how many bytes were written into the buffer. // BIO_gets wants to ensure that the response is NULL-terminated. // So add one to leave space for the NULL. StringBuilder builder = new StringBuilder(written + 1); int read = Interop.Crypto.BioGets(bioHandle, builder, builder.Capacity); if (read < 0) { throw Interop.Crypto.CreateOpenSslCryptographicException(); } return builder.ToString(); } } }
// private stuff private static string GetSeparator (X500DistinguishedNameFlags flag) { if ((flag & X500DistinguishedNameFlags.UseSemicolons) != 0) return "; "; if ((flag & X500DistinguishedNameFlags.UseCommas) != 0) return ", "; if ((flag & X500DistinguishedNameFlags.UseNewLines) != 0) return Environment.NewLine; return ", "; //default }
public byte[] X500DistinguishedNameEncode(string distinguishedName, X500DistinguishedNameFlags flag) { return(X500NameEncoder.X500DistinguishedNameEncode(distinguishedName, flag)); }
public string Decode(X500DistinguishedNameFlags flag) { ThrowIfInvalid(flag); return(X509Pal.Instance.X500DistinguishedNameDecode(RawData, flag)); }
public unsafe string X500DistinguishedNameDecode(byte[] encodedDistinguishedName, X500DistinguishedNameFlags flag) { using (SafeX509NameHandle x509Name = Interop.libcrypto.OpenSslD2I(Interop.libcrypto.d2i_X509_NAME, encodedDistinguishedName)) { Interop.libcrypto.CheckValidOpenSslHandle(x509Name); using (SafeBioHandle bioHandle = Interop.libcrypto.BIO_new(Interop.libcrypto.BIO_s_mem())) { Interop.libcrypto.CheckValidOpenSslHandle(bioHandle); OpenSslX09NameFormatFlags nativeFlags = ConvertFormatFlags(flag); int written = Interop.libcrypto.X509_NAME_print_ex( bioHandle, x509Name, 0, new UIntPtr((uint)nativeFlags)); // X509_NAME_print_ex returns how many bytes were written into the buffer. // BIO_gets wants to ensure that the response is NULL-terminated. // So add one to leave space for the NULL. StringBuilder builder = new StringBuilder(written + 1); int read = Interop.libcrypto.BIO_gets(bioHandle, builder, builder.Capacity); if (read < 0) { throw Interop.libcrypto.CreateOpenSslCryptographicException(); } return(builder.ToString()); } } }
public string X500DistinguishedNameDecode(byte[] encodedDistinguishedName, X500DistinguishedNameFlags flags) { OpenSslX09NameFormatFlags nativeFlags = ConvertFormatFlags(flags); return X500DistinguishedNameDecode(encodedDistinguishedName, nativeFlags); }
internal static byte[] X500DistinguishedNameEncode( string stringForm, X500DistinguishedNameFlags flags) { bool reverse = (flags & X500DistinguishedNameFlags.Reversed) == X500DistinguishedNameFlags.Reversed; bool noQuotes = (flags & X500DistinguishedNameFlags.DoNotUseQuotes) == X500DistinguishedNameFlags.DoNotUseQuotes; List<char> dnSeparators; // This rank ordering is based off of testing against the Windows implementation. if ((flags & X500DistinguishedNameFlags.UseSemicolons) == X500DistinguishedNameFlags.UseSemicolons) { // Just semicolon. dnSeparators = s_useSemicolonSeparators; } else if ((flags & X500DistinguishedNameFlags.UseCommas) == X500DistinguishedNameFlags.UseCommas) { // Just comma dnSeparators = s_useCommaSeparators; } else if ((flags & X500DistinguishedNameFlags.UseNewLines) == X500DistinguishedNameFlags.UseNewLines) { // CR or LF. Not "and". Whichever is first was the separator, the later one is trimmed as whitespace. dnSeparators = s_useNewlineSeparators; } else { // Comma or semicolon, but not CR or LF. dnSeparators = s_defaultSeparators; } Debug.Assert(dnSeparators.Count != 0); List<byte[][]> encodedSets = ParseDistinguishedName(stringForm, dnSeparators, noQuotes); if (reverse) { encodedSets.Reverse(); } return DerEncoder.ConstructSequence(encodedSets); }
public X500DistinguishedName(string distinguishedName, X500DistinguishedNameFlags flag) : base(new Oid(), Encode(distinguishedName, flag)) { m_distinguishedName = distinguishedName; }
public X500DistinguishedName(string distinguishedName, X500DistinguishedNameFlags flag) : base(new Oid(), Encode(distinguishedName, flag)) { this.m_distinguishedName = distinguishedName; }
// // Private methods. // private unsafe static byte[] Encode (string distinguishedName, X500DistinguishedNameFlags flag) { if (distinguishedName == null) throw new ArgumentNullException("distinguishedName"); uint cbEncoded = 0; uint dwStrType = CAPI.CERT_X500_NAME_STR | MapNameToStrFlag(flag); if (!CAPI.CertStrToNameW(CAPI.X509_ASN_ENCODING | CAPI.PKCS_7_ASN_ENCODING, distinguishedName, dwStrType, IntPtr.Zero, IntPtr.Zero, ref cbEncoded, IntPtr.Zero)) throw new CryptographicException(Marshal.GetLastWin32Error()); byte[] encodedName = new byte[cbEncoded]; fixed (byte * pbEncoded = encodedName) { if (!CAPI.CertStrToNameW(CAPI.X509_ASN_ENCODING | CAPI.PKCS_7_ASN_ENCODING, distinguishedName, dwStrType, IntPtr.Zero, new IntPtr(pbEncoded), ref cbEncoded, IntPtr.Zero)) throw new CryptographicException(Marshal.GetLastWin32Error()); } return encodedName; }
private static OpenSslX09NameFormatFlags ConvertFormatFlags(X500DistinguishedNameFlags inFlags) { OpenSslX09NameFormatFlags outFlags = 0; if (inFlags.HasFlag(X500DistinguishedNameFlags.Reversed)) { outFlags |= OpenSslX09NameFormatFlags.XN_FLAG_DN_REV; } if (inFlags.HasFlag(X500DistinguishedNameFlags.UseSemicolons)) { outFlags |= OpenSslX09NameFormatFlags.XN_FLAG_SEP_SPLUS_SPC; } else if (inFlags.HasFlag(X500DistinguishedNameFlags.UseNewLines)) { outFlags |= OpenSslX09NameFormatFlags.XN_FLAG_SEP_MULTILINE; } else { outFlags |= OpenSslX09NameFormatFlags.XN_FLAG_SEP_CPLUS_SPC; } if (inFlags.HasFlag(X500DistinguishedNameFlags.DoNotUseQuotes)) { // TODO: Handle this. } if (inFlags.HasFlag(X500DistinguishedNameFlags.ForceUTF8Encoding)) { // TODO: Handle this. } if (inFlags.HasFlag(X500DistinguishedNameFlags.UseUTF8Encoding)) { // TODO: Handle this. } else if (inFlags.HasFlag(X500DistinguishedNameFlags.UseT61Encoding)) { // TODO: Handle this. } return outFlags; }
private static uint MapNameToStrFlag (X500DistinguishedNameFlags flag) { // All values or'ed together. Change this if you add values to the enumeration. uint allFlags = 0x71F1; uint dwFlags = (uint) flag; if ((dwFlags & ~allFlags) != 0) throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, SR.GetString(SR.Arg_EnumIllegalVal), "flag")); uint dwStrType = 0; if (dwFlags != 0) { if ((flag & X500DistinguishedNameFlags.Reversed) == X500DistinguishedNameFlags.Reversed) dwStrType |= CAPI.CERT_NAME_STR_REVERSE_FLAG; if ((flag & X500DistinguishedNameFlags.UseSemicolons) == X500DistinguishedNameFlags.UseSemicolons) dwStrType |= CAPI.CERT_NAME_STR_SEMICOLON_FLAG; else if ((flag & X500DistinguishedNameFlags.UseCommas) == X500DistinguishedNameFlags.UseCommas) dwStrType |= CAPI.CERT_NAME_STR_COMMA_FLAG; else if ((flag & X500DistinguishedNameFlags.UseNewLines) == X500DistinguishedNameFlags.UseNewLines) dwStrType |= CAPI.CERT_NAME_STR_CRLF_FLAG; if ((flag & X500DistinguishedNameFlags.DoNotUsePlusSign) == X500DistinguishedNameFlags.DoNotUsePlusSign) dwStrType |= CAPI.CERT_NAME_STR_NO_PLUS_FLAG; if ((flag & X500DistinguishedNameFlags.DoNotUseQuotes) == X500DistinguishedNameFlags.DoNotUseQuotes) dwStrType |= CAPI.CERT_NAME_STR_NO_QUOTING_FLAG; if ((flag & X500DistinguishedNameFlags.ForceUTF8Encoding) == X500DistinguishedNameFlags.ForceUTF8Encoding) dwStrType |= CAPI.CERT_NAME_STR_FORCE_UTF8_DIR_STR_FLAG; if ((flag & X500DistinguishedNameFlags.UseUTF8Encoding) == X500DistinguishedNameFlags.UseUTF8Encoding) dwStrType |= CAPI.CERT_NAME_STR_ENABLE_UTF8_UNICODE_FLAG; else if ((flag & X500DistinguishedNameFlags.UseT61Encoding) == X500DistinguishedNameFlags.UseT61Encoding) dwStrType |= CAPI.CERT_NAME_STR_ENABLE_T61_UNICODE_FLAG; } return dwStrType; }
public byte[] X500DistinguishedNameEncode(string distinguishedName, X500DistinguishedNameFlags flag) { return X500NameEncoder.X500DistinguishedNameEncode(distinguishedName, flag); }
public static string FormatName (MonoBtlsX509Name name, X500DistinguishedNameFlags flag) { if ((flag != 0) && ((flag & AllFlags) == 0)) throw new ArgumentException ("flag"); if (name.GetEntryCount () == 0) return String.Empty; // Mono.Security reversed isn't the same as fx 2.0 (which is the reverse of 1.x) bool reversed = ((flag & X500DistinguishedNameFlags.Reversed) != 0); bool quotes = ((flag & X500DistinguishedNameFlags.DoNotUseQuotes) == 0); string separator = GetSeparator (flag); return FormatName (name, reversed, separator, quotes); }
public X500DistinguishedName(string distinguishedName, X500DistinguishedNameFlags flag) : base(new Oid(null, null), Encode(distinguishedName, flag)) { _lazyDistinguishedName = distinguishedName; }
public string Decode(X500DistinguishedNameFlags flag) { return default(string); }
public byte[] X500DistinguishedNameEncode(string distinguishedName, X500DistinguishedNameFlags flag) { throw new NotImplementedException(); }
internal static string X500DistinguishedNameDecode( byte[] encodedName, bool printOid, X500DistinguishedNameFlags flags) { bool reverse = (flags & X500DistinguishedNameFlags.Reversed) == X500DistinguishedNameFlags.Reversed; bool quoteIfNeeded = (flags & X500DistinguishedNameFlags.DoNotUseQuotes) != X500DistinguishedNameFlags.DoNotUseQuotes; string dnSeparator; if ((flags & X500DistinguishedNameFlags.UseSemicolons) == X500DistinguishedNameFlags.UseSemicolons) { dnSeparator = "; "; } else if ((flags & X500DistinguishedNameFlags.UseNewLines) == X500DistinguishedNameFlags.UseNewLines) { dnSeparator = Environment.NewLine; } else { // This is matching Windows (native) behavior, UseCommas does not need to be asserted, // it is just what happens if neither UseSemicolons nor UseNewLines is specified. dnSeparator = ", "; } using (SafeX509NameHandle x509Name = Interop.Crypto.DecodeX509Name(encodedName, encodedName.Length)) { if (x509Name.IsInvalid) { return(""); } // We need to allocate a StringBuilder to hold the data as we're building it, and there's the usual // arbitrary process of choosing a number that's "big enough" to minimize reallocations without wasting // too much space in the average case. // // So, let's look at an example of what our output might be. // // GitHub.com's SSL cert has a "pretty long" subject (partially due to the unknown OIDs): // businessCategory=Private Organization // 1.3.6.1.4.1.311.60.2.1.3=US // 1.3.6.1.4.1.311.60.2.1.2=Delaware // serialNumber=5157550 // street=548 4th Street // postalCode=94107 // C=US // ST=California // L=San Francisco // O=GitHub, Inc. // CN=github.com // // Which comes out to 228 characters using OpenSSL's default pretty-print // (openssl x509 -in github.cer -text -noout) // Throw in some "maybe-I-need-to-quote-this" quotes, and a couple of extra/extra-long O/OU values // and round that up to the next programmer number, and you get that 512 should avoid reallocations // in all but the most dire of cases. StringBuilder decodedName = new StringBuilder(512); int entryCount = Interop.Crypto.GetX509NameEntryCount(x509Name); bool printSpacing = false; for (int i = 0; i < entryCount; i++) { int loc = reverse ? entryCount - i - 1 : i; using (SafeSharedX509NameEntryHandle nameEntry = Interop.Crypto.GetX509NameEntry(x509Name, loc)) { Interop.Crypto.CheckValidOpenSslHandle(nameEntry); string thisOidValue; using (SafeSharedAsn1ObjectHandle oidHandle = Interop.Crypto.GetX509NameEntryOid(nameEntry)) { thisOidValue = Interop.Crypto.GetOidValue(oidHandle); } if (printSpacing) { decodedName.Append(dnSeparator); } else { printSpacing = true; } if (printOid) { AppendOid(decodedName, thisOidValue); } string rdnValue; using (SafeSharedAsn1StringHandle valueHandle = Interop.Crypto.GetX509NameEntryData(nameEntry)) { rdnValue = Interop.Crypto.Asn1StringToManagedString(valueHandle); } bool quote = quoteIfNeeded && NeedsQuoting(rdnValue); if (quote) { decodedName.Append('"'); // If the RDN itself had a quote within it, that quote needs to be escaped // with another quote. rdnValue = rdnValue.Replace("\"", "\"\""); } decodedName.Append(rdnValue); if (quote) { decodedName.Append('"'); } } } return(decodedName.ToString()); } }
public string Decode(X500DistinguishedNameFlags flag) { return(default(string)); }
public X500DistinguishedName(string distinguishedName, X500DistinguishedNameFlags flag);
private static uint MapNameToStrFlag(X500DistinguishedNameFlags flag) { uint num = 0x71f1; uint num2 = (uint) flag; if ((num2 & ~num) != 0) { throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, SR.GetString("Arg_EnumIllegalVal"), new object[] { "flag" })); } uint num3 = 0; if (num2 != 0) { if ((flag & X500DistinguishedNameFlags.Reversed) == X500DistinguishedNameFlags.Reversed) { num3 |= 0x2000000; } if ((flag & X500DistinguishedNameFlags.UseSemicolons) == X500DistinguishedNameFlags.UseSemicolons) { num3 |= 0x40000000; } else if ((flag & X500DistinguishedNameFlags.UseCommas) == X500DistinguishedNameFlags.UseCommas) { num3 |= 0x4000000; } else if ((flag & X500DistinguishedNameFlags.UseNewLines) == X500DistinguishedNameFlags.UseNewLines) { num3 |= 0x8000000; } if ((flag & X500DistinguishedNameFlags.DoNotUsePlusSign) == X500DistinguishedNameFlags.DoNotUsePlusSign) { num3 |= 0x20000000; } if ((flag & X500DistinguishedNameFlags.DoNotUseQuotes) == X500DistinguishedNameFlags.DoNotUseQuotes) { num3 |= 0x10000000; } if ((flag & X500DistinguishedNameFlags.ForceUTF8Encoding) == X500DistinguishedNameFlags.ForceUTF8Encoding) { num3 |= 0x80000; } if ((flag & X500DistinguishedNameFlags.UseUTF8Encoding) == X500DistinguishedNameFlags.UseUTF8Encoding) { return (num3 | 0x40000); } if ((flag & X500DistinguishedNameFlags.UseT61Encoding) == X500DistinguishedNameFlags.UseT61Encoding) { num3 |= 0x20000; } } return num3; }
public string Decode(X500DistinguishedNameFlags flag);
public X500DistinguishedName(string distinguishedName, X500DistinguishedNameFlags flag) : base(new Oid(null, null), Encode(distinguishedName, flag)) { _lazyDistinguishedName = distinguishedName; }
public byte[] X500DistinguishedNameEncode(string distinguishedName, X500DistinguishedNameFlags flag) { throw new NotImplementedException(); }
public string Decode(X500DistinguishedNameFlags flag) { throw new NotImplementedException(); }
public string X500DistinguishedNameDecode(byte[] encodedDistinguishedName, X500DistinguishedNameFlags flags) { OpenSslX09NameFormatFlags nativeFlags = ConvertFormatFlags(flags); return(X500DistinguishedNameDecode(encodedDistinguishedName, nativeFlags)); }
public string Decode (X500DistinguishedNameFlags flag) { if ((flag != 0) && ((flag & AllFlags) == 0)) throw new ArgumentException ("flag"); if (RawData.Length == 0) return String.Empty; // Mono.Security reversed isn't the same as fx 2.0 (which is the reverse of 1.x) bool reversed = ((flag & X500DistinguishedNameFlags.Reversed) != 0); bool quotes = ((flag & X500DistinguishedNameFlags.DoNotUseQuotes) == 0); string separator = GetSeparator (flag); ASN1 rdn = new ASN1 (RawData); return MX.X501.ToString (rdn, reversed, separator, quotes); }
public X500DistinguishedName(string distinguishedName, X500DistinguishedNameFlags flag) { }
public string X500DistinguishedNameDecode(byte[] encodedDistinguishedName, X500DistinguishedNameFlags flag) { return(X500NameEncoder.X500DistinguishedNameDecode(encodedDistinguishedName, true, flag)); }
public string X500DistinguishedNameDecode(byte[] encodedDistinguishedName, X500DistinguishedNameFlags flags) { return X500NameEncoder.X500DistinguishedNameDecode(encodedDistinguishedName, true, flags); }
internal static string X500DistinguishedNameDecode( byte[] encodedName, bool printOid, X500DistinguishedNameFlags flags, bool addTrailingDelimieter=false) { bool reverse = (flags & X500DistinguishedNameFlags.Reversed) == X500DistinguishedNameFlags.Reversed; bool quoteIfNeeded = (flags & X500DistinguishedNameFlags.DoNotUseQuotes) != X500DistinguishedNameFlags.DoNotUseQuotes; string dnSeparator; if ((flags & X500DistinguishedNameFlags.UseSemicolons) == X500DistinguishedNameFlags.UseSemicolons) { dnSeparator = "; "; } else if ((flags & X500DistinguishedNameFlags.UseNewLines) == X500DistinguishedNameFlags.UseNewLines) { dnSeparator = Environment.NewLine; } else { // This is matching Windows (native) behavior, UseCommas does not need to be asserted, // it is just what happens if neither UseSemicolons nor UseNewLines is specified. dnSeparator = ", "; } using (SafeX509NameHandle x509Name = Interop.Crypto.DecodeX509Name(encodedName, encodedName.Length)) { if (x509Name.IsInvalid) { return ""; } // We need to allocate a StringBuilder to hold the data as we're building it, and there's the usual // arbitrary process of choosing a number that's "big enough" to minimize reallocations without wasting // too much space in the average case. // // So, let's look at an example of what our output might be. // // GitHub.com's SSL cert has a "pretty long" subject (partially due to the unknown OIDs): // businessCategory=Private Organization // 1.3.6.1.4.1.311.60.2.1.3=US // 1.3.6.1.4.1.311.60.2.1.2=Delaware // serialNumber=5157550 // street=548 4th Street // postalCode=94107 // C=US // ST=California // L=San Francisco // O=GitHub, Inc. // CN=github.com // // Which comes out to 228 characters using OpenSSL's default pretty-print // (openssl x509 -in github.cer -text -noout) // Throw in some "maybe-I-need-to-quote-this" quotes, and a couple of extra/extra-long O/OU values // and round that up to the next programmer number, and you get that 512 should avoid reallocations // in all but the most dire of cases. StringBuilder decodedName = new StringBuilder(512); int entryCount = Interop.Crypto.GetX509NameEntryCount(x509Name); bool printSpacing = false; for (int i = 0; i < entryCount; i++) { int loc = reverse ? entryCount - i - 1 : i; using (SafeSharedX509NameEntryHandle nameEntry = Interop.Crypto.GetX509NameEntry(x509Name, loc)) { Interop.Crypto.CheckValidOpenSslHandle(nameEntry); string thisOidValue; using (SafeSharedAsn1ObjectHandle oidHandle = Interop.Crypto.GetX509NameEntryOid(nameEntry)) { thisOidValue = Interop.Crypto.GetOidValue(oidHandle); } if (printSpacing) { decodedName.Append(dnSeparator); } else { printSpacing = true; } if (printOid) { AppendOid(decodedName, thisOidValue); } string rdnValue; using (SafeSharedAsn1StringHandle valueHandle = Interop.Crypto.GetX509NameEntryData(nameEntry)) { rdnValue = Interop.Crypto.Asn1StringToManagedString(valueHandle); } bool quote = quoteIfNeeded && NeedsQuoting(rdnValue); if (quote) { decodedName.Append('"'); // If the RDN itself had a quote within it, that quote needs to be escaped // with another quote. rdnValue = rdnValue.Replace("\"", "\"\""); } decodedName.Append(rdnValue); if (quote) { decodedName.Append('"'); } } } if (addTrailingDelimieter) { decodedName.Append(dnSeparator); } return decodedName.ToString(); } }
public string Decode(X500DistinguishedNameFlags flag) { ThrowIfInvalid(flag); return X509Pal.Instance.X500DistinguishedNameDecode(RawData, flag); }