The identifier for an X509 certificate.
상속: IFormattable
예제 #1
0
        /// <summary>
        /// Returns the issuers for the certificate.
        /// </summary>
        /// <param name="certificate">The certificate.</param>
        /// <param name="issuers">The issuers.</param>
        /// <returns></returns>
        public async Task <bool> GetIssuers(X509Certificate2 certificate, List <CertificateIdentifier> issuers)
        {
            bool isTrusted = false;
            CertificateIdentifier issuer = null;

            do
            {
                issuer = await GetIssuer(certificate, m_trustedCertificateList, m_trustedCertificateStore, true);

                if (issuer == null)
                {
                    issuer = await GetIssuer(certificate, m_issuerCertificateList, m_issuerCertificateStore, true);
                }
                else
                {
                    isTrusted = true;
                }

                if (issuer != null)
                {
                    issuers.Add(issuer);
                    certificate = await issuer.Find(false);

                    // check for root.
                    if (Utils.CompareDistinguishedName(certificate.Subject, certificate.Issuer))
                    {
                        break;
                    }
                }
            }while (issuer != null);

            return(isTrusted);
        }
 /// <summary>
 /// Updates the object from another object (usage is not updated).
 /// </summary>
 /// <param name="certificate">The certificate.</param>
 private void Paste(CertificateIdentifier certificate)
 {
     this.SubjectName       = certificate.SubjectName;
     this.Thumbprint        = certificate.Thumbprint;
     this.RawData           = certificate.RawData;
     this.ValidationOptions = certificate.ValidationOptions;
     this.Certificate       = certificate.Certificate;
 }
        /// <summary>
        /// Initializes the object with an X509 certificate identifier
        /// </summary>
        public UserIdentity(CertificateIdentifier certificateId)
        {
            if (certificateId == null) throw new ArgumentNullException("certificateId");

            Task<X509Certificate2> task = certificateId.Find();
            task.Wait();
            X509Certificate2 certificate = task.Result;
            if (certificate != null)
            {
                Initialize(certificate);
            }
        }
 /// <summary>
 /// Remove from certificate store
 /// </summary>
 /// <param name="identifier"></param>
 /// <param name="certificate"></param>
 public static void RemoveFromStore(this CertificateIdentifier identifier,
                                    X509Certificate2 certificate)
 {
     if (certificate == null)
     {
         throw new ArgumentNullException(nameof(certificate));
     }
     using (var store = CertificateStoreIdentifier.CreateStore(identifier.StoreType)) {
         store.Open(identifier.StorePath);
         store.Remove(certificate.YieldReturn());
     }
 }
 /// <summary>
 /// Add to certificate store
 /// </summary>
 /// <param name="identifier"></param>
 /// <param name="certificate"></param>
 /// <param name="noCopy"></param>
 /// <returns></returns>
 public static void AddToStore(this CertificateIdentifier identifier,
                               X509Certificate2 certificate, bool noCopy = false)
 {
     if (certificate == null)
     {
         throw new ArgumentNullException(nameof(certificate));
     }
     using (var store = CertificateStoreIdentifier.CreateStore(identifier.StoreType)) {
         store.Open(identifier.StorePath);
         store.Add(certificate.YieldReturn(), noCopy);
     }
 }
예제 #6
0
파일: UserIdentity.cs 프로젝트: benvert/pfe
        /// <summary>
        /// Initializes the object with an X509 certificate identifier
        /// </summary>
        private void Initialize(CertificateIdentifier certificateId)
        {
            if (certificateId == null)
            {
                throw new ArgumentNullException("certificateId");
            }

            X509Certificate2 certificate = certificateId.Find();

            if (certificate != null)
            {
                Initialize(new X509SecurityToken(certificate));
            }
        }
예제 #7
0
        /// <summary>
        /// Initializes the object with an X509 certificate identifier
        /// </summary>
        public UserIdentity(CertificateIdentifier certificateId)
        {
            if (certificateId == null)
            {
                throw new ArgumentNullException("certificateId");
            }

            X509Certificate2 certificate = certificateId.Find().Result;

            if (certificate != null)
            {
                Initialize(certificate);
            }
        }
예제 #8
0
        /// <summary>
        /// Returns the issuers for the certificates.
        /// </summary>
        public async Task <bool> GetIssuers(X509Certificate2Collection certificates, List <CertificateIdentifier> issuers)
        {
            bool isTrusted = false;
            CertificateIdentifier issuer      = null;
            X509Certificate2      certificate = certificates[0];

            CertificateIdentifierCollection collection = new CertificateIdentifierCollection();

            for (int ii = 1; ii < certificates.Count; ii++)
            {
                collection.Add(new CertificateIdentifier(certificates[ii]));
            }

            do
            {
                issuer = await GetIssuer(certificate, m_trustedCertificateList, m_trustedCertificateStore, true);

                if (issuer == null)
                {
                    issuer = await GetIssuer(certificate, m_issuerCertificateList, m_issuerCertificateStore, true);

                    if (issuer == null)
                    {
                        issuer = await GetIssuer(certificate, collection, null, true);
                    }
                }

                if (issuer != null)
                {
                    isTrusted = true;

                    issuers.Add(issuer);
                    certificate = await issuer.Find(false);

                    // check for root.
                    if (Utils.CompareDistinguishedName(certificate.Subject, certificate.Issuer))
                    {
                        break;
                    }
                }
                else
                {
                    isTrusted = false;
                }
            }while (issuer != null);

            return(isTrusted);
        }
예제 #9
0
        /// <summary>
        /// Initializes the object with an X509 certificate identifier
        /// </summary>
        public UserIdentity(CertificateIdentifier certificateId)
        {
            if (certificateId == null)
            {
                throw new ArgumentNullException("certificateId");
            }

            Task <X509Certificate2> task = certificateId.Find();

            task.Wait();
            X509Certificate2 certificate = task.Result;

            if (certificate != null)
            {
                Initialize(certificate);
            }
        }
