예제 #1
0
        /// <summary>
        /// Changes the delimiter used to seperate fields in a subject name.
        /// </summary>
        private static string ChangeSubjectNameDelimiter(string name, char delimiter)
        {
            StringBuilder buffer   = new StringBuilder();
            List <string> elements = Utils.ParseDistinguishedName(name);

            for (int ii = 0; ii < elements.Count; ii++)
            {
                string element = elements[ii];

                if (buffer.Length > 0)
                {
                    buffer.Append(delimiter);
                }

                if (element.IndexOf(delimiter) != -1)
                {
                    int index = element.IndexOf('=');
                    buffer.Append(element.Substring(0, index + 1));
                    buffer.Append('"');
                    buffer.Append(element.Substring(index + 1));
                    buffer.Append('"');
                    continue;
                }

                buffer.Append(elements[ii]);
            }

            return(buffer.ToString());
        }
예제 #2
0
        /// <summary>
        /// Finds a certificate in a collection.
        /// </summary>
        /// <param name="collection">The collection of the <see cref="X509Certificate2"/> certificates objects.</param>
        /// <param name="needPrivateKey">If set to <c>true</c> the certificate must have private key.</param>
        /// <returns>An <see cref="X509Certificate2"/> certificate with matching subject name.</returns>
        public static X509Certificate2 Find(X509Certificate2Collection collection, string thumbprint, string subjectName, bool needPrivateKey)
        {
            #if !SILVERLIGHT
            // find by thumbprint.
            if (!String.IsNullOrEmpty(thumbprint))
            {
                collection = collection.Find(X509FindType.FindByThumbprint, thumbprint, false);

                foreach (X509Certificate2 certificate in collection)
                {
                    if (!needPrivateKey || certificate.HasPrivateKey)
                    {
                        if (String.IsNullOrEmpty(subjectName))
                        {
                            return(certificate);
                        }

                        List <string> subjectName2 = Utils.ParseDistinguishedName(subjectName);

                        if (Utils.CompareDistinguishedName(certificate, subjectName2))
                        {
                            return(certificate);
                        }
                    }
                }

                return(null);
            }

            // find by subject name.
            if (!String.IsNullOrEmpty(subjectName))
            {
                List <string> subjectName2 = Utils.ParseDistinguishedName(subjectName);

                foreach (X509Certificate2 certificate in collection)
                {
                    if (Utils.CompareDistinguishedName(certificate, subjectName2))
                    {
                        if (!needPrivateKey || certificate.HasPrivateKey)
                        {
                            return(certificate);
                        }
                    }
                }

                collection = collection.Find(X509FindType.FindBySubjectName, subjectName, false);

                foreach (X509Certificate2 certificate in collection)
                {
                    if (!needPrivateKey || certificate.HasPrivateKey)
                    {
                        return(certificate);
                    }
                }
            }
            #endif

            // certificate not found.
            return(null);
        }
예제 #3
0
        private void Initialize(byte[] crl)
        {
            X509CrlParser parser = new X509CrlParser();

            m_crl          = parser.ReadCrl(crl);
            UpdateTime     = m_crl.ThisUpdate;
            NextUpdateTime = (m_crl.NextUpdate == null) ? DateTime.MinValue : m_crl.NextUpdate.Value;
            // a few conversions to match System.Security conventions
            string issuerDN = m_crl.IssuerDN.ToString();

            // replace state ST= with S=
            issuerDN = issuerDN.Replace("ST=", "S=");
            // reverse DN order to match System.Security
            List <string> issuerList = Utils.ParseDistinguishedName(issuerDN);

            issuerList.Reverse();
            Issuer = string.Join(", ", issuerList);
        }
예제 #4
0
        /// <summary>
        /// Returns the file name to use for the certificate.
        /// </summary>
        private string GetFileName(X509Certificate2 certificate)
        {
            // build file name.
            string commonName = certificate.FriendlyName;

            List <string> names = Utils.ParseDistinguishedName(certificate.Subject);

            for (int ii = 0; ii < names.Count; ii++)
            {
                if (names[ii].StartsWith("CN="))
                {
                    commonName = names[ii].Substring(3).Trim();
                    break;
                }
            }

            StringBuilder fileName = new StringBuilder();

            // remove any special characters.
            for (int ii = 0; ii < commonName.Length; ii++)
            {
                char ch = commonName[ii];

                if ("<>:\"/\\|?*".IndexOf(ch) != -1)
                {
                    ch = '+';
                }

                fileName.Append(ch);
            }

            fileName.Append(" [");
            fileName.Append(certificate.Thumbprint);
            fileName.Append("]");

            return(fileName.ToString());
        }
예제 #5
0
        /// <summary>
        /// Sets the parameters to suitable defaults.
        /// </summary>
        private static void SetSuitableDefaults(
            ref string applicationUri,
            ref string applicationName,
            ref string subjectName,
            ref IList <String> domainNames,
            ref ushort keySize,
            ref ushort lifetimeInMonths,
            bool isCA)
        {
            // enforce recommended keysize unless lower value is enforced.
            if (keySize < 1024)
            {
                keySize = defaultKeySize;
            }

            if (keySize % 1024 != 0)
            {
                throw new ArgumentNullException("keySize", "KeySize must be a multiple of 1024.");
            }

            // enforce minimum lifetime.
            if (lifetimeInMonths < 1)
            {
                lifetimeInMonths = 1;
            }

            // parse the subject name if specified.
            List <string> subjectNameEntries = null;

            if (!String.IsNullOrEmpty(subjectName))
            {
                subjectNameEntries = Utils.ParseDistinguishedName(subjectName);
            }

            // check the application name.
            if (String.IsNullOrEmpty(applicationName))
            {
                if (subjectNameEntries == null)
                {
                    throw new ArgumentNullException("applicationName", "Must specify a applicationName or a subjectName.");
                }

                // use the common name as the application name.
                for (int ii = 0; ii < subjectNameEntries.Count; ii++)
                {
                    if (subjectNameEntries[ii].StartsWith("CN="))
                    {
                        applicationName = subjectNameEntries[ii].Substring(3).Trim();
                        break;
                    }
                }
            }

            // remove special characters from name.
            StringBuilder buffer = new StringBuilder();

            for (int ii = 0; ii < applicationName.Length; ii++)
            {
                char ch = applicationName[ii];

                if (Char.IsControl(ch) || ch == '/' || ch == ',' || ch == ';')
                {
                    ch = '+';
                }

                buffer.Append(ch);
            }

            applicationName = buffer.ToString();

            // ensure at least one host name.
            if (domainNames == null || domainNames.Count == 0)
            {
                domainNames = new List <string>();
                domainNames.Add(Utils.GetHostName());
            }

            // create the application uri.
            if (String.IsNullOrEmpty(applicationUri))
            {
                StringBuilder builder = new StringBuilder();

                builder.Append("urn:");
                builder.Append(domainNames[0]);
                builder.Append(":");
                builder.Append(applicationName);

                applicationUri = builder.ToString();
            }

            Uri uri = Utils.ParseUri(applicationUri);

            if (uri == null)
            {
                throw new ArgumentNullException("applicationUri", "Must specify a valid URL.");
            }

            // create the subject name,
            if (String.IsNullOrEmpty(subjectName))
            {
                subjectName = Utils.Format("CN={0}/DC={1}", applicationName, domainNames[0]);
            }
        }
        /// <summary>
        /// Loads the private key from a PFX file in the certificate store.
        /// </summary>
        public X509Certificate2 LoadPrivateKey(string thumbprint, string subjectName, string password)
        {
            if (m_certificateSubdir == null || !m_certificateSubdir.Exists)
            {
                return(null);
            }

            if (string.IsNullOrEmpty(thumbprint) && string.IsNullOrEmpty(subjectName))
            {
                return(null);
            }

            foreach (FileInfo file in m_certificateSubdir.GetFiles("*.der"))
            {
                try
                {
                    X509Certificate2 certificate = new X509Certificate2(file.FullName);

                    if (!String.IsNullOrEmpty(thumbprint))
                    {
                        if (!string.Equals(certificate.Thumbprint, thumbprint, StringComparison.CurrentCultureIgnoreCase))
                        {
                            continue;
                        }
                    }

                    if (!String.IsNullOrEmpty(subjectName))
                    {
                        if (!Utils.CompareDistinguishedName(subjectName, certificate.Subject))
                        {
                            if (subjectName.Contains("="))
                            {
                                continue;
                            }

                            if (!Utils.ParseDistinguishedName(certificate.Subject).Any(s => s.Equals("CN=" + subjectName, StringComparison.OrdinalIgnoreCase)))
                            {
                                continue;
                            }
                        }
                    }

                    string fileRoot = file.Name.Substring(0, file.Name.Length - file.Extension.Length);

                    StringBuilder filePath = new StringBuilder();
                    filePath.Append(m_privateKeySubdir.FullName);
                    filePath.Append(Path.DirectorySeparatorChar);
                    filePath.Append(fileRoot);

                    FileInfo privateKeyFile = new FileInfo(filePath.ToString() + ".pfx");
                    password = password ?? String.Empty;
                    try
                    {
                        certificate = new X509Certificate2(
                            privateKeyFile.FullName,
                            password,
                            X509KeyStorageFlags.Exportable | X509KeyStorageFlags.UserKeySet);
                        if (CertificateFactory.VerifyRSAKeyPair(certificate, certificate, true))
                        {
                            return(certificate);
                        }
                    }
                    catch (Exception)
                    {
                        certificate = new X509Certificate2(
                            privateKeyFile.FullName,
                            password,
                            X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet);
                        if (CertificateFactory.VerifyRSAKeyPair(certificate, certificate, true))
                        {
                            return(certificate);
                        }
                    }
                }
                catch (Exception e)
                {
                    Utils.Trace(e, "Could not load private key for certificate " + subjectName);
                }
            }

            return(null);
        }