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

error is given to load p7b in X509Certificate2Collection #59304

Closed
amin1best opened this issue Sep 18, 2021 · 6 comments
Closed

error is given to load p7b in X509Certificate2Collection #59304

amin1best opened this issue Sep 18, 2021 · 6 comments
Labels
area-System.Security untriaged New issue has not been triaged by the area owner

Comments

@amin1best
Copy link

Hi,
Sometimes in System.Security.Cryptography.X509Certificates.X509Certificate2Collection following error is given to load p7b file:

Unhandled exception. System.NotSupportedException: The certificate key algorithm is not supported.
       at System.Security.Cryptography.X509Certificates.PublicKey.get_Key()

I tested using following link:
https://pkijs.org/examples/P7BSimpleExample.html

I got following result:

Signature algorithm Result
RSASSA-PKCS1 OK
RSA-PSS OK
ECDSA --ERROR--
@dotnet-issue-labeler dotnet-issue-labeler bot added area-System.Security untriaged New issue has not been triaged by the area owner labels Sep 18, 2021
@ghost
Copy link

ghost commented Sep 18, 2021

Tagging subscribers to this area: @bartonjs, @vcsjones, @krwq, @GrabYourPitchforks
See info in area-owners.md if you want to be subscribed.

Issue Details

Hi,
Sometimes in System.Security.Cryptography.X509Certificates.X509Certificate2Collection following error is given to load p7b file:

Unhandled exception. System.NotSupportedException: The certificate key algorithm is not supported.
       at System.Security.Cryptography.X509Certificates.PublicKey.get_Key()

I tested using following link:
https://pkijs.org/examples/P7BSimpleExample.html

I got following result:

Signature algorithm Result
RSASSA-PKCS1 OK
RSA-PSS OK
ECDSA --ERROR--
Author: amin1best
Assignees: -
Labels:

area-System.Security, untriaged

Milestone: -

@vcsjones
Copy link
Member

vcsjones commented Sep 18, 2021

Are you sure it's the ECDSA one that is failing? I would expect ECDSA to work and RSA-PSS to fail.

.NET does not currently support certificates with RSA-PSS (1.2.840.113549.1.1.10) public keys.

@vcsjones
Copy link
Member

vcsjones commented Sep 18, 2021

at System.Security.Cryptography.X509Certificates.PublicKey.get_Key()

Oh. I see. You are using the PublicKey.Key property. This property is deprecated as of .NET 6 and never supported ECDSA keys.

Instead, on your X509Certificate2 instance you should call GetECDsaPublicKey or GetRSAPublicKey depending on what algorithm key is in the certificate. Something like this:

X509Certificate2Collection coll = new X509Certificate2Collection();

// put stuff in the collection...

foreach (X509Certificate2 cert in coll)
{
    if (cert.GetRSAPublicKey() is RSA rsa)
    {
        // It's an RSA certificate - use `rsa` here.
    }
    else if (cert.GetECDsaPublicKey() is ECDsa ecdsa)
    {
        // It's an ECDsa certificate - use `ecdsa` here.
    }
    else
    {
        throw new CryptographicException("Unhandled certificate algorithm");
    }
}

@amin1best
Copy link
Author

amin1best commented Sep 19, 2021

X509Certificate2Collection coll = new X509Certificate2Collection();

// put stuff in the collection...

foreach (X509Certificate2 cert in coll)
{
    if (cert.GetRSAPublicKey() is RSA rsa)
    {
        // It's an RSA certificate - use `rsa` here.
    }
    else if (cert.GetECDsaPublicKey() is ECDsa ecdsa)
    {
        // It's an ECDsa certificate - use `ecdsa` here.
    }
    else
    {
        throw new CryptographicException("Unhandled certificate algorithm");
    }
}

Thank you for informing me about deprecation of PublicKey.Key.
I have two Comments:

  1. The following link in RSA section states that PSS is supported:
    https://docs.microsoft.com/en-us/dotnet/standard/security/cross-platform-cryptography#asymmetric-cryptography

I do not know, maybe I'm wrong. This is also a sample p7b file generated using RSA-PSS and I have no problem reading its public key:

