Exemple #1
0
func serve(addr, fp string, cert []byte, signingKey *tao.Keys, policy *fileproxy.ProgramPolicy) error {
	m := fileproxy.NewResourceMaster(fp)

	policyCert, err := x509.ParseCertificate(cert)
	if err != nil {
		return err
	}
	conf, err := signingKey.TLSServerConfig(policyCert)
	if err != nil {
		return err
	}
	log.Println("fileserver listening")
	sock, err := tls.Listen("tcp", addr, conf)
	if err != nil {
		return err
	}

	for {
		// Accept and handle client connections one at a time.
		conn, err := sock.Accept()
		if err != nil {
			return err
		}

		var clientName string
		if err = conn.(*tls.Conn).Handshake(); err != nil {
			log.Printf("fileserver: couldn't perform handshake: %s\n", err)
			continue
		}

		peerCerts := conn.(*tls.Conn).ConnectionState().PeerCertificates
		if peerCerts == nil {
			log.Println("fileserver: couldn't get peer list")
			continue
		}

		peerCert := conn.(*tls.Conn).ConnectionState().PeerCertificates[0]
		if peerCert.Raw == nil {
			log.Println("fileserver: couldn't get peer name")
			continue
		}

		if peerCert.Subject.OrganizationalUnit != nil {
			clientName = peerCert.Subject.OrganizationalUnit[0]
		}
		log.Printf("fileserver: peer name: '%s'\n", clientName)
		ms := util.NewMessageStream(conn)

		// TODO(tmroeder): support multiple simultaneous clients. This
		// requires, e.g., adding locking to the ResourceMaster.
		if err := m.RunMessageLoop(ms, policy); err != nil {
			log.Printf("fileserver: failed to run message loop: %s\n", err)
			continue
		}

		log.Println("Finished handling the client messages")
	}
}
func serve(serverAddr string, prin string, policyCert []byte, signingKey *tao.Keys, policy *fileproxy.ProgramPolicy, m *fileproxy.RollbackMaster) error {
	pc, err := x509.ParseCertificate(policyCert)
	if err != nil {
		return err
	}
	conf, err := signingKey.TLSServerConfig(pc)
	if err != nil {
		return err
	}
	log.Println("Rollback server listening")
	sock, err := tls.Listen("tcp", serverAddr, conf)
	if err != nil {
		return err
	}

	for {
		conn, err := sock.Accept()
		if err != nil {
			return err
		}
		var clientName string
		if err = conn.(*tls.Conn).Handshake(); err != nil {
			log.Println("TLS handshake failed")
			continue
		}

		peerCerts := conn.(*tls.Conn).ConnectionState().PeerCertificates
		if peerCerts == nil {
			log.Println("rollbackserver: can't get peer list")
			continue
		}

		peerCert := conn.(*tls.Conn).ConnectionState().PeerCertificates[0]
		if peerCert.Raw == nil {
			log.Println("rollbackserver: can't get peer name")
			continue
		}

		if peerCert.Subject.OrganizationalUnit == nil {
			log.Println("No OrganizationalUnit name in the peer certificate. Refusing the connection")
			continue
		}

		clientName = peerCert.Subject.OrganizationalUnit[0]
		ms := util.NewMessageStream(conn)
		// TODO(tmroeder): support multiple simultaneous clients.
		// Add this program as a rollback program.
		log.Printf("Adding a program with name '%s'\n", clientName)
		_ = m.AddRollbackProgram(clientName)
		if err := m.RunMessageLoop(ms, policy, clientName); err != nil {
			log.Printf("rollbackserver: failed to run message loop: %s\n", err)
		}
	}
}
Exemple #3
0
func SubmitAndInstall(keys *tao.Keys, csr *CSR) {
	verbose.Printf("Obtaining certificate from CA (may take a while)\n")
	resp, err := Submit(keys, csr)
	options.FailIf(err, "can't obtain X509 certificate from CA")
	if len(resp) == 0 {
		options.Fail(nil, "no x509 certificates returned from CA")
	}
	// Add the certs to our keys...
	keys.Cert["default"] = resp[0]
	for i, c := range resp {
		name := "ca"
		if i > 0 {
			name = fmt.Sprintf("ca-%d", i)
		}
		keys.Cert[name] = c
	}
	if keys.X509Path("default") != "" {
		err = keys.SaveCerts()
	}
	options.FailIf(err, "can't save X509 certificates")

	chain := keys.CertChain("default")
	verbose.Printf("Obtained certfificate chain of length %d:\n", len(chain))
	for i, cert := range chain {
		verbose.Printf("  Cert[%d] Subject: %s\n", i, x509txt.RDNString(cert.Subject))
	}
	if Warn {
		fmt.Println("Note: You may need to install root CA's key into the browser.")
	}
}
func doRequest(guard tao.Guard, domain *tao.Domain, keys *tao.Keys) bool {
	fmt.Printf("client: connecting to %s using %s authentication.\n", serverAddr, *demoAuth)
	var conn net.Conn
	var err error
	network := "tcp"

	switch *demoAuth {
	case "tcp":
		conn, err = net.Dial(network, serverAddr)
	case "tls":
		conf, err := keys.TLSClientConfig(nil)
		options.FailIf(err, "client: couldn't encode TLS keys")
		conn, err = tls.Dial(network, serverAddr, conf)
	case "tao":
		conn, err = tao.Dial(network, serverAddr, guard, domain.Keys.VerifyingKey, keys, nil)
	}
	if err != nil {
		fmt.Fprintf(os.Stderr, "client: error connecting to %s: %s\n", serverAddr, err.Error())
		return false
	}
	defer conn.Close()

	_, err = fmt.Fprintf(conn, "Hello\n")
	if err != nil {
		fmt.Fprintf(os.Stderr, "client: can't write: %s\n", err.Error())
		return false
	}
	msg, err := bufio.NewReader(conn).ReadString('\n')
	if err != nil {
		fmt.Fprintf(os.Stderr, "client: can't read: %s\n", err.Error())
		return false
	}
	msg = strings.TrimSpace(msg)
	fmt.Printf("client: got reply: %s\n", msg)
	return true
}
Exemple #5
0
// EstablishCert contacts a CA to get a certificate signed by the policy key. It
// replaces the current delegation and cert on k with the new delegation and
// cert from the response.
func EstablishCert(network, addr string, k *tao.Keys, v *tao.Verifier) error {
	na, err := tao.RequestAttestation(network, addr, k, v)
	if err != nil {
		return err
	}

	k.Delegation = na
	pa, err := auth.UnmarshalForm(na.SerializedStatement)
	if err != nil {
		return err
	}

	// Parse the received statement.
	var saysStatement *auth.Says
	if ptr, ok := pa.(*auth.Says); ok {
		saysStatement = ptr
	} else if val, ok := pa.(auth.Says); ok {
		saysStatement = &val
	}
	sf, ok := saysStatement.Message.(auth.Speaksfor)
	if ok != true {
		return errors.New("says doesn't have speaksfor message")
	}

	kprin, ok := sf.Delegate.(auth.Term)
	if ok != true {
		return errors.New("speaksfor message doesn't have Delegate")
	}
	newCert := auth.Bytes(kprin.(auth.Bytes))
	cert, err := x509.ParseCertificate(newCert)
	if err != nil {
		return err
	}
	k.Cert["default"] = cert

	return nil
}
func doServer() {
	var sock net.Listener
	var err error
	var keys *tao.Keys
	network := "tcp"
	domain, err := tao.LoadDomain(configPath(), nil)
	options.FailIf(err, "error: couldn't load the tao domain from %s\n", configPath())

	switch *demoAuth {
	case "tcp":
		sock, err = net.Listen(network, serverAddr)
		options.FailIf(err, "server: couldn't listen to the network")

	case "tls", "tao":
		// Generate a private/public key for this hosted program (hp) and
		// request attestation from the host of the statement "hp speaksFor
		// host". The resulting certificate, keys.Delegation, is a chain of
		// "says" statements extending to the policy key. The policy is
		// checked by the host before this program is executed.
		keys, err = tao.NewTemporaryTaoDelegatedKeys(tao.Signing, tao.Parent())
		options.FailIf(err, "server: failed to generate delegated keys")

		// Create a certificate for the hp.
		keys.Cert, err = keys.SigningKey.CreateSelfSignedX509(&pkix.Name{
			Organization: []string{"Google Tao Demo"}})
		options.FailIf(err, "server: couldn't create certificate")

		g := domain.Guard
		if *ca != "" {
			// Replace keys.Delegation with a "says" statement directly from
			// the policy key.
			na, err := tao.RequestTruncatedAttestation(network, *ca, keys, domain.Keys.VerifyingKey)
			options.FailIf(err, "server: truncated attestation request failed")
			keys.Delegation = na

			g, err = newTempCAGuard(domain.Keys.VerifyingKey)
			options.FailIf(err, "server: couldn't set up a new guard")
		}

		tlsc, err := tao.EncodeTLSCert(keys)
		options.FailIf(err, "server: couldn't encode TLS certificate")

		conf := &tls.Config{
			RootCAs:            x509.NewCertPool(),
			Certificates:       []tls.Certificate{*tlsc},
			InsecureSkipVerify: true,
			ClientAuth:         tls.RequireAnyClientCert,
		}

		if *demoAuth == "tao" {
			sock, err = tao.Listen(network, serverAddr, conf, g, domain.Keys.VerifyingKey, keys.Delegation)
			options.FailIf(err, "sever: couldn't create a taonet listener")
		} else {
			sock, err = tls.Listen(network, serverAddr, conf)
			options.FailIf(err, "server: couldn't create a tls listener")
		}
	}

	fmt.Printf("server: listening at %s using %s authentication.\n", serverAddr, *demoAuth)
	defer sock.Close()

	pings := make(chan bool, 5)
	connCount := 0

	go func() {
		for connCount = 0; connCount < *pingCount || *pingCount < 0; connCount++ { // negative means forever
			conn, err := sock.Accept()
			options.FailIf(err, "server: can't accept connection")
			go doResponse(conn, pings)
		}
	}()

	pingGood := 0
	pingFail := 0

	for {
		select {
		case ok := <-pings:
			if ok {
				pingGood++
			} else {
				pingFail++
			}
		}
	}
}
// First return is terminate flag.
func handleRequest(conn net.Conn, policyKey *tao.Keys, guard tao.Guard) error {
	// Expect an attestation from the client.
	ms := util.NewMessageStream(conn)
	var a tao.Attestation
	if err := ms.ReadMessage(&a); err != nil {
		return err
	}

	peerCert := conn.(*tls.Conn).ConnectionState().PeerCertificates[0]
	p, err := tao.ValidatePeerAttestation(&a, peerCert)
	if err != nil {
		return err
	}
	// TODO(kwalsh) most of this duplicates the work of tao.Conn
	if !guard.IsAuthorized(p, "Execute", nil) {
		return fmt.Errorf("peer is not authorized to execute, hence not authorized to connect either")
	}

	// Sign cert and put it in attestation statement
	// a consists of serialized statement, sig and SignerInfo
	// a is a says speaksfor, Delegate of speaksfor is cert and should be DER encoded

	// Get underlying says
	f, err := auth.UnmarshalForm(a.SerializedStatement)
	if err != nil {
		return err
	}

	var saysStatement *auth.Says
	if ptr, ok := f.(*auth.Says); ok {
		saysStatement = ptr
	} else if val, ok := f.(auth.Says); ok {
		saysStatement = &val
	}
	sf, ok := saysStatement.Message.(auth.Speaksfor)
	if ok != true {
		return fmt.Errorf("keynegoserver: says doesn't have a speaksfor message\n")
	}

	kprin, ok := sf.Delegate.(auth.Prin)
	if ok != true {
		return fmt.Errorf("keynegoserver: speaksfor Delegate is not auth.Prin\n")
	}
	subjectPrin, ok := sf.Delegator.(auth.Prin)
	if ok != true {
		return fmt.Errorf("keynegoserver: can't get subject principal\n")
	}
	subjectName := subjectPrin.String()
	details := &tao.X509Details{
		Country:            proto.String("US"),
		Organization:       proto.String("Google"),
		OrganizationalUnit: proto.String(subjectName),
		CommonName:         proto.String("localhost"),
	}
	subjectname := tao.NewX509Name(details)
	SerialNumber = SerialNumber + 1
	verifier, err := tao.FromPrincipal(kprin)
	if err != nil {
		return errors.New("can't get principal from kprin")
	}
	template := policyKey.SigningKey.X509Template(subjectname)
	template.IsCA = false
	clientCert, err := policyKey.CreateSignedX509(verifier, template, "default")
	if err != nil {
		return fmt.Errorf("keynegoserver: can't create client certificate: %s\n", err)
	}
	clientDERCert := clientCert.Raw
	err = ioutil.WriteFile("ClientCert", clientDERCert, os.ModePerm)

	nowTime := time.Now().UnixNano()
	expireTime := time.Now().AddDate(1, 0, 0).UnixNano()
	// Replace self signed cert in attest request
	newSpeaksFor := &auth.Speaksfor{
		Delegate:  auth.Bytes(clientDERCert),
		Delegator: sf.Delegator,
	}
	keyNegoSays := auth.Says{
		Speaker:    policyKey.SigningKey.ToPrincipal(),
		Time:       &nowTime,
		Expiration: &expireTime,
		Message:    newSpeaksFor,
	}

	delegator, ok := sf.Delegator.(auth.Prin)
	if !ok {
		return fmt.Errorf("keynegoserver: the delegator must be a principal")
	}
	found := false
	for _, sprin := range delegator.Ext {
		if !found && (sprin.Name == "Program") {
			found = true
		}
		if found {
			kprin.Ext = append(kprin.Ext, sprin)
		}
	}
	ra, err := tao.GenerateAttestation(policyKey.SigningKey, nil, keyNegoSays)
	if err != nil {
		return fmt.Errorf("Couldn't attest to the new says statement: %s", err)
	}

	if _, err := ms.WriteMessage(ra); err != nil {
		return fmt.Errorf("Couldn't return the attestation on the channel: %s", err)
	}

	return nil
}