Update Reference Sources to .NET Framework 4.6.1
[mono.git] / mcs / class / referencesource / System.IdentityModel / System / IdentityModel / Tokens / X509IssuerSerialKeyIdentifierClause.cs
1 //------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation.  All rights reserved.
3 //------------------------------------------------------------
4
5 namespace System.IdentityModel.Tokens
6 {
7     using System.Diagnostics;
8     using System.Globalization;
9     using System.Security.Cryptography;
10     using System.Security.Cryptography.X509Certificates;
11
12     public class X509IssuerSerialKeyIdentifierClause : SecurityKeyIdentifierClause
13     {
14         readonly string issuerName;
15         readonly string issuerSerialNumber;
16
17         public X509IssuerSerialKeyIdentifierClause(string issuerName, string issuerSerialNumber)
18             : base(null)
19         {
20             if (string.IsNullOrEmpty(issuerName))
21                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("issuerName");
22             if (string.IsNullOrEmpty(issuerSerialNumber))
23                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("issuerSerialNumber");
24
25             this.issuerName = issuerName;
26             this.issuerSerialNumber = issuerSerialNumber;
27         }
28
29         public X509IssuerSerialKeyIdentifierClause(X509Certificate2 certificate)
30             : base(null)
31         {
32             if (certificate == null)
33                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("certificate");
34
35             this.issuerName = certificate.Issuer;
36             this.issuerSerialNumber = Asn1IntegerConverter.Asn1IntegerToDecimalString(certificate.GetSerialNumber());
37         }
38
39         public string IssuerName
40         {
41             get { return this.issuerName; }
42         }
43
44         public string IssuerSerialNumber
45         {
46             get { return this.issuerSerialNumber; }
47         }
48
49         public override bool Matches(SecurityKeyIdentifierClause keyIdentifierClause)
50         {
51             X509IssuerSerialKeyIdentifierClause that = keyIdentifierClause as X509IssuerSerialKeyIdentifierClause;
52
53             // PreSharp Bug: Parameter 'that' to this public method must be validated: A null-dereference can occur here.
54 #pragma warning suppress 56506
55             return ReferenceEquals(this, that) || (that != null && that.Matches(this.issuerName, this.issuerSerialNumber));
56         }
57
58         public bool Matches(X509Certificate2 certificate)
59         {
60             if (certificate == null)
61                 return false;
62
63             return Matches(certificate.Issuer, Asn1IntegerConverter.Asn1IntegerToDecimalString(certificate.GetSerialNumber()));
64         }
65
66         public bool Matches(string issuerName, string issuerSerialNumber)
67         {
68             if (issuerName == null)
69             {
70                 return false;
71             }
72
73             // If serial numbers dont match, we can avoid the potentially expensive issuer name comparison
74             if (this.issuerSerialNumber != issuerSerialNumber)
75             {
76                 return false;
77             }
78
79             // Serial numbers match. Do a string comparison of issuer names
80             if (this.issuerName == issuerName)
81             {
82                 return true;
83             }
84
85             // String equality comparison for issuer names failed
86             // Do a byte-level comparison of the X500 distinguished names corresponding to the issuer names. 
87             // X500DistinguishedName constructor can throw for malformed inputs
88             bool x500IssuerNameMatch = false;
89             try
90             {
91                 if (CryptoHelper.IsEqual(new X500DistinguishedName(this.issuerName).RawData,
92                                          new X500DistinguishedName(issuerName).RawData))
93                 {
94                     x500IssuerNameMatch = true;
95                 }
96             }
97             catch (CryptographicException e)
98             {
99                 // Absorb and log exception. Fallthrough and return false from method.
100                 DiagnosticUtility.TraceHandledException(e, TraceEventType.Warning);
101             }
102
103             return x500IssuerNameMatch;
104         }
105
106         public override string ToString()
107         {
108             return string.Format(CultureInfo.InvariantCulture, "X509IssuerSerialKeyIdentifierClause(Issuer = '{0}', Serial = '{1}')",
109                 this.IssuerName, this.IssuerSerialNumber);
110         }
111     }
112 }