func performHandshakeAndValidation(conn *tls.Conn, uri *url.URL) error { if err := conn.Handshake(); err != nil { return err } cs := conn.ConnectionState() if !cs.NegotiatedProtocolIsMutual || cs.NegotiatedProtocol != protocol.ProtocolName { return fmt.Errorf("protocol negotiation error") } q := uri.Query() relayIDs := q.Get("id") if relayIDs != "" { relayID, err := syncthingprotocol.DeviceIDFromString(relayIDs) if err != nil { return fmt.Errorf("relay address contains invalid verification id: %s", err) } certs := cs.PeerCertificates if cl := len(certs); cl != 1 { return fmt.Errorf("unexpected certificate count: %d", cl) } remoteID := syncthingprotocol.NewDeviceID(certs[0].Raw) if remoteID != relayID { return fmt.Errorf("relay id does not match. Expected %v got %v", relayID, remoteID) } } return nil }
// checkErr logs if an error occurs and closes the tlsConn. func checkErr(err error, tlsConn *tls.Conn) { if err != nil { tlsConn.Close() log.Fatalf("GBNetworkTools: %s\n", err.Error()) } }
func (d *relayDialer) Dial(id protocol.DeviceID, uri *url.URL) (IntermediateConnection, error) { inv, err := client.GetInvitationFromRelay(uri, id, d.tlsCfg.Certificates, 10*time.Second) if err != nil { return IntermediateConnection{}, err } conn, err := client.JoinSession(inv) if err != nil { return IntermediateConnection{}, err } err = dialer.SetTCPOptions(conn) if err != nil { conn.Close() return IntermediateConnection{}, err } var tc *tls.Conn if inv.ServerSocket { tc = tls.Server(conn, d.tlsCfg) } else { tc = tls.Client(conn, d.tlsCfg) } err = tc.Handshake() if err != nil { tc.Close() return IntermediateConnection{}, err } return IntermediateConnection{tc, "Relay (Client)", relayPriority}, nil }
func (c *connection) startTls() (err error) { if c.authOptions == nil { return nil } if c.authOptions.TlsConfig == nil { return ErrAuthMissingConfig } c.state = connTlsStarting startTlsCmd := &StartTlsCommand{} if err = c.execute(startTlsCmd); err != nil { return } var tlsConn *tls.Conn if tlsConn = tls.Client(c.conn, c.authOptions.TlsConfig); tlsConn == nil { err = ErrAuthTLSUpgradeFailed return } if err = tlsConn.Handshake(); err != nil { return } c.conn = tlsConn authCmd := &AuthCommand{ User: c.authOptions.User, Password: c.authOptions.Password, } err = c.execute(authCmd) return }
func NewConnectingPeer(logger *util.Logger, server *TLSServer, connection *tls.Conn) *Peer { inst := NewPeer(logger, server, connection.RemoteAddr().String()) inst.Connection = connection inst.State = PeerStateHandshake inst.Incoming = true return inst }
// getChain returns chain of certificates retrieved from TLS session // established at given addr (host:port) for hostname provided. If addr is // empty, then hostname:443 is used. func getChain(hostname, addr string) ([]*x509.Certificate, error) { if hostname == "" { return nil, errors.New("empty hostname") } var ( conn *tls.Conn err error ) type tempErr interface { Temporary() bool } conf := &tls.Config{ServerName: hostname} if addr == "" { addr = hostname + ":443" } dialer := &net.Dialer{ Timeout: 30 * time.Second, } for i := 0; i < 3; i++ { if i > 0 { time.Sleep(time.Duration(i) * time.Second) } conn, err = tls.DialWithDialer(dialer, "tcp", addr, conf) if e, ok := err.(tempErr); ok && e.Temporary() { continue } if err != nil { return nil, err } defer conn.Close() return conn.ConnectionState().PeerCertificates, nil } return nil, err }
// SessionResumeScan tests that host is able to resume sessions across all addresses. func sessionResumeScan(addr, hostname string) (grade Grade, output Output, err error) { config := defaultTLSConfig(hostname) config.ClientSessionCache = tls.NewLRUClientSessionCache(1) conn, err := tls.DialWithDialer(Dialer, Network, addr, config) if err != nil { return } if err = conn.Close(); err != nil { return } return multiscan(addr, func(addrport string) (g Grade, o Output, e error) { var conn *tls.Conn if conn, e = tls.DialWithDialer(Dialer, Network, addrport, config); e != nil { return } conn.Close() if o = conn.ConnectionState().DidResume; o.(bool) { g = Good } return }) }
// HandleStartTLS is the companion to StartTLS, and will do the connection upgrade. It assumes // that the TLS command byte has already been read. Like StartTLS it returns the peer name, or // an error func (p *Protocol) HandleStartTLS(identity *security.Identity, caCertificate *security.Certificate) (string, error) { var ( err error tlsConn *tls.Conn ) // Build the config config := new(tls.Config) config.ClientAuth = tls.RequireAndVerifyClientCert // Setup the tls connection if err := p.tlsSetup(config, identity, caCertificate); err != nil { return "", err } // Upgrade the connection to TLS // TODO: Add a deadline here? tlsConn = tls.Server(p.conn, config) if err = tlsConn.Handshake(); err != nil { return "", err } // Capture the connection state cs := tlsConn.ConnectionState() // And replace the original connection p.conn = net.Conn(tlsConn) p.setupBuffers() // Send an Ack p.Ack() return cs.PeerCertificates[0].Subject.CommonName, nil }
func read(client *Client, conn *tls.Conn) { buffer := make([]byte, ERR_RESPONSE_LEN) if _, err := conn.Read(buffer); err != nil { log.Printf("read err %v, %v, %p\n", err, err == io.EOF, client) client.chConnectionErr <- conn return } errRsp := &errResponse{ Command: uint8(buffer[0]), Status: uint8(buffer[1]), } if err := binary.Read(bytes.NewBuffer(buffer[2:]), binary.BigEndian, &errRsp.Identifier); err != nil { log.Println("read identifier err", err) return } if errRsp.Command != ERR_RESPONSE_CMD { log.Println("unknown err response", buffer) return } errMsg, ok := ApplePushResponses[errRsp.Status] if !ok { log.Println("unknown err status", buffer) return } log.Printf("get err response : %##v, %s\n", errRsp, errMsg) client.chErrResponse <- errRsp }
func HandleUserTimeout(UserCollection *mgo.Collection, username, RSA_Public_Key string, conn *tls.Conn, timeout_sec int) { log.Printf("Timeout:\tUser '%s' at %s\n", username, conn.RemoteAddr()) err := GBServerDatabase.UpdateLastAccessedTime(UserCollection, username, string(RSA_Public_Key), 5) checkErr(err) err = GBServerDatabase.UpdateCurrentlyBeingUsed(UserCollection, username, string(RSA_Public_Key), false) checkErr(err) }
func (c *connection) startTls() error { if c.authOptions == nil { return nil } if c.authOptions.TlsConfig == nil { return ErrAuthMissingConfig } c.setState(connTlsStarting) startTlsCmd := &startTlsCommand{} if err := c.execute(startTlsCmd); err != nil { return err } var tlsConn *tls.Conn if tlsConn = tls.Client(c.conn, c.authOptions.TlsConfig); tlsConn == nil { return ErrAuthTLSUpgradeFailed } if err := tlsConn.Handshake(); err != nil { return err } c.conn = tlsConn authCmd := &authCommand{ user: c.authOptions.User, password: c.authOptions.Password, } return c.execute(authCmd) }
func connect(app string, keyFile string, certFile string, sandbox bool) { defer CapturePanic(fmt.Sprintf("connection to apns server error %s", app)) cert, err := tls.LoadX509KeyPair(certFile, keyFile) if err != nil { log.Printf("server : loadKeys: %s", err) } config := tls.Config{Certificates: []tls.Certificate{cert}, InsecureSkipVerify: true} endPoint := APNS_ENDPOINT if sandbox { endPoint = APNS_SANDBOX_ENDPOINT } var conn *tls.Conn for { conn, err = tls.Dial("tcp", endPoint, &config) if err != nil { log.Println("连接服务器有误, 2秒后将重连", err) time.Sleep(time.Second * 2) } else { break } } log.Println("client is connect to ", conn.RemoteAddr()) state := conn.ConnectionState() log.Println("client: hand shake ", state.HandshakeComplete) log.Println("client: mutual", state.NegotiatedProtocolIsMutual) if sandbox { app = app + DEVELOP_SUBFIX } info := &ConnectInfo{Connection: conn, App: app, Sandbox: sandbox, lastActivity: time.Now().Unix()} socketCN <- info }
func (t *TCP) startTLS() (el element.Element, err error) { var tlsConn *tls.Conn if t.mode == stream.Initiating { err = t.WriteElement(element.StartTLS) if err != nil { return } el, err = t.Next() if err != nil || el.Tag != element.TLSProceed.Tag { return } tlsConn = tls.Client(t.Conn, t.conf) } else { err = t.WriteElement(element.TLSProceed) if err != nil { return } tlsConn = tls.Server(t.Conn, t.conf) } err = tlsConn.Handshake() if err != nil { return } conn := net.Conn(tlsConn) t.Conn = conn t.Decoder = xml.NewDecoder(conn) el = element.Element{} err = stream.ErrRequireRestart t.secure = true log.Println("Done upgrading connection") return }
func getPublicKey(tlsConn *tls.Conn) ([]byte, error) { state := tlsConn.ConnectionState() for _, v := range state.PeerCertificates { return x509.MarshalPKIXPublicKey(v.PublicKey) } return []byte{}, nil }
// Start the simple voice app on the encrypted channel. func startVoiceApp(tlsconn *tls.Conn, remoteCN string) { // start the speaker part and connect it to our socket spr := exec.Command("/usr/bin/aplay") spr.Stdin = tlsconn err := spr.Start() // start asynchronously check(err) // start the microphone too // defaults: 1 channel 8000 Hz sample rate, WAVE format mic := exec.Command("/usr/bin/arecord") mic.Stdout = tlsconn err = mic.Start() // start asynchronously check(err) // TODO: write a ping to signal connection // mess := text_to_speech("Connected to %s, chat away!\n", remoteCN) // spr.Write([]byte(mess)) // wait for it to finish // TODO: find a way to hang up the connection, short of killall arecord/aplay err = mic.Wait() check(err) err = spr.Wait() check(err) tlsconn.Close() }
func postVerifyTLSConnection(conn *tls.Conn, config *TLSConfig) error { st := conn.ConnectionState() if !st.HandshakeComplete { return errors.New("incomplete handshake") } // no more checks if no extra configs available if config == nil { return nil } versions := config.Versions if versions == nil { versions = tlsDefaultVersions } versionOK := false for _, version := range versions { versionOK = versionOK || st.Version == uint16(version) } if !versionOK { return fmt.Errorf("tls version %v not configured", TLSVersion(st.Version)) } return nil }
// StartTLS takes an identity and an authority certificate and upgrades the net.Conn on the protocol to TLS // It returns the CommonName from the peer certitifcate, or an error func (p *Protocol) StartTLS(identity *security.Identity, caCertificate *security.Certificate) (string, error) { var ( err error tlsConn *tls.Conn ) if err = p.WriteBytesWithDeadline([]byte{TLS}); err != nil { return "", err } // Build the config config := new(tls.Config) config.ServerName = p.serverName // Setup the tls connection if err = p.tlsSetup(config, identity, caCertificate); err != nil { return "", err } // Upgrade the connection to TLS // TODO: Add a deadline here? tlsConn = tls.Client(p.conn, config) if err = tlsConn.Handshake(); err != nil { return "", err } // Capture the connection state cs := tlsConn.ConnectionState() // And replace the original connection p.conn = net.Conn(tlsConn) p.setupBuffers() return cs.PeerCertificates[0].Subject.CommonName, nil }
func closeAndCountFDs(t *testing.T, conn *tls.Conn, err error, fdStart int) { if err == nil { conn.Close() } fdEnd := countTCPFiles() assert.Equal(t, fdStart, fdEnd, "Number of open TCP files should be the same after test as before") }
func Connect(cert_filename string, key_filename string, server string) (*Apn, error) { rchan := make(chan NotificationError) cert, cert_err := tls.LoadX509KeyPair(cert_filename, key_filename) if cert_err != nil { return nil, cert_err } conn, err := net.Dial("tcp", server) if err != nil { return nil, err } certificate := []tls.Certificate{cert} conf := tls.Config{ Certificates: certificate, } var client_conn *tls.Conn = tls.Client(conn, &conf) err = client_conn.Handshake() if err != nil { return nil, err } go readError(client_conn, rchan) return &Apn{cert, server, client_conn, rchan}, nil }
// Start the simple chat app on the encrypted channel. func startChatApp(tlsconn *tls.Conn, remoteCN string) { // Create listener socket for the simple chat socket, err := net.Listen("tcp", "[::1]:0") check(err) port := getPort(socket.Addr().String()) // start the chat app and point it to our socket cmd := exec.Command("uxterm", "-e", "nc", "-6", "::1", port) err = cmd.Start() // start asynchronously check(err) // wait for it to connect app, err := socket.Accept() check(err) // show a welcome message mess := fmt.Sprintf("Connected to %s, chat away!\n", remoteCN) app.Write([]byte(mess)) app.Write([]byte(fmt.Sprintf("%s\n", strings.Repeat("-", len(mess)-1)))) // copy the TLS-connection to the chat app and back go io.Copy(app, tlsconn) go io.Copy(tlsconn, app) // wait for it to finish err = cmd.Wait() check(err) // Close all, including the socket and the TLS channel. // We run this only once. app.Close() socket.Close() tlsconn.Close() }
func (options *ScanOptions) SSLMatchHosts(conn *tls.Conn) []string { hosts := make([]string, 0) options.hostsMutex.Lock() for _, host := range options.inputHosts { testhost := host.Host if strings.Contains(testhost, ".appspot.com") { testhost = "appengine.google.com" } else if strings.Contains(testhost, "ggpht.com") { testhost = "googleusercontent.com" } else if strings.Contains(testhost, ".books.google.com") { testhost = "books.google.com" } else if strings.Contains(testhost, ".googleusercontent.com") { testhost = "googleusercontent.com" } if conn.VerifyHostname(testhost) == nil { hosts = append(hosts, host.Host) } } options.hostsMutex.Unlock() dest := make([]string, len(hosts)) perm := rand.Perm(len(hosts)) for i, v := range perm { dest[v] = hosts[i] } hosts = dest return hosts }
func test_conn(conn *tls.Conn, options *ScanOptions, record *ScanRecord) bool { //check SSL certificate success := false for _, cert := range conn.ConnectionState().PeerCertificates { for _, verifyHost := range options.Config.ScanGoogleIP.SSLCertVerifyHosts { if cert.VerifyHostname(verifyHost) != nil { return false } else { success = true } } if success { break } } for _, verifyHost := range options.Config.ScanGoogleIP.HTTPVerifyHosts { conn.SetReadDeadline(time.Now().Add(record.httpVerifyTimeout)) req, _ := http.NewRequest("HEAD", "https://"+verifyHost, nil) res, err := httputil.NewClientConn(conn, nil).Do(req) if nil != err || res.StatusCode >= 400 { return false } } return true }
func (r *invitationReceiver) Serve() { for { select { case inv := <-r.invitations: l.Debugln("Received relay invitation", inv) conn, err := client.JoinSession(inv) if err != nil { l.Debugf("Failed to join relay session %s: %v", inv, err) continue } var tc *tls.Conn if inv.ServerSocket { tc = tls.Server(conn, r.tlsCfg) } else { tc = tls.Client(conn, r.tlsCfg) } err = tc.Handshake() if err != nil { l.Infof("TLS handshake (BEP/relay %s): %v", inv, err) tc.Close() continue } r.conns <- tc case <-r.stop: return } } }
func find_match_hosts(conn *tls.Conn, options *ScanOptions, record *ScanRecord) bool { if nil == record.MatchHosts || len(record.MatchHosts) == 0 { record.MatchHosts = options.SSLMatchHosts(conn) } newhosts := make([]string, 0) for _, host := range record.MatchHosts { if options.HaveHostInRecords(host) { continue } newhosts = append(newhosts, host) valid := true for _, pattern := range options.Config.ScanGoogleHosts.HTTPVerifyHosts { if matchHostnames(pattern, host) { conn.SetReadDeadline(time.Now().Add(record.httpVerifyTimeout)) req, _ := http.NewRequest("HEAD", "https://"+host, nil) res, err := httputil.NewClientConn(conn, nil).Do(req) if nil != err || res.StatusCode >= 400 { valid = false } break } } if valid { newhosts = append(newhosts, host) } } record.MatchHosts = newhosts return len(record.MatchHosts) > 0 }
// dial dials the host specified by req, using TLS if appropriate. func (s *SpdyRoundTripper) dial(req *http.Request) (net.Conn, error) { dialAddr := netutil.CanonicalAddr(req.URL) if req.URL.Scheme == "http" { if s.Dialer == nil { return net.Dial("tcp", dialAddr) } else { return s.Dialer.Dial("tcp", dialAddr) } } // TODO validate the TLSClientConfig is set up? var conn *tls.Conn var err error if s.Dialer == nil { conn, err = tls.Dial("tcp", dialAddr, s.tlsConfig) } else { conn, err = tls.DialWithDialer(s.Dialer, "tcp", dialAddr, s.tlsConfig) } if err != nil { return nil, err } host, _, err := net.SplitHostPort(dialAddr) if err != nil { return nil, err } err = conn.VerifyHostname(host) if err != nil { return nil, err } return conn, nil }
func WritePacket(logger *log.Logger, conn *tls.Conn, p *Packet) error { jsbuf, err := json.Marshal(&p) if err != nil { return err } plen := len(jsbuf) pilen := uint32(plen) outlen := new(bytes.Buffer) binary.Write(outlen, binary.BigEndian, &pilen) jsbuf = append(outlen.Bytes(), jsbuf...) bw := 0 for { if bw >= (plen + 4) { break } w, err := conn.Write(jsbuf) if err != nil { return err } bw = bw + w } return nil }
func handle_tlsconn(conn *tls.Conn, context *Context) bool { conn.SetDeadline(time.Now().Add(config.TimeoutTLS)) err := conn.Handshake() if err != nil { util.Log(0, "ERROR! [SECURITY] TLS Handshake: %v", err) return false } var no_deadline time.Time conn.SetDeadline(no_deadline) state := conn.ConnectionState() if len(state.PeerCertificates) == 0 { util.Log(0, "ERROR! [SECURITY] TLS peer has no certificate") return false } cert := state.PeerCertificates[0] // docs are unclear about this but I think leaf certificate is the first entry because that's as it is in tls.Certificate if util.LogLevel >= 2 { // because creating the dump is expensive util.Log(2, "DEBUG! [SECURITY] Peer certificate presented by %v:\n%v", conn.RemoteAddr(), CertificateInfo(cert)) } for _, cacert := range config.CACert { err = cert.CheckSignatureFrom(cacert) if err == nil { if string(cacert.RawSubject) != string(cert.RawIssuer) { err = fmt.Errorf("Certificate was issued by wrong CA: \"%v\" instead of \"%v\"", cacert.Subject, cert.Issuer) } else { break // stop checking if we found a match for a CA. err == nil here! } } } if err != nil { util.Log(0, "ERROR! [SECURITY] TLS peer presented certificate not signed by trusted CA: %v", err) return false } for _, e := range cert.Extensions { if len(e.Id) == 4 && e.Id[0] == 2 && e.Id[1] == 5 && e.Id[2] == 29 && e.Id[3] == 17 { parseSANExtension(e.Value, context) } else if len(e.Id) == 9 && e.Id[0] == 1 && e.Id[1] == 3 && e.Id[2] == 6 && e.Id[3] == 1 && e.Id[4] == 4 && e.Id[5] == 1 && e.Id[6] == 45753 && e.Id[7] == 1 { switch e.Id[8] { case 5: err = parseConnectionLimits(e.Value, context) if err != nil { util.Log(0, "ERROR! [SECURITY] GosaConnectionLimits: %v", err) } case 6: //err = parseAccessControl(e.Value, context) //if err != nil { util.Log(0, "ERROR! [SECURITY] GosaAccessControl: %v", err) } } } } context.TLS = true return true }
func closeAndCountFDs(t *testing.T, conn *tls.Conn, err error, fdc *fdcount.Counter) { if err == nil { if err := conn.Close(); err != nil { t.Fatalf("Unable to close connection: %v", err) } } assert.NoError(t, fdc.AssertDelta(0), "Number of open TCP files should be the same after test as before") }
// Default TLS peer name function - returns the CN of the certificate func defaultTlsPeerName(tlsConn *tls.Conn) (tlsPeer string, ok bool) { state := tlsConn.ConnectionState() if len(state.PeerCertificates) <= 0 { return "", false } cn := state.PeerCertificates[0].Subject.CommonName return cn, true }
// DialTLSFunc returns the adequate dial function, when using SSL, depending on // whether we're using insecure TLS (certificate verification is disabled), or we // have some trusted certs, or we're on android.1 // If the client's config has some trusted certs, the server's certificate will // be checked against those in the config after the TLS handshake. func (c *Client) DialTLSFunc() func(network, addr string) (net.Conn, error) { if !c.useTLS() { return nil } trustedCerts := c.getTrustedCerts() var stdTLS bool if !c.insecureAnyTLSCert && len(trustedCerts) == 0 { // TLS with normal/full verification. stdTLS = true if !android.IsChild() { // Not android, so let the stdlib deal with it return nil } } return func(network, addr string) (net.Conn, error) { var conn *tls.Conn var err error if android.IsChild() { ac, err := android.Dial(network, addr) if err != nil { return nil, err } var tlsConfig *tls.Config if stdTLS { tlsConfig, err = android.TLSConfig() if err != nil { return nil, err } } else { tlsConfig = &tls.Config{InsecureSkipVerify: true} } conn = tls.Client(ac, tlsConfig) if err := conn.Handshake(); err != nil { return nil, err } } else { conn, err = tls.Dial(network, addr, &tls.Config{InsecureSkipVerify: true}) if err != nil { return nil, err } } if c.insecureAnyTLSCert { return conn, nil } certs := conn.ConnectionState().PeerCertificates if len(certs) < 1 { return nil, fmt.Errorf("no TLS peer certificates from %s", addr) } sig := hashutil.SHA256Prefix(certs[0].Raw) for _, v := range trustedCerts { if v == sig { return conn, nil } } return nil, fmt.Errorf("TLS server at %v presented untrusted certificate (signature %q)", addr, sig) } }