Example #1
0
func (c *ClientKeyManager) loadKeys() error {
	// Load authorized keys file
	var clients []libtrust.PublicKey
	if c.clientFile != "" {
		fileClients, err := libtrust.LoadKeySetFile(c.clientFile)
		if err != nil {
			return fmt.Errorf("unable to load authorized keys: %s", err)
		}
		clients = fileClients
	}

	// Add clients from authorized keys directory
	files, err := ioutil.ReadDir(c.clientDir)
	if err != nil && !os.IsNotExist(err) {
		return fmt.Errorf("unable to open authorized keys directory: %s", err)
	}
	for _, f := range files {
		if !f.IsDir() {
			publicKey, err := libtrust.LoadPublicKeyFile(path.Join(c.clientDir, f.Name()))
			if err != nil {
				return fmt.Errorf("unable to load authorized key file: %s", err)
			}
			clients = append(clients, publicKey)
		}
	}

	c.clientLock.Lock()
	c.clients = clients
	c.clientLock.Unlock()

	return nil
}
Example #2
0
func main() {
	// Load server key.
	serverKey, err := libtrust.LoadKeyFile(privateKeyFilename)
	if err != nil {
		log.Fatal(err)
	}

	// Generate server certificate.
	selfSignedServerCert, err := libtrust.GenerateSelfSignedServerCert(
		serverKey, []string{"localhost"}, []net.IP{net.ParseIP("127.0.0.1")},
	)
	if err != nil {
		log.Fatal(err)
	}

	// Load authorized client keys.
	authorizedClients, err := libtrust.LoadKeySetFile(authorizedClientsFilename)
	if err != nil {
		log.Fatal(err)
	}

	// Create CA pool using trusted client keys.
	caPool, err := libtrust.GenerateCACertPool(serverKey, authorizedClients)
	if err != nil {
		log.Fatal(err)
	}

	// Create TLS config, requiring client certificates.
	tlsConfig := &tls.Config{
		Certificates: []tls.Certificate{
			tls.Certificate{
				Certificate: [][]byte{selfSignedServerCert.Raw},
				PrivateKey:  serverKey.CryptoPrivateKey(),
				Leaf:        selfSignedServerCert,
			},
		},
		ClientAuth: tls.RequireAndVerifyClientCert,
		ClientCAs:  caPool,
	}

	// Create HTTP server with simple request handler.
	server := &http.Server{
		Addr:    serverAddress,
		Handler: http.HandlerFunc(requestHandler),
	}

	// Listen and server HTTPS using the libtrust TLS config.
	listener, err := net.Listen("tcp", server.Addr)
	if err != nil {
		log.Fatal(err)
	}
	tlsListener := tls.NewListener(listener, tlsConfig)
	server.Serve(tlsListener)
}
Example #3
0
func main() {
	key, err := libtrust.LoadKeyFile(clientPrivateKeyFilename)
	if err != nil {
		log.Fatal(err)
	}

	keyPEMBlock, err := key.PEMBlock()
	if err != nil {
		log.Fatal(err)
	}

	encodedPrivKey := pem.EncodeToMemory(keyPEMBlock)
	fmt.Printf("Client Key:\n\n%s\n", string(encodedPrivKey))

	cert, err := libtrust.GenerateSelfSignedClientCert(key)
	if err != nil {
		log.Fatal(err)
	}

	encodedCert := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: cert.Raw})
	fmt.Printf("Client Cert:\n\n%s\n", string(encodedCert))

	trustedServerKeys, err := libtrust.LoadKeySetFile(trustedHostsFilename)
	if err != nil {
		log.Fatal(err)
	}

	hostname, _, err := net.SplitHostPort(serverAddress)
	if err != nil {
		log.Fatal(err)
	}

	trustedServerKeys, err = libtrust.FilterByHosts(trustedServerKeys, hostname, false)
	if err != nil {
		log.Fatal(err)
	}

	caCert, err := libtrust.GenerateCACert(key, trustedServerKeys[0])
	if err != nil {
		log.Fatal(err)
	}

	encodedCert = pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: caCert.Raw})
	fmt.Printf("CA Cert:\n\n%s\n", string(encodedCert))
}
Example #4
0
// NewIdentityAuthTLSConfig creates a tls.Config for the client to use for
// libtrust identity authentication
func NewIdentityAuthTLSConfig(trustKey libtrust.PrivateKey, knownHostsPath, proto, addr string) (*tls.Config, error) {
	tlsConfig := createTLSConfig()

	// Load known hosts
	knownHosts, err := libtrust.LoadKeySetFile(knownHostsPath)
	if err != nil {
		return nil, fmt.Errorf("Could not load trusted hosts file: %s", err)
	}

	// Generate CA pool from known hosts
	allowedHosts, err := libtrust.FilterByHosts(knownHosts, addr, false)
	if err != nil {
		return nil, fmt.Errorf("Error filtering hosts: %s", err)
	}
	certPool, err := libtrust.GenerateCACertPool(trustKey, allowedHosts)
	if err != nil {
		return nil, fmt.Errorf("Could not create CA pool: %s", err)
	}
	tlsConfig.ServerName = "docker"
	tlsConfig.RootCAs = certPool

	// Generate client cert from trust key
	x509Cert, err := libtrust.GenerateSelfSignedClientCert(trustKey)
	if err != nil {
		return nil, fmt.Errorf("Certificate generation error: %s", err)
	}
	tlsConfig.Certificates = []tls.Certificate{{
		Certificate: [][]byte{x509Cert.Raw},
		PrivateKey:  trustKey.CryptoPrivateKey(),
		Leaf:        x509Cert,
	}}

	// Connect to server to see if it is a known host
	tlsConfig.InsecureSkipVerify = true
	testConn, err := tls.Dial(proto, addr, tlsConfig)
	if err != nil {
		return nil, fmt.Errorf("TLS Handshake error: %s", err)
	}
	opts := x509.VerifyOptions{
		Roots:         tlsConfig.RootCAs,
		CurrentTime:   time.Now(),
		DNSName:       tlsConfig.ServerName,
		Intermediates: x509.NewCertPool(),
	}

	certs := testConn.ConnectionState().PeerCertificates
	for i, cert := range certs {
		if i == 0 {
			continue
		}
		opts.Intermediates.AddCert(cert)
	}
	_, err = certs[0].Verify(opts)
	if err != nil {
		if _, ok := err.(x509.UnknownAuthorityError); ok {
			pubKey, err := libtrust.FromCryptoPublicKey(certs[0].PublicKey)
			if err != nil {
				return nil, fmt.Errorf("Error extracting public key from certificate: %s", err)
			}

			// If server is not a known host, prompt user to ask whether it should
			// be trusted and add to the known hosts file
			if promptUnknownKey(pubKey, addr) {
				pubKey.AddExtendedField("hosts", []string{addr})
				err = libtrust.AddKeySetFile(knownHostsPath, pubKey)
				if err != nil {
					return nil, fmt.Errorf("Error saving updated host keys file: %s", err)
				}

				ca, err := libtrust.GenerateCACert(trustKey, pubKey)
				if err != nil {
					return nil, fmt.Errorf("Error generating CA: %s", err)
				}
				tlsConfig.RootCAs.AddCert(ca)
			} else {
				return nil, fmt.Errorf("Cancelling request due to invalid certificate")
			}
		} else {
			return nil, fmt.Errorf("TLS verification error: %s", err)
		}
	}

	testConn.Close()
	tlsConfig.InsecureSkipVerify = false

	return tlsConfig, nil
}
Example #5
0
func main() {
	// Load Client Key.
	clientKey, err := libtrust.LoadKeyFile(privateKeyFilename)
	if err != nil {
		log.Fatal(err)
	}

	// Generate Client Certificate.
	selfSignedClientCert, err := libtrust.GenerateSelfSignedClientCert(clientKey)
	if err != nil {
		log.Fatal(err)
	}

	// Load trusted host keys.
	hostKeys, err := libtrust.LoadKeySetFile(trustedHostsFilename)
	if err != nil {
		log.Fatal(err)
	}

	// Ensure the host we want to connect to is trusted!
	host, _, err := net.SplitHostPort(serverAddress)
	if err != nil {
		log.Fatal(err)
	}
	serverKeys, err := libtrust.FilterByHosts(hostKeys, host, false)
	if err != nil {
		log.Fatalf("%q is not a known and trusted host", host)
	}

	// Generate a CA pool with the trusted host's key.
	caPool, err := libtrust.GenerateCACertPool(clientKey, serverKeys)
	if err != nil {
		log.Fatal(err)
	}

	// Create HTTP Client.
	client := &http.Client{
		Transport: &http.Transport{
			TLSClientConfig: &tls.Config{
				Certificates: []tls.Certificate{
					tls.Certificate{
						Certificate: [][]byte{selfSignedClientCert.Raw},
						PrivateKey:  clientKey.CryptoPrivateKey(),
						Leaf:        selfSignedClientCert,
					},
				},
				RootCAs: caPool,
			},
		},
	}

	var makeRequest = func(url string) {
		resp, err := client.Get(url)
		if err != nil {
			log.Fatal(err)
		}
		defer resp.Body.Close()

		body, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			log.Fatal(err)
		}

		log.Println(resp.Status)
		log.Println(string(body))
	}

	// Make the request to the trusted server!
	makeRequest(fmt.Sprintf("https://%s", serverAddress))
}