github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/go/tao/root_host.go (about)

     1  // Copyright (c) 2014, 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  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package tao
    16  
    17  import (
    18  	"crypto/rand"
    19  	"crypto/x509"
    20  	"errors"
    21  
    22  	"github.com/golang/protobuf/proto"
    23  	"github.com/jlmucb/cloudproxy/go/tao/auth"
    24  )
    25  
    26  // A RootHost is a standalone implementation of Host.
    27  type RootHost struct {
    28  	keys        *Keys
    29  	taoHostName auth.Prin
    30  }
    31  
    32  // NewTaoRootHostFromKeys returns a RootHost that uses these keys.
    33  func NewTaoRootHostFromKeys(k *Keys) (*RootHost, error) {
    34  	if k.SigningKey == nil || k.CryptingKey == nil || k.VerifyingKey == nil {
    35  		return nil, newError("missing required key for RootHost")
    36  	}
    37  
    38  	t := &RootHost{
    39  		keys:        k,
    40  		taoHostName: k.SigningKey.ToPrincipal(),
    41  	}
    42  
    43  	return t, nil
    44  }
    45  
    46  // NewTaoRootHost generates a new RootHost with a fresh set of temporary
    47  // keys.
    48  func NewTaoRootHost() (*RootHost, error) {
    49  	k, err := NewTemporaryKeys(Signing | Crypting)
    50  	if err != nil {
    51  		return nil, err
    52  	}
    53  
    54  	return NewTaoRootHostFromKeys(k)
    55  }
    56  
    57  // LoadCert loads a given cert into the root host key.
    58  func (t *RootHost) LoadCert(cert *x509.Certificate) {
    59  	t.keys.Cert = cert
    60  }
    61  
    62  func (t *RootHost) GetVerifier() *Verifier {
    63  	return t.keys.VerifyingKey
    64  }
    65  
    66  // GetRandomBytes returns a slice of n random bytes.
    67  func (t *RootHost) GetRandomBytes(childSubprin auth.SubPrin, n int) (bytes []byte, err error) {
    68  	b := make([]byte, n)
    69  	if _, err := rand.Read(b); err != nil {
    70  		return nil, err
    71  	}
    72  
    73  	return b, nil
    74  }
    75  
    76  // GetSharedSecret returns a slice of n secret bytes.
    77  func (t *RootHost) GetSharedSecret(tag string, n int) (bytes []byte, err error) {
    78  	if t.keys.DerivingKey == nil {
    79  		return nil, newError("this RootHost does not implement shared secrets")
    80  	}
    81  
    82  	// For now, all our key deriving with keys.DerivingKey uses a fixed 0-length salt.
    83  	var salt []byte
    84  	material := make([]byte, n)
    85  	if err := t.keys.DerivingKey.Derive(salt, []byte(tag), material); err != nil {
    86  		return nil, err
    87  	}
    88  
    89  	return material, nil
    90  }
    91  
    92  // Attest requests the Tao host sign a statement on behalf of the caller.
    93  func (t *RootHost) Attest(childSubprin auth.SubPrin, issuer *auth.Prin,
    94  	time, expiration *int64, message auth.Form) (*Attestation, error) {
    95  
    96  	child := t.taoHostName.MakeSubprincipal(childSubprin)
    97  	if issuer != nil {
    98  		if !auth.SubprinOrIdentical(*issuer, child) {
    99  			return nil, newError("invalid issuer in statement")
   100  		}
   101  	} else {
   102  		issuer = &child
   103  	}
   104  
   105  	stmt := auth.Says{Speaker: *issuer, Time: time, Expiration: expiration, Message: message}
   106  
   107  	att, err := GenerateAttestation(t.keys.SigningKey, nil /* delegation */, stmt)
   108  	if err != nil {
   109  		return nil, err
   110  	}
   111  	if t.keys.Cert != nil {
   112  		att.RootEndorsement = t.keys.Cert.Raw
   113  	}
   114  	return att, nil
   115  }
   116  
   117  // Encrypt data so that only this host can access it.
   118  func (t *RootHost) Encrypt(data []byte) (encrypted []byte, err error) {
   119  	return t.keys.CryptingKey.Encrypt(data)
   120  }
   121  
   122  // Decrypt data that only this host can access.
   123  func (t *RootHost) Decrypt(encrypted []byte) (data []byte, err error) {
   124  	return t.keys.CryptingKey.Decrypt(encrypted)
   125  }
   126  
   127  // AddedHostedProgram notifies this Host that a new hosted program has been
   128  // created.
   129  func (t *RootHost) AddedHostedProgram(childSubprin auth.SubPrin) error {
   130  	return nil
   131  }
   132  
   133  // RemovedHostedProgram notifies this Host that a hosted program has been
   134  // killed.
   135  func (t *RootHost) RemovedHostedProgram(childSubprin auth.SubPrin) error {
   136  	return nil
   137  }
   138  
   139  // HostName gets the Tao principal name assigned to this hosted Tao host.
   140  // The name encodes the full path from the root Tao, through all intermediary
   141  // Tao hosts, to this hosted Tao host.
   142  func (t *RootHost) HostName() auth.Prin {
   143  	return t.taoHostName
   144  }
   145  
   146  func (s *RootHost) InitCounter(label string, c int64) error {
   147  	softtao_counter = c
   148  	return nil
   149  }
   150  
   151  func (s *RootHost) GetCounter(label string) (int64, error) {
   152  	return softtao_counter, nil
   153  }
   154  
   155  func (s *RootHost) RollbackProtectedSeal(label string, data []byte, policy string) ([]byte, error) {
   156  	// TODO(jlm): Add counter to root_host struct instead?
   157  	softtao_counter = softtao_counter + 1
   158  	sd := new(RollbackSealedData)
   159  	sd.Entry = new(RollbackEntry)
   160  	programName := ""
   161  	sd.Entry.HostedProgramName = &programName
   162  	sd.Entry.EntryLabel = &label
   163  	sd.Entry.Counter = &softtao_counter
   164  	sd.ProtectedData = data
   165  	toSeal, err := proto.Marshal(sd)
   166  	if err != nil {
   167  		return nil, errors.New("Can't marshall roothost rollback data")
   168  	}
   169  	sealed, err := s.Encrypt(toSeal)
   170  	if err != nil {
   171  		return nil, errors.New("Can't encrypt roothost rollback data")
   172  	}
   173  	return sealed, nil
   174  }
   175  
   176  func (s *RootHost) RollbackProtectedUnseal(sealed []byte) ([]byte, string, error) {
   177  	c, err := s.GetCounter("label")
   178  	if err != nil {
   179  		c = int64(0)
   180  	}
   181  	b, err := s.Decrypt(sealed)
   182  	if err != nil {
   183  		return nil, "", errors.New("Can't decrypt roothost rollback data")
   184  	}
   185  	var sd RollbackSealedData
   186  	err = proto.Unmarshal(b, &sd)
   187  	if err != nil {
   188  		return nil, "", errors.New("RollbackProtectedUnseal can't Unmarshal")
   189  	}
   190  	if sd.Entry == nil || sd.Entry.Counter == nil || *sd.Entry.Counter != c {
   191  		return nil, "", errors.New("RollbackProtectedUnseal bad counter")
   192  	}
   193  	return sd.ProtectedData, "", nil
   194  }