func (d *dialer) startTLS(c interfaces.Conn, conn net.Conn) error { fmt.Fprintf(c.Out(), "<starttls xmlns='%s'/>", NsTLS) proceed, err := nextStart(c.In()) if err != nil { return err } if proceed.Name.Space != NsTLS || proceed.Name.Local != "proceed" { return errors.New("xmpp: expected <proceed> after <starttls> but got <" + proceed.Name.Local + "> in " + proceed.Name.Space) } l := c.Config().GetLog() io.WriteString(l, "Starting TLS handshake\n") var tlsConfig tls.Config if c.Config().TLSConfig != nil { tlsConfig = *c.Config().TLSConfig } tlsConfig.ServerName = c.OriginDomain() tlsConfig.InsecureSkipVerify = true tlsConn := tls.Client(conn, &tlsConfig) if err := tlsConn.Handshake(); err != nil { return err } tlsState := tlsConn.ConnectionState() printTLSDetails(l, tlsState) if err = d.verifier.Verify(tlsState, tlsConfig, c.OriginDomain()); err != nil { return err } d.bindTransport(c, tlsConn) return nil }
func (d *dialer) startTLS(c interfaces.Conn, conn net.Conn) error { address := d.GetServer() fmt.Fprintf(c.Out(), "<starttls xmlns='%s'/>", NsTLS) proceed, err := nextStart(c.In()) if err != nil { return err } if proceed.Name.Space != NsTLS || proceed.Name.Local != "proceed" { return errors.New("xmpp: expected <proceed> after <starttls> but got <" + proceed.Name.Local + "> in " + proceed.Name.Space) } l := c.Config().GetLog() io.WriteString(l, "Starting TLS handshake\n") var tlsConfig tls.Config if c.Config().TLSConfig != nil { tlsConfig = *c.Config().TLSConfig } tlsConfig.ServerName = c.OriginDomain() tlsConfig.InsecureSkipVerify = true tlsConn := tls.Client(conn, &tlsConfig) if err := tlsConn.Handshake(); err != nil { return err } tlsState := tlsConn.ConnectionState() printTLSDetails(l, tlsState) haveCertHash := len(c.Config().ServerCertificateSHA256) != 0 if haveCertHash { h := sha256.New() h.Write(tlsState.PeerCertificates[0].Raw) if digest := h.Sum(nil); !bytes.Equal(digest, c.Config().ServerCertificateSHA256) { return fmt.Errorf("xmpp: server certificate does not match expected hash (got: %x, want: %x)", digest, c.Config().ServerCertificateSHA256) } } else { if len(tlsState.PeerCertificates) == 0 { return errors.New("xmpp: server has no certificates") } opts := x509.VerifyOptions{ Intermediates: x509.NewCertPool(), Roots: tlsConfig.RootCAs, } for _, cert := range tlsState.PeerCertificates[1:] { opts.Intermediates.AddCert(cert) } verifiedChains, err := tlsState.PeerCertificates[0].Verify(opts) if err != nil { return errors.New("xmpp: failed to verify TLS certificate: " + err.Error()) } for i, cert := range verifiedChains[0] { fmt.Fprintf(l, " certificate %d: %s\n", i, certName(cert)) } leafCert := verifiedChains[0][0] if err := leafCert.VerifyHostname(c.OriginDomain()); err != nil { if c.Config().TrustedAddress { fmt.Fprintf(l, "Certificate fails to verify against domain in username: %s\n", err) host, _, err := net.SplitHostPort(address) if err != nil { return errors.New("xmpp: failed to split address when checking whether TLS certificate is valid: " + err.Error()) } if err = leafCert.VerifyHostname(host); err != nil { return errors.New("xmpp: failed to match TLS certificate to address after failing to match to username: "******"Certificate matches against trusted server hostname: %s\n", host) } else { return errors.New("xmpp: failed to match TLS certificate to name: " + err.Error()) } } } d.bindTransport(c, tlsConn) return nil }