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) } } }
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 }
// 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 }