-----BEGIN CMS-----
MIIIiQYJKoZIhvcNAQcCoIIIejCCCHYCAQExADALBgkqhkiG9w0BBwGgggheMIIC
xjCCAa6gAwIBAgIBATANBgkqhkiG9w0BAQowADAeMRwwCQYDVQQGEwJSVTAPBgNV
BAMeCABUAGUAcwB0MB4XDTEyMTIzMTIwMzAwMFoXDTE1MTIzMTIwMzAwMFowHjEc
MAkGA1UEBhMCUlUwDwYDVQQDHggAVABlAHMAdDCCASIwDQYJKoZIhvcNAQEBBQAD
ggEPADCCAQoCggEBAOexwyECYKRaEE9IiEN3yjRGy6UI0fhqZA1I6Val3NoMFmZE
bLxWPYF28P6o0A1n4UXAV4ucgs+vfCIC1rNrQl+Y33M64F/h4Yia5CL69ItbrwF6
+mvAO8pkbAocZpxTwPVaHtzD5CSfci6x2yYuqVkhrc3KeZ5hCdI/VxhILHojgEW+
TbRBBbNu6BXd8GullqEvhX5wZUq5Q6ZR3MqTNtW9S3wwgD5r9yfyOySYyJKJjqlo
hvBqQVXcdtC7WpBIqy1/ZEJJ39uHnqo/rH60hFARKi6LoHIolAL3mgoI+5miWNvb
x8lO8PByCQ32jOwrHfTFcGEFHioKhR5V+XoAkmkCAwEAAaMPMA0wCwYDVR0PBAQD
AgACMA0GCSqGSIb3DQEBCjAAA4IBAQDif6tXu6Usvh/J4c007MMycfOT62Olcqre
9lBFzcJuOj4WyklUPHbQIx+JRBV0GJjbNdVbIj8A4E7THYiq6WJvwOUwnXre4/4o
6E+Uw2UOHY+VbUpIFvD6SAdq0CZu+XRD0vx53gU++rcOI8QdDBVp0f5BLIQkQQMO
JALIyVb9ogL5BVSzQXw3VozFyT9ZlZFN+qb1W07lcD1vtTUWZIbvpRU3vJ9xoe0U
l0mEXVAsohhrJmHymzjuNE+0O6aY6+3r9uyX/YcyjYqeskzhX0VLr5+sxiwemywK
GMktwm6dpH7AKAdtqr/dq9W8sCcOnU7iTu1AUx08UhMn/paEKfLeMIICxjCCAa6g
AwIBAgIBATANBgkqhkiG9w0BAQowADAeMRwwCQYDVQQGEwJSVTAPBgNVBAMeCABU
AGUAcwB0MB4XDTEyMTIzMTIwMzAwMFoXDTE1MTIzMTIwMzAwMFowHjEcMAkGA1UE
BhMCUlUwDwYDVQQDHggAVABlAHMAdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
AQoCggEBAOexwyECYKRaEE9IiEN3yjRGy6UI0fhqZA1I6Val3NoMFmZEbLxWPYF2
8P6o0A1n4UXAV4ucgs+vfCIC1rNrQl+Y33M64F/h4Yia5CL69ItbrwF6+mvAO8pk
bAocZpxTwPVaHtzD5CSfci6x2yYuqVkhrc3KeZ5hCdI/VxhILHojgEW+TbRBBbNu
6BXd8GullqEvhX5wZUq5Q6ZR3MqTNtW9S3wwgD5r9yfyOySYyJKJjqlohvBqQVXc
dtC7WpBIqy1/ZEJJ39uHnqo/rH60hFARKi6LoHIolAL3mgoI+5miWNvbx8lO8PBy
CQ32jOwrHfTFcGEFHioKhR5V+XoAkmkCAwEAAaMPMA0wCwYDVR0PBAQDAgACMA0G
CSqGSIb3DQEBCjAAA4IBAQDif6tXu6Usvh/J4c007MMycfOT62Olcqre9lBFzcJu
Oj4WyklUPHbQIx+JRBV0GJjbNdVbIj8A4E7THYiq6WJvwOUwnXre4/4o6E+Uw2UO
HY+VbUpIFvD6SAdq0CZu+XRD0vx53gU++rcOI8QdDBVp0f5BLIQkQQMOJALIyVb9
ogL5BVSzQXw3VozFyT9ZlZFN+qb1W07lcD1vtTUWZIbvpRU3vJ9xoe0Ul0mEXVAs
ohhrJmHymzjuNE+0O6aY6+3r9uyX/YcyjYqeskzhX0VLr5+sxiwemywKGMktwm6d
pH7AKAdtqr/dq9W8sCcOnU7iTu1AUx08UhMn/paEKfLeMIICxjCCAa6gAwIBAgIB
ATANBgkqhkiG9w0BAQowADAeMRwwCQYDVQQGEwJSVTAPBgNVBAMeCABUAGUAcwB0
MB4XDTEyMTIzMTIwMzAwMFoXDTE1MTIzMTIwMzAwMFowHjEcMAkGA1UEBhMCUlUw
DwYDVQQDHggAVABlAHMAdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
AOexwyECYKRaEE9IiEN3yjRGy6UI0fhqZA1I6Val3NoMFmZEbLxWPYF28P6o0A1n
4UXAV4ucgs+vfCIC1rNrQl+Y33M64F/h4Yia5CL69ItbrwF6+mvAO8pkbAocZpxT
wPVaHtzD5CSfci6x2yYuqVkhrc3KeZ5hCdI/VxhILHojgEW+TbRBBbNu6BXd8Gul
lqEvhX5wZUq5Q6ZR3MqTNtW9S3wwgD5r9yfyOySYyJKJjqlohvBqQVXcdtC7WpBI
qy1/ZEJJ39uHnqo/rH60hFARKi6LoHIolAL3mgoI+5miWNvbx8lO8PByCQ32jOwr
HfTFcGEFHioKhR5V+XoAkmkCAwEAAaMPMA0wCwYDVR0PBAQDAgACMA0GCSqGSIb3
DQEBCjAAA4IBAQDif6tXu6Usvh/J4c007MMycfOT62Olcqre9lBFzcJuOj4WyklU
PHbQIx+JRBV0GJjbNdVbIj8A4E7THYiq6WJvwOUwnXre4/4o6E+Uw2UOHY+VbUpI
FvD6SAdq0CZu+XRD0vx53gU++rcOI8QdDBVp0f5BLIQkQQMOJALIyVb9ogL5BVSz
QXw3VozFyT9ZlZFN+qb1W07lcD1vtTUWZIbvpRU3vJ9xoe0Ul0mEXVAsohhrJmHy
mzjuNE+0O6aY6+3r9uyX/YcyjYqeskzhX0VLr5+sxiwemywKGMktwm6dpH7AKAdt
qr/dq9W8sCcOnU7iTu1AUx08UhMn/paEKfLeMQA=
-----END CMS-----
  1. But I still have a problem with ECDSA. The return type in cert.GetECDsaPublicKey() is System.Security.Cryptography.ECDsaCng
    I can only read public key in binary form as follows:
