blob: 1d1a0fb72bfca515c1e6a646404864f8b5c239d6 [file] [log] [blame]
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////
package tink
import (
"fmt"
tinkpb "github.com/google/tink/proto/tink_go_proto"
)
var errKeysetHandleInvalidKeyset = fmt.Errorf("keyset_handle: invalid keyset")
// KeysetHandle provides abstracted access to Keysets, to limit the exposure
// of actual protocol buffers that hold sensitive key material.
type KeysetHandle struct {
keyset *tinkpb.Keyset
encryptedKeyset *tinkpb.EncryptedKeyset
}
// newKeysetHandle creates a new instance of KeysetHandle using the given keyset
// and encrypted keyset. The given keyset must not be nil. Otherwise, an error will
// be returned.
func newKeysetHandle(keyset *tinkpb.Keyset,
encryptedKeyset *tinkpb.EncryptedKeyset) (*KeysetHandle, error) {
if keyset == nil || len(keyset.Key) == 0 {
return nil, errKeysetHandleInvalidKeyset
}
return &KeysetHandle{
keyset: keyset,
encryptedKeyset: encryptedKeyset,
}, nil
}
// GetPublicKeysetHandle returns a KeysetHandle of the public keys if the managed
// keyset contains private keys.
func (h *KeysetHandle) GetPublicKeysetHandle() (*KeysetHandle, error) {
privKeys := h.keyset.Key
pubKeys := make([]*tinkpb.Keyset_Key, len(privKeys))
for i := 0; i < len(privKeys); i++ {
if privKeys[i] == nil || privKeys[i].KeyData == nil {
return nil, errKeysetHandleInvalidKeyset
}
privKeyData := privKeys[i].KeyData
if privKeyData.KeyMaterialType != tinkpb.KeyData_ASYMMETRIC_PRIVATE {
return nil, fmt.Errorf("keyset_handle: keyset contains a non-private key")
}
pubKeyData, err := getPublicKeyData(privKeyData.TypeUrl, privKeyData.Value)
if err != nil {
return nil, fmt.Errorf("keyset_handle: %s", err)
}
if err := h.validateKeyData(pubKeyData); err != nil {
return nil, fmt.Errorf("keyset_handle: %s", err)
}
pubKeys[i] = &tinkpb.Keyset_Key{
KeyData: pubKeyData,
Status: privKeys[i].Status,
KeyId: privKeys[i].KeyId,
OutputPrefixType: privKeys[i].OutputPrefixType,
}
}
pubKeyset := &tinkpb.Keyset{
PrimaryKeyId: h.keyset.PrimaryKeyId,
Key: pubKeys,
}
return newKeysetHandle(pubKeyset, nil)
}
// Keyset returns the Keyset component of this handle.
func (h *KeysetHandle) Keyset() *tinkpb.Keyset {
return h.keyset
}
// EncryptedKeyset returns the EncryptedKeyset component of this handle.
func (h *KeysetHandle) EncryptedKeyset() *tinkpb.EncryptedKeyset {
return h.encryptedKeyset
}
// KeysetInfo returns a KeysetInfo of the Keyset of this handle.
// KeysetInfo doesn't contain actual key material.
func (h *KeysetHandle) KeysetInfo() (*tinkpb.KeysetInfo, error) {
return GetKeysetInfo(h.keyset)
}
// String returns the string representation of the KeysetInfo.
func (h *KeysetHandle) String() string {
info, err := h.KeysetInfo()
if err != nil {
return ""
}
return info.String()
}
func (h *KeysetHandle) validateKeyData(keyData *tinkpb.KeyData) error {
_, err := GetPrimitiveFromKeyData(keyData)
return err
}