-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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
proposal: crypto/tls: Expose maps for cipher suite IDs/names #30325
Comments
This is a utility function that allows you to parse a set of cipher suites, and get a slice containing the const values for each cipher suite. The main purpose of this is to be able to easily parse such configurations for HTTP(s) servers without much boiler plate code. Fixes: golang#30325
This is a utility function that allows you to parse a set of cipher suites, and get a slice containing the const values for each cipher suite. The main purpose of this is to be able to easily parse such configurations for HTTP(s) servers without much boiler plate code. Fixes: golang#30325
Sample docs from https://golang.org/cl/163119:
|
Change https://golang.org/cl/163119 mentions this issue: |
Rather than defining a specific configuration format (what if it would make more sense for you to have a YAML list instead of a colon-separated string?) it might be time to add a A |
I'm thinking we should just add this
and let parsers build the inverse map, as they are the rarer use case. @golang/osp-team |
@FiloSottile I have no strong opinion the format really. As long as we get something that works :D. The only reason I used colons is because it's similar to what OpenSSL uses. Can you give an example on what you're thinking about with the yaml-like format? |
|
@FiloSottile @bcmills this is the current code proposal #30326 . What do you think about the naming? I can definitely add the inverse mapping (map[uint16]string) if needed. |
I'm thinking we should not prescribe any format at all, and instead expose only A parser could then invert the map (which would be directly useful to anyone printing the name of a suite, which I've seen done many times) var cipherSuites = make(map[string]uint16, len(tls.NameForCipherSuite))
for id, name := range tls.NameForCipherSuite {
cipherSuites[name] = id
} and use it to parse whatever format it wants. (JSON, colon separated, multiple flags, YAML, INI...) |
FWIW, pretty much every time I've exported a map variable, it has turned out that I should have exported a function or two instead. Global maps are prone to data races (particularly if the program does anything interesting in an Given that we're talking about adding stable API surface to the standard library, the more I think about it the less I like the idea of a map. |
I was about to backtrack on it being a map, but it satisfies three use cases, which otherwise would be three different exported symbols, unless you have a better idea:
|
Well, it could be a couple of functions that return the two maps that @FiloSottile is talking about. That way we don't expose global instances, but ephemeral instances returned by those functions instead. |
These are utility functions that allow you to get maps that translate from Cipher Suite names towards IDs and vice versa. The main purpose of this is to be able to easily parse such configurations for HTTP(s) servers without much boiler plate code. Fixes: golang#30325
I just pushed an update to #30326 to make it a couple of functions that return maps. What do you think @FiloSottile @bcmills ? |
I updated the topic to match the current proposal. |
Moreover, the use of How is this as an alternative? // […]
type CipherSuite uint16
// […]
func CipherSuiteByName(string) (CipherSuite, bool) {
[…]
}
// […]
func (s CipherSuite) Name() string {
[…]
}
var cipherSuites [...]CipherSuite = […]
// […]
func CipherSuites() []CipherSuite {
return append([]CipherSuite(nil), cipherSuites...)
} |
@bcmills I'm very much into the idea of creating a type for cipher suites. Perhaps with further iterations, we could switch the current usage of the uint16 const cipher suites to use this type too. |
Hi everyone! I'm usually using Go to write security related checks and scanners. I often have issues with Go because some valuable information is either held private within a package, or in a format that cannot be accessed dynamically. In this case, the valuable information is the available cipher suites. They are accessible, but I cannot query them. So I have to hard-code them in my package. Of course, this means, that I have to monitor this package for the infinite future for potential changes (e.g. if another cipher is added, or one gets disabled by default). A simple use case in my situation is, to always enable as many ciphers as available (implemented). The more the better. Becasue, I don't care about confidentiality/integrity, I just want to make sure to be able to connect to as many (legacy) devices as possible in order to check them for something. So in my code I would like to read the slice of existing cipher suites and put them into the TLS config. Other people might have other criteria to chose their ciphers, e.g. any with certain attribtues,... All the issue because of a single letter ;-) If This would also be the most easy change, and every body could filter and apply the slice as needed. All information would be accessible from the outside. But I assume, this won't be the change implemented because of compatibility reasons. Second best option would be to add kind of a getter function returning that slice (or a copy if you want to maintain the isolation) Thrid best option would be a function returning something else, like a simple slice of cipher IDs or a map,... just as you were discussing above. But then we would be deciding other peoples use cases. best regards, |
This change exposes the CipherSuite structure, so folks can actually use it in their code-bases. It also exposes the needed functions to get the cipher suite both by name and by ID. The "name" of the cipher suite was added to the struct. Fixes: golang#30325
@bcmills @FiloSottile @noneymous I submitted an alternative proposal (though a little more invasive) in #30654 . What do you think? |
This change exposes the CipherSuite structure, so folks can actually use it in their code-bases. It also exposes the needed functions to get the cipher suite both by name and by ID. The "name" of the cipher suite was added to the struct. Fixes: golang#30325
Alright, spent some time thinking about this, and crypto/tls serves applications, not testing tools, but if we think applications won't need a cipher suite we should not implement it in the first place. If we do implement it, I don't think we should require hardcoding it in order to use it. I renamed I expect most applications will be using |
My totally valid application which just doesn't care about transport security takes this personally ^^ But other than that, I go conform with the current suggestion. |
Change https://golang.org/cl/175517 mentions this issue: |
Do we really need suites names in What about exposing them instead in a non-stdlib package under |
@dolmen We already have exported constants for all cipher suite names, that's not changing. The new functions just return a slice, so they don't grow problematically. |
Incidentally, is there a particular reason that these two consts don't use the full IANA name, whereas all the others do?
Why are they missing the _SHA256?
https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml |
I don't remember the timeline of Go's implementation, but the suffix got added at the last minute during standardization, so a lot of things are missing it. :-/ https://tools.ietf.org/rfcdiff?url2=draft-ietf-tls-chacha20-poly1305-04.txt |
We discussed this with @rsc for Go 1.14, and came up with this API. It has a nice to use helper for the common case of turning an ID into a name, and relegates the insecure entries to their own API.
I think this should still work for all the use cases we discussed, but please do provide your feedback. |
Nice! That will work for our use case in Caddy. (is there any particular reason to use |
I always use pointers to structs that are not comparable in nature to a native value (like say, time.Time). This one even has a slice, so it has some indirection anyway. If we are worried about accidental changes, we can make deep copies, but not sure it's worth it. |
Adopting the new proposal tracking process, this seems like a likely accept. Leaving open a week for final comments. |
Setting up a set of cipher suites for your HTTP(s) server requires a lot of boilerplate code. It would be nice to have an easy way to parse the cipher suites, say, from a configuration file.
This would make the TLS configuration friendlier (no need for more builder plate code) and easier to audit (given that some folks have opted not to configure this).
We could achieve this by having a mapping from a string value towards the cipher suite constant, which would be kept alongside the constants that are already in the source code.
Having this as part of the source code has the added benefit that, since the mapping would be besides the const values, it would be easier to maintain. As opposed to having this functionality as part of an external library.
This would help address requests like #21167
The text was updated successfully, but these errors were encountered: