Created
February 15, 2013 12:38
-
-
Save suapapa/4960160 to your computer and use it in GitHub Desktop.
fixed it to work with Go 1.x
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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 ( | |
"encoding/xml" | |
"fmt" | |
"io/ioutil" | |
"sort" | |
"strings" | |
) | |
// Structures for parsing the XML | |
type TLSRegistry struct { | |
Registry []Registry `xml:"registry"` | |
} | |
type Registry struct { | |
Id string `xml:"id,attr"` | |
Title string `xml:"titile"` | |
Record []Record `xml:"record"` | |
} | |
type Record struct { | |
Value string `xml:"value"` | |
Description string `xml:"description"` | |
} | |
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 := ioutil.ReadFile("/tmp/tls-parameters.xml") | |
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") | |
return | |
} | |
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 > 32 || mac_n > 7 { | |
fmt.Println(kx_n, cipher_n, mac_n) | |
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") | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment