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

Problem creating self signed cert with ECDSA algorithm and using as client identity in native-tls #82

Open
DerAndereAndi opened this issue Apr 11, 2022 · 4 comments

Comments

@DerAndereAndi
Copy link

Hi everyone,

I am having trouble creating a self signed certificate with ECDSA that will be usable (on macOS) with native-tls as a client identity.

This is the code I have so far:

fn get_identity() -> Result<native_tls::Identity, String>
    let mut dn = DistinguishedName::new();
    dn.push(rcgen::DnType::OrganizationName, "Demo");
    dn.push(rcgen::DnType::CountryName, "DE");
    dn.push(rcgen::DnType::CommonName, "Demo");
    
    let mut cert_params = CertificateParams::default();
    cert_params.distinguished_name = dn;
    cert_params.serial_number = Option::Some(1);
    cert_params.alg = &rcgen::PKCS_ECDSA_P256_SHA256;
    cert_params.is_ca = rcgen::IsCa::Ca(rcgen::BasicConstraints::Unconstrained);

    let certificate = match Certificate::from_params(cert_params) {
        Ok(certificate) => certificate,
        Err(e) => return Err(e.to_string()),
    };

    let certificate = match Certificate::from_params(cert_params) {
        Ok(certificate) => certificate,
        Err(e) => return Err(e.to_string()),
    };

    let cert = match certificate.serialize_pem() {
        Ok(cert) => cert,
        Err(err) => return Err(format!("Error in serializing the cert pem: {}", err)),
    };
    let key = certificate.serialize_private_key_pem();
    
    match native_tls::Identity::from_pkcs8(cert.as_bytes(), key.as_bytes()) {
        Ok(identity) => return Ok(identity),
        Err(err) => {
            println!("Error in creating identity: {}", err);
        },
    };
}

The error I am getting from macOS security framework is:

Error in creating identity: Unknown format in import.

I got as far as identifying the issue being with the private key.

Is there anything I am doing completely wrong?

Thanks
Andreas

@est31
Copy link
Member

est31 commented Apr 11, 2022

How have you isolated the issue to the private key?

rcgen uses ring to generate and serialize private keys. How ring serializes them is described here.

@est31
Copy link
Member

est31 commented Apr 11, 2022

There might be an incompatibility between how ring serializes a key and how Mac OS expects it. Can you paste two keys here in base64 / PEM format, one that works, and one that doesn't?

@DerAndereAndi
Copy link
Author

Thanks for getting back to me @est31!

This key/cert combo does not work (generated with the code above):

-----BEGIN CERTIFICATE-----
MIIBhzCCAS2gAwIBAgIBATAKBggqhkjOPQQDAjAzMQswCQYDVQQGEwJERTENMAsG
A1UEChMERGVtbzEVMBMGA1UEAwwMRGVtb19IRU1TXzAxMB4XDTIyMDQxMTA3Mjkw
MVoXDTMyMDQwODA3MjkwMVowMzELMAkGA1UEBhMCREUxDTALBgNVBAoTBERlbW8x
FTATBgNVBAMMDERlbW9fSEVNU18wMTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA
BFfdQRrIFEmc15iKOI4Td32nMxZJmC41+wGitMcEndMpWxvsuuVNxik+D9rmwJAB
FDFwS44pSWNhD1hsetHXcI2jMjAwMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE
FDMxP7cy+9BPEklleh4Olm0/fiXKMAoGCCqGSM49BAMCA0gAMEUCIQCQNt8yCsmC
A7mgPPTGxSmyjs7fEIij9grwYPAShQ87sAIgY6UVkjYoVIhjeLb6JidlbfgSaGCy
iGNqqCHNvQsoDck=
-----END CERTIFICATE-----

-----BEGIN PRIVATE KEY-----
MHcCAQEEIEiV2KaB52ENY5TJOda017QhPZxtnzuN+bmBQVnhH+3loAoGCCqGSM49
AwEHoUQDQgAEV91BGsgUSZzXmIo4jhN3faczFkmYLjX7AaK0xwSd0ylbG+y65U3G
KT4P2ubAkAEUMXBLjilJY2EPWGx60ddwjQ==
-----END PRIVATE KEY-----

While this one works (generated via code in golang):

-----BEGIN CERTIFICATE-----
MIIBhjCCAS2gAwIBAgIBATAKBggqhkjOPQQDAjAzMQswCQYDVQQGEwJERTENMAsG
A1UEChMERVZDQzEVMBMGA1UEAwwMRVZDQ19IRU1TXzAxMB4XDTIxMDgyMTEyNDA1
OFoXDTMxMDgxOTEyNDA1OFowMzELMAkGA1UEBhMCREUxDTALBgNVBAoTBEVWQ0Mx
FTATBgNVBAMMDEVWQ0NfSEVNU18wMTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA
BIUT9ohxaI3G7WtrldpXqAukOVi1UyDC8oyg5Nv/fqoYw3IhnrnbW7tW3D+VVKDe
bWWcQV2OkLA/ST8QBmXc96ejMjAwMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE
FC3G8mo/K72eo1H09Sw/tRC1Y+60MAoGCCqGSM49BAMCA0cAMEQCIBj+gJMQWuqk
FFwcNmJBs3hp9h6SVJa2bVPZATctNYjOAiBXyDpRb5N2wzj0iEBA7fp15ScqCY9y
My65SZKV4Ek+EQ==
-----END CERTIFICATE-----

-----BEGIN PRIVATE KEY-----
MHcCAQEEIFtMo1SGAWOqjbhFlO4Qxnv2M1WHQ3rdMS7tEPgyYrPUoAoGCCqGSM49
AwEHoUQDQgAEhRP2iHFojcbta2uV2leoC6Q5WLVTIMLyjKDk2/9+qhjDciGeudtb
u1bcP5VUoN5tZZxBXY6QsD9JPxAGZdz3pw==
-----END PRIVATE KEY-----

Had to replace the header string -----BEGIN EC PRIVATE KEY----- into -----BEGIN PRIVATE KEY----- in the second one for native-tls. (of course the footer as well)

@est31
Copy link
Member

est31 commented Apr 11, 2022

Huh, that's interesting. I've put the cert as well as the key generated by rcgen/ring into lapo.it, and couldn't find a difference in the ASN.1 to the cert and the key generated by golang (outside of ASN.1 payloads of course).

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

2 participants