Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit 385286a

Browse files
Paulo Janottistephentoub
authored andcommitted
Make X509_store_add_crl throw on unexpected errors (#28966)
* X509_store_add_crl throws on unexpected errors Fixes #3063 and it is part 2 of #25676: clear error queue on X509_store_add_crl failures. * PR feedback
1 parent 33f5c25 commit 385286a

File tree

3 files changed

+41
-12
lines changed
  • src
    • Common/src/Interop/Unix/System.Security.Cryptography.Native
    • Native/Unix/System.Security.Cryptography.Native
    • System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix

3 files changed

+41
-12
lines changed

src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.ERR.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,14 @@ internal static partial class Crypto
1818
[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_ErrGetError")]
1919
internal static extern ulong ErrGetError();
2020

21+
[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_ErrGetErrorAlloc")]
22+
private static extern ulong ErrGetErrorAlloc([MarshalAs(UnmanagedType.Bool)] out bool isAllocFailure);
23+
2124
[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_ErrPeekError")]
2225
internal static extern ulong ErrPeekError();
2326

24-
[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_ErrGetErrorAlloc")]
25-
private static extern ulong ErrGetErrorAlloc([MarshalAs(UnmanagedType.Bool)] out bool isAllocFailure);
27+
[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_ErrPeekLastError")]
28+
internal static extern ulong ErrPeekLastError();
2629

2730
[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_ErrReasonErrorString")]
2831
internal static extern IntPtr ErrReasonErrorString(ulong error);

src/Native/Unix/System.Security.Cryptography.Native/pal_err.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,6 @@ extern "C" uint64_t CryptoNative_ErrGetError()
1515
return ERR_get_error();
1616
}
1717

18-
extern "C" uint64_t CryptoNative_ErrPeekError()
19-
{
20-
return ERR_peek_error();
21-
}
2218
extern "C" uint64_t CryptoNative_ErrGetErrorAlloc(int32_t* isAllocFailure)
2319
{
2420
unsigned long err = ERR_get_error();
@@ -31,6 +27,16 @@ extern "C" uint64_t CryptoNative_ErrGetErrorAlloc(int32_t* isAllocFailure)
3127
return err;
3228
}
3329

30+
extern "C" uint64_t CryptoNative_ErrPeekError()
31+
{
32+
return ERR_peek_error();
33+
}
34+
35+
extern "C" uint64_t CryptoNative_ErrPeekLastError()
36+
{
37+
return ERR_peek_last_error();
38+
}
39+
3440
extern "C" const char* CryptoNative_ErrReasonErrorString(uint64_t error)
3541
{
3642
return ERR_reason_error_string(static_cast<unsigned long>(error));

src/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/CrlCache.cs

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ namespace Internal.Cryptography.Pal
1313
{
1414
internal static class CrlCache
1515
{
16+
private const ulong X509_R_CERT_ALREADY_IN_HASH_TABLE = 0x0B07D065;
17+
1618
public static void AddCrlForCertificate(
1719
X509Certificate2 cert,
1820
SafeX509StoreHandle store,
@@ -83,9 +85,18 @@ private static bool AddCachedCrl(X509Certificate2 cert, SafeX509StoreHandle stor
8385
return false;
8486
}
8587

86-
// TODO (#3063): Check the return value of X509_STORE_add_crl, and throw on any error other
87-
// than X509_R_CERT_ALREADY_IN_HASH_TABLE
88-
Interop.Crypto.X509StoreAddCrl(store, crl);
88+
if (!Interop.Crypto.X509StoreAddCrl(store, crl))
89+
{
90+
// Ignore error "cert already in store", throw on anything else. In any case the error queue will be cleared.
91+
if (X509_R_CERT_ALREADY_IN_HASH_TABLE == Interop.Crypto.ErrPeekLastError())
92+
{
93+
Interop.Crypto.ErrClearError();
94+
}
95+
else
96+
{
97+
throw Interop.Crypto.CreateOpenSslCryptographicException();
98+
}
99+
}
89100

90101
return true;
91102
}
@@ -111,9 +122,18 @@ private static void DownloadAndAddCrl(
111122
// null is a valid return (e.g. no remainingDownloadTime)
112123
if (crl != null && !crl.IsInvalid)
113124
{
114-
// TODO (#3063): Check the return value of X509_STORE_add_crl, and throw on any error other
115-
// than X509_R_CERT_ALREADY_IN_HASH_TABLE
116-
Interop.Crypto.X509StoreAddCrl(store, crl);
125+
if (!Interop.Crypto.X509StoreAddCrl(store, crl))
126+
{
127+
// Ignore error "cert already in store", throw on anything else. In any case the error queue will be cleared.
128+
if (X509_R_CERT_ALREADY_IN_HASH_TABLE == Interop.Crypto.ErrPeekLastError())
129+
{
130+
Interop.Crypto.ErrClearError();
131+
}
132+
else
133+
{
134+
throw Interop.Crypto.CreateOpenSslCryptographicException();
135+
}
136+
}
117137

118138
// Saving the CRL to the disk is just a performance optimization for later requests to not
119139
// need to use the network again, so failure to save shouldn't throw an exception or mark

0 commit comments

Comments
 (0)