Beispiel #1
1
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
}
Beispiel #2
0
// 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
}
Beispiel #3
0
// 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
}
Beispiel #4
0
// 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
}
Beispiel #5
0
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
}
Beispiel #6
0
// 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
	})
}
Beispiel #7
0
func enrichWithOwnChecks(conn *tls.Conn, tlsConfig *tls.Config) error {
	var err error
	if err = conn.Handshake(); err != nil {
		conn.Close()
		return err
	}

	opts := x509.VerifyOptions{
		Roots:         tlsConfig.RootCAs,
		CurrentTime:   time.Now(),
		DNSName:       "",
		Intermediates: x509.NewCertPool(),
	}

	certs := conn.ConnectionState().PeerCertificates
	for i, cert := range certs {
		if i == 0 {
			continue
		}
		opts.Intermediates.AddCert(cert)
	}

	_, err = certs[0].Verify(opts)
	if err != nil {
		conn.Close()
		return err
	}

	return nil
}
Beispiel #8
0
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
}
Beispiel #9
0
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
}
Beispiel #10
0
func main() {
	ripmgr := randip.NewRandIPv4Mgr(true, 1249767200)
	for {
		newIP, err := ripmgr.GetNextIP()
		if err != nil {
			log.Println("IP Addr Exhausted")
			return
		} else {
			go func() {
				log.Println(newIP.String())
				config := tls.Config{InsecureSkipVerify: true, ServerName: "google.com"}
				var err error
				var newConn *tls.Conn
				newConn, err = tls.DialWithDialer(&net.Dialer{Timeout: 2 * time.Second}, "tcp", newIP.String()+":443", &config)
				if err != nil {
					log.Println(err)
				} else {
					conState := newConn.ConnectionState()
					fmt.Println(newConn.RemoteAddr(), conState.PeerCertificates[0].NotBefore, conState.PeerCertificates[0].NotAfter, conState.PeerCertificates[0].SerialNumber)
					//jsonCert,_ := json.MarshalIndent(conState.PeerCertificates[0],""," ")
					//fmt.Println(string(jsonCert))
					newConn.Close()
				}
			}()
		}
	}
}
func getPublicKey(tlsConn *tls.Conn) ([]byte, error) {
	state := tlsConn.ConnectionState()
	for _, v := range state.PeerCertificates {
		return x509.MarshalPKIXPublicKey(v.PublicKey)
	}
	return []byte{}, nil
}
Beispiel #12
0
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
}
Beispiel #13
0
// 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
}
Beispiel #14
0
// 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)
	}
}
Beispiel #15
0
// 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.
// 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.InsecureTLS && 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() {
			con, 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(con, 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.InsecureTLS {
			return conn, nil
		}
		certs := conn.ConnectionState().PeerCertificates
		if certs == nil || len(certs) < 1 {
			return nil, errors.New("Could not get server's certificate from the TLS connection.")
		}
		sig := hashutil.SHA256Prefix(certs[0].Raw)
		for _, v := range trustedCerts {
			if v == sig {
				return conn, nil
			}
		}
		return nil, fmt.Errorf("Server's certificate %v is not in the trusted list", sig)
	}
}
func verifyLegacyCertificate(conn *tls.Conn, expectedCertificate *x509.Certificate) error {
	certs := conn.ConnectionState().PeerCertificates
	if len(certs) < 1 {
		return ContextError(errors.New("no certificate to verify"))
	}
	if !bytes.Equal(certs[0].Raw, expectedCertificate.Raw) {
		return ContextError(errors.New("unexpected certificate"))
	}
	return nil
}
func verifyClientAddrMatch(c *tls.Conn) error {
	err := c.Handshake()
	if err != nil {
		return err
	}
	addr, _, err := net.SplitHostPort(c.RemoteAddr().String())
	if err != nil {
		return err
	}
	return c.ConnectionState().VerifiedChains[0][0].VerifyHostname(addr)
}
Beispiel #18
0
func NewResolver(conn *tls.Conn, endpoint string, logger *logrus.Entry) (*Resolver, error) {
	certs := conn.ConnectionState().PeerCertificates
	chain := []ResolverPair{}

	for _, cert := range certs {
		cn := cert.Subject.CommonName
		if len(cert.Subject.OrganizationalUnit) > 0 && cn != "" {
			ou := cert.Subject.OrganizationalUnit[0]
			chain = append(chain, ResolverPair{cn, ou})
		}
	}

	if len(chain) == 0 {
		return nil, errors.New("Cannot found CommonName or OrganizationalUnit in peer certificate")
	}

	userId := chain[0].userId
	role := chain[0].role

	endpoint = strings.Replace(endpoint, ":userId", userId, 1)
	endpoint = strings.Replace(endpoint, ":role", role, 1)

	logger.Debug("Resolve using ", endpoint)

	response, err := http.Get(endpoint)
	if err != nil {
		return nil, err
	}

	defer response.Body.Close()

	content, err := ioutil.ReadAll(response.Body)
	if err != nil {
		return nil, err
	}

	res := &Resolver{}

	err = json.Unmarshal(content, res)
	if err != nil {
		return nil, err
	}

	addrAndPort := strings.Join([]string{res.RawAddr, "2376"}, ":")

	addr, err := net.ResolveTCPAddr("tcp", addrAndPort)
	if err != nil {
		return nil, err
	}

	res.Addr = addr

	return res, nil
}
Beispiel #19
0
// tlsConnectionStateString выводит в лог информацию о TLS-соединении.
func tlsConnectionStateString(conn *tls.Conn) string {
	var state = conn.ConnectionState()
	return fmt.Sprint("Connection state:",
		"\n------------------------------------------------------------",
		"\n  Local Address:       ", conn.LocalAddr(),
		"\n  Remote Address:      ", conn.RemoteAddr(),
		"\n  TLS version:         ", state.Version,
		"\n  Handshake Complete:  ", state.HandshakeComplete,
		"\n  Did Resume:          ", state.DidResume,
		"\n  Cipher Suite:        ", state.CipherSuite,
		"\n------------------------------------------------------------")
}
Beispiel #20
0
func (tcc *TLSClientConfig) Verify(conn *tls.Conn) (*TLSState, error) {
	var ocsprep *ocsp.Response
	var der []byte
	var err error

	res := new(TLSState)
	cstate := conn.ConnectionState()

	res.SNIExist = (tcc.SNI != "")
	res.PKPExist = (tcc.PKPs != nil && len(tcc.PKPs) > 0)

	if cstate.OCSPResponse != nil {
		ocsprep, err = ocsp.ParseResponse(cstate.OCSPResponse, nil)
		if err != nil {
			return nil, err
		}
		res.OCSPExist = true
		res.OCSPValid = (ocsprep.Status == ocsp.Good)
		res.OCSPUnknown = (ocsprep.Status == ocsp.Unknown)
	}

	for _, peercert := range cstate.PeerCertificates {
		der, err = x509.MarshalPKIXPublicKey(peercert.PublicKey)
		if err != nil {
			return nil, err
		}

		if res.SNIExist && !res.SNIValid && peercert.VerifyHostname(tcc.SNI) == nil {
			res.SNIValid = true
		}

		if res.OCSPValid && !res.OCSPChecked && ocsprep.CheckSignatureFrom(peercert) == nil {
			res.OCSPChecked = true
		}

		rawhash := sha256.Sum256(der)
		hash := base64.StdEncoding.EncodeToString(rawhash[:])

		if res.PKPExist {
			res.PKPCerts++
			valid, ok := tcc.PKPs[hash]
			switch {
			case ok && valid:
				res.PKPValid++
			case ok && !valid:
				res.PKPInvalid++
			}
		}
	}

	return res, nil
}
Beispiel #21
0
func NewTLSRedialTransport(conn *tls.Conn, serverName string) *TLSRedialTransport {
	t := &TLSRedialTransport{
		ServerConn: conn,
		ServerName: serverName,
		serverAddr: conn.RemoteAddr().String(),
		publicKey:  conn.ConnectionState().PeerCertificates[0].RawSubjectPublicKeyInfo,
	}

	t.Dial = t.dial
	t.timeout = time.AfterFunc(10*time.Second, t.CloseIdleConnections)

	return t
}
Beispiel #22
0
// Handle closing down a connection when the handshake has timedout.
func tlsTimeout(c *client, conn *tls.Conn) {
	c.mu.Lock()
	nc := c.nc
	c.mu.Unlock()
	// Check if already closed
	if nc == nil {
		return
	}
	cs := conn.ConnectionState()
	if cs.HandshakeComplete == false {
		c.Debugf("TLS handshake timeout")
		c.sendErr("Secure Connection - TLS Required")
		c.closeConnection()
	}
}
func tryConnect(addr string, strict bool) (errchan chan error) {
	errchan = make(chan error)
	go func() {

		caCertFile, err := ioutil.TempFile("", "logstash-forwarder-cacert")
		if err != nil {
			panic(err)
		}
		defer func() { os.Remove(caCertFile.Name()) }()
		ioutil.WriteFile(caCertFile.Name(), []byte(caCert), os.ModeTemporary)

		// this can be messy because of localhost resolving to ipv6 addresses
		// but there's no easy way to disable v6 resolution here
		const wait = 5
		const retryLimit = 3
		tryAttempt := 0
		exinfo := ""
		config := &NetworkConfig{
			SSLCA:   caCertFile.Name(),
			Servers: []string{addr},
			Timeout: wait,
			timeout: time.Second * wait,
		}

		var socket *tls.Conn
		for socket == nil && tryAttempt < retryLimit {
			select {
			case socket = <-doConnect(config):
			case <-time.After(time.Second * wait):
				log.Printf("INFO: Connect timeout: attempt: %d\n", tryAttempt)
				tryAttempt++
			}
		}
		if socket == nil {
			errchan <- errors.New("Client connect failed. " + exinfo)
			return
		}
		defer socket.Close()
		log.Printf("INFO: Connected to %s\n", socket.RemoteAddr())

		if !socket.ConnectionState().HandshakeComplete {
			errchan <- errors.New("handshake should be complete")
			return
		}
		errchan <- nil
	}()
	return errchan
}
Beispiel #24
0
func getClientID(tlsConn *tls.Conn) (string, error) {
	state := tlsConn.ConnectionState()

	if len(state.PeerCertificates) == 0 {
		return "", fmt.Errorf("client certificate not found")
	}

	cert := state.PeerCertificates[0]

	parts := strings.Split(cert.Subject.CommonName, "-")
	if len(parts) != 3 || parts[0] != appname || parts[1] != "client" || len(parts[2]) == 0 {
		return "", fmt.Errorf("bad client common name")
	}

	return parts[2], nil
}
Beispiel #25
0
// DialFunc returns the adequate dial function, depending on
// whether SSL is required, the client's config has some trusted
// certs, and we're on android.
// 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) DialFunc() func(network, addr string) (net.Conn, error) {
	trustedCerts := c.GetTrustedCerts()
	if !c.useTLS() || (!c.InsecureTLS && len(trustedCerts) == 0) {
		// No TLS, or TLS with normal/full verification
		if onAndroid() {
			return func(network, addr string) (net.Conn, error) {
				return androidDial(network, addr)
			}
		}
		return nil
	}

	return func(network, addr string) (net.Conn, error) {
		var conn *tls.Conn
		var err error
		if onAndroid() {
			con, err := androidDial(network, addr)
			if err != nil {
				return nil, err
			}
			conn = tls.Client(con, &tls.Config{InsecureSkipVerify: true})
			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.InsecureTLS {
			return conn, nil
		}
		certs := conn.ConnectionState().PeerCertificates
		if certs == nil || len(certs) < 1 {
			return nil, errors.New("Could not get server's certificate from the TLS connection.")
		}
		sig := misc.SHA1Prefix(certs[0].Raw)
		for _, v := range trustedCerts {
			if v == sig {
				return conn, nil
			}
		}
		return nil, fmt.Errorf("Server's certificate %v is not in the trusted list", sig)
	}
}
// getChain is a helper function that retreives the host's certificate chain.
func getChain(addr string, config *tls.Config) (chain []*x509.Certificate, err error) {
	var conn *tls.Conn
	conn, err = tls.DialWithDialer(Dialer, Network, addr, config)
	if err != nil {
		return
	}

	err = conn.Close()
	if err != nil {
		return
	}

	chain = conn.ConnectionState().PeerCertificates
	if len(chain) == 0 {
		err = fmt.Errorf("%s returned empty certificate chain", addr)
	}
	return
}
Beispiel #27
0
/* Check that the TLS connection's certficate can be applied to this connection.
Because irc.coldfront.net presents a certificate not as irc.coldfront.net, but as it's actual host (e.g. snow.coldfront.net),

We do this by comparing the IP address of the certs name to the IP address of our connection.
If they match we're OK.
*/
func isCertValid(conn *tls.Conn) bool {
	connAddr := strings.Split(conn.RemoteAddr().String(), ":")[0]
	cert := conn.ConnectionState().PeerCertificates[0]

	if len(cert.DNSNames) == 0 {
		// Cert has single name, the usual case
		return isIPMatch(cert.Subject.CommonName, connAddr)

	}
	// Cert has several valid names
	for _, certname := range cert.DNSNames {
		if isIPMatch(certname, connAddr) {
			return true
		}
	}

	return false
}
Beispiel #28
0
func verifyServerCerts(conn *tls.Conn, serverName string, config *tls.Config) ([][]*x509.Certificate, error) {
	certs := conn.ConnectionState().PeerCertificates

	opts := x509.VerifyOptions{
		Roots:         config.RootCAs,
		CurrentTime:   time.Now(),
		DNSName:       serverName,
		Intermediates: x509.NewCertPool(),
	}

	for i, cert := range certs {
		if i == 0 {
			continue
		}
		opts.Intermediates.AddCert(cert)
	}
	return certs[0].Verify(opts)
}
Beispiel #29
0
func verifyCrypto(conn *tls.Conn) (*Connection, error) {

	if err := conn.Handshake(); err != nil {
		return nil, err
	}

	certs := conn.ConnectionState().PeerCertificates
	if len(certs) != 1 {
		return nil, errors.New(fmt.Sprintf("Illegal number of certificates presented by peer (%d)", len(certs)))
	}

	cert := certs[0]

	if err := cert.CheckSignature(cert.SignatureAlgorithm, cert.RawTBSCertificate, cert.Signature); err != nil {
		return nil, err
	}

	return &Connection{Conn: conn, Id: NewIdentity(cert)}, nil
}
Beispiel #30
0
// Wrap a net.Conn into a client tls connection, performing any
// additional verification as needed.
//
// As of go 1.3, crypto/tls only supports either doing no certificate
// verification, or doing full verification including of the peer's
// DNS name. For consul, we want to validate that the certificate is
// signed by a known CA, but because consul doesn't use DNS names for
// node names, we don't verify the certificate DNS names. Since go 1.3
// no longer supports this mode of operation, we have to do it
// manually.
func WrapTLSClient(conn net.Conn, tlsConfig *tls.Config) (net.Conn, error) {
	var err error
	var tlsConn *tls.Conn

	tlsConn = tls.Client(conn, tlsConfig)

	// If crypto/tls is doing verification, there's no need to do
	// our own.
	if tlsConfig.InsecureSkipVerify == false {
		return tlsConn, nil
	}

	if err = tlsConn.Handshake(); err != nil {
		tlsConn.Close()
		return nil, err
	}

	// The following is lightly-modified from the doFullHandshake
	// method in crypto/tls's handshake_client.go.
	opts := x509.VerifyOptions{
		Roots:         tlsConfig.RootCAs,
		CurrentTime:   time.Now(),
		DNSName:       "",
		Intermediates: x509.NewCertPool(),
	}

	certs := tlsConn.ConnectionState().PeerCertificates
	for i, cert := range certs {
		if i == 0 {
			continue
		}
		opts.Intermediates.AddCert(cert)
	}

	_, err = certs[0].Verify(opts)
	if err != nil {
		tlsConn.Close()
		return nil, err
	}

	return tlsConn, err
}