File: System\IdentityModel\Tokens\X509IssuerSerialKeyIdentifierClause.cs
Web Access
Project: src\src\System.ServiceModel.Primitives\src\System.ServiceModel.Primitives.csproj (System.ServiceModel.Primitives)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
 
using System.Globalization;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.ServiceModel;
 
namespace System.IdentityModel.Tokens
{
    public class X509IssuerSerialKeyIdentifierClause : SecurityKeyIdentifierClause
    {
        private readonly string _issuerSerialNumber;
 
        public X509IssuerSerialKeyIdentifierClause(string issuerName, string issuerSerialNumber)
            : base(null)
        {
            if (string.IsNullOrEmpty(issuerName))
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(issuerName));
            }
 
            if (string.IsNullOrEmpty(issuerSerialNumber))
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(issuerSerialNumber));
            }
 
            IssuerName = issuerName;
            _issuerSerialNumber = issuerSerialNumber;
        }
 
        public X509IssuerSerialKeyIdentifierClause(X509Certificate2 certificate)
            : base(null)
        {
            if (certificate == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(certificate));
            }
 
            IssuerName = certificate.Issuer;
            _issuerSerialNumber = certificate.GetSerialNumberString();
        }
 
        public string IssuerName { get; }
 
        public string IssuerSerialNumber
        {
            get { return _issuerSerialNumber; }
        }
 
        public override bool Matches(SecurityKeyIdentifierClause keyIdentifierClause)
        {
            X509IssuerSerialKeyIdentifierClause that = keyIdentifierClause as X509IssuerSerialKeyIdentifierClause;
            return ReferenceEquals(this, that) || (that != null && that.Matches(IssuerName, _issuerSerialNumber));
        }
 
        public bool Matches(X509Certificate2 certificate)
        {
            if (certificate == null)
            {
                return false;
            }
 
            return Matches(certificate.Issuer, certificate.GetSerialNumberString());
        }
 
        public bool Matches(string issuerName, string issuerSerialNumber)
        {
            if (issuerName == null)
            {
                return false;
            }
 
            // If serial numbers dont match, we can avoid the potentially expensive issuer name comparison
            if (_issuerSerialNumber != issuerSerialNumber)
            {
                return false;
            }
 
            // Serial numbers match. Do a string comparison of issuer names
            if (IssuerName == issuerName)
            {
                return true;
            }
 
            // String equality comparison for issuer names failed
            // Do a byte-level comparison of the X500 distinguished names corresponding to the issuer names. 
            // X500DistinguishedName constructor can throw for malformed inputs
            bool x500IssuerNameMatch = false;
            try
            {
                if (System.ServiceModel.Security.SecurityUtils.IsEqual(new X500DistinguishedName(IssuerName).RawData,
                                                                       new X500DistinguishedName(issuerName).RawData))
                {
                    x500IssuerNameMatch = true;
                }
            }
            catch (CryptographicException)
            {
            }
 
            return x500IssuerNameMatch;
        }
 
        public override string ToString()
        {
            return string.Format(CultureInfo.InvariantCulture, "X509IssuerSerialKeyIdentifierClause(Issuer = '{0}', Serial = '{1}')",
                IssuerName, IssuerSerialNumber);
        }
    }
}