CngKey k = ecdsa.Key;
byte[] blob = k.Export(CngKeyBlobFormat.EccPublicBlob);

If I try to read XmlString like the following, I get an error:

ecdsa.ToXmlString(ECKeyXmlFormat.Rfc4050);

Error:

Unhandled exception. System.PlatformNotSupportedException: Operation is not supported on this platform.
   at System.Security.Cryptography.ECDsaCng.ToXmlString(ECKeyXmlFormat format)

My Operating System is Windows 10 21H1 and sample p7b file generated using ECDSA is as follows:

-----BEGIN CMS-----
MIID3AYJKoZIhvcNAQcCoIIDzTCCA8kCAQExADALBgkqhkiG9w0BBwGgggOxMIIB
NzCB36ADAgECAgEBMAkGByqGSM49BAEwHjEcMAkGA1UEBhMCUlUwDwYDVQQDHggA
VABlAHMAdDAeFw0xMjEyMzEyMDMwMDBaFw0xNTEyMzEyMDMwMDBaMB4xHDAJBgNV
BAYTAlJVMA8GA1UEAx4IAFQAZQBzAHQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNC
AASG4UtZrlzx9Uo7PBWxRTUND0xGdHfUow4FNV3R+0PXv880DWB0clJ27Tj++Zrl
/TjRuNYFh25tQ0NSD0WdDmndow8wDTALBgNVHQ8EBAMCAAIwCQYHKoZIzj0EAQNI
ADBFAiAX22/LqC8QeyJyViPrZ07k+ee5HOMYgkQNfXnnwfaHKQIhAO4cPlN6oIqE
39ZEVv8fEZkErQI8CBFTB98cEuodmJ69MIIBNzCB36ADAgECAgEBMAkGByqGSM49
BAEwHjEcMAkGA1UEBhMCUlUwDwYDVQQDHggAVABlAHMAdDAeFw0xMjEyMzEyMDMw
MDBaFw0xNTEyMzEyMDMwMDBaMB4xHDAJBgNVBAYTAlJVMA8GA1UEAx4IAFQAZQBz
AHQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASG4UtZrlzx9Uo7PBWxRTUND0xG
dHfUow4FNV3R+0PXv880DWB0clJ27Tj++Zrl/TjRuNYFh25tQ0NSD0WdDmndow8w
DTALBgNVHQ8EBAMCAAIwCQYHKoZIzj0EAQNIADBFAiAX22/LqC8QeyJyViPrZ07k
+ee5HOMYgkQNfXnnwfaHKQIhAO4cPlN6oIqE39ZEVv8fEZkErQI8CBFTB98cEuod
mJ69MIIBNzCB36ADAgECAgEBMAkGByqGSM49BAEwHjEcMAkGA1UEBhMCUlUwDwYD
VQQDHggAVABlAHMAdDAeFw0xMjEyMzEyMDMwMDBaFw0xNTEyMzEyMDMwMDBaMB4x
HDAJBgNVBAYTAlJVMA8GA1UEAx4IAFQAZQBzAHQwWTATBgcqhkjOPQIBBggqhkjO
PQMBBwNCAASG4UtZrlzx9Uo7PBWxRTUND0xGdHfUow4FNV3R+0PXv880DWB0clJ2
7Tj++Zrl/TjRuNYFh25tQ0NSD0WdDmndow8wDTALBgNVHQ8EBAMCAAIwCQYHKoZI
zj0EAQNIADBFAiAX22/LqC8QeyJyViPrZ07k+ee5HOMYgkQNfXnnwfaHKQIhAO4c
PlN6oIqE39ZEVv8fEZkErQI8CBFTB98cEuodmJ69MQA=
-----END CMS-----