예제 #10
0
        /// <summary>
        /// Initializes the object with an X509 certificate identifier
        /// </summary>
        public UserIdentity(CertificateIdentifier certificateId)
        {
            if (certificateId == null)
            {
                throw new ArgumentNullException("certificateId");
            }

            Task <X509Certificate2> task = certificateId.Find();

            task.Wait();
            X509Certificate2 certificate = task.Result;

            if (certificate != null)
            {
                X509IdentityToken token = new X509IdentityToken();
                token.CertificateData = certificate.RawData;
                token.Certificate     = certificate;
                Initialize(token);
            }
        }
        /// <summary>
        /// Returns true if the objects are equal.
        /// </summary>
        public override bool Equals(object obj)
        {
            if (Object.ReferenceEquals(this, obj))
            {
                return(true);
            }

            CertificateIdentifier id = obj as CertificateIdentifier;

            if (id == null)
            {
                return(false);
            }

            if (m_certificate != null && id.m_certificate != null)
            {
                return(m_certificate.Thumbprint == id.m_certificate.Thumbprint);
            }

            if (Thumbprint == id.Thumbprint)
            {
                return(true);
            }

            if (m_storeLocation != id.m_storeLocation)
            {
                return(false);
            }

            if (m_storeName != id.m_storeName)
            {
                return(false);
            }

            if (SubjectName != id.SubjectName)
            {
                return(false);
            }

            return(true);
        }
