internal static extern int GetX509Version(SafeX509Handle x509);
internal static partial SafeX509Handle X509Duplicate(SafeX509Handle handle);
private static partial SafeSharedAsn1IntegerHandle X509GetSerialNumber_private(SafeX509Handle x);
internal static partial IntPtr GetX509PublicKeyBytes(SafeX509Handle x509);
internal static partial int GetX509DerSize(SafeX509Handle x);
internal static partial IntPtr GetX509SignatureAlgorithm(SafeX509Handle x509);
internal static partial IntPtr GetX509PublicKeyAlgorithm(SafeX509Handle x509);
internal static extern bool PushX509StackField(SafeX509StackHandle stack, SafeX509Handle x509);
internal Interop.Crypto.X509VerifyStatusCode FindChainViaAia( ref List <X509Certificate2> downloadedCerts) { IntPtr lastCert = IntPtr.Zero; SafeX509StoreCtxHandle storeCtx = _storeCtx; Interop.Crypto.X509VerifyStatusCode statusCode = Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT; while (!IsCompleteChain(statusCode)) { using (SafeX509Handle currentCert = Interop.Crypto.X509StoreCtxGetCurrentCert(storeCtx)) { IntPtr currentHandle = currentCert.DangerousGetHandle(); // No progress was made, give up. if (currentHandle == lastCert) { break; } lastCert = currentHandle; ArraySegment <byte> authorityInformationAccess = OpenSslX509CertificateReader.FindFirstExtension( currentCert, Oids.AuthorityInformationAccess); if (authorityInformationAccess.Count == 0) { break; } X509Certificate2 downloaded = DownloadCertificate( authorityInformationAccess, ref _remainingDownloadTime); // The AIA record is contained in a public structure, so no need to clear it. CryptoPool.Return(authorityInformationAccess.Array, clearSize: 0); if (downloaded == null) { break; } if (downloadedCerts == null) { downloadedCerts = new List <X509Certificate2>(); } AddToStackAndUpRef(downloaded.Handle, _untrustedLookup); downloadedCerts.Add(downloaded); Interop.Crypto.X509StoreCtxRebuildChain(storeCtx); statusCode = Interop.Crypto.X509StoreCtxGetError(storeCtx); } } if (statusCode == Interop.Crypto.X509VerifyStatusCode.X509_V_OK && downloadedCerts != null) { using (SafeX509StackHandle chainStack = Interop.Crypto.X509StoreCtxGetChain(_storeCtx)) { int chainSize = Interop.Crypto.GetX509StackFieldCount(chainStack); Span <IntPtr> tempChain = stackalloc IntPtr[DefaultChainCapacity]; byte[] tempChainRent = null; if (chainSize <= tempChain.Length) { tempChain = tempChain.Slice(0, chainSize); } else { int targetSize = checked (chainSize * IntPtr.Size); tempChainRent = CryptoPool.Rent(targetSize); tempChain = MemoryMarshal.Cast <byte, IntPtr>(tempChainRent.AsSpan(0, targetSize)); } for (int i = 0; i < chainSize; i++) { tempChain[i] = Interop.Crypto.GetX509StackField(chainStack, i); } // In the average case we never made it here. // // Given that we made it here, in the average remaining case // we are doing a one item for which will match in the second position // of an (on-average) 3 item collection. // // The only case where this loop really matters is if downloading the // certificate made an alternate chain better, which may have resulted in // an extra download and made the first one not be involved any longer. In // that case, it's a 2 item for loop matching against a three item set. // // So N*M is well contained. for (int i = downloadedCerts.Count - 1; i >= 0; i--) { X509Certificate2 downloadedCert = downloadedCerts[i]; if (!tempChain.Contains(downloadedCert.Handle)) { downloadedCert.Dispose(); downloadedCerts.RemoveAt(i); } } if (downloadedCerts.Count == 0) { downloadedCerts = null; } if (tempChainRent != null) { CryptoPool.Return(tempChainRent); } } } return(statusCode); }
internal static extern IntPtr GetX509PublicKeyBytes(SafeX509Handle x509);
internal static extern SafeBioHandle GetX509NameInfo(SafeX509Handle x509, int nameType, [MarshalAs(UnmanagedType.Bool)] bool forIssuer);
private static extern int GetX509PublicKeyParameterBytes(SafeX509Handle x509, byte[] buf, int cBuf);
internal static extern IntPtr GetX509PublicKeyAlgorithm(SafeX509Handle x509);
internal static extern IntPtr GetX509SignatureAlgorithm(SafeX509Handle x509);
internal static partial bool X509StoreCtxInit( SafeX509StoreCtxHandle ctx, SafeX509StoreHandle store, SafeX509Handle x509, SafeX509StackHandle extraCerts);
internal static partial IntPtr X509GetSubjectName(SafeX509Handle x);
internal static partial IntPtr GetX509NotAfter(SafeX509Handle x509);
internal static partial bool X509CheckPurpose(SafeX509Handle x, int id, int ca);
internal static partial int GetX509SubjectPublicKeyInfoDerSize(SafeX509Handle x509);
internal static partial ulong X509IssuerNameHash(SafeX509Handle x);
internal static partial int EncodeX509SubjectPublicKeyInfo(SafeX509Handle x509, byte[] buf);
private static partial SafeSharedAsn1OctetStringHandle CryptoNative_X509FindExtensionData( SafeX509Handle x, int extensionNid);
internal static partial SafeEvpPKeyHandle GetX509EvpPublicKey(SafeX509Handle x509);
internal static partial int X509GetExtCount(SafeX509Handle x);
internal static partial int EncodeX509(SafeX509Handle x, byte[] buf);
internal static partial IntPtr X509GetExt(SafeX509Handle x, int loc);
internal static partial SafeX509Handle X509UpRef(SafeX509Handle handle);
internal static partial IntPtr GetX509NotBefore(SafeX509Handle x509);
internal static partial IntPtr X509GetIssuerName(SafeX509Handle x);
internal static extern IntPtr GetX509NotAfter(SafeX509Handle x509);