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

Commit 6585f9c

Browse files
committed
Retry failed calls to open SecTrust enumerators.
It doesn't seem to fail very often, but I've seen it fail, and CI has seen it fail. Presumably there's some sort of race/sync condition in the OS that's being encountered, so treat it as an intermittent problem and retry.
1 parent 7e72a82 commit 6585f9c

File tree

1 file changed

+38
-24
lines changed
  • src/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple

1 file changed

+38
-24
lines changed

src/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.Trust.cs

Lines changed: 38 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -55,36 +55,50 @@ private static SafeCFArrayHandle EnumerateStore(
5555
StoreEnumerator userEnumerator,
5656
StoreEnumerator machineEnumerator)
5757
{
58-
int result;
59-
SafeCFArrayHandle matches;
60-
int osStatus;
58+
const int RetryLimit = 3;
59+
int osStatus = 0;
6160

62-
if (location == StoreLocation.CurrentUser)
61+
// Occasionally calls to enumerate the trust list get errSecInvalidRecord.
62+
// So, if we fail with result 0 ("see osStatus") just retry and see if the
63+
// intermediate state has flushed itself.
64+
for (int i = 0; i < RetryLimit; i++)
6365
{
64-
result = userEnumerator(out matches, out osStatus);
65-
}
66-
else if (location == StoreLocation.LocalMachine)
67-
{
68-
result = machineEnumerator(out matches, out osStatus);
69-
}
70-
else
71-
{
72-
Debug.Fail($"Unrecognized StoreLocation value: {location}");
73-
throw new CryptographicException();
74-
}
66+
int result;
67+
SafeCFArrayHandle matches;
7568

76-
if (result == 1)
77-
{
78-
return matches;
79-
}
69+
if (location == StoreLocation.CurrentUser)
70+
{
71+
result = userEnumerator(out matches, out osStatus);
72+
}
73+
else if (location == StoreLocation.LocalMachine)
74+
{
75+
result = machineEnumerator(out matches, out osStatus);
76+
}
77+
else
78+
{
79+
Debug.Fail($"Unrecognized StoreLocation value: {location}");
80+
throw new CryptographicException();
81+
}
82+
83+
if (result == 1)
84+
{
85+
return matches;
86+
}
8087

81-
matches.Dispose();
88+
matches.Dispose();
8289

83-
if (result == 0)
84-
throw CreateExceptionForOSStatus(osStatus);
90+
if (result == 0)
91+
{
92+
// Instead of limiting it to particular error codes, just try it again.
93+
// A permanent error will be stable, a temporary one will hopefully go away.
94+
continue;
95+
}
96+
97+
Debug.Fail($"Unexpected result from {location} trust store enumeration: {result}");
98+
throw new CryptographicException();
99+
}
85100

86-
Debug.Fail($"Unexpected result from {location} trust store enumeration: {result}");
87-
throw new CryptographicException();
101+
throw CreateExceptionForOSStatus(osStatus);
88102
}
89103
}
90104
}

0 commit comments

Comments
 (0)