예제 #12
0
        /// <summary>
        /// Throws an exception if validation fails.
        /// </summary>
        /// <param name="certificates">The certificates to be checked.</param>
        /// <exception cref="ServiceResultException">If certificate[0] cannot be accepted</exception>
        protected virtual async Task InternalValidate(X509Certificate2Collection certificates)
        {
            X509Certificate2 certificate = certificates[0];

            // check for previously validated certificate.
            X509Certificate2 certificate2 = null;

            if (m_validatedCertificates.TryGetValue(certificate.Thumbprint, out certificate2))
            {
                if (Utils.IsEqual(certificate2.RawData, certificate.RawData))
                {
                    return;
                }
            }

            CertificateIdentifier trustedCertificate = await GetTrustedCertificate(certificate);

            // get the issuers (checks the revocation lists if using directory stores).
            List <CertificateIdentifier> issuers = new List <CertificateIdentifier>();
            bool isIssuerTrusted = await GetIssuers(certificates, issuers);

            // setup policy chain
            X509ChainPolicy policy = new X509ChainPolicy();

            policy.RevocationFlag    = X509RevocationFlag.EntireChain;
            policy.RevocationMode    = X509RevocationMode.NoCheck;
            policy.VerificationFlags = X509VerificationFlags.NoFlag;

            foreach (CertificateIdentifier issuer in issuers)
            {
                if ((issuer.ValidationOptions & CertificateValidationOptions.SuppressRevocationStatusUnknown) != 0)
                {
                    policy.VerificationFlags |= X509VerificationFlags.IgnoreCertificateAuthorityRevocationUnknown;
                    policy.VerificationFlags |= X509VerificationFlags.IgnoreCtlSignerRevocationUnknown;
                    policy.VerificationFlags |= X509VerificationFlags.IgnoreEndRevocationUnknown;
                    policy.VerificationFlags |= X509VerificationFlags.IgnoreRootRevocationUnknown;
                }

                // we did the revocation check in the GetIssuers call. No need here.
                policy.RevocationMode = X509RevocationMode.NoCheck;
                policy.ExtraStore.Add(issuer.Certificate);
            }

            // build chain.
            X509Chain chain = new X509Chain();

            chain.ChainPolicy = policy;
            chain.Build(certificate);

            // check the chain results.
            CertificateIdentifier target = trustedCertificate;

            if (target == null)
            {
                target = new CertificateIdentifier(certificate);
            }

            for (int ii = 0; ii < chain.ChainElements.Count; ii++)
            {
                X509ChainElement element = chain.ChainElements[ii];

                CertificateIdentifier issuer = null;

                if (ii < issuers.Count)
                {
                    issuer = issuers[ii];
                }

                // check for chain status errors.
                foreach (X509ChainStatus status in element.ChainElementStatus)
                {
                    ServiceResult result = CheckChainStatus(status, target, issuer, (ii != 0));

                    if (ServiceResult.IsBad(result))
                    {
                        // check untrusted certificates.
                        if (trustedCertificate == null)
                        {
                            throw new ServiceResultException(StatusCodes.BadSecurityChecksFailed);
                        }

                        throw new ServiceResultException(result);
                    }
                }

                if (issuer != null)
                {
                    target = issuer;
                }
            }

            bool issuedByCA = !Utils.CompareDistinguishedName(certificate.Subject, certificate.Issuer);

            // check if certificate issuer is trusted.
            if (issuedByCA && !isIssuerTrusted)
            {
                if (m_applicationCertificate == null || !Utils.IsEqual(m_applicationCertificate.RawData, certificate.RawData))
                {
                    throw ServiceResultException.Create(
                              StatusCodes.BadCertificateUntrusted,
                              "Certificate issuer is not trusted.\r\nSubjectName: {0}\r\nIssuerName: {1}",
                              certificate.SubjectName.Name,
                              certificate.IssuerName.Name);
                }
            }

            // check if certificate is trusted.
            if (trustedCertificate == null && !isIssuerTrusted)
            {
                if (m_applicationCertificate == null || !Utils.IsEqual(m_applicationCertificate.RawData, certificate.RawData))
                {
                    throw ServiceResultException.Create(
                              StatusCodes.BadCertificateUntrusted,
                              "Certificate is not trusted.\r\nSubjectName: {0}\r\nIssuerName: {1}",
                              certificate.SubjectName.Name,
                              certificate.IssuerName.Name);
                }
            }
        }
        /// <summary>
        /// Throws an exception if validation fails.
        /// </summary>
        /// <param name="certificate">The certificate to be checked.</param>
        /// <exception cref="ServiceResultException">If certificate cannot be accepted</exception>
        protected virtual void InternalValidate(X509Certificate2 certificate)
        {
            lock (m_lock)
            {
                // check for previously validated certificate.
                X509Certificate2 certificate2 = null;

                if (m_validatedCertificates.TryGetValue(certificate.Thumbprint, out certificate2))
                {
                    if (Utils.IsEqual(certificate2.RawData, certificate.RawData))
                    {
                        return;
                    }
                }

                CertificateIdentifier trustedCertificate = GetTrustedCertificate(certificate);

                // get the issuers (checks the revocation lists if using directory stores).
                List<CertificateIdentifier> issuers = new List<CertificateIdentifier>();
                bool isIssuerTrusted = GetIssuers(certificate, issuers);

                // setup policy chain
                X509ChainPolicy policy = new X509ChainPolicy();

                policy.RevocationFlag = X509RevocationFlag.EntireChain;
                policy.RevocationMode = X509RevocationMode.NoCheck;
                policy.VerificationFlags = X509VerificationFlags.NoFlag;

                foreach (CertificateIdentifier issuer in issuers)
                {
                    if ((issuer.ValidationOptions & CertificateValidationOptions.SuppressRevocationStatusUnknown) != 0)
                    {
                        policy.VerificationFlags |= X509VerificationFlags.IgnoreCertificateAuthorityRevocationUnknown;
                        policy.VerificationFlags |= X509VerificationFlags.IgnoreCtlSignerRevocationUnknown;
                        policy.VerificationFlags |= X509VerificationFlags.IgnoreEndRevocationUnknown;
                        policy.VerificationFlags |= X509VerificationFlags.IgnoreRootRevocationUnknown;
                    }

                    // we did the revocation check in the GetIssuers call. No need here.
                    policy.RevocationMode = X509RevocationMode.NoCheck;
                    policy.ExtraStore.Add(issuer.Certificate);
                }

                // build chain.
                X509Chain chain = new X509Chain();
                chain.ChainPolicy = policy;
                chain.Build(certificate);

                // check the chain results.
                CertificateIdentifier target = trustedCertificate;

                if (target == null)
                {
                    target = new CertificateIdentifier(certificate);
                }

                for (int ii = 0; ii < chain.ChainElements.Count; ii++)
                {
                    X509ChainElement element = chain.ChainElements[ii];

                    CertificateIdentifier issuer = null;

                    if (ii < issuers.Count)
                    {
                        issuer = issuers[ii];
                    }

                    // check for chain status errors.
                    foreach (X509ChainStatus status in element.ChainElementStatus)
                    {
                        ServiceResult result = CheckChainStatus(status, target, issuer, (ii != 0));

                        if (ServiceResult.IsBad(result))
                        {
                            throw new ServiceResultException(result);
                        }
                    }

                    if (issuer != null)
                    {
                        target = issuer;
                    }
                }

                // check if certificate is trusted.
                if (trustedCertificate == null && !isIssuerTrusted)
                {
                    if (m_applicationCertificate == null || !Utils.IsEqual(m_applicationCertificate.RawData, certificate.RawData))
                    {
                        throw ServiceResultException.Create(
                            StatusCodes.BadCertificateUntrusted,
                            "Certificate is not trusted.\r\nSubjectName: {0}\r\nIssuerName: {1}",
                            certificate.SubjectName.Name,
                            certificate.IssuerName.Name);
                    }
                }
            }
        }
        private static ServiceResult CheckChainStatus(X509ChainStatus status, CertificateIdentifier id, CertificateIdentifier issuer, bool isIssuer)
        {
            switch (status.Status)
            {
                case X509ChainStatusFlags.NotValidForUsage:
                {
                    return ServiceResult.Create(
                        (isIssuer) ? StatusCodes.BadCertificateUseNotAllowed : StatusCodes.BadCertificateIssuerUseNotAllowed,
                        "Certificate may not be used as an application instance certificate. {0}: {1}",
                        status.Status,
                        status.StatusInformation);
                }

                case X509ChainStatusFlags.NoError:
                case X509ChainStatusFlags.OfflineRevocation:
                case X509ChainStatusFlags.InvalidBasicConstraints:
                case X509ChainStatusFlags.PartialChain:
                {
                    break;
                }

                case X509ChainStatusFlags.UntrustedRoot:
                {
                    // ignore this error because the root check is done
                    // by looking the certificate up in the trusted issuer stores passed to the validator.
                    // the ChainStatus uses the Windows trusted issuer stores.
                    break;
                }

                case X509ChainStatusFlags.RevocationStatusUnknown:
                {
                    if (issuer != null)
                    {
                        if ((issuer.ValidationOptions & CertificateValidationOptions.SuppressRevocationStatusUnknown) != 0)
                        {
                            break;
                        }
                    }
                    
                    // check for meaning less errors for self-signed certificates.
                    if (id.Certificate != null && Utils.CompareDistinguishedName(id.Certificate.Subject, id.Certificate.Subject))
                    {
                        break;
                    }

                    return ServiceResult.Create(
                        (isIssuer) ? StatusCodes.BadCertificateIssuerRevocationUnknown : StatusCodes.BadCertificateRevocationUnknown,
                        "Certificate revocation status cannot be verified. {0}: {1}",
                        status.Status,
                        status.StatusInformation);
                }

                case X509ChainStatusFlags.Revoked:
                {
                    return ServiceResult.Create(
                        (isIssuer) ? StatusCodes.BadCertificateIssuerRevoked : StatusCodes.BadCertificateRevoked,
                        "Certificate has been revoked. {0}: {1}",
                        status.Status,
                        status.StatusInformation);
                }

                case X509ChainStatusFlags.NotTimeNested:
                {
                    if (id != null && ((id.ValidationOptions & CertificateValidationOptions.SuppressCertificateExpired) != 0))
                    {
                        break;
                    }

                    return ServiceResult.Create(
                        StatusCodes.BadCertificateIssuerTimeInvalid,
                        "Certificate issuer validatity time does not overhas is expired or not yet valid. {0}: {1}",
                        status.Status,
                        status.StatusInformation);
                }


                case X509ChainStatusFlags.NotTimeValid:
                {
                    if (id != null && ((id.ValidationOptions & CertificateValidationOptions.SuppressCertificateExpired) != 0))
                    {
                        break;
                    }

                    return ServiceResult.Create(
                        (isIssuer) ? StatusCodes.BadCertificateIssuerTimeInvalid : StatusCodes.BadCertificateTimeInvalid,
                        "Certificate has is expired or not yet valid. {0}: {1}",
                        status.Status,
                        status.StatusInformation);
                }

                default:
                {
                    return ServiceResult.Create(
                        StatusCodes.BadCertificateInvalid,
                        "Certificate validation failed. {0}: {1}",
                        status.Status,
                        status.StatusInformation);
                }
            }

            return null;
        }
        /// <summary>
        /// Throws an exception if validation fails.
        /// </summary>
        /// <param name="certificates">The certificates to be checked.</param>
        /// <exception cref="ServiceResultException">If certificate[0] cannot be accepted</exception>
        protected virtual async Task InternalValidate(X509Certificate2Collection certificates)
        {
            X509Certificate2 certificate = certificates[0];

            // check for previously validated certificate.
            X509Certificate2 certificate2 = null;

            if (m_validatedCertificates.TryGetValue(certificate.Thumbprint, out certificate2))
            {
                if (Utils.IsEqual(certificate2.RawData, certificate.RawData))
                {
                    return;
                }
            }

            CertificateIdentifier trustedCertificate = await GetTrustedCertificate(certificate);

            // get the issuers (checks the revocation lists if using directory stores).
            List <CertificateIdentifier> issuers = new List <CertificateIdentifier>();
            bool isIssuerTrusted = await GetIssuers(certificates, issuers);

            // setup policy chain
            X509ChainPolicy policy = new X509ChainPolicy();

            policy.RevocationFlag    = X509RevocationFlag.EntireChain;
            policy.RevocationMode    = X509RevocationMode.NoCheck;
            policy.VerificationFlags = X509VerificationFlags.NoFlag;

            foreach (CertificateIdentifier issuer in issuers)
            {
                if ((issuer.ValidationOptions & CertificateValidationOptions.SuppressRevocationStatusUnknown) != 0)
                {
                    policy.VerificationFlags |= X509VerificationFlags.IgnoreCertificateAuthorityRevocationUnknown;
                    policy.VerificationFlags |= X509VerificationFlags.IgnoreCtlSignerRevocationUnknown;
                    policy.VerificationFlags |= X509VerificationFlags.IgnoreEndRevocationUnknown;
                    policy.VerificationFlags |= X509VerificationFlags.IgnoreRootRevocationUnknown;
                }

                // we did the revocation check in the GetIssuers call. No need here.
                policy.RevocationMode = X509RevocationMode.NoCheck;
                policy.ExtraStore.Add(issuer.Certificate);
            }

            // build chain.
            bool      chainStatusChecked = false;
            X509Chain chain = new X509Chain();

            chain.ChainPolicy = policy;
            chain.Build(certificate);

            // check the chain results.
            CertificateIdentifier target = trustedCertificate;

            if (target == null)
            {
                target = new CertificateIdentifier(certificate);
            }

            for (int ii = 0; ii < chain.ChainElements.Count; ii++)
            {
                X509ChainElement element = chain.ChainElements[ii];

                CertificateIdentifier issuer = null;

                if (ii < issuers.Count)
                {
                    issuer = issuers[ii];
                }

                // check for chain status errors.
                foreach (X509ChainStatus status in element.ChainElementStatus)
                {
                    ServiceResult result = CheckChainStatus(status, target, issuer, (ii != 0));

                    if (ServiceResult.IsBad(result))
                    {
                        // check untrusted certificates.
                        if (trustedCertificate == null)
                        {
                            throw new ServiceResultException(StatusCodes.BadSecurityChecksFailed);
                        }

                        throw new ServiceResultException(result);
                    }
                    chainStatusChecked = true;
                }

                if (issuer != null)
                {
                    target = issuer;
                }
            }

            // check whether the chain is complete (if there is a chain)
            bool issuedByCA      = !Utils.CompareDistinguishedName(certificate.Subject, certificate.Issuer);
            bool chainIncomplete = false;

            if (issuers.Count > 0)
            {
                var rootCertificate = issuers[issuers.Count - 1].Certificate;
                if (!Utils.CompareDistinguishedName(rootCertificate.Subject, rootCertificate.Issuer))
                {
                    chainIncomplete = true;
                }
            }
            else
            {
                if (issuedByCA)
                {
                    // no issuer found at all
                    chainIncomplete = true;
                }
            }

            if (issuedByCA && (!chainStatusChecked || chainIncomplete))
            {
                throw ServiceResultException.Create(
                          StatusCodes.BadCertificateChainIncomplete,
                          "Certificate chain validation incomplete.\r\nSubjectName: {0}\r\nIssuerName: {1}",
                          certificate.SubjectName.Name,
                          certificate.IssuerName.Name);
            }

            // check if certificate issuer is trusted.
            if (issuedByCA && !isIssuerTrusted && trustedCertificate == null)
            {
                if (m_applicationCertificate == null || !Utils.IsEqual(m_applicationCertificate.RawData, certificate.RawData))
                {
                    throw ServiceResultException.Create(
                              StatusCodes.BadCertificateUntrusted,
                              "Certificate issuer is not trusted.\r\nSubjectName: {0}\r\nIssuerName: {1}",
                              certificate.SubjectName.Name,
                              certificate.IssuerName.Name);
                }
            }

            // check if certificate is trusted.
            if (trustedCertificate == null && !isIssuerTrusted)
            {
                if (m_applicationCertificate == null || !Utils.IsEqual(m_applicationCertificate.RawData, certificate.RawData))
                {
                    throw ServiceResultException.Create(
                              StatusCodes.BadCertificateUntrusted,
                              "Certificate is not trusted.\r\nSubjectName: {0}\r\nIssuerName: {1}",
                              certificate.SubjectName.Name,
                              certificate.IssuerName.Name);
                }
            }

            // check if certificate is valid for use as app/sw or user cert
            X509KeyUsageFlags certificateKeyUsage = CertificateFactory.GetKeyUsage(certificate);

            if ((certificateKeyUsage & X509KeyUsageFlags.DataEncipherment) == 0)
            {
                throw new ServiceResultException(StatusCodes.BadCertificateUseNotAllowed, "Usage of certificate is not allowed.");
            }

            // check if minimum requirements are met
            if (m_rejectSHA1SignedCertificates && IsSHA1SignatureAlgorithm(certificate.SignatureAlgorithm))
            {
                throw new ServiceResultException(StatusCodes.BadCertificatePolicyCheckFailed, "SHA1 signed certificates are not trusted");
            }

            if (certificate.GetRSAPublicKey().KeySize < m_minimumCertificateKeySize)
            {
                throw new ServiceResultException(StatusCodes.BadCertificatePolicyCheckFailed, "Certificate doesn't meet minimum key length requirement");
            }
        }
