This repository has been archived by the owner on Jan 23, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 4.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for OCSP on Linux, overhaul Linux X509Chain processing
This change moves a lot of the chain building work from managed code into the native shim, largely to cut down on the number of P/Invokes required to set up the chain builder. Once a chain has been built to a point where only one issuer will be considered, if revocation was requested and a CRL is not available, attempt an OCSP request if the certificate indicates the CA has an OCSP endpoint. Based on CA/Browser Forum's requirements this expects CRL for all intermediates and only attempts OCSP for the end-entity certificate. "Conforming" OCSP requests are opportunistically cached on the basis that local filesystem re-reads are more reliable (and faster) than doing a live request to the CA.
- Loading branch information
Showing
35 changed files
with
2,373 additions
and
504 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
128 changes: 128 additions & 0 deletions
128
src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OCSP.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
// 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; | ||
using System.Diagnostics; | ||
using System.Runtime.InteropServices; | ||
using System.Security.Cryptography; | ||
using System.Security.Cryptography.X509Certificates; | ||
using Microsoft.Win32.SafeHandles; | ||
|
||
internal static partial class Interop | ||
{ | ||
internal static partial class Crypto | ||
{ | ||
[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_OcspRequestDestroy")] | ||
internal static extern void OcspRequestDestroy(IntPtr ocspReq); | ||
|
||
[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_GetOcspRequestDerSize")] | ||
internal static extern int GetOcspRequestDerSize(SafeOcspRequestHandle req); | ||
|
||
[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EncodeOcspRequest")] | ||
internal static extern int EncodeOcspRequest(SafeOcspRequestHandle req, byte[] buf); | ||
|
||
[DllImport(Libraries.CryptoNative)] | ||
private static extern SafeOcspResponseHandle CryptoNative_DecodeOcspResponse(ref byte buf, int len); | ||
|
||
internal static SafeOcspResponseHandle DecodeOcspResponse(ReadOnlySpan<byte> buf) | ||
{ | ||
return CryptoNative_DecodeOcspResponse( | ||
ref MemoryMarshal.GetReference(buf), | ||
buf.Length); | ||
} | ||
|
||
[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_OcspResponseDestroy")] | ||
internal static extern void OcspResponseDestroy(IntPtr ocspReq); | ||
|
||
|
||
[DllImport(Libraries.CryptoNative)] | ||
private static extern X509VerifyStatusCode CryptoNative_X509ChainGetCachedOcspStatus(SafeX509StoreCtxHandle ctx, string cachePath); | ||
|
||
internal static X509VerifyStatusCode X509ChainGetCachedOcspStatus(SafeX509StoreCtxHandle ctx, string cachePath) | ||
{ | ||
X509VerifyStatusCode response = CryptoNative_X509ChainGetCachedOcspStatus(ctx, cachePath); | ||
|
||
if (response < 0) | ||
{ | ||
Debug.Fail($"Unexpected response from X509ChainGetCachedOcspSuccess: {response}"); | ||
throw new CryptographicException(); | ||
} | ||
|
||
return response; | ||
} | ||
|
||
[DllImport(Libraries.CryptoNative)] | ||
private static extern X509VerifyStatusCode CryptoNative_X509ChainVerifyOcsp( | ||
SafeX509StoreCtxHandle ctx, | ||
SafeOcspRequestHandle req, | ||
SafeOcspResponseHandle resp, | ||
string cachePath); | ||
|
||
internal static X509VerifyStatusCode X509ChainVerifyOcsp( | ||
SafeX509StoreCtxHandle ctx, | ||
SafeOcspRequestHandle req, | ||
SafeOcspResponseHandle resp, | ||
string cachePath) | ||
{ | ||
X509VerifyStatusCode response = CryptoNative_X509ChainVerifyOcsp(ctx, req, resp, cachePath); | ||
|
||
if (response < 0) | ||
{ | ||
Debug.Fail($"Unexpected response from X509ChainGetCachedOcspSuccess: {response}"); | ||
throw new CryptographicException(); | ||
} | ||
|
||
return response; | ||
} | ||
|
||
[DllImport(Libraries.CryptoNative)] | ||
private static extern SafeOcspRequestHandle CryptoNative_X509ChainBuildOcspRequest(SafeX509StoreCtxHandle storeCtx); | ||
|
||
internal static SafeOcspRequestHandle X509ChainBuildOcspRequest(SafeX509StoreCtxHandle storeCtx) | ||
{ | ||
SafeOcspRequestHandle req = CryptoNative_X509ChainBuildOcspRequest(storeCtx); | ||
|
||
if (req.IsInvalid) | ||
{ | ||
req.Dispose(); | ||
throw CreateOpenSslCryptographicException(); | ||
} | ||
|
||
return req; | ||
} | ||
} | ||
} | ||
|
||
namespace System.Security.Cryptography.X509Certificates | ||
{ | ||
internal class SafeOcspRequestHandle : SafeHandleZeroOrMinusOneIsInvalid | ||
{ | ||
public SafeOcspRequestHandle() | ||
: base(true) | ||
{ | ||
} | ||
|
||
protected override bool ReleaseHandle() | ||
{ | ||
Interop.Crypto.OcspRequestDestroy(handle); | ||
handle = IntPtr.Zero; | ||
return true; | ||
} | ||
} | ||
|
||
internal class SafeOcspResponseHandle : SafeHandleZeroOrMinusOneIsInvalid | ||
{ | ||
public SafeOcspResponseHandle() | ||
: base(true) | ||
{ | ||
} | ||
|
||
protected override bool ReleaseHandle() | ||
{ | ||
Interop.Crypto.OcspResponseDestroy(handle); | ||
handle = IntPtr.Zero; | ||
return true; | ||
} | ||
} | ||
} |
Oops, something went wrong.