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  }