예제 #16
0
        /// <summary>
        /// Creates a SAML token for the specified email address.
        /// </summary>
        public static UserIdentity CreateSAMLToken(string emailAddress)
        {
            // Normally this would be done by a server that is capable of verifying that
            // the user is a legimate holder of email address. Using a local certficate to
            // signed the SAML token is a short cut that would never be done in a real system.
            CertificateIdentifier userid = new CertificateIdentifier();

            userid.StoreType = CertificateStoreType.Windows;
            userid.StorePath = "LocalMachine\\My";
            userid.SubjectName = "UA Sample Client";

            X509Certificate2 certificate = userid.Find();
            X509SecurityToken signingToken = new X509SecurityToken(certificate);

            // Create list of confirmation strings
            List<string> confirmations = new List<string>();

            // Add holder-of-key string to list of confirmation strings
            confirmations.Add("urn:oasis:names:tc:SAML:1.0:cm:bearer");

            // Create SAML subject statement based on issuer member variable, confirmation string collection 
            // local variable and proof key identifier parameter
            SamlSubject subject = new SamlSubject("urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress", null, emailAddress);

            // Create a list of SAML attributes
            List<SamlAttribute> attributes = new List<SamlAttribute>();
            Claim claim = Claim.CreateNameClaim(emailAddress);
            attributes.Add(new SamlAttribute(claim));

            // Create list of SAML statements
            List<SamlStatement> statements = new List<SamlStatement>();

            // Add a SAML attribute statement to the list of statements. Attribute statement is based on 
            // subject statement and SAML attributes resulting from claims
            statements.Add(new SamlAttributeStatement(subject, attributes));

            // Create a valid from/until condition
            DateTime validFrom = DateTime.UtcNow;
            DateTime validTo = DateTime.UtcNow.AddHours(12);

            SamlConditions conditions = new SamlConditions(validFrom, validTo);

            // Create the SAML assertion
            SamlAssertion assertion = new SamlAssertion(
                "_" + Guid.NewGuid().ToString(),
                signingToken.Certificate.Subject,
                validFrom,
                conditions,
                null,
                statements);

            SecurityKey signingKey = new System.IdentityModel.Tokens.RsaSecurityKey((RSA)signingToken.Certificate.PrivateKey);

            // Set the signing credentials for the SAML assertion
            assertion.SigningCredentials = new SigningCredentials(
                signingKey,
                System.IdentityModel.Tokens.SecurityAlgorithms.RsaSha1Signature,
                System.IdentityModel.Tokens.SecurityAlgorithms.Sha1Digest,
                new SecurityKeyIdentifier(signingToken.CreateKeyIdentifierClause<X509ThumbprintKeyIdentifierClause>()));

            return new UserIdentity(new SamlSecurityToken(assertion));
        }
        /// <summary>
        /// Initializes the validator from the configuration for a token policy.
        /// </summary>
        /// <param name="issuerCertificate">The issuer certificate.</param>
        private SecurityTokenResolver CreateSecurityTokenResolver(CertificateIdentifier issuerCertificate)
        {
            if (issuerCertificate == null)
            {
                throw new ArgumentNullException("issuerCertificate");
            }

            // find the certificate.
            X509Certificate2 certificate = issuerCertificate.Find(false);

            if (certificate == null)
            {
                throw ServiceResultException.Create(
                    StatusCodes.BadCertificateInvalid,
                    "Could not find issuer certificate: {0}",
                    issuerCertificate);
            }

            // create a security token representing the certificate.
            List<SecurityToken> tokens = new List<SecurityToken>();
            tokens.Add(new X509SecurityToken(certificate));

            // create issued token resolver.
            SecurityTokenResolver tokenResolver = SecurityTokenResolver.CreateDefaultSecurityTokenResolver(
                new System.Collections.ObjectModel.ReadOnlyCollection<SecurityToken>(tokens),
                false);

            return tokenResolver;
        }
