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

X509Certificate2/CommonCrypto: Unable to open PKCS#12 files with no password and valid MAC #24225

Open
qmfrederik opened this issue Sep 23, 2017 · 6 comments

Comments

Projects
None yet
5 participants
@qmfrederik
Copy link
Collaborator

commented Sep 23, 2017

If you have a PKCS#12 file which is not protected with a password, and which does have a MAC entry, opening the file will work on Windows and Linux but fails on Mac (which use CommonCrypto).

This is a regression on macOS as this worked with .NET Core 1.x (when using OpenSSL) and no longer works with .NET Core 2.0.

The following unit test reproduces the behavior:

using System;
using System.Security.Cryptography.X509Certificates;
using Xunit;

namespace temp
{
  public class UnitTest1
  {
    [Fact]
    public void Test1()
    {
      var cert = new X509Certificate("my_pkcs12.pfx");
      Assert.NotNull(cert);
    }
  }
}

The test passes on Windows & Linux but fails on macOS with the following error message:

Failed   certs.UnitTest1.Test1
Error Message:
 Interop+AppleCrypto+AppleCommonCryptoCryptographicException : MAC verification failed during PKCS12 import (wrong password?)
Stack Trace:
   at Interop.AppleCrypto.X509ImportCertificate(Byte[] bytes, X509ContentType contentType, SafePasswordHandle importPassword, SafeKeychainHandle keychain, Boolean exportable, SafeSecIdentityHandle& identityHandle)
   at Internal.Cryptography.Pal.CertificatePal.FromBlob(Byte[] rawData, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags)
   at System.Security.Cryptography.X509Certificates.X509Certificate..ctor(String fileName, String password, X509KeyStorageFlags keyStorageFlags)
   at System.Security.Cryptography.X509Certificates.X509Certificate..ctor(String fileName)
   at certs.UnitTest1.Test1() in /Users/quamotion/scratch/certs/UnitTest1.cs:line 12

my_pkcs12.pfx can be generated using the following script, use an empty password when prompted:

openssl genrsa -out my_key.key 2048
openssl req -new -key my_key.key -out my_request.csr
openssl x509 -req -days 3650 -in my_request.csr -signkey my_key.key -out my_cert.crt
openssl pkcs12 -keypbe PBE-SHA1-3DES -certpbe PBE-SHA1-3DES -export -in my_cert.crt -inkey my_key.key -out my_pkcs12.pfx -name "my-name"

This is not the same as #11046, that one was about p12 stores where the MAC is absent; in this case there is a valid MAC.

@qmfrederik

This comment has been minimized.

Copy link
Collaborator Author

commented Sep 23, 2017

/cc @bartonjs

@qmfrederik

This comment has been minimized.

Copy link
Collaborator Author

commented Sep 26, 2017

@bartonjs Is this a known compatibility issue?
From what I can gather, it's not listed at cross-platform-cryptography.md, so wanted to make sure.

@qmfrederik

This comment has been minimized.

Copy link
Collaborator Author

commented Sep 26, 2017

As a FYI for others who may hit the same issue, here's code that may act as a workaround based on BouncyCastle.

Pkcs12Store store = new Pkcs12Store();;

using (Stream stream = File.OpenRead(filename))
{
    store.Load(stream, new char[] {});
}

var keyAlias = store.Aliases.Cast<string>().SingleOrDefault(a => store.IsKeyEntry(a));

var key = (RsaPrivateCrtKeyParameters)store.GetKey(keyAlias).Key;
var bouncyCertificate = store.GetCertificate(keyAlias).Certificate;

var certificate = new X509Certificate2(DotNetUtilities.ToX509Certificate(bouncyCertificate));
var parameters = DotNetUtilities.ToRSAParameters(key);

RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();  
rsa.ImportParameters(parameters);

certificate = RSACertificateExtensions.CopyWithPrivateKey(certificate, rsa);

return certificate;
@kae

This comment has been minimized.

Copy link

commented Oct 2, 2017

Is any triage planned on this issue?

At least bug/non bug decision

@danmosemsft

This comment has been minimized.

Copy link
Member

commented Oct 2, 2017

cc @bartonjs ..

@bartonjs

This comment has been minimized.

Copy link
Member

commented Oct 4, 2017

Based on testing I did in the past, Apple cannot read a PFX that contains non-encrypted keys. So while this is a bug, it's probably not something that we would work around in .NET without a very compelling argument (like it being a key distribution model by a government CA, or something like that); but rather something which ideally would be resolved by Apple (https://bugreport.apple.com/, for SecItemImport).

What's the scenario here? Where are these PFX files coming from?

@bartonjs bartonjs added this to the Future milestone Jan 10, 2018

Dotnet-GitSync-Bot pushed a commit to Dotnet-GitSync-Bot/corefx that referenced this issue Apr 25, 2019

Removing EventPipe file polling (EventPipeController+Timer) (dotnet#2…
…4225)

* Remove file polling only, and leave the COMPlus_* functionality.
* Fix bug/typo introduced with dotnet/coreclr#21718

Signed-off-by: dotnet-bot <dotnet-bot@microsoft.com>

jkotas added a commit that referenced this issue Apr 26, 2019

Removing EventPipe file polling (EventPipeController+Timer) (#24225)
* Remove file polling only, and leave the COMPlus_* functionality.
* Fix bug/typo introduced with dotnet/coreclr#21718

Signed-off-by: dotnet-bot <dotnet-bot@microsoft.com>

schaabs added a commit to schaabs/azure-sdk-for-net that referenced this issue Jun 19, 2019

schaabs added a commit to Azure/azure-sdk-for-net that referenced this issue Jun 19, 2019

Adding ClientCertificateCredential to Azure.Idenity (#6636)
* Adding ClientCertificateCredential to Azure.Idenity

* fixing test assertion

* adding cert with password to work around dotnet/corefx#24225
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.