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

Apple M1: Identity::from_pkcs8 does not work with "PKCS_ECDSA_P256_SHA256" #225

Open
gyuho opened this issue Apr 28, 2022 · 8 comments
Open

Comments

@gyuho
Copy link

gyuho commented Apr 28, 2022

Hi,

The following code does not work for no apparent reason, and any hint for using ECDSA keys would be greatly appreciated!

use rcgen::{PKCS_ECDSA_P256_SHA256, CertificateParams};

let mut cert_params = CertificateParams::default();
cert_params.alg = &PKCS_ECDSA_P256_SHA256;

let cert = Certificate::from_params(cert_params).unwrap();
let cert_contents = cert.serialize_pem().unwrap();
let key_contents = cert.serialize_private_key_pem();

native_tls::Identity::from_pkcs8(cert_contents.as_bytes(), key_contents.as_bytes()).unwrap()
Custom { kind: Other, error: "failed to create native-tls Identity Unknown format in import." }'

NOTE: CertificateParams will generate the ECDSA keys as follows, and it should be the correct pkcs8 encoding:

impl KeyPair {
	/// Generate a new random key pair for the specified signature algorithm
	pub fn generate(alg :&'static SignatureAlgorithm) -> Result<Self, RcgenError> {
		let system_random = SystemRandom::new();
		match alg.sign_alg {
			SignAlgo::EcDsa(sign_alg) => {
				let key_pair_doc = EcdsaKeyPair::generate_pkcs8(sign_alg, &system_random)?;
				let key_pair_serialized = key_pair_doc.as_ref().to_vec();

				let key_pair = EcdsaKeyPair::from_pkcs8(&sign_alg, &&key_pair_doc.as_ref()).unwrap();
				Ok(KeyPair {
					kind : KeyPairKind::Ec(key_pair),
					alg,
					serialized_der : key_pair_serialized,
				})
			},
			SignAlgo::EdDsa(_sign_alg) => {
				let key_pair_doc = Ed25519KeyPair::generate_pkcs8(&system_random)?;
				let key_pair_serialized = key_pair_doc.as_ref().to_vec();

				let key_pair = Ed25519KeyPair::from_pkcs8(&&key_pair_doc.as_ref()).unwrap();
				Ok(KeyPair {
					kind : KeyPairKind::Ed(key_pair),
					alg,
					serialized_der : key_pair_serialized,
				})
			},

Similar code works fine for RSA keys...

@sfackler
Copy link
Owner

What does the PEM for one of these keys look like?

@gyuho
Copy link
Author

gyuho commented Apr 28, 2022

@sfackler Here's the openssl output

openssl x509 -in /tmp/test.insecure.cert -text -noout
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 5564983925622557331 (0x4d3acb65537dca93)
    Signature Algorithm: ecdsa-with-SHA256
        Issuer: C=US, ST=NY, O=Ava Labs, CN=avalanche-ops
        Validity
            Not Before: Jan  1 00:00:00 2022 GMT
            Not After : Jan  1 00:00:00 5000 GMT
        Subject: C=US, ST=NY, O=Ava Labs, CN=avalanche-ops
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
                pub: 
                    04:49:d2:4e:78:cf:c7:b5:04:8f:92:7e:ee:2a:4b:
                    f3:10:2a:28:bb:6b:d7:78:d8:60:6a:99:b2:32:4f:
                    02:31:69:82:24:4e:31:a2:0a:22:74:a8:4c:22:b3:
                    4e:b5:51:da:49:d1:74:6b:c3:8d:c2:e5:53:e9:9b:
                    fe:cb:f6:46:09
                ASN1 OID: prime256v1
                NIST CURVE: P-256
    Signature Algorithm: ecdsa-with-SHA256
         30:44:02:20:05:11:b8:7f:3d:c3:9b:be:0c:0e:e4:b5:7b:3d:
         12:51:96:5b:44:3e:cd:15:42:1f:89:7b:84:4c:b7:e6:37:64:
         02:20:34:b4:97:5f:eb:cb:fe:e7:e9:0b:9a:65:36:c3:8f:0f:
         2b:f1:1d:27:0d:bc:de:30:b4:c8:7f:5c:3f:60:ac:02

And here's the raw PEM cert:

cat /tmp/test.insecure.cert
-----BEGIN CERTIFICATE-----
MIIBfzCCASagAwIBAgIITTrLZVN9ypMwCgYIKoZIzj0EAwIwRTELMAkGA1UEBgwC
VVMxCzAJBgNVBAgMAk5ZMREwDwYDVQQKDAhBdmEgTGFiczEWMBQGA1UEAwwNYXZh
bGFuY2hlLW9wczAgFw0yMjAxMDEwMDAwMDBaGA81MDAwMDEwMTAwMDAwMFowRTEL
MAkGA1UEBgwCVVMxCzAJBgNVBAgMAk5ZMREwDwYDVQQKDAhBdmEgTGFiczEWMBQG
A1UEAwwNYXZhbGFuY2hlLW9wczBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABEnS
TnjPx7UEj5J+7ipL8xAqKLtr13jYYGqZsjJPAjFpgiROMaIKInSoTCKzTrVR2knR
dGvDjcLlU+mb/sv2RgkwCgYIKoZIzj0EAwIDRwAwRAIgBRG4fz3Dm74MDuS1ez0S
UZZbRD7NFUIfiXuETLfmN2QCIDS0l1/ry/7n6QuaZTbDjw8r8R0nDbzeMLTIf1w/
YKwC
-----END CERTIFICATE-----

@sfackler
Copy link
Owner

That's the certificate rather than the private key.

@sfackler
Copy link
Owner

Also, which OS are you running this on?

@gyuho
Copy link
Author

gyuho commented Apr 28, 2022

@sfackler

Here's the key:

cat /tmp/test.insecure.key 
-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgGYZMDckD0VzoYsxG
EYR/s2sob7jlvR5oY9ZT5U5iqfehRANCAARJ0k54z8e1BI+Sfu4qS/MQKii7a9d4
2GBqmbIyTwIxaYIkTjGiCiJ0qEwis061UdpJ0XRrw43C5VPpm/7L9kYJ
-----END PRIVATE KEY-----

And I am running on OS with M1

@gyuho
Copy link
Author

gyuho commented Apr 28, 2022

Hmm, works fine on linux machine...

❯ uname -r
5.10.102-99.473.amzn2.x86_64

@gyuho gyuho changed the title native_tls::Identity::from_pkcs8 does not work for "PKCS_ECDSA_P256_SHA256" Apple M1: Identity::from_pkcs8 does not work with "PKCS_ECDSA_P256_SHA256" Apr 28, 2022
@sfackler
Copy link
Owner

That makes me think that macOS's Security.framework library may not support ECDSA keys then unfortunately.

@andyleiserson
Copy link

I looked at this a bit. I don't think the issue is complete lack of ECDSA key support. I think it is an issue with importing ECDSA keys from unencrypted PKCS8 format. Using the command line security import importer, I was able to import a P256 key from encrypted PKCS8, and I was also able to import the same key in unencrypted "OpenSSL" format.

I was hoping it might be possible to import the unencrypted pkcs8 by explicitly specifying the format, but I was unsuccessful. The keychain importer seems to interpret "pkcs8" to mean only encrypted pkcs8. If I manually specify pkcs8 format, the import fails trying to parse EncryptedPrivateKeyInfo. If I don't specify pkcs8 format, impExpGuessKeyParams tries to detect the format, and can't find something that works, because the only format it tries for ECDSA keys is OpenSSL.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants