public void RemoveCounterSignature(SignerInfo counterSignerInfo) { // We only support one level of counter signing. if (m_parentSignerInfo != null) { throw new CryptographicException(CAPI.E_NOTIMPL); } if (counterSignerInfo == null) { throw new ArgumentNullException("counterSignerInfo"); } foreach (CryptographicAttributeObject attribute in UnsignedAttributes) { if (String.Compare(attribute.Oid.Value, CAPI.szOID_RSA_counterSign, StringComparison.OrdinalIgnoreCase) == 0) { for (int index = 0; index < attribute.Values.Count; index++) { AsnEncodedData encodedCounterSignature = (AsnEncodedData)attribute.Values[index]; SignerInfo counterSignerInfo2 = new SignerInfo(m_signedCms, m_parentSignerInfo, encodedCounterSignature.RawData); if ((counterSignerInfo.SignerIdentifier.Type == SubjectIdentifierType.IssuerAndSerialNumber) && (counterSignerInfo2.SignerIdentifier.Type == SubjectIdentifierType.IssuerAndSerialNumber)) { X509IssuerSerial issuerSerial1 = (X509IssuerSerial)counterSignerInfo.SignerIdentifier.Value; X509IssuerSerial issuerSerial2 = (X509IssuerSerial)counterSignerInfo2.SignerIdentifier.Value; if ((String.Compare(issuerSerial1.IssuerName, issuerSerial2.IssuerName, StringComparison.OrdinalIgnoreCase) == 0) && (String.Compare(issuerSerial1.SerialNumber, issuerSerial2.SerialNumber, StringComparison.OrdinalIgnoreCase) == 0)) { RemoveCounterSignature(PkcsUtils.GetSignerIndex(m_signedCms.GetCryptMsgHandle(), this, 0), index); return; } } else if ((counterSignerInfo.SignerIdentifier.Type == SubjectIdentifierType.SubjectKeyIdentifier) && (counterSignerInfo2.SignerIdentifier.Type == SubjectIdentifierType.SubjectKeyIdentifier)) { string keyIdentifier1 = counterSignerInfo.SignerIdentifier.Value as string; string keyIdentifier2 = counterSignerInfo2.SignerIdentifier.Value as string; if (String.Compare(keyIdentifier1, keyIdentifier2, StringComparison.OrdinalIgnoreCase) == 0) { RemoveCounterSignature(PkcsUtils.GetSignerIndex(m_signedCms.GetCryptMsgHandle(), this, 0), index); return; } } } } } throw new CryptographicException(CAPI.CRYPT_E_SIGNER_NOT_FOUND); }
// methods private X509IssuerSerial GetIssuerSerial(string issuer, byte[] serial) { X509IssuerSerial xis = new X509IssuerSerial(); xis.IssuerName = issuer; StringBuilder sb = new StringBuilder(); foreach (byte b in serial) { sb.Append(b.ToString("X2")); } xis.SerialNumber = sb.ToString(); return(xis); }
public void RemoveCounterSignature(SignerInfo counterSignerInfo) { if (this.m_parentSignerInfo != null) { throw new CryptographicException(-2147483647); } if (counterSignerInfo == null) { throw new ArgumentNullException("counterSignerInfo"); } CryptographicAttributeObjectEnumerator enumerator = this.UnsignedAttributes.GetEnumerator(); while (enumerator.MoveNext()) { CryptographicAttributeObject current = enumerator.Current; if (string.Compare(current.Oid.Value, "1.2.840.113549.1.9.6", StringComparison.OrdinalIgnoreCase) == 0) { for (int i = 0; i < current.Values.Count; i++) { AsnEncodedData data = current.Values[i]; SignerInfo info = new SignerInfo(this.m_signedCms, this.m_parentSignerInfo, data.RawData); if ((counterSignerInfo.SignerIdentifier.Type == SubjectIdentifierType.IssuerAndSerialNumber) && (info.SignerIdentifier.Type == SubjectIdentifierType.IssuerAndSerialNumber)) { X509IssuerSerial serial = (X509IssuerSerial)counterSignerInfo.SignerIdentifier.Value; X509IssuerSerial serial2 = (X509IssuerSerial)info.SignerIdentifier.Value; if ((string.Compare(serial.IssuerName, serial2.IssuerName, StringComparison.OrdinalIgnoreCase) != 0) || (string.Compare(serial.SerialNumber, serial2.SerialNumber, StringComparison.OrdinalIgnoreCase) != 0)) { continue; } this.RemoveCounterSignature(PkcsUtils.GetSignerIndex(this.m_signedCms.GetCryptMsgHandle(), this, 0), i); return; } if ((counterSignerInfo.SignerIdentifier.Type == SubjectIdentifierType.SubjectKeyIdentifier) && (info.SignerIdentifier.Type == SubjectIdentifierType.SubjectKeyIdentifier)) { string strA = counterSignerInfo.SignerIdentifier.Value as string; string strB = info.SignerIdentifier.Value as string; if (string.Compare(strA, strB, StringComparison.OrdinalIgnoreCase) == 0) { this.RemoveCounterSignature(PkcsUtils.GetSignerIndex(this.m_signedCms.GetCryptMsgHandle(), this, 0), i); return; } } } } } throw new CryptographicException(-2146889714); }
public void Decode(byte[] encodedMessage) { if (encodedMessage == null) { throw new ArgumentNullException("encodedMessage"); } PKCS7.ContentInfo ci = new PKCS7.ContentInfo(encodedMessage); if (ci.ContentType != PKCS7.Oid.envelopedData) { throw new Exception(""); } PKCS7.EnvelopedData ed = new PKCS7.EnvelopedData(ci.Content); Oid oid = new Oid(ed.ContentInfo.ContentType); _content = new ContentInfo(oid, new byte [0]); //ed.ContentInfo.Content.Value); foreach (PKCS7.RecipientInfo ri in ed.RecipientInfos) { Oid o = new Oid(ri.Oid); AlgorithmIdentifier ai = new AlgorithmIdentifier(o); SubjectIdentifier si = null; if (ri.SubjectKeyIdentifier != null) { si = new SubjectIdentifier(SubjectIdentifierType.SubjectKeyIdentifier, ri.SubjectKeyIdentifier); } else if ((ri.Issuer != null) && (ri.Serial != null)) { X509IssuerSerial xis = GetIssuerSerial(ri.Issuer, ri.Serial); si = new SubjectIdentifier(SubjectIdentifierType.IssuerAndSerialNumber, (object)xis); } KeyTransRecipientInfo _keyTrans = new KeyTransRecipientInfo(ri.Key, ai, si, ri.Version); _recipients.Add(_keyTrans); } // TODO - Certificates // TODO - UnprotectedAttributes _version = ed.Version; }
internal SubjectIdentifierOrKey(CAPI.CERT_ID certId) { switch (certId.dwIdChoice) { case CAPI.CERT_ID_ISSUER_SERIAL_NUMBER: X509IssuerSerial issuerSerial = PkcsUtils.DecodeIssuerSerial(certId.Value.IssuerSerialNumber); Reset(SubjectIdentifierOrKeyType.IssuerAndSerialNumber, issuerSerial); break; case CAPI.CERT_ID_KEY_IDENTIFIER: byte[] ski = new byte[certId.Value.KeyId.cbData]; Marshal.Copy(certId.Value.KeyId.pbData, ski, 0, ski.Length); Reset(SubjectIdentifierOrKeyType.SubjectKeyIdentifier, X509Utils.EncodeHexString(ski)); break; default: throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Cms_Invalid_Subject_Identifier_Type"), certId.dwIdChoice.ToString(CultureInfo.InvariantCulture)); } }
internal SubjectIdentifier(System.Security.Cryptography.CAPI.CERT_ID certId) { switch (certId.dwIdChoice) { case 1: { X509IssuerSerial serial = PkcsUtils.DecodeIssuerSerial(certId.Value.IssuerSerialNumber); this.Reset(SubjectIdentifierType.IssuerAndSerialNumber, serial); return; } case 2: { byte[] destination = new byte[certId.Value.KeyId.cbData]; Marshal.Copy(certId.Value.KeyId.pbData, destination, 0, destination.Length); this.Reset(SubjectIdentifierType.SubjectKeyIdentifier, System.Security.Cryptography.X509Certificates.X509Utils.EncodeHexString(destination)); return; } } throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Cms_Invalid_Subject_Identifier_Type"), certId.dwIdChoice.ToString(CultureInfo.InvariantCulture)); }
internal static X509Certificate2 FindCertificate(SubjectIdentifier identifier, X509Certificate2Collection certificates) { X509Certificate2 certificate = null; if ((certificates != null) && (certificates.Count > 0)) { X509Certificate2Collection certificates2; switch (identifier.Type) { case SubjectIdentifierType.IssuerAndSerialNumber: { X509IssuerSerial serial = (X509IssuerSerial)identifier.Value; certificates2 = certificates.Find(X509FindType.FindByIssuerDistinguishedName, serial.IssuerName, false); if (certificates2.Count > 0) { X509IssuerSerial serial2 = (X509IssuerSerial)identifier.Value; certificates2 = certificates2.Find(X509FindType.FindBySerialNumber, serial2.SerialNumber, false); if (certificates2.Count > 0) { certificate = certificates2[0]; } } return(certificate); } case SubjectIdentifierType.SubjectKeyIdentifier: certificates2 = certificates.Find(X509FindType.FindBySubjectKeyIdentifier, identifier.Value, false); if (certificates2.Count > 0) { certificate = certificates2[0]; } return(certificate); } } return(certificate); }
internal static unsafe X509IssuerSerial DecodeIssuerSerial(System.Security.Cryptography.CAPI.CERT_ISSUER_SERIAL_NUMBER pIssuerAndSerial) { System.Security.Cryptography.SafeLocalAllocHandle invalidHandle = System.Security.Cryptography.SafeLocalAllocHandle.InvalidHandle; uint csz = System.Security.Cryptography.CAPI.CAPISafe.CertNameToStrW(0x10001, new IntPtr((void *)&pIssuerAndSerial.Issuer), 0x2000003, invalidHandle, 0); if (csz <= 1) { throw new CryptographicException(Marshal.GetLastWin32Error()); } invalidHandle = System.Security.Cryptography.CAPI.LocalAlloc(0, new IntPtr((long)(2 * csz))); if (System.Security.Cryptography.CAPI.CAPISafe.CertNameToStrW(0x10001, new IntPtr((void *)&pIssuerAndSerial.Issuer), 0x2000003, invalidHandle, csz) <= 1) { throw new CryptographicException(Marshal.GetLastWin32Error()); } X509IssuerSerial serial = new X509IssuerSerial { IssuerName = Marshal.PtrToStringUni(invalidHandle.DangerousGetHandle()) }; byte[] destination = new byte[pIssuerAndSerial.SerialNumber.cbData]; Marshal.Copy(pIssuerAndSerial.SerialNumber.pbData, destination, 0, destination.Length); serial.SerialNumber = System.Security.Cryptography.X509Certificates.X509Utils.EncodeHexStringFromInt(destination); invalidHandle.Dispose(); return(serial); }
public void Decode(byte[] encodedMessage) { PKCS7.ContentInfo ci = new PKCS7.ContentInfo(encodedMessage); if (ci.ContentType != PKCS7.Oid.signedData) { throw new Exception(""); } PKCS7.SignedData sd = new PKCS7.SignedData(ci.Content); SubjectIdentifierType type = SubjectIdentifierType.Unknown; object o = null; X509Certificate2 x509 = null; if (sd.SignerInfo.Certificate != null) { x509 = new X509Certificate2(sd.SignerInfo.Certificate.RawData); } else if ((sd.SignerInfo.IssuerName != null) && (sd.SignerInfo.SerialNumber != null)) { byte[] serial = sd.SignerInfo.SerialNumber; Array.Reverse(serial); // ??? type = SubjectIdentifierType.IssuerAndSerialNumber; X509IssuerSerial xis = new X509IssuerSerial(); xis.IssuerName = sd.SignerInfo.IssuerName; xis.SerialNumber = ToString(serial, true); o = xis; // TODO: move to a FindCertificate (issuer, serial, collection) foreach (Mono.Security.X509.X509Certificate x in sd.Certificates) { if (x.IssuerName == sd.SignerInfo.IssuerName) { if (ToString(x.SerialNumber, true) == xis.SerialNumber) { x509 = new X509Certificate2(x.RawData); break; } } } } else if (sd.SignerInfo.SubjectKeyIdentifier != null) { string ski = ToString(sd.SignerInfo.SubjectKeyIdentifier, false); type = SubjectIdentifierType.SubjectKeyIdentifier; o = (object)ski; // TODO: move to a FindCertificate (ski, collection) foreach (Mono.Security.X509.X509Certificate x in sd.Certificates) { if (ToString(GetKeyIdentifier(x), false) == ski) { x509 = new X509Certificate2(x.RawData); break; } } } SignerInfo si = new SignerInfo(sd.SignerInfo.HashName, x509, type, o, sd.SignerInfo.Version); // si.AuthenticatedAttributes // si.UnauthenticatedAttributes _info.Add(si); ASN1 content = sd.ContentInfo.Content; Oid oid = new Oid(sd.ContentInfo.ContentType); if (!_detached || _content == null) { if (content[0] == null) { throw new ArgumentException("ContentInfo has no content. Detached signature ?"); } _content = new ContentInfo(oid, content[0].Value); } foreach (Mono.Security.X509.X509Certificate x in sd.Certificates) { _certs.Add(new X509Certificate2(x.RawData)); } _version = sd.Version; }
internal unsafe SubjectIdentifier(System.Security.Cryptography.CAPI.CRYPTOAPI_BLOB issuer, System.Security.Cryptography.CAPI.CRYPTOAPI_BLOB serialNumber) { System.Security.Cryptography.CAPI.CERT_ISSUER_SERIAL_NUMBER cert_issuer_serial_number; bool flag = true; byte *pbData = (byte *)serialNumber.pbData; for (uint i = 0; i < serialNumber.cbData; i++) { pbData++; if (pbData[0] != 0) { flag = false; break; } } if (flag) { byte[] destination = new byte[issuer.cbData]; Marshal.Copy(issuer.pbData, destination, 0, destination.Length); X500DistinguishedName name = new X500DistinguishedName(destination); if (string.Compare("CN=Dummy Signer", name.Name, StringComparison.OrdinalIgnoreCase) == 0) { this.Reset(SubjectIdentifierType.NoSignature, null); return; } } if (flag) { this.m_type = SubjectIdentifierType.SubjectKeyIdentifier; this.m_value = string.Empty; uint cbDecodedValue = 0; System.Security.Cryptography.SafeLocalAllocHandle invalidHandle = System.Security.Cryptography.SafeLocalAllocHandle.InvalidHandle; if (!System.Security.Cryptography.CAPI.DecodeObject(new IntPtr(7L), issuer.pbData, issuer.cbData, out invalidHandle, out cbDecodedValue)) { throw new CryptographicException(Marshal.GetLastWin32Error()); } using (invalidHandle) { System.Security.Cryptography.CAPI.CERT_NAME_INFO cert_name_info = (System.Security.Cryptography.CAPI.CERT_NAME_INFO)Marshal.PtrToStructure(invalidHandle.DangerousGetHandle(), typeof(System.Security.Cryptography.CAPI.CERT_NAME_INFO)); for (uint j = 0; j < cert_name_info.cRDN; j++) { System.Security.Cryptography.CAPI.CERT_RDN cert_rdn = (System.Security.Cryptography.CAPI.CERT_RDN)Marshal.PtrToStructure(new IntPtr(((long)cert_name_info.rgRDN) + (j * Marshal.SizeOf(typeof(System.Security.Cryptography.CAPI.CERT_RDN)))), typeof(System.Security.Cryptography.CAPI.CERT_RDN)); for (uint k = 0; k < cert_rdn.cRDNAttr; k++) { System.Security.Cryptography.CAPI.CERT_RDN_ATTR cert_rdn_attr = (System.Security.Cryptography.CAPI.CERT_RDN_ATTR)Marshal.PtrToStructure(new IntPtr(((long)cert_rdn.rgRDNAttr) + (k * Marshal.SizeOf(typeof(System.Security.Cryptography.CAPI.CERT_RDN_ATTR)))), typeof(System.Security.Cryptography.CAPI.CERT_RDN_ATTR)); if ((string.Compare("1.3.6.1.4.1.311.10.7.1", cert_rdn_attr.pszObjId, StringComparison.OrdinalIgnoreCase) == 0) && (cert_rdn_attr.dwValueType == 2)) { byte[] buffer2 = new byte[cert_rdn_attr.Value.cbData]; Marshal.Copy(cert_rdn_attr.Value.pbData, buffer2, 0, buffer2.Length); this.Reset(SubjectIdentifierType.SubjectKeyIdentifier, System.Security.Cryptography.X509Certificates.X509Utils.EncodeHexString(buffer2)); return; } } } } throw new CryptographicException(-2146889715); } cert_issuer_serial_number.Issuer = issuer; cert_issuer_serial_number.SerialNumber = serialNumber; X509IssuerSerial serial = PkcsUtils.DecodeIssuerSerial(cert_issuer_serial_number); this.Reset(SubjectIdentifierType.IssuerAndSerialNumber, serial); }
internal unsafe SubjectIdentifier(CAPI.CRYPTOAPI_BLOB issuer, CAPI.CRYPTOAPI_BLOB serialNumber) { // If serial number is 0, then it is the special SKI encoding or NoSignature bool isSKIorHashOnly = true; byte *pb = (byte *)serialNumber.pbData; for (uint i = 0; i < serialNumber.cbData; i++) { if (*pb++ != (byte)0) { isSKIorHashOnly = false; break; } } if (isSKIorHashOnly) { byte[] issuerBytes = new byte[issuer.cbData]; Marshal.Copy(issuer.pbData, issuerBytes, 0, issuerBytes.Length); X500DistinguishedName dummyName = new X500DistinguishedName(issuerBytes); if (String.Compare(CAPI.DummySignerCommonName, dummyName.Name, StringComparison.OrdinalIgnoreCase) == 0) { Reset(SubjectIdentifierType.NoSignature, null); return; } } if (isSKIorHashOnly) { // Decode disguised SKI in issuer field (See WinCrypt.h for more info). Note that some certificates may contain // an all-zero serial number but not be encoded with an szOID_KEYID_RDN. In order to allow use of signatures created // using these certificates, we will first try to find the szOID_KEYID_RDN, but if it does not exist, fall back to just // decoding the incoming issuer and serial number. m_type = SubjectIdentifierType.SubjectKeyIdentifier; m_value = String.Empty; uint cbCertNameInfo = 0; SafeLocalAllocHandle pbCertNameInfo = SafeLocalAllocHandle.InvalidHandle; if (CAPI.DecodeObject(new IntPtr(CAPI.X509_NAME), issuer.pbData, issuer.cbData, out pbCertNameInfo, out cbCertNameInfo)) { using (pbCertNameInfo) { checked { CAPI.CERT_NAME_INFO certNameInfo = (CAPI.CERT_NAME_INFO)Marshal.PtrToStructure(pbCertNameInfo.DangerousGetHandle(), typeof(CAPI.CERT_NAME_INFO)); for (uint i = 0; i < certNameInfo.cRDN; i++) { CAPI.CERT_RDN certRdn = (CAPI.CERT_RDN)Marshal.PtrToStructure(new IntPtr((long)certNameInfo.rgRDN + (long)(i * Marshal.SizeOf(typeof(CAPI.CERT_RDN)))), typeof(CAPI.CERT_RDN)); for (uint j = 0; j < certRdn.cRDNAttr; j++) { CAPI.CERT_RDN_ATTR certRdnAttr = (CAPI.CERT_RDN_ATTR)Marshal.PtrToStructure(new IntPtr((long)certRdn.rgRDNAttr + (long)(j * Marshal.SizeOf(typeof(CAPI.CERT_RDN_ATTR)))), typeof(CAPI.CERT_RDN_ATTR)); if (String.Compare(CAPI.szOID_KEYID_RDN, certRdnAttr.pszObjId, StringComparison.OrdinalIgnoreCase) == 0) { if (certRdnAttr.dwValueType == CAPI.CERT_RDN_OCTET_STRING) { byte[] ski = new byte[certRdnAttr.Value.cbData]; Marshal.Copy(certRdnAttr.Value.pbData, ski, 0, ski.Length); Reset(SubjectIdentifierType.SubjectKeyIdentifier, X509Utils.EncodeHexString(ski)); return; } } } } } } } } CAPI.CERT_ISSUER_SERIAL_NUMBER IssuerAndSerial; IssuerAndSerial.Issuer = issuer; IssuerAndSerial.SerialNumber = serialNumber; X509IssuerSerial issuerSerial = PkcsUtils.DecodeIssuerSerial(IssuerAndSerial); Reset(SubjectIdentifierType.IssuerAndSerialNumber, issuerSerial); }
public static bool TryDecode(ReadOnlyMemory <byte> source, out Rfc3161TimestampToken token, out int bytesConsumed) { bytesConsumed = 0; token = null; try { ContentInfoAsn contentInfo = AsnSerializer.Deserialize <ContentInfoAsn>(source, AsnEncodingRules.BER, out int bytesActuallyRead); // https://tools.ietf.org/html/rfc3161#section-2.4.2 // // A TimeStampToken is as follows. It is defined as a ContentInfo // ([CMS]) and SHALL encapsulate a signed data content type. // // TimeStampToken::= ContentInfo // --contentType is id-signedData([CMS]) // --content is SignedData ([CMS]) if (contentInfo.ContentType != Oids.Pkcs7Signed) { return(false); } SignedCms cms = new SignedCms(); cms.Decode(source); // The fields of type EncapsulatedContentInfo of the SignedData // construct have the following meanings: // // eContentType is an object identifier that uniquely specifies the // content type. For a time-stamp token it is defined as: // // id-ct-TSTInfo OBJECT IDENTIFIER ::= { iso(1) member-body(2) // us(840) rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) ct(1) 4} // // eContent is the content itself, carried as an octet string. // The eContent SHALL be the DER-encoded value of TSTInfo. if (cms.ContentInfo.ContentType.Value != Oids.TstInfo) { return(false); } // RFC3161: // The time-stamp token MUST NOT contain any signatures other than the // signature of the TSA. The certificate identifier (ESSCertID) of the // TSA certificate MUST be included as a signerInfo attribute inside a // SigningCertificate attribute. // RFC5816 says that ESSCertIDv2 should be allowed instead. SignerInfoCollection signerInfos = cms.SignerInfos; if (signerInfos.Count != 1) { return(false); } SignerInfo signer = signerInfos[0]; EssCertId certId; EssCertIdV2 certId2; if (!TryGetCertIds(signer, out certId, out certId2)) { return(false); } X509Certificate2 signerCert = signer.Certificate; if (signerCert == null && signer.SignerIdentifier.Type == SubjectIdentifierType.IssuerAndSerialNumber) { // If the cert wasn't provided, but the identifier was IssuerAndSerialNumber, // and the ESSCertId(V2) has specified an issuerSerial value, ensure it's a match. X509IssuerSerial issuerSerial = (X509IssuerSerial)signer.SignerIdentifier.Value; if (certId?.IssuerSerial != null) { if (!IssuerAndSerialMatch( certId.IssuerSerial.Value, issuerSerial.IssuerName, issuerSerial.SerialNumber)) { return(false); } } if (certId2?.IssuerSerial != null) { if (!IssuerAndSerialMatch( certId2.IssuerSerial.Value, issuerSerial.IssuerName, issuerSerial.SerialNumber)) { return(false); } } } Rfc3161TimestampTokenInfo tokenInfo; if (Rfc3161TimestampTokenInfo.TryDecode(cms.ContentInfo.Content, out tokenInfo, out _)) { if (signerCert != null && !CheckCertificate(signerCert, signer, certId, certId2, tokenInfo)) { return(false); } token = new Rfc3161TimestampToken { _parsedDocument = cms, _signerInfo = signer, _essCertId = certId, _essCertIdV2 = certId2, TokenInfo = tokenInfo, }; bytesConsumed = bytesActuallyRead; return(true); } } catch (CryptographicException) { } return(false); }
internal int FindIndexForSigner(SignerInfo signer) { Debug.Assert(signer != null); SubjectIdentifier id = signer.SignerIdentifier; X509IssuerSerial issuerSerial = default; if (id.Type == SubjectIdentifierType.IssuerAndSerialNumber) { issuerSerial = (X509IssuerSerial)id.Value; } for (int i = 0; i < _signerInfos.Length; i++) { SignerInfo current = _signerInfos[i]; SubjectIdentifier currentId = current.SignerIdentifier; if (currentId.Type != id.Type) { continue; } bool equal = false; switch (id.Type) { case SubjectIdentifierType.IssuerAndSerialNumber: { X509IssuerSerial currentIssuerSerial = (X509IssuerSerial)currentId.Value; if (currentIssuerSerial.IssuerName == issuerSerial.IssuerName && currentIssuerSerial.SerialNumber == issuerSerial.SerialNumber) { equal = true; } break; } case SubjectIdentifierType.SubjectKeyIdentifier: if ((string)id.Value == (string)currentId.Value) { equal = true; } break; case SubjectIdentifierType.NoSignature: equal = true; break; default: Debug.Fail($"No match logic for SubjectIdentifierType {id.Type}"); throw new CryptographicException(); } if (equal) { return(i); } } return(-1); }