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.")
	}
}
Example #3
0
// 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
}
Example #4
0
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())
}
Example #5
0
// 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
}
Example #7
0
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")
}
Example #8
0
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")
}
Example #12
0
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")
}
Example #13
0
// 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
}
Example #14
0
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")
}