github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/go/tao/rollback.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 tao
    14  
    15  import (
    16  	"crypto/rand"
    17  	"fmt"
    18  	"io/ioutil"
    19  	"log"
    20  
    21  	"github.com/golang/protobuf/proto"
    22  )
    23  
    24  // Read the counter table.
    25  func ReadRollbackTable(fileName string, tableKey []byte) *RollbackCounterTable {
    26  	blob, err := ioutil.ReadFile(fileName)
    27  	if blob == nil || err != nil {
    28  		// In either case we need a new table.
    29  		return new(RollbackCounterTable)
    30  	}
    31  
    32  	// Decrypt and deserialize table.
    33  	b, err := Unprotect(tableKey, blob)
    34  	if err != nil {
    35  		log.Printf("ReadRollbackTable: Unprotect failed %s", err)
    36  		return nil
    37  	}
    38  
    39  	var t RollbackCounterTable
    40  	err = proto.Unmarshal(b, &t)
    41  	if err != nil {
    42  		log.Printf("ReadRollbackTable: Unmarshal failed %s", err)
    43  		return nil
    44  	}
    45  	return &t
    46  }
    47  
    48  // Write the counter table.
    49  func WriteRollbackTable(rollBackTable *RollbackCounterTable, fileName string, tableKey []byte) bool {
    50  
    51  	// Serialize and encrypt rollback table.
    52  	blob, err := proto.Marshal(rollBackTable)
    53  	if err != nil {
    54  		log.Printf("WriteRollbackTable: Marshal failed\n")
    55  		return false
    56  	}
    57  	b, err := Protect(tableKey, blob)
    58  	if err != nil {
    59  		log.Printf("WriteRollbackTable: Protect failed " + err.Error() + "\n")
    60  		return false
    61  	}
    62  	err = ioutil.WriteFile(fileName, b, 0644)
    63  	if err != nil {
    64  		log.Printf("WriteRollbackTable: WriteFile failed " + err.Error() + "\n")
    65  		return false
    66  	}
    67  	return true
    68  }
    69  
    70  func (e *RollbackEntry) PrintRollbackEntry() {
    71  	if e.HostedProgramName == nil {
    72  		fmt.Printf("HostedProgramName: empty, ")
    73  	} else {
    74  		fmt.Printf("HostedProgramName: %s, ", *e.HostedProgramName)
    75  	}
    76  	if e.EntryLabel == nil {
    77  		fmt.Printf("EntryLabel: empty, ")
    78  	} else {
    79  		fmt.Printf("EntryLabel: %s, ", *e.EntryLabel)
    80  	}
    81  	if e.Counter == nil {
    82  		fmt.Printf("Counter: empty\n")
    83  	} else {
    84  		fmt.Printf("Counter: %d\n", *e.Counter)
    85  	}
    86  }
    87  
    88  func PrintSealedData(d *RollbackSealedData) {
    89  	if d.Entry == nil {
    90  		fmt.Printf("Rollback entry empty\n")
    91  	} else {
    92  		d.Entry.PrintRollbackEntry()
    93  	}
    94  	if d.ProtectedData == nil {
    95  		fmt.Printf("Protected data: empty\n")
    96  	} else {
    97  		fmt.Printf("Protected data: %x\n", d.ProtectedData)
    98  	}
    99  }
   100  
   101  func (t *RollbackCounterTable) PrintRollbackTable() {
   102  	if t == nil {
   103  		fmt.Printf("No rollback table\n")
   104  		return
   105  	}
   106  	for i := 0; i < len(t.Entries); i++ {
   107  		t.Entries[i].PrintRollbackEntry()
   108  	}
   109  }
   110  
   111  func (t *RollbackCounterTable) SaveHostRollbackTableWithNewKeys(lh *LinuxHost, child *LinuxHostChild,
   112  	sealedKeyFileName string, tableFileName string) bool {
   113  	// TODO(jlm): child argument not used, remove?
   114  	// Generate new rollback table sealing keys
   115  	keyType := CrypterTypeFromSuiteName(TaoCryptoSuite)
   116  	if keyType == nil {
   117  		return false
   118  	}
   119  	totalKeySize := CombinedKeySizeFromAlgorithmName(*keyType)
   120  	if totalKeySize == nil {
   121  		return false
   122  	}
   123  	newKeys := make([]byte, *totalKeySize, *totalKeySize)
   124  	rand.Read(newKeys[0:*totalKeySize])
   125  
   126  	b, err := lh.Host.RollbackProtectedSeal("Table_secret", newKeys[0:*totalKeySize], "self")
   127  	if err != nil {
   128  		log.Printf("SaveHostRollbackTable: Can't do RollbackProtectedSeal\n")
   129  		return false
   130  	}
   131  	err = ioutil.WriteFile(sealedKeyFileName, b, 0644)
   132  	if err != nil {
   133  		log.Printf("SaveHostRollbackTable: Can't write sealedKeyFile\n")
   134  		return false
   135  	}
   136  
   137  	// Save table.
   138  	if !WriteRollbackTable(t, tableFileName, newKeys[0:*totalKeySize]) {
   139  		log.Printf("WriteRollbackTable failed\n")
   140  		return false
   141  	}
   142  
   143  	return true
   144  }
   145  
   146  // Lookup Rollback entry for programName, entryName).
   147  func (t *RollbackCounterTable) LookupRollbackEntry(programName string, entryName string) *RollbackEntry {
   148  	for i := 0; i < len(t.Entries); i++ {
   149  		if t.Entries[i].HostedProgramName != nil && *t.Entries[i].HostedProgramName == programName &&
   150  			t.Entries[i].EntryLabel != nil && *t.Entries[i].EntryLabel == entryName {
   151  			return t.Entries[i]
   152  		}
   153  	}
   154  	return nil
   155  }
   156  
   157  // Update Rollback entry for programName, entryName).
   158  func (t *RollbackCounterTable) UpdateRollbackEntry(programName string, entryName string,
   159  	c *int64) *RollbackEntry {
   160  	ent := t.LookupRollbackEntry(programName, entryName)
   161  	if ent == nil {
   162  		ent = new(RollbackEntry)
   163  		ent.HostedProgramName = &programName
   164  		ent.EntryLabel = &entryName
   165  		zero := int64(0)
   166  		ent.Counter = &zero
   167  		t.Entries = append(t.Entries, ent)
   168  	}
   169  	if c != nil {
   170  		ent.Counter = c
   171  	}
   172  	return ent
   173  }