Skip to content

Commit

Permalink
Fix openid certificates on Azure App Services (#3255)
Browse files Browse the repository at this point in the history
Fixes #3222
  • Loading branch information
sebastienros authored Mar 5, 2019
1 parent a72353b commit 29e26e4
Showing 1 changed file with 38 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -488,20 +488,8 @@ private static X509Certificate2 GetCertificate(StoreLocation location, StoreName
{
try
{
// Extract the certificate password from the separate .pwd file.
var password = await GetPasswordAsync(Path.ChangeExtension(file.FullName, ".pwd"));

var flags =
#if SUPPORTS_EPHEMERAL_KEY_SETS
RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ?
X509KeyStorageFlags.EphemeralKeySet :
X509KeyStorageFlags.MachineKeySet;
#else
X509KeyStorageFlags.MachineKeySet;
#endif

// Only add the certificate if it's still valid.
var certificate = new X509Certificate2(file.FullName, password, flags);
var certificate = await GetCertificateAsync(file.FullName);
if (certificate.NotBefore <= DateTime.Now && certificate.NotAfter > DateTime.Now)
{
certificates.Add((file.FullName, certificate));
Expand All @@ -525,6 +513,43 @@ async Task<string> GetPasswordAsync(string path)
return _dataProtector.Unprotect(await reader.ReadToEndAsync());
}
}

async Task<X509Certificate2> GetCertificateAsync(string path)
{
// Extract the certificate password from the separate .pwd file.
var password = await GetPasswordAsync(Path.ChangeExtension(path, ".pwd"));

try
{
// Note: ephemeral key sets are not supported on non-Windows platforms.
var flags =
#if SUPPORTS_EPHEMERAL_KEY_SETS
RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ?
X509KeyStorageFlags.EphemeralKeySet :
X509KeyStorageFlags.MachineKeySet;
#else
X509KeyStorageFlags.MachineKeySet;
#endif

return new X509Certificate2(path, password, flags);
}
// Some cloud platforms (e.g Azure App Service/Antares) are known to fail to import .pfx files if the
// private key is not persisted or marked as exportable. To ensure X.509 certificates can be correctly
// read on these platforms, a second pass is made by specifying the PersistKeySet and Exportable flags.
// For more information, visit https://github.com/OrchardCMS/OrchardCore/issues/3222.
catch (CryptographicException exception)
{
_logger.LogDebug(exception, "A first-chance exception occurred while trying to extract " +
"a X.509 certificate with the default key storage options.");

return new X509Certificate2(path, password,
X509KeyStorageFlags.MachineKeySet |
X509KeyStorageFlags.PersistKeySet |
X509KeyStorageFlags.Exportable);
}
// Don't swallow exceptions thrown from the catch handler to ensure unrecoverable exceptions
// (e.g caused by malformed X.509 certificates or invalid password) are correctly logged.
}
}
}
}

0 comments on commit 29e26e4

Please sign in to comment.