예제 #18
0
        /// <summary>
        /// Initializes the object with an X509 certificate identifier
        /// </summary>
        private void Initialize(CertificateIdentifier certificateId)
        {
            if (certificateId == null) throw new ArgumentNullException("certificateId");

            X509Certificate2 certificate = certificateId.Find();

            if (certificate != null)
            {
                Initialize(new X509SecurityToken(certificate));
            }
        }
예제 #19
0
 /// <summary>
 /// Initializes the object with an X509 certificate identifier
 /// </summary>
 /// <param name="certificateId">The certificate identifier.</param>
 public UserIdentity(CertificateIdentifier certificateId)
 {
     Initialize(certificateId);
 }
 /// <summary>
 /// Updates the object from another object (usage is not updated).
 /// </summary>
 /// <param name="certificate">The certificate.</param>
 private void Paste(CertificateIdentifier certificate)
 {
     this.SubjectName = certificate.SubjectName;
     this.Thumbprint = certificate.Thumbprint;
     this.RawData = certificate.RawData;
     this.ValidationOptions = certificate.ValidationOptions;
     this.Certificate = certificate.Certificate;
 }
예제 #21
0
파일: UserIdentity.cs 프로젝트: benvert/pfe
 /// <summary>
 /// Initializes the object with an X509 certificate identifier
 /// </summary>
 /// <param name="certificateId">The certificate identifier.</param>
 public UserIdentity(CertificateIdentifier certificateId)
 {
     Initialize(certificateId);
 }
        /// <summary>
        /// Synchronous helper implementation of CheckApplicationInstanceCertificate for C++ Proxy
        /// </summary>
        public static void CheckApplicationInstanceCertificate(ApplicationConfiguration configuration)
        {
            // create a default certificate id none specified.
            CertificateIdentifier id = configuration.SecurityConfiguration.ApplicationCertificate;

            if (id == null)
            {
                id = new CertificateIdentifier();
                id.StoreType = Utils.DefaultStoreType;
                id.StorePath = Utils.DefaultStorePath;
                id.SubjectName = configuration.ApplicationName;
            }

            // check for certificate with a private key.
            X509Certificate2 certificate = null;
            Task.Run(async () => certificate = await id.Find(true)).Wait();

            if (certificate != null)
            {
                return;
            }

            // construct the subject name from the 
            List<string> hostNames = new List<string>();
            hostNames.Add(Utils.GetHostName());

            string commonName = Utils.Format("CN={0}", configuration.ApplicationName);
            string domainName = Utils.Format("DC={0}", hostNames[0]);
            string subjectName = Utils.Format("{0}, {1}", commonName, domainName);

            // create a new certificate with a new public key pair.
            certificate = CertificateFactory.CreateCertificate(
                id.StoreType,
                id.StorePath,
                configuration.ApplicationUri,
                configuration.ApplicationName,
                subjectName,
                hostNames,
                2048,
                120,
                256);

            // update and save the configuration file.
            id.Certificate = certificate;
            configuration.SaveToFile(configuration.SourceFilePath);

            // add certificate to the trusted peer store so other applications will trust it.
            ICertificateStore store = configuration.SecurityConfiguration.TrustedPeerCertificates.OpenStore();

            try
            {
                Task.Run(async () =>
                    {
                        X509Certificate2Collection certificateCollection = await store.FindByThumbprint(certificate.Thumbprint);
                        if (certificateCollection != null)
                        {
                            await store.Add(certificateCollection[0]);
                        }
                    }
                ).Wait();
            }
            finally
            {
                store.Close();
            }

            // tell the certificate validator about the new certificate.
            configuration.CertificateValidator.Update(configuration.SecurityConfiguration);

        }
예제 #23
0
        /// <summary>
        /// Throws an exception if validation fails.
        /// </summary>
        /// <param name="certificates">The certificates to be checked.</param>
        /// <exception cref="ServiceResultException">If certificate[0] cannot be accepted</exception>
        protected virtual void InternalValidateWithChainSupportEnabled(X509Certificate2Collection certificates)
        {
            lock (m_lock) {
                X509Certificate2 certificate = certificates[0];

                // check for previously validated certificate.
                X509Certificate2 certificate2 = null;

                if (m_validatedCertificates.TryGetValue(certificate.Thumbprint, out certificate2))
                {
                    if (Utils.IsEqual(certificate2.RawData, certificate.RawData))
                    {
                        return;
                    }
                }

                CertificateIdentifier trustedCertificate = GetTrustedCertificate(certificate);

                // get the issuers (checks the revocation lists if using directory stores).
                List <CertificateIdentifier> issuers = new List <CertificateIdentifier>();
                bool isIssuerTrusted = GetIssuersWithChainSupportEnabled(certificates, issuers);
                // setup policy chain
                X509ChainPolicy policy = new X509ChainPolicy();

                policy.RevocationFlag    = X509RevocationFlag.EntireChain;
                policy.RevocationMode    = X509RevocationMode.NoCheck;
                policy.VerificationFlags = X509VerificationFlags.NoFlag;

                foreach (CertificateIdentifier issuer in issuers)
                {
                    if ((issuer.ValidationOptions & CertificateValidationOptions.SuppressRevocationStatusUnknown) !=
                        0)
                    {
                        policy.VerificationFlags |= X509VerificationFlags.IgnoreCertificateAuthorityRevocationUnknown;
                        policy.VerificationFlags |= X509VerificationFlags.IgnoreCtlSignerRevocationUnknown;
                        policy.VerificationFlags |= X509VerificationFlags.IgnoreEndRevocationUnknown;
                        policy.VerificationFlags |= X509VerificationFlags.IgnoreRootRevocationUnknown;
                    }

                    // we did the revocation check in the GetIssuers call. No need here.
                    policy.RevocationMode = X509RevocationMode.NoCheck;
                    policy.ExtraStore.Add(issuer.Certificate);
                }

                // build chain.
                X509Chain chain = new X509Chain();
                chain.ChainPolicy = policy;
                chain.Build(certificate);

                // check the chain results.
                CertificateIdentifier target = trustedCertificate;

                if (target == null)
                {
                    target = new CertificateIdentifier(certificate);
                }

                for (int ii = 0; ii < chain.ChainElements.Count; ii++)
                {
                    X509ChainElement element = chain.ChainElements[ii];

                    CertificateIdentifier issuer = null;

                    if (ii < issuers.Count)
                    {
                        issuer = issuers[ii];
                    }

                    // check for chain status errors.
                    foreach (X509ChainStatus status in element.ChainElementStatus)
                    {
                        ServiceResult result = CheckChainStatus(status, target, issuer, (ii != 0));

                        if (ServiceResult.IsBad(result))
                        {
                            throw new ServiceResultException(result);
                        }
                    }

                    if (issuer != null)
                    {
                        target = issuer;
                    }
                }
            }
        }
