Skip to content

Rumqttc: Support for SEC1 encoded ECC keys. #751

@ijager

Description

@ijager

Expected Behavior

I would like to use an "ECC" key with an ECDSA certificate. I have generated the key with the following openssl command:

openssl ecparam -name prime256v1 -genkey -noout -out client.key

Current Behavior

rumqtt cannot parse this key and this results in a Tls(NoValidCertInChain) error.

Failure Information (for bugs)

Things go wrong in rumqttc/src/tls.rs

let read_keys = match &client.1 {
    Key::RSA(k) => rustls_pemfile::rsa_private_keys(&mut BufReader::new(
        Cursor::new(k.clone()),
    )),
    Key::ECC(k) => rustls_pemfile::pkcs8_private_keys(&mut BufReader::new(
        Cursor::new(k.clone()),
    )),
};

The ECC() variant uses pkcs8_private_keys() to parse the key. However my key does not use PKCS#8 encoding, instead it uses SEC1 encoding, which was specifically designed for Elliptic Curve Cryptography. (PKCS#8 can also encode ECC keys, but it involves converting the keys).

Rustls does support SEC1 encoding via ec_private_keys(). Rumqtt could add support by adding a Key variant.

Perhaps something like this:

 let read_keys = match &client.1 {
    Key::RSA(k) => rustls_pemfile::rsa_private_keys(&mut BufReader::new(
        Cursor::new(k.clone()),
    )),
    Key::PKCS(k) => rustls_pemfile::pkcs8_private_keys(&mut BufReader::new(
        Cursor::new(k.clone()),
    )),
    Key::EC(k) => rustls_pemfile:: ec_private_keys(&mut BufReader::new(
        Cursor::new(k.clone()),
    )),
};

I changed ECC to PKCS And added EC. This would be a breaking change, so not sure if that is desired. But we could also keep the Key::ECC(k) => rustls_pemfile::pkcs8_private_keys( variant for backwards compatibility and make it deprecated.

It would be in line with the three variants that Rustls has for keys:

/// A DER-encoded plaintext RSA private key; as specified in PKCS#1/RFC3447
RSAKey(Vec<u8>),

/// A DER-encoded plaintext private key; as specified in PKCS#8/RFC5958
PKCS8Key(Vec<u8>),

/// A Sec1-encoded plaintext private key; as specified in RFC5915
ECKey(Vec<u8>),

I'll be happy to make a PR, but I'd like to check with this crate's preferences first via this issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions