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 }