How can I get a Public Key as XmlString?
Thanks @vcsjones

@vcsjones
Copy link
Member

vcsjones commented Sep 19, 2021

  1. The following link in RSA section states that PSS is supported:
    https://docs.microsoft.com/en-us/dotnet/standard/security/cross-platform-cryptography#asymmetric-cryptography

Yeah. Producing an RSA-PSS signature is supported with an RSA key. However there are X.509 certificates that have special RSA-PSS SubjectPublicKeyInfo's, and that is what I was alluding to not being supported. If you aren't running in to that, great.

If I try to read XmlString like the following, I get an error:

The ToXmlString and FromXmlString stuff in EC types is going to be deprecated in .NET 7, because:

  1. It was never implemented, as you have found.
  2. There are more preferred export / import formats.
  3. See Annotate unsupported APIs in System.Security.* #50528 (comment) for more background

I think the better thing to do in .NET is to use ExportSubjectPublicKeyInfo. This is a binary format but is ideal because it is a standard, is supported widely by other ecosystems because it is a standard, and lastly because it is supported by all key types.

@bartonjs
Copy link
Member

I think the original question, and variants, have been answered (@vcsjones' answers are all correct), so closing the issue.

To restate the problems and answers:

  • PublicKey.get_Key does not work for ECDSA/ECDH: This is known, and a permanent limitation of this property (for one, it can't distinguish between ECDSA and ECDH). We've marked the property as Obsolete in .NET 6.
    • The replacement is to do PublicKey.Get[Algorithm]PublicKey, where [Algorithm] is the algorithm you want to try using it as. RSA and DSA are obviously "it's this, or it isn't". ECDsa and ECDiffieHellman both work for id-ecPublicKey keys, unless their key usage forces it to be one or the other.
  • ECDSA.ToXmlString and ECDH.ToXmlString don't work: This is known, and has always been true in .NET. We're going to mark the methods as Obsolete in the next version.
    • The replacement is to use a more standard export routine, like ExportSubjectPublicKeyInfo (X.509 SubjectPublicKeyInfo).

@ghost ghost locked as resolved and limited conversation to collaborators Nov 3, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-System.Security untriaged New issue has not been triaged by the area owner
Projects
None yet
Development

No branches or pull requests

3 participants