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

Introduce a way to resolve certificates on the fly #137

Open
MathiasKoch opened this issue Feb 27, 2024 · 3 comments
Open

Introduce a way to resolve certificates on the fly #137

MathiasKoch opened this issue Feb 27, 2024 · 3 comments

Comments

@MathiasKoch
Copy link
Contributor

This is a follow-up to #135

Currently, the TlsConfig holds CA, Device Certificate and Private Key in memory, basically for the full lifetime of the TLS connection, even though they are only used during the handshake.
This can be very costly on the RAM usage for no reason at all.

I would like to introduce some sort of resolver, that can load the certificates on the fly in the handshake, and then drop them again when no longer needed.

It could be something along the lines of rustls's resolves traits:

I am not quite sure if these should be part of the TlsConfig or if it would make more sense to have them as part of the provider implementation somehow:

pub trait CryptoProvider {
    type CipherSuite: TlsCipherSuite;
    type Signature: AsRef<[u8]>;

    fn rng(&mut self) -> impl CryptoRngCore;

    fn verifier(
        &mut self,
    ) -> Result<&mut impl TlsVerifier<'_, Self::CipherSuite>, crate::TlsError> {
        Err::<&mut NoVerify, _>(crate::TlsError::Unimplemented)
    }

    /// Decode and validate a private signing key from `key_der`.
    fn signer(
        &mut self,
        _key_der: &[u8], <-- REMOVE THIS
    ) -> Result<(impl signature::SignerMut<Self::Signature>, SignatureScheme), crate::TlsError>
    {
        // Resolve private key here. This could be as simple as self.priv_key, which would be the same as today.
        // It could also be I/O or flash read using self.
        
        // Return a signer impl based on above private key
    }
}

Similarly, the Verifier could resolve the CA, left is only something to resolve the ClientCertificate?

Not sure if i am missing something obvious here though?

@lulf
Copy link
Member

lulf commented Feb 27, 2024

Sounds like a great idea to me!

@MathiasKoch
Copy link
Contributor Author

MathiasKoch commented Feb 28, 2024

Sounds like a great idea to me!

Do you have any preferences whether it ends up being rustls'like with a new trait in the TlsConfig, or an implied part of CryptoProvider?

Another option is to add additional functions to the provider, along the lines of resolve_ca(), etc.? That would make it less implied, than requiring the signer() fn to also resolve a private key as part of the impl, on the other hand it might make lifetimes etc. much more tricky, at no other win than what could just as well be solved by proper docs?

I think I am leaning towards the implied resolution in verifier, signer and then a new fn client_cert() or similar? Solely because I would like to avoid introducing the additional generic in the config, as i this a config should be as lean as possible?

@lulf
Copy link
Member

lulf commented Feb 28, 2024

Sounds like a great idea to me!

Do you have any preferences whether it ends up being rustls'like with a new trait in the TlsConfig, or an implied part of CryptoProvider?

I don't, I think you're in a better position to make that judgement really.

Another option is to add additional functions to the provider, along the lines of resolve_ca(), etc.? That would make it less implied, than requiring the signer() fn to also resolve a private key as part of the impl, on the other hand it might make lifetimes etc. much more tricky, at no other win than what could just as well be solved by proper docs?

I think I am leaning towards the implied resolution in verifier, signer and then a new fn client_cert() or similar? Solely because I would like to avoid introducing the additional generic in the config, as i this a config should be as lean as possible?

Yeah, I think that approach is the best path forward. If it turns out not to be, we can always change it.

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