func TestProcessDirectiveAndUpdateGuard(t *testing.T) { domain := setUpDomain(t) err := domain.Guard.Authorize(Delegator, OwnPredicate, []string{ProtectedObjectId.String()}) failOnError(t, err) programKey, err := tao.NewTemporaryKeys(tao.Signing) failOnError(t, err) info := x509Info speakerStr := Delegator.String() info.CommonName = &speakerStr subject := tao.NewX509Name(&info) programKey.Cert, err = domain.Keys.SigningKey.CreateSignedX509( domain.Keys.Cert, 1, programKey.SigningKey.GetVerifier(), subject) failOnError(t, err) directive, err := CreateSecretDisclosureDirective(programKey, &Delegator, &Delegate, ReadPredicate, &ProtectedObjectId) failOnError(t, err) directive.Cert = programKey.Cert.Raw err = ProcessDirectiveAndUpdateGuard(domain, directive) failOnError(t, err) if !domain.Guard.IsAuthorized(Delegate, ReadPredicate, []string{ProtectedObjectId.String()}) { t.Fatal("Domain guard not updated as expected.") } tearDown(t) }
func TestCreateAndVerifyDirectiveSignedByProgram(t *testing.T) { policyKey, _, err := generatePolicyKeyAndSignedDirective(Params{}) programKey, err := tao.NewTemporaryKeys(tao.Signing) failOnError(t, err) info := x509Info speakerStr := Delegator.String() info.CommonName = &speakerStr subject := tao.NewX509Name(&info) programKey.Cert, err = policyKey.SigningKey.CreateSignedX509( policyKey.Cert, 1, programKey.SigningKey.GetVerifier(), subject) failOnError(t, err) directive, err := CreateSecretDisclosureDirective(programKey, &Delegator, &Delegate, ReadPredicate, &ProtectedObjectId) failOnError(t, err) directive.Cert = programKey.Cert.Raw speaker, prog, pred, pobj, err := VerifySecretDisclosureDirective(policyKey, directive) failOnError(t, err) if !speaker.Identical(Delegator) { t.Fatal(fmt.Sprintf("verify returns Speaker %v different from expected value %v", speaker, Delegator)) } if !prog.Identical(Delegate) { t.Fatal(fmt.Sprintf("verify returns program %v different from expected value %v", prog, Delegate)) } if *pred != ReadPredicate { t.Fatal(fmt.Sprintf("verify returns predicate %v different from expected value %v", pred, ReadPredicate)) } if *pobj.ObjName != *ProtectedObjectId.ObjName || *pobj.ObjEpoch != *ProtectedObjectId.ObjEpoch { t.Fatal("Verify returns different protectedObjectId from expected value.") } }
// This function generates a Program Certificate. In particular, it generates an attestation // signed by the domain policy key, with a statement of the form // 'policyKey says programCert speaksFor program' // where programCert is a X509 cert signed by the policy key with subject CommonName being the // Tao name of the program and subject public key being programKey. // Certificate expiration time is one year from issuing time. func GenerateProgramCert(domain *tao.Domain, serialNumber int, programPrin *auth.Prin, verifier *tao.Verifier, now, expiry time.Time) (*x509.Certificate, error) { policyCert := domain.Keys.Cert x509Info := domain.Config.GetX509Info() programName := programPrin.String() x509Info.CommonName = &programName x509Info.OrganizationalUnit = &programName subjectName := tao.NewX509Name(x509Info) clientCert, err := domain.Keys.SigningKey.CreateSignedX509( policyCert, serialNumber, verifier, subjectName) if err != nil { return nil, err } return clientCert, nil }
func createSoftTaoKeys() { dt := template() args := flag.Args() if len(args) != 1 { options.Usage("Must supply a path for the new key set") } keypath := args[0] pwd := getKey("soft tao key password", "soft_pass") k, err := tao.NewOnDiskPBEKeys(tao.Signing|tao.Crypting|tao.Deriving, pwd, keypath, tao.NewX509Name(dt.Config.X509Info)) options.FailIf(err, "Can't create keys") fmt.Println(k.VerifyingKey.ToPrincipal()) }
// Create a Program Public/Private key. func CreateSigningKey(t tao.Tao) (*tao.Keys, []byte, error) { self, err := t.GetTaoName() k, err := tao.NewTemporaryKeys(tao.Signing) if k == nil || err != nil { return nil, nil, errors.New("Can't generate signing key") } publicString := strings.Replace(self.String(), "(", "", -1) publicString = strings.Replace(publicString, ")", "", -1) // publicString is now a canonicalized Tao Principal name us := "US" google := "Google" details := tao.X509Details{ Country: &us, Organization: &google, CommonName: &publicString} subjectname := tao.NewX509Name(&details) derCert, err := k.SigningKey.CreateSelfSignedDER(subjectname) if err != nil { return nil, nil, errors.New("Can't self sign cert\n") } cert, err := x509.ParseCertificate(derCert) if err != nil { return nil, nil, err } // Construct statement: "ProgramKey (new key) speaksfor Principal Name" // ToPrincipal retrieves key's Tao Principal Name. k.Cert = cert s := &auth.Speaksfor{ Delegate: k.SigningKey.ToPrincipal(), Delegator: self} if s == nil { return nil, nil, errors.New("Can't produce speaksfor") } // Sign attestation statement k.Delegation, err = t.Attest(&self, nil, nil, s) if err != nil { return nil, nil, err } _, _ = auth.UnmarshalForm(k.Delegation.SerializedStatement) return k, derCert, nil }
func generatePolicyKey(t *testing.T) (*tao.Keys, *x509.Certificate) { k, err := tao.NewTemporaryKeys(tao.Signing) if k == nil || err != nil { t.Fatal("Can't generate signing key") } us := "US" google := "Google" subjectName := "Policy" details := tao.X509Details{ Country: &us, Organization: &google, CommonName: &subjectName} subjectname := tao.NewX509Name(&details) cert, err := k.SigningKey.CreateSelfSignedX509(subjectname) if err != nil { t.Fatal("Can't self sign cert\n") } return k, cert }
func createUserKeys() { // Read the X509Details for this user from a text protobuf file. userKeyDetails := *options.String["user_key_details"] xdb, err := ioutil.ReadFile(userKeyDetails) options.FailIf(err, "Can't read user details") var xd tao.X509Details err = proto.UnmarshalText(string(xdb), &xd) options.FailIf(err, "Can't parse user details: %s", userKeyDetails) upwd := getKey("user password", "user_pass") pwd := getKey("domain policy key password", "pass") domain, err := tao.LoadDomain(configPath(), pwd) options.FailIf(err, "Can't load domain") policyKey := domain.Keys subjectName := tao.NewX509Name(&xd) userKeyPath := *options.String["user_key_path"] _, err = tao.NewSignedOnDiskPBEKeys(tao.Signing, upwd, userKeyPath, subjectName, int(xd.GetSerialNumber()), policyKey) options.FailIf(err, "Can't create user signing key") }
func generateEndorsementCertficate(policyKey *tao.Keys, policyCert *x509.Certificate) (*tao.Keys, *x509.Certificate) { k, err := tao.NewTemporaryKeys(tao.Signing) if k == nil || err != nil { log.Fatalln("Can't generate signing key") } us := "US" google := "Google" machineName := "Encoded Machine Information" details := tao.X509Details{ Country: &us, Organization: &google, CommonName: &machineName} subject := tao.NewX509Name(&details) cert, err := policyKey.SigningKey.CreateSignedX509( policyCert, 0, k.SigningKey.GetVerifier(), subject) if err != nil { log.Fatalln(err) } return k, cert }
func generateEndorsementCertficate(t *testing.T, policyKey *tao.Keys, hwPublicKey *rsa.PublicKey, policyCert *x509.Certificate) *x509.Certificate { us := "US" google := "Google" details := tao.X509Details{ Country: &us, Organization: &google, CommonName: &machineName} subject := tao.NewX509Name(&details) signTemplate := tao.PrepareX509Template(subject) derSignedCert, err := x509.CreateCertificate(rand.Reader, signTemplate, policyCert, hwPublicKey, policyKey.SigningKey.GetSigner()) if err != nil { t.Fatal(err) } cert, err := x509.ParseCertificate(derSignedCert) if err != nil { t.Fatal(err) } return cert }
func generatePolicyKeyAndSignedDirective(params Params) (*tao.Keys, *DirectiveMessage, error) { var programName auth.Term if params.Delegate != nil { programName = params.Delegate } else { programName = Delegate } var serializedObjectId auth.Term if params.SerializedObjectId != nil { serializedObjectId = params.SerializedObjectId } else { bytes, err := proto.Marshal(&ProtectedObjectId) if err != nil { return nil, nil, err } serializedObjectId = auth.Bytes(bytes) } terms := []auth.Term{programName, serializedObjectId} if params.CanReadTerms != nil { terms = params.CanReadTerms } var canRead auth.Form if params.CanRead != nil { canRead = params.CanRead } else { canRead = auth.Pred{ Name: ReadPredicate, Arg: terms, } } policyKey, err := tao.NewTemporaryKeys(tao.Signing) if err != nil { return nil, nil, err } info := x509Info name := policyKey.SigningKey.ToPrincipal().String() info.CommonName = &name subject := tao.NewX509Name(&info) policyKey.Cert, err = policyKey.SigningKey.CreateSelfSignedX509(subject) if err != nil { return nil, nil, err } var says auth.Form if params.Says != nil { says = params.Says } else { says = auth.Says{ Speaker: policyKey.SigningKey.ToPrincipal(), Time: nil, Expiration: nil, Message: canRead, } } serializedSays := auth.Marshal(says) var directiveType *DirectiveMessageDirectiveType if params.DirectiveType != nil { directiveType = params.DirectiveType } else { directiveType = DirectiveMessage_SECRET_DISCLOSURE.Enum() } var signature []byte if params.Signature != nil { signature = params.Signature } else { signature, err = policyKey.SigningKey.Sign(serializedSays, SigningContext) if err != nil { return nil, nil, err } } var signer []byte if params.Signer != nil { signer = params.Signer } else { signer = auth.Marshal(policyKey.SigningKey.ToPrincipal()) } directive := &DirectiveMessage{ Type: directiveType, SerializedStatement: serializedSays, Signature: signature, Signer: signer, } return policyKey, directive, nil }
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", "8129", "port for client/server") rollbackServerPath := flag.String("rollbackserver_files", "rollbackserver_files", "rollbackserver directory") 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("rollbackserver: can't load domain:", err) } var policyCert []byte if hostDomain.Keys.Cert != nil { policyCert = hostDomain.Keys.Cert.Raw } if policyCert == nil { log.Fatalln("rollbackserver: can't retrieve policy cert") } parentTao := tao.Parent() if err := hostDomain.ExtendTaoName(parentTao); err != nil { log.Fatalln("fileserver: can't extend the Tao with the policy key") } e := auth.PrinExt{Name: "rollbackserver_version_1"} if err = parentTao.ExtendTaoName(auth.SubPrin{e}); err != nil { log.Fatalln("rollbackserver: can't extend name") } taoName, err := parentTao.GetTaoName() if err != nil { return } // Create or read the keys for rollbackserver. rbKeys, err := tao.NewOnDiskTaoSealedKeys(tao.Signing|tao.Crypting, parentTao, *rollbackServerPath, tao.SealPolicyDefault) if err != nil { log.Fatalln("rollbackserver: couldn't set up the Tao-sealed keys:", err) } // Set up a temporary cert for communication with keyNegoServer. rbKeys.Cert, err = rbKeys.SigningKey.CreateSelfSignedX509(tao.NewX509Name(&tao.X509Details{ Country: proto.String(*country), Organization: proto.String(*org), CommonName: proto.String(taoName.String()), })) if err != nil { log.Fatalln("rollbackserver: couldn't create a self-signed cert for rollbackserver keys:", err) } // Contact keyNegoServer for the certificate. if err := fileproxy.EstablishCert("tcp", *caAddr, rbKeys, hostDomain.Keys.VerifyingKey); err != nil { log.Fatalf("rollbackserver: couldn't establish a cert signed by the policy key: %s", err) } // The symmetric keys aren't used by the rollback server. progPolicy := fileproxy.NewProgramPolicy(policyCert, taoName.String(), rbKeys, nil, rbKeys.Cert.Raw) m := fileproxy.NewRollbackMaster(taoName.String()) if err := serve(serverAddr, taoName.String(), policyCert, rbKeys, progPolicy, m); err != nil { log.Fatalf("rollbackserver: server error: %s\n", err) } log.Println("rollbackserver: done") }
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") fileServerPath := flag.String("fileserver_files", "fileserver_files/", "fileserver directory") fileServerFilePath := flag.String("stored_files", "fileserver_files/stored_files/", "fileserver directory") 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("fileserver: can't LoadDomain") } var policyCert []byte if hostDomain.Keys.Cert != nil { policyCert = hostDomain.Keys.Cert.Raw } if policyCert == nil { log.Fatalln("fileserver: can't retrieve policy cert") } parentTao := tao.Parent() if err := hostDomain.ExtendTaoName(parentTao); err != nil { log.Fatalln("fileserver: can't extend the Tao with the policy key") } e := auth.PrinExt{Name: "fileserver_version_1"} if err = parentTao.ExtendTaoName(auth.SubPrin{e}); err != nil { log.Fatalln("fileserver: couldn't extend the Tao name") } taoName, err := parentTao.GetTaoName() if err != nil { log.Fatalln("fileserver: couldn't get tao name") } // Create or read the keys for fileclient. fsKeys, err := tao.NewOnDiskTaoSealedKeys(tao.Signing|tao.Crypting, parentTao, *fileServerPath, tao.SealPolicyDefault) if err != nil { log.Fatalln("fileserver: couldn't set up the Tao-sealed keys:", err) } // Set up a temporary cert for communication with keyNegoServer. fsKeys.Cert, err = fsKeys.SigningKey.CreateSelfSignedX509(tao.NewX509Name(&tao.X509Details{ Country: proto.String(*country), Organization: proto.String(*org), CommonName: proto.String(taoName.String()), })) if err != nil { log.Fatalln("fileserver: couldn't create a self-signed cert for fileclient keys:", err) } // Contact keyNegoServer for the certificate. if err := fileproxy.EstablishCert("tcp", *caAddr, fsKeys, hostDomain.Keys.VerifyingKey); err != nil { log.Fatalf("fileserver: couldn't establish a cert signed by the policy key: %s", err) } symKeysPath := path.Join(*fileServerPath, "sealedEncKeys") symKeys, err := fsKeys.NewSecret(symKeysPath, fileproxy.SymmetricKeySize) if err != nil { log.Fatalln("fileserver: couldn't get the file encryption keys") } tao.ZeroBytes(symKeys) progPolicy := fileproxy.NewProgramPolicy(policyCert, taoName.String(), fsKeys, symKeys, fsKeys.Cert.Raw) // Set up the file storage path if it doesn't exist. if _, err := os.Stat(*fileServerFilePath); err != nil { if err := os.MkdirAll(*fileServerFilePath, 0700); err != nil { log.Fatalln("fileserver: couldn't create a file storage directory:", err) } } if err := serve(serverAddr, *fileServerFilePath, policyCert, fsKeys, progPolicy); err != nil { log.Fatalln("fileserver: couldn't serve connections:", err) } log.Printf("fileserver: done\n") }
// 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 }
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["default"] != nil { derPolicyCert = hostDomain.Keys.Cert["default"].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. // Set up a temporary cert for communication with keyNegoServer. // TODO(kwalsh) This may no longer be needed. Is there a significance to // this cert? name := tao.NewX509Name(&tao.X509Details{ Country: proto.String(*country), Organization: proto.String(*org), CommonName: proto.String(taoName.String()), }) fcKeys, err := tao.NewOnDiskTaoSealedKeys(tao.Signing|tao.Crypting, name, parentTao, *fileClientPath, tao.SealPolicyDefault) if err != nil { log.Fatalln("fileclient: couldn't set up the Tao-sealed keys:", err) } 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. conf, err := fcKeys.TLSClientConfig(hostDomain.Keys.Cert["default"]) if err != nil { log.Fatalln("fileclient, encode error: ", err) } conn, err := tls.Dial("tcp", serverAddr, conf) 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["default"].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, conf) 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") }