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

Support cipher suite selection #4

Open
sfackler opened this issue Aug 24, 2016 · 2 comments · May be fixed by #167
Open

Support cipher suite selection #4

sfackler opened this issue Aug 24, 2016 · 2 comments · May be fixed by #167

Comments

@sfackler
Copy link
Owner

sfackler commented Aug 24, 2016

OpenSSL's the most flexible here, and SChannel is the least. The cross-platform solution will probably look something like an SChannel style enum of algorithms that will be unioned:

pub enum Algorithm {
    Sha256,
    Aes,
    Dhe,
    Rsa,
    ...
}

If you then call

client_builder.supported_algorithms(&[Algorithm::Rsa, Algorithm::Aes, Algorithm::Sha256, Algorithm::Dhe])

would mean all ciphers that use RSA or DHE for key exchange, AES as a bulk cipher, and SHA256 as a hash algorithm would be enabled. That'd translate in SChannel to

cred_builder.supported_algorithms(&[Algorithm::Rsa, Algorithm::Aes, Algorithm::Sha256. Algorithm::Dhe])

and in OpenSSL to (note that we have to generate the cartesian product of key exchange, bulk cipher and hash algorithms)

ctx.set_cipher_suite("RSA+AES+SHA256:DHE+AES+SHA256:@STRENGTH")

and in Secure Transport to a somewhat complicated dance where we load supported ciphers and filter them through the provided algorithms:

let supported = ctx.supported_ciphers();
let enabled = supported.into_iter().filter(|c| suite_supported(c, algorithms)).collect();
ctx.set_enabled_ciphers(&enabled);

One interesting question is what to do if no algorithm in a category is specified (e.g. just &[Algorithm::Aes, Algorithm::Dhe] is passed). Should that mean that no suites match and no connections will work, or that all algorithms of that type can be used?

An alternative design would be to have separate enums for each algorithm type:

client_builder.supported_algorithms(&[KeyExchange::Rsa, KeyExchange::Dhe], &[BulkCipher::Aes], &[Hash::Sha256]);

It would be a bit more clear, but more verbose as well.

@sfackler
Copy link
Owner Author

We'll also probably want to disable unauthenticated and anonymous suites entirely.

@cyang1
Copy link

cyang1 commented Mar 23, 2020

I'm interested in this. I took a stab at the security-framework and schannel-rs implementations, and the public API in cyang1@a82bfbe. I think the OpenSSL implementation would be simple as you mentioned above.

I don't think my change is necessarily production ready yet, as it's not necessarily maintainable in its current state.

In my change, the questions I still have are:

  • What to do if no algorithm in a category is specified, as you mentioned in your comment. In my proof of concept, I chose to interpret this roughly as "allow all", although I think there is a valid argument for having to specify at least 1 algorithm for all categories.
  • Making the macOS implementation maintainable. I currently have explicit lists of all cipher suites corresponding to a given algorithm, which required a good deal of manual labor. Maybe you had a clever idea in mind for your suite_supported() function in your proposal above? (Maybe there's some underlying structure to the cipher suite constants on macOS, haven't dug too far into that.)

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

Successfully merging a pull request may close this issue.

2 participants