diff options
author | agl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-07-18 16:01:32 +0000 |
---|---|---|
committer | agl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-07-18 16:01:32 +0000 |
commit | d8654bf1406e9cd0338e9e2c0e18f5295a08efce (patch) | |
tree | ab65c080c7cbbb03908f585b4842f28c7d5668f2 /net/base/ssl_cipher_suite_names_generate.go | |
parent | 19abe9a4b01c5f3933679266a7e8f6647ea59582 (diff) | |
download | chromium_src-d8654bf1406e9cd0338e9e2c0e18f5295a08efce.zip chromium_src-d8654bf1406e9cd0338e9e2c0e18f5295a08efce.tar.gz chromium_src-d8654bf1406e9cd0338e9e2c0e18f5295a08efce.tar.bz2 |
net: add ciphersuite and compression to the SSL connection status.
18 bits of the connection status word are reserved for the negotiated
cipher suite and compression method. This plumbs those bits for NSS.
It also includes a lookup table to convert the cipher suite id into
strings for the frontend. Although NSS already has a function which
does something similar (SSL_GetCipherSuiteInfo), it's backed by a
table which is limited only to those cipher suites which are compiled
into NSS. Since we have other SSL library backends (and because we can
do a better job of representing the data anyway), we have our own.
In the future we might want to compile these tables out of NSS and
save some space.
BUG=27507
TEST=none
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@52856 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/base/ssl_cipher_suite_names_generate.go')
-rw-r--r-- | net/base/ssl_cipher_suite_names_generate.go | 189 |
1 files changed, 189 insertions, 0 deletions
diff --git a/net/base/ssl_cipher_suite_names_generate.go b/net/base/ssl_cipher_suite_names_generate.go new file mode 100644 index 0000000..f286ce3 --- /dev/null +++ b/net/base/ssl_cipher_suite_names_generate.go @@ -0,0 +1,189 @@ +// This program reads in the contents of [1] from /tmp/tls-parameters.xml and +// writes out a compact form the ciphersuite information found there in. +// It's used to generate the tables in net/base/ssl_cipher_suite_names.cc +// +// [1] http://www.iana.org/assignments/tls-parameters/tls-parameters.xml +package main + +import ( + "fmt" + "os" + "sort" + "strings" + "xml" +) + +// Structures for parsing the XML + +type TLSRegistry struct { + Registry []Registry +} + +type Registry struct { + Id string "attr" + Title string + Record []Record +} + +type Record struct { + Value string + Description string +} + +type CipherSuite struct { + value uint16 + kx string + cipher string + mac string +} + +func fromHex(c byte) int { + if c >= '0' && c <= '9' { + return int(c - '0') + } + if c >= 'a' && c <= 'f' { + return int(c - 'a' + 10) + } + if c >= 'A' && c <= 'F' { + return int(c - 'A' + 10) + } + panic("Bad char passed to fromHex") +} + +type TLSValue struct { + v int + name string +} + +type TLSMapping []TLSValue + +func (m TLSMapping) Len() int { + return len(m) +} + +func (m TLSMapping) Less(i, j int) bool { + return m[i].v < m[j].v +} + +func (m TLSMapping) Swap(i, j int) { + m[i], m[j] = m[j], m[i] +} + +func printDict(d map[string]int, name string) { + a := make([]TLSValue, len(d)) + + maxLen := 0 + i := 0 + for k, v := range d { + if len(k) > maxLen { + maxLen = len(k) + } + a[i].v = v + a[i].name = k + i++ + } + + sort.Sort(TLSMapping(a)) + + fmt.Printf("static const struct {\n char name[%d];\n} %s[%d] = {\n", maxLen+1, name, len(d)) + for _, m := range a { + fmt.Printf(" {\"%s\"}, // %d\n", m.name, m.v) + } + + fmt.Printf("};\n\n") +} + +func parseCipherSuiteString(s string) (kx, cipher, mac string) { + s = s[4:] + i := strings.Index(s, "_WITH_") + kx = s[0:i] + s = s[i+6:] + i = strings.LastIndex(s, "_") + cipher = s[0:i] + mac = s[i+1:] + return +} + +func main() { + infile, err := os.Open("/tmp/tls-parameters.xml", os.O_RDONLY, 0) + if err != nil { + fmt.Printf("Cannot open input: %s\n", err) + return + } + + var input TLSRegistry + err = xml.Unmarshal(infile, &input) + if err != nil { + fmt.Printf("Error parsing XML: %s\n", err) + return + } + + var cipherSuitesRegistry *Registry + for _, r := range input.Registry { + if r.Id == "tls-parameters-4" { + cipherSuitesRegistry = &r + break + } + } + + if cipherSuitesRegistry == nil { + fmt.Printf("Didn't find tls-parameters-4 registry\n") + } + + kxs := make(map[string]int) + next_kx := 0 + ciphers := make(map[string]int) + next_cipher := 0 + macs := make(map[string]int) + next_mac := 0 + lastValue := uint16(0) + + fmt.Printf("struct CipherSuite {\n uint16 cipher_suite, encoded;\n};\n\n") + fmt.Printf("static const struct CipherSuite kCipherSuites[] = {\n") + + for _, r := range cipherSuitesRegistry.Record { + if strings.Index(r.Description, "_WITH_") == -1 { + continue + } + + value := uint16(fromHex(r.Value[2])<<12 | fromHex(r.Value[3])<<8 | fromHex(r.Value[7])<<4 | fromHex(r.Value[8])) + kx, cipher, mac := parseCipherSuiteString(r.Description) + + if value < lastValue { + panic("Input isn't sorted") + } + lastValue = value + + var kx_n, cipher_n, mac_n int + var ok bool + + if kx_n, ok = kxs[kx]; !ok { + kxs[kx] = next_kx + kx_n = next_kx + next_kx++ + } + if cipher_n, ok = ciphers[cipher]; !ok { + ciphers[cipher] = next_cipher + cipher_n = next_cipher + next_cipher++ + } + if mac_n, ok = macs[mac]; !ok { + macs[mac] = next_mac + mac_n = next_mac + next_mac++ + } + + if kx_n > 32 || cipher_n > 15 || mac_n > 7 { + panic("Need to shift bit boundaries") + } + + encoded := (kx_n << 7) | (cipher_n << 3) | mac_n + fmt.Printf(" {0x%x, 0x%x}, // %s\n", value, encoded, r.Description) + } + + fmt.Printf("};\n\n") + + printDict(kxs, "kKeyExchangeNames") + printDict(ciphers, "kCipherNames") + printDict(macs, "kMacNames") +} |