github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/go/support_infrastructure/secret_service/secret_service_test.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  package secret_service
    14  
    15  import (
    16  	"bytes"
    17  	"container/list"
    18  	"fmt"
    19  	"os"
    20  	"testing"
    21  
    22  	"github.com/jlmucb/cloudproxy/go/support_libraries/protected_objects"
    23  	"github.com/jlmucb/cloudproxy/go/tao"
    24  	"github.com/jlmucb/cloudproxy/go/tao/auth"
    25  )
    26  
    27  var epoch = int32(1)
    28  
    29  var rootName = "RootName"
    30  var rootKey []byte
    31  var rootId *protected_objects.ObjectIdMessage
    32  
    33  var name = "KeyName"
    34  var secretType = "key"
    35  var value = []byte("I am a key.")
    36  
    37  var domain *tao.Domain
    38  var encKey *tao.Keys
    39  
    40  var authorizedPrin = &auth.Prin{
    41  	Type: "program",
    42  	KeyHash:  auth.Str("AuthorizedProgram"),
    43  	Ext:  []auth.PrinExt{}}
    44  
    45  var unAuthorizedPrin = &auth.Prin{
    46  	Type: "program",
    47  	KeyHash:  auth.Str("UnAuthorizedProgram"),
    48  	Ext:  []auth.PrinExt{}}
    49  
    50  func TestReadObject(t *testing.T) {
    51  	setUpDomain(t)
    52  	l := list.New()
    53  	l.PushFront(createRootKey(t))
    54  	obj := createObject(name, epoch, value, secretType)
    55  	protected_objects.PrintObject(obj)
    56  	pObj, err := protected_objects.MakeProtectedObject(*obj, rootName, epoch, rootKey)
    57  	failOnError(t, err)
    58  	l.PushFront(*pObj)
    59  	protected_objects.PrintProtectedObject(pObj)
    60  
    61  	err = domain.Guard.Authorize(*authorizedPrin, "READ", []string{obj.ObjId.String()})
    62  	failOnError(t, err)
    63  
    64  	typ, val, err := ReadObject(l, encKey, obj.ObjId, authorizedPrin, domain)
    65  	failOnError(t, err)
    66  	if *typ != secretType {
    67  		t.Fatal("Object type read does not match expected type.")
    68  	}
    69  	if !bytes.Equal(val, value) {
    70  		t.Fatal("Object value read does not match expected value.")
    71  	}
    72  
    73  	_, _, err = ReadObject(l, encKey, createObjectId("Not there", int32(0)),
    74  		authorizedPrin, domain)
    75  	if err == nil {
    76  		t.Fatal("Reading for a missing object returned nil error.")
    77  	}
    78  
    79  	_, _, err = ReadObject(list.New(), encKey, obj.ObjId, authorizedPrin, domain)
    80  	if err == nil {
    81  		t.Fatal("Reading an empty list returned nil error.")
    82  	}
    83  
    84  	_, _, err = ReadObject(l, encKey, obj.ObjId, unAuthorizedPrin, domain)
    85  	if err == nil {
    86  		t.Fatal("Reading by an unauthorized principal returned nil error.")
    87  	}
    88  	tearDown(t)
    89  }
    90  
    91  func TestWriteObject(t *testing.T) {
    92  	setUpDomain(t)
    93  	l := list.New()
    94  	l.PushFront(createRootKey(t))
    95  	obj := createObject(name, epoch, value, secretType)
    96  	pObj, err := protected_objects.MakeProtectedObject(*obj, rootName, epoch, rootKey)
    97  	failOnError(t, err)
    98  	l.PushFront(*pObj)
    99  
   100  	err = domain.Guard.Authorize(*authorizedPrin, "WRITE", []string{obj.ObjId.String()})
   101  	failOnError(t, err)
   102  	err = domain.Guard.Authorize(*authorizedPrin, "READ", []string{obj.ObjId.String()})
   103  	failOnError(t, err)
   104  
   105  	newType := "file"
   106  	newVal := []byte("I am a new file")
   107  	err = WriteObject(l, encKey, obj.ObjId, authorizedPrin, domain, newType, newVal)
   108  	failOnError(t, err)
   109  	typ, val, err := ReadObject(l, encKey, obj.ObjId, authorizedPrin, domain)
   110  	failOnError(t, err)
   111  	if *typ != newType {
   112  		t.Fatal(fmt.Sprintf("Expected secret type %v got %v", newType, typ))
   113  	}
   114  	if !bytes.Equal(val, newVal) {
   115  		t.Fatal("value read after write does not match expected value.")
   116  	}
   117  	tearDown(t)
   118  }
   119  
   120  func TestCreateObject(t *testing.T) {
   121  	setUpDomain(t)
   122  	l := list.New()
   123  	l.PushFront(createRootKey(t))
   124  
   125  	err := domain.Guard.Authorize(*authorizedPrin, "CREATE", []string{rootId.String()})
   126  	failOnError(t, err)
   127  	id := createObjectId(name, epoch)
   128  	err = domain.Guard.Authorize(*authorizedPrin, "READ", []string{id.String()})
   129  	failOnError(t, err)
   130  	fileType := "file"
   131  	err = CreateObject(l, id, rootId, encKey, authorizedPrin, domain, fileType, value)
   132  	failOnError(t, err)
   133  	typ, val, err := ReadObject(l, encKey, id, authorizedPrin, domain)
   134  	failOnError(t, err)
   135  	if *typ != fileType {
   136  		t.Fatal(fmt.Sprintf("Expected secret type %v got %v", secretType, typ))
   137  	}
   138  	if !bytes.Equal(val, value) {
   139  		t.Fatal("value read after create does not match expected value.")
   140  	}
   141  
   142  	err = CreateObject(l, id, rootId, encKey, authorizedPrin, domain, secretType, value)
   143  	if err == nil {
   144  		t.Fatal("Did not get error by creating new object with existing id.")
   145  	}
   146  
   147  	newId := createObjectId("NewKey", epoch)
   148  	newValue := []byte("A New Value!")
   149  	err = CreateObject(l, newId, id, encKey, authorizedPrin, domain, secretType, newValue)
   150  	if err == nil {
   151  		t.Fatal("Did not get error by creating new object with unauthorized program.")
   152  	}
   153  
   154  	err = domain.Guard.Authorize(*authorizedPrin, "CREATE", []string{id.String()})
   155  	failOnError(t, err)
   156  	err = CreateObject(l, newId, newId, encKey, authorizedPrin, domain, secretType, newValue)
   157  	if err == nil {
   158  		t.Fatal("Did not get error by creating new object with a non existant protectorId.")
   159  	}
   160  
   161  	err = CreateObject(l, newId, id, encKey, authorizedPrin, domain, secretType, newValue)
   162  	if err == nil {
   163  		t.Fatal("Did not get error by creating new object with non-key protector.")
   164  	}
   165  	tearDown(t)
   166  }
   167  
   168  func TestDeleteObject(t *testing.T) {
   169  	setUpDomain(t)
   170  	l := list.New()
   171  	l.PushFront(createRootKey(t))
   172  
   173  	newId := createObjectId(name, epoch)
   174  	err := DeleteObject(l, newId, authorizedPrin, domain)
   175  	if err == nil {
   176  		t.Fatal("Did not get error when unauthorized program attempted to delete object.")
   177  	}
   178  
   179  	err = domain.Guard.Authorize(*authorizedPrin, "DELETE", []string{newId.String()})
   180  	failOnError(t, err)
   181  	err = DeleteObject(l, newId, authorizedPrin, domain)
   182  	if err == nil {
   183  		t.Fatal("Did not get error when program attempts to delete non-existant object.")
   184  	}
   185  
   186  	err = domain.Guard.Authorize(*authorizedPrin, "CREATE", []string{rootId.String()})
   187  	failOnError(t, err)
   188  	err = CreateObject(l, newId, rootId, encKey, authorizedPrin, domain, secretType, value)
   189  	failOnError(t, err)
   190  	err = DeleteObject(l, newId, authorizedPrin, domain)
   191  	failOnError(t, err)
   192  	err = domain.Guard.Authorize(*authorizedPrin, "READ", []string{newId.String()})
   193  	failOnError(t, err)
   194  	_, _, err = ReadObject(l, encKey, newId, authorizedPrin, domain)
   195  	if err == nil {
   196  		t.Fatal("Reading a previously deleted object did not return error.")
   197  	}
   198  	tearDown(t)
   199  }
   200  
   201  func failOnError(t *testing.T, err error) {
   202  	if err != nil {
   203  		t.Fatal(err)
   204  	}
   205  }
   206  
   207  func createObject(name string, epoch int32, value []byte,
   208  	objType string) *protected_objects.ObjectMessage {
   209  	return &protected_objects.ObjectMessage{
   210  		ObjId:   createObjectId(name, epoch),
   211  		ObjVal:  value,
   212  		ObjType: &objType}
   213  }
   214  
   215  func createObjectId(name string, epoch int32) *protected_objects.ObjectIdMessage {
   216  	return &protected_objects.ObjectIdMessage{
   217  		ObjName:  &name,
   218  		ObjEpoch: &epoch}
   219  }
   220  
   221  func createRootKey(t *testing.T) protected_objects.ProtectedObjectMessage {
   222  	rootKey = []byte{
   223  		0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
   224  		0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
   225  		0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
   226  	}
   227  	p := new(protected_objects.ProtectedObjectMessage)
   228  	rootId = createObjectId(rootName, epoch)
   229  	p.ProtectedObjId = rootId
   230  	encrypted, err := encKey.CryptingKey.Encrypt(rootKey)
   231  	if err != nil {
   232  		t.Fatal(err)
   233  	}
   234  	p.Blob = encrypted
   235  	return *p
   236  }
   237  
   238  func setUpDomain(t *testing.T) {
   239  	var err error
   240  	if _, err = os.Stat("./tmpdir"); os.IsNotExist(err) {
   241  		err = os.Mkdir("./tmpdir", 0777)
   242  		if err != nil {
   243  			t.Fatal(err)
   244  		}
   245  	}
   246  	aclGuardType := "ACLs"
   247  	aclGuardPath := "acls"
   248  	cfg := tao.DomainConfig{
   249  		DomainInfo: &tao.DomainDetails{
   250  			GuardType: &aclGuardType},
   251  		AclGuardInfo: &tao.ACLGuardDetails{
   252  			SignedAclsPath: &aclGuardPath}}
   253  	domain, err = tao.CreateDomain(cfg, "./tmpdir/domain", []byte("xxx"))
   254  	if err != nil {
   255  		t.Fatal(err)
   256  	}
   257  	encKey, err = tao.NewOnDiskPBEKeys(tao.Signing | tao.Crypting, []byte("xxx"), "./tmpdir/keys", nil)
   258  	if err != nil {
   259  		t.Fatal(err)
   260  	}
   261  }
   262  
   263  func tearDown(t *testing.T) {
   264  	err := os.RemoveAll("./tmpdir")
   265  	if err != nil {
   266  		t.Fatal(err)
   267  	}
   268  }