github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/go/tao/soft_tao.go (about) 1 // Copyright (c 2015, 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 "fmt" 20 "io" 21 22 "github.com/golang/protobuf/proto" 23 "github.com/jlmucb/cloudproxy/go/tao/auth" 24 ) 25 26 // A SoftTao is an implementation of the Tao that isn't backed by any hardware 27 // mechanisms. It's used for testing components that rely on the Tao. 28 type SoftTao struct { 29 keys *Keys 30 name auth.Prin 31 nameExtension auth.SubPrin 32 } 33 34 // NewSoftTao initializes the SoftTao with a crypter and a signer. 35 func NewSoftTao(path string, password []byte) (Tao, error) { 36 s := &SoftTao{} 37 38 var err error 39 if path == "" { 40 s.keys, err = NewTemporaryKeys(Signing | Crypting | Deriving) 41 } else { 42 s.keys, err = NewOnDiskPBEKeys(Signing|Crypting|Deriving, password, path, nil) 43 } 44 45 s.name = s.keys.VerifyingKey.ToPrincipal() 46 47 if err != nil { 48 return nil, err 49 } 50 51 return s, nil 52 } 53 54 // GetTaoName returns the Tao principal name assigned to the caller. 55 func (s *SoftTao) GetTaoName() (auth.Prin, error) { 56 return s.name.MakeSubprincipal(s.nameExtension), nil 57 } 58 59 // ExtendTaoName irreversibly extends the Tao principal name of the caller. 60 func (s *SoftTao) ExtendTaoName(subprin auth.SubPrin) error { 61 s.nameExtension = append(s.nameExtension, subprin...) 62 return nil 63 } 64 65 // GetRandomBytes fills the slice with random bytes. 66 func (s *SoftTao) GetRandomBytes(n int) ([]byte, error) { 67 b := make([]byte, n) 68 if _, err := rand.Read(b); err != nil { 69 return nil, err 70 } 71 72 return b, nil 73 } 74 75 // Read implements io.Reader to read random bytes from the Tao. 76 func (s *SoftTao) Read(p []byte) (int, error) { 77 bytes, err := s.GetRandomBytes(len(p)) 78 if err != nil { 79 return 0, err 80 } 81 82 copy(p, bytes) 83 return len(p), nil 84 } 85 86 // Rand returns an io.Reader for the SoftTao's source of randomness. 87 func (s *SoftTao) Rand() io.Reader { 88 return s 89 } 90 91 // GetSharedSecret returns a slice of n secret bytes. 92 func (s *SoftTao) GetSharedSecret(n int, policy string) ([]byte, error) { 93 if policy != SharedSecretPolicyDefault { 94 return nil, newError("SoftTao policies not yet implemented") 95 } 96 97 // TODO(tmroeder): for now, we're using a fixed salt and counting on 98 // the strength of HKDF with a strong key. 99 salt := make([]byte, 8) 100 material := make([]byte, n) 101 if err := s.keys.DerivingKey.Derive(salt, []byte("derive shared secret"), material); err != nil { 102 return nil, err 103 } 104 105 return material, nil 106 } 107 108 // Seal encrypts the data in a way that can only be opened by the Tao for the 109 // program that sealed it. In the case of the SoftTao, this policy is 110 // implicit. 111 func (s *SoftTao) Seal(data []byte, policy string) ([]byte, error) { 112 // The SoftTao insists on the trivial policy, since it just encrypts the bytes directly 113 if policy != SealPolicyDefault { 114 return nil, newError("The SoftTao requires SealPolicyDefault") 115 } 116 117 return s.keys.CryptingKey.Encrypt(data) 118 } 119 120 // Unseal decrypts data that has been sealed by the Seal operation, but only if 121 // the policy specified during the Seal operation is satisfied. 122 func (s *SoftTao) Unseal(sealed []byte) (data []byte, policy string, err error) { 123 data, err = s.keys.CryptingKey.Decrypt(sealed) 124 policy = SealPolicyDefault 125 return data, policy, err 126 } 127 128 // Attest requests that the Tao host sign a statement on behalf of the caller. 129 func (s *SoftTao) Attest(issuer *auth.Prin, time, expiration *int64, message auth.Form) (*Attestation, error) { 130 child := s.name.MakeSubprincipal(s.nameExtension) 131 if issuer == nil { 132 issuer = &child 133 } else if !auth.SubprinOrIdentical(issuer, child) { 134 return nil, newError("Invalid issuer in statement: %s may not speak for %s", child, issuer) 135 } 136 137 stmt := auth.Says{Speaker: *issuer, Time: time, Expiration: expiration, Message: message} 138 139 var delegation []byte 140 if s.keys.Delegation != nil { 141 var err error 142 delegation, err = proto.Marshal(s.keys.Delegation) 143 if err != nil { 144 return nil, err 145 } 146 } 147 148 return GenerateAttestation(s.keys.SigningKey, delegation, stmt) 149 } 150 151 var softtao_counter int64 152 153 func (s *SoftTao) InitCounter(label string, c int64) error { 154 softtao_counter = c 155 return nil 156 } 157 158 func (s *SoftTao) GetCounter(label string) (int64, error) { 159 fmt.Printf("SoftTao.GetCounter %d\n", softtao_counter) 160 return softtao_counter, nil 161 } 162 163 func (s *SoftTao) RollbackProtectedSeal(label string, data []byte, policy string) ([]byte, error) { 164 return nil, nil 165 } 166 167 func (s *SoftTao) RollbackProtectedUnseal(sealed []byte) ([]byte, string, error) { 168 return nil, "", nil 169 } 170 171 // GetVerifier returns the verifying key for this Tao. 172 func (s *SoftTao) GetVerifier() *Verifier { 173 return s.keys.VerifyingKey 174 }