예제 #24
0
        /// <summary>
        /// Checks for a valid application instance certificate.
        /// </summary>
        /// <param name="silent">if set to <c>true</c> no dialogs will be displayed.</param>
        /// <param name="minimumKeySize">Minimum size of the key.</param>
        public void CheckApplicationInstanceCertificate(
            bool silent,
            ushort minimumKeySize)
        {
            Utils.Trace(Utils.TraceMasks.Information, "Checking application instance certificate.");

            ApplicationConfiguration configuration = null;

            if (m_applicationConfiguration == null)
            {
                LoadApplicationConfiguration(silent);
            }

            configuration = m_applicationConfiguration;
            bool createNewCertificate = true;

            // find the existing certificate.
            CertificateIdentifier id = configuration.SecurityConfiguration.ApplicationCertificate;

            if (id == null)
            {
                throw ServiceResultException.Create(StatusCodes.BadConfigurationError, "Configuration file does not specify a certificate.");
            }

            X509Certificate2 certificate = id.Find(true);

            // check that it is ok.
            if (certificate != null)
            {
                createNewCertificate = !CheckApplicationInstanceCertificate(configuration, certificate, silent, minimumKeySize);
            }
            else
            {
                // check for missing private key.
                certificate = id.Find(false);

                if (certificate != null)
                {
                    throw ServiceResultException.Create(StatusCodes.BadConfigurationError, "Cannot access certificate private key. Subject={0}", certificate.Subject);
                }

                // check for missing thumbprint.
                if (!String.IsNullOrEmpty(id.Thumbprint))
                {
                    if (!String.IsNullOrEmpty(id.SubjectName))
                    {
                        CertificateIdentifier id2 = new CertificateIdentifier();
                        id2.StoreType = id.StoreType;
                        id2.StorePath = id.StorePath;
                        id2.SubjectName = id.SubjectName;

                        certificate = id2.Find(true);
                    }

                    if (certificate != null)
                    {
                        string message = Utils.Format(
                            "Thumbprint was explicitly specified in the configuration." +
                            "\r\nAnother certificate with the same subject name was found." +
                            "\r\nUse it instead?\r\n" +
                            "\r\nRequested: {0}" +
                            "\r\nFound: {1}",
                            id.SubjectName,
                            certificate.Subject);

                        throw ServiceResultException.Create(StatusCodes.BadConfigurationError, message);
                    }
                    else
                    {
                        string message = Utils.Format("Thumbprint was explicitly specified in the configuration. Cannot generate a new certificate.");
                        throw ServiceResultException.Create(StatusCodes.BadConfigurationError, message);
                    }
                }
                else
                {
                    if (String.IsNullOrEmpty(id.SubjectName))
                    {
                        string message = Utils.Format("Both SubjectName and Thumbprint are not specified in the configuration. Cannot generate a new certificate.");
                        throw ServiceResultException.Create(StatusCodes.BadConfigurationError, message);
                    }
                }
            }
            
            // create a new certificate.
            if (createNewCertificate)
            {
                certificate = CreateApplicationInstanceCertificate(configuration, minimumKeySize, 600);
            }

            // ensure it is trusted.
            else
            {
                AddToTrustedStore(configuration, certificate);
            }

            // add to discovery server.
            if (configuration.ApplicationType == ApplicationType.Server || configuration.ApplicationType == ApplicationType.ClientAndServer)
            {
                try
                {
                    AddToDiscoveryServerTrustList(certificate, null, null, configuration.SecurityConfiguration.TrustedPeerCertificates);
                }
                catch (Exception e)
                {
                    Utils.Trace(e, "Could not add certificate to LDS trust list.");
                }
            }
        }
예제 #25
0
파일: Helpers.cs 프로젝트: yuriik83/UA-.NET
        /// <summary>
        /// Creates a minimal endpoint description which allows a client to connect to a server.
        /// </summary>
        /// <remarks>
        /// In most cases the client will use the server's discovery endpoint to fetch the information
        /// constained in this structure.
        /// </remarks>
        public static EndpointDescription CreateEndpointDescription()
        {
            // create the endpoint description.
            EndpointDescription endpointDescription = new EndpointDescription();
            
           endpointDescription.EndpointUrl = Utils.Format("http://{0}:61211/UA/SampleClient", System.Net.Dns.GetHostName());
           // endpointDescription.EndpointUrl = Utils.Format("opc.tcp://{0}:51210/UA/SampleServer", System.Net.Dns.GetHostName());
           // endpointDescription.EndpointUrl = Utils.Format("http://{0}:51211/UA/SampleServer/None", System.Net.Dns.GetHostName());
           // endpointDescription.EndpointUrl = Utils.Format("http://{0}:51211/UA/SampleServer", System.Net.Dns.GetHostName());
            
            // specify the security policy to use.
            // endpointDescription.SecurityPolicyUri = SecurityPolicies.None;
            // endpointDescription.SecurityMode      = MessageSecurityMode.None;;
            endpointDescription.SecurityPolicyUri = SecurityPolicies.Basic128Rsa15;
            endpointDescription.SecurityMode      = MessageSecurityMode.SignAndEncrypt;
            
            // specify the transport profile.
             endpointDescription.TransportProfileUri = Profiles.WsHttpXmlOrBinaryTransport;
            // endpointDescription.TransportProfileUri = Profiles.WsHttpXmlTransport;
            // endpointDescription.TransportProfileUri = Profiles.UaTcpTransport;

            endpointDescription.Server.DiscoveryUrls.Add(Utils.Format("http://{0}:61211/UA/SampleClient/discovery", System.Net.Dns.GetHostName()));

            // load the the server certificate from the local certificate store.
            CertificateIdentifier certificateIdentifier = new CertificateIdentifier();

            certificateIdentifier.StoreType = CertificateStoreType.Windows;
            certificateIdentifier.StorePath = "LocalMachine\\My";
            certificateIdentifier.SubjectName = "UA Sample Client";
            
            X509Certificate2 serverCertificate = certificateIdentifier.Find();

            if (serverCertificate == null)
            {
                throw ServiceResultException.Create(StatusCodes.BadCertificateInvalid, "Could not find server certificate: {0}", certificateIdentifier.SubjectName);
            }

            endpointDescription.ServerCertificate = serverCertificate.RawData;

            return endpointDescription;
        }
