github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/go/apps/newfileproxy/fileclient/fileclient.go (about)

     1  // Copyright (c) 2016, Google, Inc.,  All rights reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //     http://www.apache.org/licenses/LICENSE-2.0
     7  // Unless required by applicable law or agreed to in writing, software
     8  // distributed under the License is distributed on an "AS IS" BASIS,
     9  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    10  // See the License for the specific language governing permissions and
    11  // limitations under the License.
    12  //
    13  // File: fileclient.go
    14  
    15  package main
    16  
    17  import (
    18  	"bytes"
    19  	"crypto/rand"
    20  	"crypto/x509"
    21  	"flag"
    22  	"fmt"
    23  	"io/ioutil"
    24  	"path"
    25  
    26  	"github.com/golang/protobuf/proto"
    27  	taosupport "github.com/jlmucb/cloudproxy/go/support_libraries/tao_support"
    28  
    29  	"github.com/jlmucb/cloudproxy/go/apps/newfileproxy/common"
    30  	"github.com/jlmucb/cloudproxy/go/apps/newfileproxy/resourcemanager"
    31  )
    32  
    33  var caAddr = flag.String("caAddr", "localhost:8124", "The address to listen on")
    34  var simpleCfg = flag.String("domain_config",
    35  	"./tao.config",
    36  	"path to tao configuration")
    37  var fileClientPath = flag.String("path",
    38  	"./FileClient",
    39  	"path to FileClient files")
    40  var serverHost = flag.String("host", "localhost", "address for client/server")
    41  var serverPort = flag.String("port", "8123", "port for client/server")
    42  var useSimpleDomainService = flag.Bool("use_simpledomainservice", true,
    43  	"whether to use simple domain service")
    44  var serverAddr string
    45  
    46  func main() {
    47  
    48  	// This holds the cloudproxy specific data for fileclient
    49  	// including the Program Cert and Program Private key.
    50  	var clientProgramData taosupport.TaoProgramData
    51  
    52  	// Make sure we zero keys when we're done.
    53  	defer clientProgramData.ClearTaoProgramData()
    54  
    55  	// Parse flags
    56  	flag.Parse()
    57  	serverAddr = *serverHost + ":" + *serverPort
    58  
    59  	// If TaoParadigm completes without error, clientProgramData contains all the
    60  	// Cloudproxy information needed throughout fileclient execution.
    61  	err := taosupport.TaoParadigm(simpleCfg, fileClientPath,
    62  		*useSimpleDomainService, *caAddr, &clientProgramData)
    63  	if err != nil {
    64  		fmt.Printf("fileclient: Can't establish Tao: ", err)
    65  	}
    66  	fmt.Printf("newfileclient: TaoParadigm complete, name: %s\n",
    67  		clientProgramData.TaoName)
    68  
    69  	// Fill Client data
    70  	clientData := new(common.ClientData)
    71  	if clientData == nil {
    72  		fmt.Printf("fileclient: bad clientData init ")
    73  		return
    74  	}
    75  	certificate, err := x509.ParseCertificate(clientProgramData.PolicyCert)
    76  	if err != nil {
    77  		fmt.Printf("fileclient: bad ParseCertificate: ", err)
    78  		return
    79  	}
    80  	clientData.PolicyCert = certificate
    81  	// initialize user keys
    82  
    83  	// Get File Secrets
    84  	secretsFileName := path.Join(*fileClientPath, "FileSecrets.bin")
    85  
    86  	// fileSecrets is used to encrypt/decrypt client files.
    87  	fileSecrets := make([]byte, 48)
    88  
    89  	encryptedFileSecrets, err := ioutil.ReadFile(secretsFileName)
    90  	if err != nil {
    91  		rand.Read(fileSecrets)
    92  	} else {
    93  		fileSecrets, err = clientProgramData.ProgramCryptingKey.Decrypt(encryptedFileSecrets)
    94  		if err != nil {
    95  			fmt.Printf("fileclient: can't decrypt program key\n")
    96  			return
    97  		}
    98  	}
    99  
   100  	// Get User Certificates and Private keys
   101  	userKeysFileName := path.Join(*fileClientPath, "serialized_user_keys")
   102  	userKeyFile, err := ioutil.ReadFile(userKeysFileName)
   103  	if err != nil {
   104  		fmt.Printf("fileclient: bad user certs: ", err)
   105  		return
   106  	}
   107  	userKeys := new(common.UserKeysMessage)
   108  	err = proto.Unmarshal(userKeyFile, userKeys)
   109  	if err != nil {
   110  		fmt.Printf("fileclient: bad user certs unmarshal: ", err)
   111  		return
   112  	}
   113  
   114  	// Deserialize keys.
   115  	var UserKeyArray []common.KeyData
   116  	for i := 0; i < len(userKeys.SerializedKeys); i++ {
   117  		userKey, err := common.ParseUserKey(userKeys.SerializedKeys[i])
   118  		if err != nil {
   119  		}
   120  		certificate, err := x509.ParseCertificate(userKey.Cert)
   121  		if err != nil {
   122  		}
   123  		userKey.Certificate = certificate
   124  		UserKeyArray = append(UserKeyArray, *userKey)
   125  	}
   126  
   127  	// Open the Tao Channel using the Program key. This program does all the
   128  	// standard channel negotiation and presents the secure server name
   129  	// after negotiation is complete.
   130  	ms, serverName, err := taosupport.OpenTaoChannel(&clientProgramData, &serverAddr)
   131  	if err != nil {
   132  		fmt.Printf("fileclient: Can't establish Tao Channel")
   133  		return
   134  	}
   135  	fmt.Printf("fileclient: established Tao Channel with %s, %s\n",
   136  		serverAddr, serverName)
   137  
   138  	// Authenticate Principals
   139  	for i := 0; i < len(UserKeyArray); i++ {
   140  		err = common.RequestChallenge(ms, UserKeyArray[i])
   141  		if err != nil {
   142  			fmt.Printf("fileclient: common.RequestChallenge %d fails\n", i)
   143  			return
   144  		}
   145  	}
   146  	fmt.Printf("All common.RequestChallenge's succeeded\n")
   147  
   148  	// Create a directory.
   149  	err = common.Create(ms, "directory1", resourcemanager.ResourceType_DIRECTORY, UserKeyArray[0].Cert)
   150  	if err != nil {
   151  		fmt.Printf("fileclient: common.Create 1 fails\n")
   152  		return
   153  	}
   154  
   155  	// Create a file.
   156  	err = common.Create(ms, "directory1/file1", resourcemanager.ResourceType_FILE, UserKeyArray[0].Cert)
   157  	if err != nil {
   158  		fmt.Printf("fileclient: common.Create 2 fails\n")
   159  		return
   160  	}
   161  	fmt.Printf("Creates succeeded\n")
   162  
   163  	// Add a few owners, readers, writers
   164  	var newcerts [][]byte
   165  	newcerts = append(newcerts, UserKeyArray[1].Cert)
   166  	err = common.AddOwner(ms, "directory1/file1", newcerts)
   167  	if err != nil {
   168  		fmt.Printf("fileclient: common.AddOwner fails\n")
   169  		return
   170  	}
   171  	fmt.Printf("AddOwner succeeded\n")
   172  
   173  	newcerts = append(newcerts, UserKeyArray[2].Cert)
   174  	err = common.AddReader(ms, "directory1/file1", newcerts)
   175  	if err != nil {
   176  		fmt.Printf("fileclient: common.AddReader fails\n")
   177  		return
   178  	}
   179  	fmt.Printf("AddReader succeeded\n")
   180  
   181  	err = common.AddWriter(ms, "directory1/file1", newcerts)
   182  	if err != nil {
   183  		fmt.Printf("fileclient: common.AddWriter fails\n")
   184  		return
   185  	}
   186  	fmt.Printf("AddWriter succeeded\n")
   187  
   188  	// Write a resource.
   189  	file1Contents := []byte{1, 2, 3}
   190  	err = common.WriteResource(ms, "directory1/file1", file1Contents)
   191  	if err != nil {
   192  		fmt.Printf("fileclient: common.WriteResource fails\n")
   193  		return
   194  	}
   195  	fmt.Printf("common.WriteResource succeeded\n")
   196  
   197  	// Read a resource.
   198  	recoverdFile1Contents, err := common.ReadResource(ms, "directory1/file1")
   199  	if err != nil {
   200  		fmt.Printf("fileclient: common.ReadResource fails\n")
   201  		return
   202  	}
   203  	if bytes.Compare(file1Contents, recoverdFile1Contents) != 0 {
   204  		fmt.Printf("fileclient: written file differs from read file\n")
   205  	}
   206  	fmt.Printf("common.ReadResource succeeded\n")
   207  
   208  	// Tell Server to save state
   209  	err = common.SaveState(ms)
   210  	if err == nil {
   211  		fmt.Printf("common.SaveState succeeded\n")
   212  	} else {
   213  		fmt.Printf("common.SaveState failed\n")
   214  	}
   215  
   216  	// Encrypt and store the secret in fileclient's save area.
   217  	encryptedFileSecrets, err = clientProgramData.ProgramCryptingKey.Encrypt(fileSecrets)
   218  	if err != nil {
   219  		fmt.Printf("fileclient: Error protecting data\n")
   220  	}
   221  	err = ioutil.WriteFile(secretsFileName, encryptedFileSecrets, 0666)
   222  	if err != nil {
   223  		fmt.Printf("fileclient: error saving retrieved secret\n")
   224  	}
   225  	fmt.Printf("Secrets and table saved\n")
   226  
   227  	// Close down.
   228  	fmt.Printf("fileclient completes with no errors\n")
   229  }