// Establishes the Tao Channel for a client using the Program Key. // This program does all the standard client side channel negotiation. // After negotiation is complete. ms is the bi-directional confidentiality and // integrity protected channel. OpenTaoChannel returns the stream (ms) for subsequent reads // and writes as well as the server's Tao Principal Name. func OpenTaoChannel(programObject *TaoProgramData, serverAddr *string) ( *util.MessageStream, *string, error) { // Parse policy cert and make it the root of our // hierarchy for verifying Tao Channel peer. policyCert, err := x509.ParseCertificate(programObject.PolicyCert) if err != nil { return nil, nil, errors.New("OpenTaoChannel: Can't ParseCertificate") } pool := x509.NewCertPool() pool.AddCert(policyCert) // Open the Tao Channel using the Program key. tlsc, err := tao.EncodeTLSCert(&programObject.ProgramKey) if err != nil { log.Fatalln("OpenTaoChannel, encode error: ", err) } // TODO(manferdelli): Replace this with tao.Dial conn, err := tls.Dial("tcp", *serverAddr, &tls.Config{ RootCAs: pool, Certificates: []tls.Certificate{*tlsc}, InsecureSkipVerify: false, }) if err != nil { fmt.Printf("OpenTaoChannel: Can't establish channel ", err, "\n") return nil, nil, errors.New("OpenTaoChannel: Can't establish channel") } peerName := policyCert.Subject.OrganizationalUnit[0] // Stream for Tao Channel. ms := util.NewMessageStream(conn) return ms, &peerName, nil }
func main() { network := flag.String("network", "tcp", "The network to use for connections") addr := flag.String("addr", "localhost:8124", "The address to listen on") domainPass := flag.String("password", "nopassword", "The domain password for the policy key") configPath := flag.String("config", "tao.config", "The Tao domain config") flag.Parse() domain, err := tao.LoadDomain(*configPath, []byte(*domainPass)) if err != nil { log.Fatalf("keynegoserver: Couldn't load the config path %s: %s\n", *configPath, err) } // Set up temporary keys for the connection, since the only thing that // matters to the remote client is that they receive a correctly-signed new // attestation from the policy key. // JLM: I left this in place but I'm not sure what a TLS connection with a // self signed Cert buys in terms of security. The security of this protocol should // not depend on the confidentiality or intergity of the channel. All that said, // if we do ever distribute a signed keynegoserver cert for this TLS channel, it would // be good. keys, err := tao.NewTemporaryKeys(tao.Signing) if err != nil { log.Fatalln("keynegoserver: Couldn't set up temporary keys for the connection:", err) } keys.Cert, err = keys.SigningKey.CreateSelfSignedX509(&pkix.Name{ Organization: []string{"Google Tao Demo"}}) if err != nil { log.Fatalln("keynegoserver: Couldn't set up a self-signed cert:", err) } SerialNumber = int64(time.Now().UnixNano()) / (1000000) policyKey, err := tao.NewOnDiskPBEKeys(tao.Signing, []byte(*domainPass), "policy_keys", nil) if err != nil { log.Fatalln("keynegoserver: Couldn't get policy key:", err) } tlsc, err := tao.EncodeTLSCert(keys) if err != nil { log.Fatalln("keynegoserver: Couldn't encode a TLS cert:", err) } conf := &tls.Config{ RootCAs: x509.NewCertPool(), Certificates: []tls.Certificate{*tlsc}, InsecureSkipVerify: true, ClientAuth: tls.RequireAnyClientCert, } sock, err := tls.Listen(*network, *addr, conf) if err != nil { log.Printf("keynegoserver: error: %s", err) } defer sock.Close() for { conn, err := sock.Accept() if err != nil { log.Fatalln("keynegoserver: couldn't accept a connection:", err) } go handleRequest(conn, policyKey, domain.Guard) } }
// NewRouterContext generates new keys, loads a local domain configuration from // path and binds an anonymous listener socket to addr on network // network. A delegation is requested from the Tao t which is nominally // the parent of this hosted program. func NewRouterContext(path, network, addr string, batchSize int, timeout time.Duration, x509Identity *pkix.Name, t tao.Tao) (hp *RouterContext, err error) { hp = new(RouterContext) hp.network = network hp.timeout = timeout // Generate keys and get attestation from parent. if hp.keys, err = tao.NewTemporaryTaoDelegatedKeys(tao.Signing|tao.Crypting, t); err != nil { return nil, err } // Create a certificate. if hp.keys.Cert, err = hp.keys.SigningKey.CreateSelfSignedX509(x509Identity); err != nil { return nil, err } // Load domain from local configuration. if hp.domain, err = tao.LoadDomain(path, nil); err != nil { return nil, err } // Encode TLS certificate. cert, err := tao.EncodeTLSCert(hp.keys) if err != nil { return nil, err } tlsConfig := &tls.Config{ RootCAs: x509.NewCertPool(), Certificates: []tls.Certificate{*cert}, InsecureSkipVerify: true, ClientAuth: tls.NoClientCert, } // Bind address to socket. if hp.proxyListener, err = tao.ListenAnonymous(network, addr, tlsConfig, hp.domain.Guard, hp.domain.Keys.VerifyingKey, hp.keys.Delegation); err != nil { return nil, err } // Instantiate the queues. hp.sendQueue = NewQueue(network, batchSize, timeout) hp.replyQueue = NewQueue(network, batchSize, timeout) hp.killQueue = make(chan bool) hp.killQueueErrorHandler = make(chan bool) go hp.sendQueue.DoQueue(hp.killQueue) go hp.replyQueue.DoQueue(hp.killQueue) go hp.sendQueue.DoQueueErrorHandler(hp.replyQueue, hp.killQueueErrorHandler) go hp.replyQueue.DoQueueErrorHandlerLog("reply queue", hp.killQueueErrorHandler) return hp, nil }
// RequestDomainServiceCert requests the signed Program // Certificate from simpledomainservice. // TODO: This needs to change in a way that is tao supplier dependent. // For tpm2 we need the ekCert and the tao and we need the data // for ActivateCredential. // For tpm1.2, we need the aikCert. func RequestDomainServiceCert(network, addr string, requesting_key *tao.Keys, v *tao.Verifier) (*domain_policy.DomainCertResponse, error) { // Note requesting program key contains a self-signed cert to open channel. if requesting_key.Cert == nil { return nil, errors.New("RequestDomainServiceCert: Can't dial with an empty client certificate") } tlsCert, err := tao.EncodeTLSCert(requesting_key) if err != nil { return nil, err } conn, err := tls.Dial(network, addr, &tls.Config{ RootCAs: x509.NewCertPool(), Certificates: []tls.Certificate{*tlsCert}, InsecureSkipVerify: true, }) if err != nil { return nil, err } defer conn.Close() var request domain_policy.DomainCertRequest request.Attestation, err = proto.Marshal(requesting_key.Delegation) signer := requesting_key.SigningKey.GetSigner() if signer == nil { return nil, err } key_type := "ECDSA" request.KeyType = &key_type request.SubjectPublicKey, err = domain_policy.GetPublicDerFromEcdsaKey(&signer.PublicKey) if err != nil { return nil, err } // Tao handshake: send client delegation. ms := util.NewMessageStream(conn) _, err = ms.WriteMessage(&request) if err != nil { return nil, err } // Read the new cert var response domain_policy.DomainCertResponse err = ms.ReadMessage(&response) if err != nil { return nil, err } return &response, nil }
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 } pool := x509.NewCertPool() pool.AddCert(pc) tlsc, err := tao.EncodeTLSCert(signingKey) if err != nil { return err } conf := &tls.Config{ RootCAs: pool, Certificates: []tls.Certificate{*tlsc}, InsecureSkipVerify: false, ClientAuth: tls.RequireAnyClientCert, } 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) } } }
// This is the server. It implements the server Tao Channel negotiation corresponding // to the client's taosupport.OpenTaoChannel. It's possible we should move this into // taosupport/taosupport.go since it should not vary very much from implementation to // implementation. func server(serverAddr string, serverProgramData *taosupport.TaoProgramData) { var sock net.Listener // Set up the single root certificate for channel negotiation which is the // policy key cert. pool := x509.NewCertPool() policyCert, err := x509.ParseCertificate(serverProgramData.PolicyCert) if err != nil { log.Printf("simpleserver, can't parse policyCert: ", err, "\n") return } // Make the policy cert the unique root of the verification chain. pool.AddCert(policyCert) tlsc, err := tao.EncodeTLSCert(&serverProgramData.ProgramKey) if err != nil { log.Printf("simpleserver, encode error: ", err, "\n") return } conf := &tls.Config{ RootCAs: pool, Certificates: []tls.Certificate{*tlsc}, InsecureSkipVerify: false, ClientAuth: tls.RequireAnyClientCert, } // Listen for clients. log.Printf("simpleserver: Listening\n") sock, err = tls.Listen("tcp", serverAddr, conf) if err != nil { log.Printf("simpleserver, listen error: ", err, "\n") return } // Service client connections. for { log.Printf("server: at accept\n") conn, err := sock.Accept() if err != nil { fmt.Printf("simpleserver: can't accept connection: %s\n", err.Error()) log.Printf("server: can't accept connection: %s\n", err.Error()) continue } var clientName string err = conn.(*tls.Conn).Handshake() if err != nil { log.Printf("server: TLS handshake failed\n") continue } peerCerts := conn.(*tls.Conn).ConnectionState().PeerCertificates if peerCerts == nil { log.Printf("server: can't get peer list\n") continue } peerCert := conn.(*tls.Conn).ConnectionState().PeerCertificates[0] if peerCert.Raw == nil { log.Printf("server: can't get peer cert\n") continue } if peerCert.Subject.OrganizationalUnit == nil { log.Printf("server: can't get peer name\n") continue } clientName = peerCert.Subject.OrganizationalUnit[0] log.Printf("server, peer client name: %s\n", clientName) ms := util.NewMessageStream(conn) // At this point the handshake is complete and we fork a service thread // to communicate with this simpleclient. ms is the bi-directional // confidentiality and integrity protected channel corresponding to the // channel opened by OpenTaoChannel. go serviceThead(ms, clientName, serverProgramData) } }
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 } pool := x509.NewCertPool() pool.AddCert(policyCert) tlsc, err := tao.EncodeTLSCert(signingKey) if err != nil { return err } conf := &tls.Config{ RootCAs: pool, Certificates: []tls.Certificate{*tlsc}, InsecureSkipVerify: false, ClientAuth: tls.RequireAnyClientCert, } 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 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++ } } } }
func main() { flag.Parse() domain, err := tao.LoadDomain(*configPath, []byte(*domainPass)) if domain == nil { log.Printf("simpledomainservice: no domain path - %s, pass - %s, err - %s\n", *configPath, *domainPass, err) return } else if err != nil { log.Printf("simpledomainservice: Couldn't load the config path %s: %s\n", *configPath, err) return } log.Printf("simpledomainservice: Loaded domain\n") // Set up temporary keys for the connection, since the only thing that // matters to the remote client is that they receive a correctly-signed new // attestation from the policy key. // JLM: I left this in place but I'm not sure what a TLS connection with a // self signed Cert buys in terms of security. // The security of this protocol should not depend on the // confidentiality or intergity of the channel. All that said, if we // do ever distribute a signed simpledomainservice cert // for this TLS channel, it would be good. keys, err := tao.NewTemporaryKeys(tao.Signing) if keys == nil || err != nil { log.Fatalln("simpledomainservice: Couldn't set up temporary keys for connection:", err) return } keys.Cert, err = keys.SigningKey.CreateSelfSignedX509(&pkix.Name{ Organization: []string{"Google Tao Demo"}}) if err != nil { log.Fatalln("simpledomainservice: Couldn't set up a self-signed cert:", err) return } SerialNumber = int64(time.Now().UnixNano()) / (1000000) policyKey := domain.Keys fmt.Printf("\nSimpleDomainService: policyKey: %x\n", policyKey) tlsc, err := tao.EncodeTLSCert(keys) if err != nil { log.Fatalln("simpledomainservice: Couldn't encode a TLS cert:", err) } conf := &tls.Config{ RootCAs: x509.NewCertPool(), Certificates: []tls.Certificate{*tlsc}, InsecureSkipVerify: true, ClientAuth: tls.RequireAnyClientCert, } sock, err := tls.Listen(*network, *addr, conf) if err != nil { log.Printf("simpledomainservice: error: %s\n", err) } if sock == nil { log.Printf("simpledomainservice: Empty socket, terminating\n") return } defer sock.Close() log.Printf("simpledomainservice: accepting connections\n") fmt.Printf("\n\nsimpledomainservice: accepting connections\n") for { conn, err := sock.Accept() if conn == nil { fmt.Printf("simpledomainservice: Empty connection\n") log.Printf("simpledomainservice: Empty connection\n") return } else if err != nil { fmt.Printf("simpledomainservice: Couldn't accept a connection on %s: %s\n", *addr, err) log.Printf("simpledomainservice: Couldn't accept a connection on %s: %s\n", *addr, err) return } go DomainRequest(conn, policyKey, domain.Guard) } log.Printf("simpledomainservice: finishing\n") }
func main() { caAddr := flag.String("caAddr", "localhost:8124", "The address of the CA for setting up a certificate signed by the policy key") hostcfg := flag.String("hostconfig", "tao.config", "path to host tao configuration") serverHost := flag.String("host", "localhost", "address for client/server") serverPort := flag.String("port", "8123", "port for client/server") rollbackServerHost := flag.String("rollbackhost", "localhost", "address for rollback client/server") rollbackServerPort := flag.String("rollbackport", "8129", "port for client/server") fileClientPassword := flag.String("password", "BogusPass", "A password for unlocking the user certificates") fileClientPath := flag.String("fileclient_files", "fileclient_files", "fileclient directory") fileClientFilePath := flag.String("stored_files", "fileclient_files/stored_files", "fileclient file directory") testFile := flag.String("test_file", "originalTestFile", "test file") fileClientKeyPath := flag.String("usercreds", "usercreds", "user keys and certs") country := flag.String("country", "US", "The country for the fileclient certificate") org := flag.String("organization", "Google", "The organization for the fileclient certificate") flag.Parse() serverAddr := net.JoinHostPort(*serverHost, *serverPort) hostDomain, err := tao.LoadDomain(*hostcfg, nil) if err != nil { log.Fatalln("fileclient: Can't load domain") } var derPolicyCert []byte if hostDomain.Keys.Cert != nil { derPolicyCert = hostDomain.Keys.Cert.Raw } if derPolicyCert == nil { log.Fatalln("fileclient: Can't retrieve policy cert") } parentTao := tao.Parent() if err := hostDomain.ExtendTaoName(parentTao); err != nil { log.Fatalln("fileclient: can't extend the Tao with the policy key") } e := auth.PrinExt{Name: "fileclient_version_1"} if err = parentTao.ExtendTaoName(auth.SubPrin{e}); err != nil { log.Fatalln("fileclient: couldn't extend the tao name with the policy key") } taoName, err := parentTao.GetTaoName() if err != nil { log.Fatalln("fileclient: Can't get tao name") } // Create or read the keys for fileclient. fcKeys, err := tao.NewOnDiskTaoSealedKeys(tao.Signing|tao.Crypting, parentTao, *fileClientPath, tao.SealPolicyDefault) if err != nil { log.Fatalln("fileclient: couldn't set up the Tao-sealed keys:", err) } // Set up a temporary cert for communication with keyNegoServer. fcKeys.Cert, err = fcKeys.SigningKey.CreateSelfSignedX509(tao.NewX509Name(&tao.X509Details{ Country: proto.String(*country), Organization: proto.String(*org), CommonName: proto.String(taoName.String()), })) if err != nil { log.Fatalln("fileclient: couldn't create a self-signed cert for fileclient keys:", err) } // Contact keyNegoServer for the certificate. if err := fileproxy.EstablishCert("tcp", *caAddr, fcKeys, hostDomain.Keys.VerifyingKey); err != nil { log.Fatalf("fileclient: couldn't establish a cert signed by the policy key: %s", err) } // Get the policy cert and set up TLS. pool := x509.NewCertPool() pool.AddCert(hostDomain.Keys.Cert) tlsc, err := tao.EncodeTLSCert(fcKeys) if err != nil { log.Fatalln("fileclient, encode error: ", err) } conn, err := tls.Dial("tcp", serverAddr, &tls.Config{ RootCAs: pool, Certificates: []tls.Certificate{*tlsc}, InsecureSkipVerify: false, }) if err != nil { log.Fatalln("fileclient: can't establish channel: ", err) } ms := util.NewMessageStream(conn) // Before doing any tests, create a simple file to send to the server. testContents := ` This is a simple file to test It has some new lines And it doesn't have very much content. ` if _, err := os.Stat(*fileClientFilePath); err != nil { if err := os.MkdirAll(*fileClientFilePath, 0700); err != nil { log.Fatalf("fileclient: couldn't create the file storage path %s: %s", *fileClientFilePath, err) } } sentFileName := *testFile sentFilePath := path.Join(*fileClientFilePath, sentFileName) if err := ioutil.WriteFile(sentFilePath, []byte(testContents), 0600); err != nil { log.Fatalf("fileclient: couldn't create a test file at %s: %s", sentFilePath, err) } // Authenticate user principal(s). if _, err := os.Stat(*fileClientKeyPath); err != nil { log.Fatalf("fileclient: couldn't get user credentials from %s: %s\n", *fileClientKeyPath, err) } // This method won't generate the right certificate in general for // signing, which is why we check first to make sure the right directory // already exists. But it will successfully read the signer and the // certificate. userKeys, err := tao.NewOnDiskPBEKeys(tao.Signing, []byte(*fileClientPassword), *fileClientKeyPath, nil) if err != nil { log.Fatalf("Couldn't read the keys from %s: %s\n", *fileClientKeyPath, err) } userCert := userKeys.Cert.Raw // Authenticate a key to use for requests to the server. if err = fileproxy.AuthenticatePrincipal(ms, userKeys, userCert); err != nil { log.Fatalf("fileclient: can't authenticate principal: %s", err) } // Create a file. if err = fileproxy.CreateFile(ms, userCert, sentFileName); err != nil { log.Fatalln("fileclient: can't create file:", err) } // Send File. if err = fileproxy.WriteFile(ms, userCert, *fileClientFilePath, sentFileName); err != nil { log.Fatalf("fileclient: couldn't write the file %s to the server: %s", sentFileName, err) } // Get file. outputFileName := sentFileName + ".out" if err = fileproxy.ReadFile(ms, userCert, *fileClientFilePath, sentFileName, outputFileName); err != nil { log.Fatalf("fileclient: couldn't get file %s to output file %s: %s", sentFileName, outputFileName, err) } // TODO(tmroeder): compare the received file against the sent file. // Set up a TLS connection to the rollback server, just like the one to // the file server. rollbackServerAddr := net.JoinHostPort(*rollbackServerHost, *rollbackServerPort) rbconn, err := tls.Dial("tcp", rollbackServerAddr, &tls.Config{ RootCAs: pool, Certificates: []tls.Certificate{*tlsc}, InsecureSkipVerify: false, }) if err != nil { log.Fatalf("fileclient: can't establish rollback channel: %s", err) } newms := util.NewMessageStream(rbconn) // Create a fake hash value, and set this value for an item. hashLen := 32 hash := make([]byte, hashLen) if _, err := rand.Read(hash); err != nil { log.Fatalf("fileclient: failed to read a random value for the hash") } progName := taoName.String() resName := "test_resource" if err := fileproxy.SetHash(newms, resName, hash); err != nil { log.Fatalf("Couldn't set the hash for program '%s', resource '%s', hash % x on the remote server: %s", progName, resName, hash, err) } // Set the counter to 10 and check that we get the same value back. if err := fileproxy.SetCounter(newms, uint64(10)); err != nil { log.Fatalf("fileclient: couldn't set the counter in the file client") } c, err := fileproxy.GetCounter(newms) if err != nil { log.Fatalf("fileclient: couldn't get the value of the counter from the rollback server") } // Get the hash verification value. newHash, err := fileproxy.GetHashedVerifier(newms, resName) if err != nil { log.Fatalf("fileclient: couldn't get the hashed verifier from the rollback server") } // Try to recompute the hashed verifier directly to see if it matches. sh := sha256.New() vi := fileproxy.EncodeCounter(c) sh.Write(vi) sh.Write(hash) sh.Write(vi) computed := sh.Sum(nil) if subtle.ConstantTimeCompare(newHash, computed) != 1 { log.Fatalf("fileclient: the hashed verifier % x returned by the server didn't match the value % x computed locally", newHash, computed) } log.Println("All fileclient tests pass") }