예제 #26
0
        private static ServiceResult CheckChainStatus(X509ChainStatus status, CertificateIdentifier id, CertificateIdentifier issuer, bool isIssuer)
        {
            switch (status.Status)
            {
            case X509ChainStatusFlags.NotValidForUsage:
            {
                return(ServiceResult.Create(
                           (isIssuer) ? StatusCodes.BadCertificateUseNotAllowed : StatusCodes.BadCertificateIssuerUseNotAllowed,
                           "Certificate may not be used as an application instance certificate. {0}: {1}",
                           status.Status,
                           status.StatusInformation));
            }

            case X509ChainStatusFlags.NoError:
            case X509ChainStatusFlags.OfflineRevocation:
            case X509ChainStatusFlags.InvalidBasicConstraints:
            case X509ChainStatusFlags.PartialChain:
            {
                break;
            }

            case X509ChainStatusFlags.UntrustedRoot:
            {
                // ignore this error because the root check is done
                // by looking the certificate up in the trusted issuer stores passed to the validator.
                // the ChainStatus uses the Windows trusted issuer stores.
                break;
            }

            case X509ChainStatusFlags.RevocationStatusUnknown:
            {
                if (issuer != null)
                {
                    if ((issuer.ValidationOptions & CertificateValidationOptions.SuppressRevocationStatusUnknown) != 0)
                    {
                        break;
                    }
                }

                // check for meaning less errors for self-signed certificates.
                if (id.Certificate != null && Utils.CompareDistinguishedName(id.Certificate.Subject, id.Certificate.Subject))
                {
                    break;
                }

                return(ServiceResult.Create(
                           (isIssuer) ? StatusCodes.BadCertificateIssuerRevocationUnknown : StatusCodes.BadCertificateRevocationUnknown,
                           "Certificate revocation status cannot be verified. {0}: {1}",
                           status.Status,
                           status.StatusInformation));
            }

            case X509ChainStatusFlags.Revoked:
            {
                return(ServiceResult.Create(
                           (isIssuer) ? StatusCodes.BadCertificateIssuerRevoked : StatusCodes.BadCertificateRevoked,
                           "Certificate has been revoked. {0}: {1}",
                           status.Status,
                           status.StatusInformation));
            }

            case X509ChainStatusFlags.NotTimeNested:
            {
                if (id != null && ((id.ValidationOptions & CertificateValidationOptions.SuppressCertificateExpired) != 0))
                {
                    break;
                }

                return(ServiceResult.Create(
                           StatusCodes.BadCertificateIssuerTimeInvalid,
                           "Certificate issuer validatity time does not overhas is expired or not yet valid. {0}: {1}",
                           status.Status,
                           status.StatusInformation));
            }


            case X509ChainStatusFlags.NotTimeValid:
            {
                if (id != null && ((id.ValidationOptions & CertificateValidationOptions.SuppressCertificateExpired) != 0))
                {
                    break;
                }

                return(ServiceResult.Create(
                           (isIssuer) ? StatusCodes.BadCertificateIssuerTimeInvalid : StatusCodes.BadCertificateTimeInvalid,
                           "Certificate has is expired or not yet valid. {0}: {1}",
                           status.Status,
                           status.StatusInformation));
            }

            default:
            {
                return(ServiceResult.Create(
                           StatusCodes.BadCertificateInvalid,
                           "Certificate validation failed. {0}: {1}",
                           status.Status,
                           status.StatusInformation));
            }
            }

            return(null);
        }
예제 #27
0
        /// <summary>
        /// Returns the issuers for the certificates.
        /// </summary>
        public bool GetIssuersWithChainSupportEnabled(X509Certificate2Collection certificates,
                                                      List <CertificateIdentifier> issuers)
        {
            bool isTrusted                    = false;
            bool isChainComplete              = false;
            CertificateIdentifier issuer      = null;
            X509Certificate2      certificate = certificates[0];

            // application certificate is trusted
            CertificateIdentifier trustedCertificate = GetTrustedCertificate(certificate);

            if (trustedCertificate != null)
            {
                isTrusted = true;
            }

            if (Utils.CompareDistinguishedName(certificate.Subject, certificate.Issuer))
            {
                if (!isTrusted)
                {
                    throw ServiceResultException.Create(
                              StatusCodes.BadCertificateUntrusted,
                              "Self Signed Certificate is not trusted.\r\nIssuerName: {0}",
                              certificate.IssuerName.Name);
                }

                return(isTrusted);
            }

            CertificateIdentifierCollection collection = new CertificateIdentifierCollection();

            for (int ii = 1; ii < certificates.Count; ii++)
            {
                collection.Add(new CertificateIdentifier(certificates[ii]));
            }

            do
            {
                issuer = GetIssuer(certificate, m_trustedCertificateList, m_trustedCertificateStore, true);
                if (issuer != null)
                {
                    isTrusted = true;
                }

                if (issuer == null)
                {
                    issuer = GetIssuer(certificate, m_issuerCertificateList, m_issuerCertificateStore, true);

                    if (issuer == null)
                    {
                        issuer = GetIssuer(certificate, collection, null, true);
                    }
                }

                if (issuer != null)
                {
                    //isTrusted = true;

                    issuers.Add(issuer);
                    certificate = issuer.Find(false);

                    // check for root.
                    if (Utils.CompareDistinguishedName(certificate.Subject, certificate.Issuer))
                    {
                        isChainComplete = true;
                        break;
                    }
                }
                else
                {
                    isTrusted = false;
                }
            } while (issuer != null);

            if (!isChainComplete)
            {
                throw ServiceResultException.Create(
                          StatusCodes.BadSecurityChecksFailed,
                          "Certificate chain not complete.\r\nSubjectName: {0}\r\nIssuerName: {1}",
                          certificates[0].SubjectName.Name,
                          certificates[0].IssuerName.Name);
            }

            if (!isTrusted)
            {
                throw ServiceResultException.Create(
                          StatusCodes.BadCertificateUntrusted,
                          "Certificate issuer is not trusted.\r\nSubjectName: {0}\r\nIssuerName: {1}",
                          certificates[0].SubjectName.Name,
                          certificates[0].IssuerName.Name);
            }

            return(isTrusted);
        }