diff options
Diffstat (limited to 'libgo/go/crypto/tls')
-rw-r--r-- | libgo/go/crypto/tls/cipher_suites.go | 34 | ||||
-rw-r--r-- | libgo/go/crypto/tls/common.go | 12 | ||||
-rw-r--r-- | libgo/go/crypto/tls/handshake_client.go | 10 | ||||
-rw-r--r-- | libgo/go/crypto/tls/handshake_server.go | 23 | ||||
-rw-r--r-- | libgo/go/crypto/tls/handshake_server_test.go | 3 | ||||
-rw-r--r-- | libgo/go/crypto/tls/key_agreement.go | 4 | ||||
-rw-r--r-- | libgo/go/crypto/tls/prf.go | 26 | ||||
-rw-r--r-- | libgo/go/crypto/tls/root_unix.go | 1 | ||||
-rw-r--r-- | libgo/go/crypto/tls/root_windows.go | 27 | ||||
-rw-r--r-- | libgo/go/crypto/tls/tls.go | 19 |
10 files changed, 88 insertions, 71 deletions
diff --git a/libgo/go/crypto/tls/cipher_suites.go b/libgo/go/crypto/tls/cipher_suites.go index 1134f362583..c0e8656f79b 100644 --- a/libgo/go/crypto/tls/cipher_suites.go +++ b/libgo/go/crypto/tls/cipher_suites.go @@ -37,6 +37,7 @@ type keyAgreement interface { // A cipherSuite is a specific combination of key agreement, cipher and MAC // function. All cipher suites currently assume RSA key agreement. type cipherSuite struct { + id uint16 // the lengths, in bytes, of the key material needed for each component. keyLen int macLen int @@ -50,13 +51,13 @@ type cipherSuite struct { mac func(version uint16, macKey []byte) macFunction } -var cipherSuites = map[uint16]*cipherSuite{ - TLS_RSA_WITH_RC4_128_SHA: &cipherSuite{16, 20, 0, rsaKA, false, cipherRC4, macSHA1}, - TLS_RSA_WITH_3DES_EDE_CBC_SHA: &cipherSuite{24, 20, 8, rsaKA, false, cipher3DES, macSHA1}, - TLS_RSA_WITH_AES_128_CBC_SHA: &cipherSuite{16, 20, 16, rsaKA, false, cipherAES, macSHA1}, - TLS_ECDHE_RSA_WITH_RC4_128_SHA: &cipherSuite{16, 20, 0, ecdheRSAKA, true, cipherRC4, macSHA1}, - TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: &cipherSuite{24, 20, 8, ecdheRSAKA, true, cipher3DES, macSHA1}, - TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: &cipherSuite{16, 20, 16, ecdheRSAKA, true, cipherAES, macSHA1}, +var cipherSuites = []*cipherSuite{ + &cipherSuite{TLS_RSA_WITH_RC4_128_SHA, 16, 20, 0, rsaKA, false, cipherRC4, macSHA1}, + &cipherSuite{TLS_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, rsaKA, false, cipher3DES, macSHA1}, + &cipherSuite{TLS_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, rsaKA, false, cipherAES, macSHA1}, + &cipherSuite{TLS_ECDHE_RSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheRSAKA, true, cipherRC4, macSHA1}, + &cipherSuite{TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, ecdheRSAKA, true, cipher3DES, macSHA1}, + &cipherSuite{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheRSAKA, true, cipherAES, macSHA1}, } func cipherRC4(key, iv []byte, isRead bool) interface{} { @@ -126,13 +127,13 @@ func (s ssl30MAC) MAC(seq, record []byte) []byte { s.h.Write(record[:1]) s.h.Write(record[3:5]) s.h.Write(record[recordHeaderLen:]) - digest := s.h.Sum() + digest := s.h.Sum(nil) s.h.Reset() s.h.Write(s.key) s.h.Write(ssl30Pad2[:padLength]) s.h.Write(digest) - return s.h.Sum() + return s.h.Sum(nil) } // tls10MAC implements the TLS 1.0 MAC function. RFC 2246, section 6.2.3. @@ -148,7 +149,7 @@ func (s tls10MAC) MAC(seq, record []byte) []byte { s.h.Reset() s.h.Write(seq) s.h.Write(record) - return s.h.Sum() + return s.h.Sum(nil) } func rsaKA() keyAgreement { @@ -159,15 +160,20 @@ func ecdheRSAKA() keyAgreement { return new(ecdheRSAKeyAgreement) } -// mutualCipherSuite returns a cipherSuite and its id given a list of supported +// mutualCipherSuite returns a cipherSuite given a list of supported // ciphersuites and the id requested by the peer. -func mutualCipherSuite(have []uint16, want uint16) (suite *cipherSuite, id uint16) { +func mutualCipherSuite(have []uint16, want uint16) *cipherSuite { for _, id := range have { if id == want { - return cipherSuites[id], id + for _, suite := range cipherSuites { + if suite.id == want { + return suite + } + } + return nil } } - return + return nil } // A list of the possible cipher suite ids. Taken from diff --git a/libgo/go/crypto/tls/common.go b/libgo/go/crypto/tls/common.go index ea520859b82..f57d932a98f 100644 --- a/libgo/go/crypto/tls/common.go +++ b/libgo/go/crypto/tls/common.go @@ -121,7 +121,7 @@ type Config struct { // Time returns the current time as the number of seconds since the epoch. // If Time is nil, TLS uses the system time.Seconds. - Time func() int64 + Time func() time.Time // Certificates contains one or more certificate chains // to present to the other side of the connection. @@ -175,10 +175,10 @@ func (c *Config) rand() io.Reader { return r } -func (c *Config) time() int64 { +func (c *Config) time() time.Time { t := c.Time if t == nil { - t = time.Seconds + t = time.Now } return t() } @@ -315,9 +315,7 @@ var ( func initDefaultCipherSuites() { varDefaultCipherSuites = make([]uint16, len(cipherSuites)) - i := 0 - for id := range cipherSuites { - varDefaultCipherSuites[i] = id - i++ + for i, suite := range cipherSuites { + varDefaultCipherSuites[i] = suite.id } } diff --git a/libgo/go/crypto/tls/handshake_client.go b/libgo/go/crypto/tls/handshake_client.go index aed991ccd1b..b4337f2aac6 100644 --- a/libgo/go/crypto/tls/handshake_client.go +++ b/libgo/go/crypto/tls/handshake_client.go @@ -32,7 +32,7 @@ func (c *Conn) clientHandshake() error { nextProtoNeg: len(c.config.NextProtos) > 0, } - t := uint32(c.config.time()) + t := uint32(c.config.time().Unix()) hello.random[0] = byte(t >> 24) hello.random[1] = byte(t >> 16) hello.random[2] = byte(t >> 8) @@ -72,7 +72,7 @@ func (c *Conn) clientHandshake() error { return errors.New("server advertised unrequested NPN") } - suite, suiteId := mutualCipherSuite(c.config.cipherSuites(), serverHello.cipherSuite) + suite := mutualCipherSuite(c.config.cipherSuites(), serverHello.cipherSuite) if suite == nil { return c.sendAlert(alertHandshakeFailure) } @@ -232,8 +232,8 @@ func (c *Conn) clientHandshake() error { if cert != nil { certVerify := new(certificateVerifyMsg) var digest [36]byte - copy(digest[0:16], finishedHash.serverMD5.Sum()) - copy(digest[16:36], finishedHash.serverSHA1.Sum()) + copy(digest[0:16], finishedHash.serverMD5.Sum(nil)) + copy(digest[16:36], finishedHash.serverSHA1.Sum(nil)) signed, err := rsa.SignPKCS1v15(c.config.rand(), c.config.Certificates[0].PrivateKey, crypto.MD5SHA1, digest[0:]) if err != nil { return c.sendAlert(alertInternalError) @@ -292,7 +292,7 @@ func (c *Conn) clientHandshake() error { } c.handshakeComplete = true - c.cipherSuite = suiteId + c.cipherSuite = suite.id return nil } diff --git a/libgo/go/crypto/tls/handshake_server.go b/libgo/go/crypto/tls/handshake_server.go index d5af084eda5..bbb23c0c9f6 100644 --- a/libgo/go/crypto/tls/handshake_server.go +++ b/libgo/go/crypto/tls/handshake_server.go @@ -56,18 +56,25 @@ Curves: ellipticOk := supportedCurve && supportedPointFormat var suite *cipherSuite - var suiteId uint16 FindCipherSuite: for _, id := range clientHello.cipherSuites { for _, supported := range config.cipherSuites() { if id == supported { - suite = cipherSuites[id] + suite = nil + for _, s := range cipherSuites { + if s.id == id { + suite = s + break + } + } + if suite == nil { + continue + } // Don't select a ciphersuite which we can't // support for this client. if suite.elliptic && !ellipticOk { continue } - suiteId = id break FindCipherSuite } } @@ -87,8 +94,8 @@ FindCipherSuite: } hello.vers = vers - hello.cipherSuite = suiteId - t := uint32(config.time()) + hello.cipherSuite = suite.id + t := uint32(config.time().Unix()) hello.random = make([]byte, 32) hello.random[0] = byte(t >> 24) hello.random[1] = byte(t >> 16) @@ -228,8 +235,8 @@ FindCipherSuite: } digest := make([]byte, 36) - copy(digest[0:16], finishedHash.serverMD5.Sum()) - copy(digest[16:36], finishedHash.serverSHA1.Sum()) + copy(digest[0:16], finishedHash.serverMD5.Sum(nil)) + copy(digest[16:36], finishedHash.serverSHA1.Sum(nil)) err = rsa.VerifyPKCS1v15(pub, crypto.MD5SHA1, digest, certVerify.signature) if err != nil { c.sendAlert(alertBadCertificate) @@ -296,7 +303,7 @@ FindCipherSuite: c.writeRecord(recordTypeHandshake, finished.marshal()) c.handshakeComplete = true - c.cipherSuite = suiteId + c.cipherSuite = suite.id return nil } diff --git a/libgo/go/crypto/tls/handshake_server_test.go b/libgo/go/crypto/tls/handshake_server_test.go index bc3797947f5..e00c32c5508 100644 --- a/libgo/go/crypto/tls/handshake_server_test.go +++ b/libgo/go/crypto/tls/handshake_server_test.go @@ -15,6 +15,7 @@ import ( "strconv" "strings" "testing" + "time" ) type zeroSource struct{} @@ -31,7 +32,7 @@ var testConfig *Config func init() { testConfig = new(Config) - testConfig.Time = func() int64 { return 0 } + testConfig.Time = func() time.Time { return time.Unix(0, 0) } testConfig.Rand = zeroSource{} testConfig.Certificates = make([]Certificate, 1) testConfig.Certificates[0].Certificate = [][]byte{testCertificate} diff --git a/libgo/go/crypto/tls/key_agreement.go b/libgo/go/crypto/tls/key_agreement.go index 08fb852d66a..b531717d840 100644 --- a/libgo/go/crypto/tls/key_agreement.go +++ b/libgo/go/crypto/tls/key_agreement.go @@ -90,13 +90,13 @@ func md5SHA1Hash(slices ...[]byte) []byte { for _, slice := range slices { hmd5.Write(slice) } - copy(md5sha1, hmd5.Sum()) + copy(md5sha1, hmd5.Sum(nil)) hsha1 := sha1.New() for _, slice := range slices { hsha1.Write(slice) } - copy(md5sha1[md5.Size:], hsha1.Sum()) + copy(md5sha1[md5.Size:], hsha1.Sum(nil)) return md5sha1 } diff --git a/libgo/go/crypto/tls/prf.go b/libgo/go/crypto/tls/prf.go index d758f21aa8e..637ef03e2d7 100644 --- a/libgo/go/crypto/tls/prf.go +++ b/libgo/go/crypto/tls/prf.go @@ -22,14 +22,14 @@ func splitPreMasterSecret(secret []byte) (s1, s2 []byte) { func pHash(result, secret, seed []byte, hash func() hash.Hash) { h := hmac.New(hash, secret) h.Write(seed) - a := h.Sum() + a := h.Sum(nil) j := 0 for j < len(result) { h.Reset() h.Write(a) h.Write(seed) - b := h.Sum() + b := h.Sum(nil) todo := len(b) if j+todo > len(result) { todo = len(result) - j @@ -39,7 +39,7 @@ func pHash(result, secret, seed []byte, hash func() hash.Hash) { h.Reset() h.Write(a) - a = h.Sum() + a = h.Sum(nil) } } @@ -84,13 +84,13 @@ func pRF30(result, secret, label, seed []byte) { hashSHA1.Write(b[:i+1]) hashSHA1.Write(secret) hashSHA1.Write(seed) - digest := hashSHA1.Sum() + digest := hashSHA1.Sum(nil) hashMD5.Reset() hashMD5.Write(secret) hashMD5.Write(digest) - done += copy(result[done:], hashMD5.Sum()) + done += copy(result[done:], hashMD5.Sum(nil)) i++ } } @@ -182,24 +182,24 @@ func finishedSum30(md5, sha1 hash.Hash, masterSecret []byte, magic [4]byte) []by md5.Write(magic[:]) md5.Write(masterSecret) md5.Write(ssl30Pad1[:]) - md5Digest := md5.Sum() + md5Digest := md5.Sum(nil) md5.Reset() md5.Write(masterSecret) md5.Write(ssl30Pad2[:]) md5.Write(md5Digest) - md5Digest = md5.Sum() + md5Digest = md5.Sum(nil) sha1.Write(magic[:]) sha1.Write(masterSecret) sha1.Write(ssl30Pad1[:40]) - sha1Digest := sha1.Sum() + sha1Digest := sha1.Sum(nil) sha1.Reset() sha1.Write(masterSecret) sha1.Write(ssl30Pad2[:40]) sha1.Write(sha1Digest) - sha1Digest = sha1.Sum() + sha1Digest = sha1.Sum(nil) ret := make([]byte, len(md5Digest)+len(sha1Digest)) copy(ret, md5Digest) @@ -217,8 +217,8 @@ func (h finishedHash) clientSum(masterSecret []byte) []byte { return finishedSum30(h.clientMD5, h.clientSHA1, masterSecret, ssl3ClientFinishedMagic) } - md5 := h.clientMD5.Sum() - sha1 := h.clientSHA1.Sum() + md5 := h.clientMD5.Sum(nil) + sha1 := h.clientSHA1.Sum(nil) return finishedSum10(md5, sha1, clientFinishedLabel, masterSecret) } @@ -229,7 +229,7 @@ func (h finishedHash) serverSum(masterSecret []byte) []byte { return finishedSum30(h.serverMD5, h.serverSHA1, masterSecret, ssl3ServerFinishedMagic) } - md5 := h.serverMD5.Sum() - sha1 := h.serverSHA1.Sum() + md5 := h.serverMD5.Sum(nil) + sha1 := h.serverSHA1.Sum(nil) return finishedSum10(md5, sha1, serverFinishedLabel, masterSecret) } diff --git a/libgo/go/crypto/tls/root_unix.go b/libgo/go/crypto/tls/root_unix.go index 095beec104a..1b9aeb03b5b 100644 --- a/libgo/go/crypto/tls/root_unix.go +++ b/libgo/go/crypto/tls/root_unix.go @@ -14,6 +14,7 @@ var certFiles = []string{ "/etc/ssl/certs/ca-certificates.crt", // Linux etc "/etc/pki/tls/certs/ca-bundle.crt", // Fedora/RHEL "/etc/ssl/ca-bundle.pem", // OpenSUSE + "/etc/ssl/cert.pem", // OpenBSD } func initDefaultRoots() { diff --git a/libgo/go/crypto/tls/root_windows.go b/libgo/go/crypto/tls/root_windows.go index 13073dcee78..319309ae6e7 100644 --- a/libgo/go/crypto/tls/root_windows.go +++ b/libgo/go/crypto/tls/root_windows.go @@ -6,7 +6,6 @@ package tls import ( "crypto/x509" - "reflect" "syscall" "unsafe" ) @@ -16,29 +15,23 @@ func loadStore(roots *x509.CertPool, name string) { if err != nil { return } + defer syscall.CertCloseStore(store, 0) var cert *syscall.CertContext for { - cert = syscall.CertEnumCertificatesInStore(store, cert) - if cert == nil { - break + cert, err = syscall.CertEnumCertificatesInStore(store, cert) + if err != nil { + return } - var asn1Slice []byte - hdrp := (*reflect.SliceHeader)(unsafe.Pointer(&asn1Slice)) - hdrp.Data = cert.EncodedCert - hdrp.Len = int(cert.Length) - hdrp.Cap = int(cert.Length) - - buf := make([]byte, len(asn1Slice)) - copy(buf, asn1Slice) - - if cert, err := x509.ParseCertificate(buf); err == nil { - roots.AddCert(cert) + buf := (*[1 << 20]byte)(unsafe.Pointer(cert.EncodedCert))[:] + // ParseCertificate requires its own copy of certificate data to keep. + buf2 := make([]byte, cert.Length) + copy(buf2, buf) + if c, err := x509.ParseCertificate(buf2); err == nil { + roots.AddCert(c) } } - - syscall.CertCloseStore(store, 0) } func initDefaultRoots() { diff --git a/libgo/go/crypto/tls/tls.go b/libgo/go/crypto/tls/tls.go index 3ca62407ff0..79ab5023129 100644 --- a/libgo/go/crypto/tls/tls.go +++ b/libgo/go/crypto/tls/tls.go @@ -157,10 +157,21 @@ func X509KeyPair(certPEMBlock, keyPEMBlock []byte) (cert Certificate, err error) return } - key, err := x509.ParsePKCS1PrivateKey(keyDERBlock.Bytes) - if err != nil { - err = errors.New("crypto/tls: failed to parse key: " + err.Error()) - return + // OpenSSL 0.9.8 generates PKCS#1 private keys by default, while + // OpenSSL 1.0.0 generates PKCS#8 keys. We try both. + var key *rsa.PrivateKey + if key, err = x509.ParsePKCS1PrivateKey(keyDERBlock.Bytes); err != nil { + var privKey interface{} + if privKey, err = x509.ParsePKCS8PrivateKey(keyDERBlock.Bytes); err != nil { + err = errors.New("crypto/tls: failed to parse key: " + err.Error()) + return + } + + var ok bool + if key, ok = privKey.(*rsa.PrivateKey); !ok { + err = errors.New("crypto/tls: found non-RSA private key in PKCS#8 wrapping") + return + } } cert.PrivateKey = key |