public void AddRange(BCX509CertificateCollection value)
        {
            if (value == null)
            {
                throw new ArgumentNullException("value");
            }

            for (int i = 0; i < value.InnerList.Count; i++)
            {
                InnerList.Add(value[i]);
            }
        }
Exemplo n.º 2
0
        private BCX509Certificate2 FindParent(BCX509Certificate2 certificate)
        {
            BCX509CertificateCollection subset = CertificateCollection.Find(BCX509FindType.FindBySubjectDistinguishedName, certificate.IssuerDN, false);
            string aki = GetAuthorityKeyIdentifier(certificate);

            if ((aki != null) && (aki.Length > 0))
            {
                subset.AddRange(CertificateCollection.Find(BCX509FindType.FindBySubjectKeyIdentifier, aki, false));
            }
            BCX509Certificate2 parent = SelectBestFromCollection(certificate, subset);

            // if parent==certificate we're looping but it's not (probably) a bug and not a true cyclic (over n certs)
            return(certificate.Equals(parent) ? null : parent);
        }
Exemplo n.º 3
0
        private BCX509Certificate2 SelectBestFromCollection(BCX509Certificate2 child, BCX509CertificateCollection c)
        {
            switch (c.Count)
            {
            case 0:
                return(null);

            case 1:
                return(c[0]);

            default:
                // multiple candidate, keep only the ones that are still valid
                BCX509CertificateCollection time_valid = c.Find(BCX509FindType.FindByTimeValid, ChainPolicy.VerificationTime, false);
                switch (time_valid.Count)
                {
                case 0:
                    // that's too restrictive, let's revert and try another thing...
                    time_valid = c;
                    break;

                case 1:
                    return(time_valid[0]);

                default:
                    break;
                }

                // again multiple candidates, let's find the AKI that match the SKI (if we have one)
                string aki = GetAuthorityKeyIdentifier(child);
                if (String.IsNullOrEmpty(aki))
                {
                    return(time_valid[0]);                            // FIXME: out of luck, you get the first one
                }
                foreach (BCX509Certificate2 parent in time_valid)
                {
                    string ski = GetSubjectKeyIdentifier(parent);
                    // if both id are available then they must match
                    if (aki == ski)
                    {
                        return(parent);
                    }
                }
                return(time_valid[0]);                        // FIXME: out of luck, you get the first one
            }
        }
 public BCX509CertificateCollection(BCX509CertificateCollection value)
 {
     AddRange(value);
 }
            // Constructors

            public BCX509CertificateEnumerator(BCX509CertificateCollection mappings)
            {
                enumerator = ((IEnumerable)mappings).GetEnumerator();
            }
        public BCX509CertificateCollection Find(BCX509FindType findType, object findValue, bool validOnly)
        {
            if (findValue == null)
            {
                throw new ArgumentNullException("findValue");
            }

            string str = String.Empty;
            DerObjectIdentifier oid = null;
            string   oidStr         = String.Empty;
            KeyUsage ku             = new KeyUsage(0);
            DateTime dt             = DateTime.MinValue;

            switch (findType)
            {
            case BCX509FindType.FindByThumbprint:
            case BCX509FindType.FindBySubjectName:
            case BCX509FindType.FindBySubjectDistinguishedName:
            case BCX509FindType.FindByIssuerName:
            case BCX509FindType.FindByIssuerDistinguishedName:
            case BCX509FindType.FindBySerialNumber:
            case BCX509FindType.FindByTemplateName:
            case BCX509FindType.FindBySubjectKeyIdentifier:
                try
                {
                    str = (string)findValue;
                }
                catch (Exception e)
                {
                    string msg = String.Format("Invalid find value type '{0}', expected '{1}'.", findValue.GetType(), "string");
                    throw new CryptographicException(msg, e);
                }
                break;

            case BCX509FindType.FindByApplicationPolicy:
            case BCX509FindType.FindByCertificatePolicy:
            case BCX509FindType.FindByExtension:
                try
                {
                    oidStr = (string)findValue;
                }
                catch (Exception e)
                {
                    string msg = String.Format("Invalid find value type '{0}', expected '{1}'.", findValue.GetType(), "X509KeyUsageFlags");
                    throw new CryptographicException(msg, e);
                }
                // OID validation
                try
                {
                    oid = new DerObjectIdentifier(oidStr);
                }
                catch (FormatException)
                {
                    string msg = String.Format("Invalid OID value '{0}'.", oidStr);
                    throw new ArgumentException("findValue", msg);
                }
                break;

            case BCX509FindType.FindByKeyUsage:
                try
                {
                    ku = new KeyUsage((int)findValue);
                }
                catch (Exception e)
                {
                    string msg = String.Format("Invalid find value type '{0}', expected '{1}'.", findValue.GetType(), "X509KeyUsageFlags");
                    throw new CryptographicException(msg, e);
                }
                break;

            case BCX509FindType.FindByTimeValid:
            case BCX509FindType.FindByTimeNotYetValid:
            case BCX509FindType.FindByTimeExpired:
                try
                {
                    dt = (DateTime)findValue;
                }
                catch (Exception e)
                {
                    string msg = String.Format("Invalid find value type '{0}', expected '{1}'.", findValue.GetType(), "X509DateTime");
                    throw new CryptographicException(msg, e);
                }
                break;

            default:
            {
                string msg = String.Format("Invalid find type '{0}'.", findType);
                throw new CryptographicException(msg);
            }
            }

            CultureInfo cinv = CultureInfo.InvariantCulture;
            BCX509CertificateCollection results = new BCX509CertificateCollection();

            foreach (BCX509Certificate2 x in InnerList)
            {
                bool value_match = false;

                switch (findType)
                {
                case BCX509FindType.FindByThumbprint:
                    // works with Thumbprint, GetCertHashString in both normal (upper) and lower case
                    value_match = ((String.Compare(str, Hex.ToHexString(x.GetSignature()), true, cinv) == 0) || (String.Compare(str, DotNetUtilities.ToX509Certificate(x).GetCertHashString(), true, cinv) == 0));
                    break;

                case BCX509FindType.FindBySubjectName:
                {
                    string[] names = x.SubjectDN.ToString().Split(new [] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                    foreach (string name in names)
                    {
                        int pos = name.IndexOf('=');
                        value_match = (name.IndexOf(str, pos, StringComparison.InvariantCultureIgnoreCase) >= 0);
                        if (value_match)
                        {
                            break;
                        }
                    }
                    break;
                }

                case BCX509FindType.FindBySubjectDistinguishedName:
                    value_match = (String.Compare(str, x.SubjectDN.ToString(), true, cinv) == 0);
                    break;

                case BCX509FindType.FindByIssuerName:
                {
                    //string iname = x.GetNameInfo (X509NameType.SimpleName, true);
                    //value_match = (iname.IndexOf (str, StringComparison.InvariantCultureIgnoreCase) >= 0);
                    string[] names = x.IssuerDN.ToString().Split(new [] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                    foreach (string name in names)
                    {
                        int pos = name.IndexOf('=');
                        value_match = (name.IndexOf(str, pos, StringComparison.InvariantCultureIgnoreCase) >= 0);
                        if (value_match)
                        {
                            break;
                        }
                    }
                }
                break;

                case BCX509FindType.FindByIssuerDistinguishedName:
                    value_match = (String.Compare(str, x.IssuerDN.ToString(), true, cinv) == 0);
                    break;

                case BCX509FindType.FindBySerialNumber:
                    value_match = (String.Compare(str, x.SerialNumber.ToString(), true, cinv) == 0);
                    break;

                case BCX509FindType.FindByTemplateName:
                    // TODO - find a valid test case
                    break;

                case BCX509FindType.FindBySubjectKeyIdentifier:
                    SubjectKeyIdentifier ski = SubjectKeyIdentifier.GetInstance(x.CertificateStructure.TbsCertificate.Extensions.GetExtension(X509Extensions.SubjectKeyIdentifier));
                    if (ski != null)
                    {
                        value_match = (String.Compare(str, Hex.ToHexString(ski.GetKeyIdentifier()), true, cinv) == 0);
                    }
                    break;

                case BCX509FindType.FindByApplicationPolicy:
                    // note: include when no extensions are present (even if v3)
                    value_match = (x.GetCriticalExtensionOids().Count == 0 && x.GetNonCriticalExtensionOids().Count == 0);
                    // TODO - find test case with extension
                    break;

                case BCX509FindType.FindByCertificatePolicy:
                    // TODO - find test case with extension
                    break;

                case BCX509FindType.FindByExtension:
                    value_match = (x.GetExtensionValue(oid) != null);
                    break;

                case BCX509FindType.FindByKeyUsage:
                    KeyUsage kue = KeyUsage.GetInstance(x.CertificateStructure.TbsCertificate.Extensions.GetExtension(X509Extensions.KeyUsage));
                    if (kue == null)
                    {
                        // key doesn't have any hard coded limitations
                        // note: MS doesn't check for ExtendedKeyUsage
                        value_match = true;
                    }
                    else
                    {
                        value_match = ((kue.IntValue & ku.IntValue) == ku.IntValue);
                    }
                    break;

                case BCX509FindType.FindByTimeValid:
                    value_match = ((dt >= x.NotBefore) && (dt <= x.NotAfter));
                    break;

                case BCX509FindType.FindByTimeNotYetValid:
                    value_match = (dt < x.NotBefore);
                    break;

                case BCX509FindType.FindByTimeExpired:
                    value_match = (dt > x.NotAfter);
                    break;
                }

                if (!value_match)
                {
                    continue;
                }

                if (validOnly)
                {
                    try
                    {
                        x.Verify(x.GetPublicKey());
                        results.Add(x);
                    }
                    catch
                    {
                    }
                }
                else
                {
                    results.Add(x);
                }
            }
            return(results);
        }