Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add name of corrupted certificate to CryptographicException on Mac #54477

Merged
merged 6 commits into from
Jun 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ internal static partial class AppleCrypto
out SafeCFDataHandle cfDataOut,
out int pOSStatus);

[DllImport(Libraries.AppleCryptoNative)]
private static extern int AppleCryptoNative_X509GetSubjectSummary(
SafeSecCertificateHandle cert,
out SafeCFStringHandle cfSubjectSummaryOut);

[DllImport(Libraries.AppleCryptoNative)]
private static extern int AppleCryptoNative_X509GetPublicKey(SafeSecCertificateHandle cert, out SafeSecKeyRefHandle publicKey, out int pOSStatus);

Expand Down Expand Up @@ -69,6 +74,31 @@ internal static byte[] X509GetRawData(SafeSecCertificateHandle cert)
throw new CryptographicException();
}

internal static string? X509GetSubjectSummary(SafeSecCertificateHandle cert)
{
SafeCFStringHandle subjectSummary;

int ret = AppleCryptoNative_X509GetSubjectSummary(
cert,
out subjectSummary);

using (subjectSummary)
{
if (ret == 1)
{
return CoreFoundation.CFStringToString(subjectSummary);
}
}

if (ret == 0)
{
return null;
}

Debug.Fail($"Unexpected return value {ret}");
throw new CryptographicException();
}

internal static SafeSecKeyRefHandle X509GetPrivateKeyFromIdentity(SafeSecIdentityHandle identity)
{
SafeSecKeyRefHandle key;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ static const Entry s_cryptoAppleNative[] =
DllImportEntry(AppleCryptoNative_GetOSStatusForChainStatus)
DllImportEntry(AppleCryptoNative_X509ChainSetTrustAnchorCertificates)
DllImportEntry(AppleCryptoNative_Pbkdf2)
DllImportEntry(AppleCryptoNative_X509GetSubjectSummary)
};

EXTERN_C const void* CryptoAppleResolveDllImport(const char* name);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -230,3 +230,15 @@ int32_t AppleCryptoNative_X509GetRawData(SecCertificateRef cert, CFDataRef* ppDa
*pOSStatus = *ppDataOut == NULL ? errSecParam : noErr;
return (*pOSStatus == noErr);
}

int32_t AppleCryptoNative_X509GetSubjectSummary(SecCertificateRef cert, CFStringRef* ppSummaryOut)
{
if (ppSummaryOut != NULL)
*ppSummaryOut = NULL;

if (cert == NULL || ppSummaryOut == NULL)
return kErrorBadInput;

*ppSummaryOut = SecCertificateCopySubjectSummary(cert);
return (*ppSummaryOut != NULL);
}
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,13 @@ ppDataOut: Receives a CFDataRef with the exported blob
pOSStatus: Receives the result of SecItemExport
*/
PALEXPORT int32_t AppleCryptoNative_X509GetRawData(SecCertificateRef cert, CFDataRef* ppDataOut, int32_t* pOSStatus);

/*
Extract a string that contains a human-readable summary of the contents of the certificate

Returns 1 on success, 0 on failure, any other value indicates invalid state.

Output:
ppSummaryOut: Receives a CFDataRef with the exported blob
*/
PALEXPORT int32_t AppleCryptoNative_X509GetSubjectSummary(SecCertificateRef cert, CFStringRef* ppSummaryOut);
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,26 @@ private void EnsureCertData()
return;

Debug.Assert(!_certHandle.IsInvalid);
_certData = new CertificateData(Interop.AppleCrypto.X509GetRawData(_certHandle));
string? subjectSummary = Interop.AppleCrypto.X509GetSubjectSummary(_certHandle);

try
{
_certData = new CertificateData(Interop.AppleCrypto.X509GetRawData(_certHandle));
}
catch (CryptographicException e)
{
if (subjectSummary is null)
{
throw;
}

string message = SR.Format(
SR.Cryptography_X509_CertificateCorrupted,
subjectSummary);

throw new CryptographicException(message, e);
}

_readCertData = true;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,9 @@
<data name="Cryptography_X509_NoOrMismatchedPemKey" xml:space="preserve">
<value>The key contents do not contain a PEM, the content is malformed, or the key does not match the certificate.</value>
</data>
<data name="Cryptography_X509_CertificateCorrupted" xml:space="preserve">
<value>Certificate '{0}' is corrupted.</value>
</data>
<data name="InvalidOperation_EnumNotStarted" xml:space="preserve">
<value>Enumeration has not started. Call MoveNext.</value>
</data>
Expand Down