github.com/trustbloc/kms-go@v1.1.2/kms/localkms/internal/keywrapper/kms_aead.go (about)

     1  /*
     2  Copyright SecureKey Technologies Inc. All Rights Reserved.
     3  
     4   SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package keywrapper
     8  
     9  import (
    10  	"encoding/base64"
    11  	"errors"
    12  	"regexp"
    13  
    14  	"github.com/google/tink/go/tink"
    15  
    16  	"github.com/trustbloc/kms-go/spi/secretlock"
    17  )
    18  
    19  // LocalKeyURIPrefix for locally stored keys.
    20  const LocalKeyURIPrefix = "local-lock://"
    21  
    22  // LocalAEAD represents a local kms aead service invoking a local SecretLock to a particular key URI.
    23  // Instances of LocalAEAD are invoked internally by Tink for wrapping/unwrapping keys. It must not
    24  // be used elsewhere.
    25  type LocalAEAD struct {
    26  	keyURI     string
    27  	secretLock secretlock.Service
    28  }
    29  
    30  // New creates a new key wrapper with the given uriPrefix and a local secretLock service.
    31  func New(secretLock secretlock.Service, keyURI string) (tink.AEAD, error) {
    32  	uri, err := trimPrefix(keyURI)
    33  	if err != nil {
    34  		return nil, err
    35  	}
    36  
    37  	return &LocalAEAD{
    38  		keyURI:     uri,
    39  		secretLock: secretLock,
    40  	}, nil
    41  }
    42  
    43  // Encrypt LocalAEAD encrypts plaintext with addtionaldata.
    44  func (a *LocalAEAD) Encrypt(plaintext, additionalData []byte) ([]byte, error) {
    45  	req := &secretlock.EncryptRequest{
    46  		Plaintext:                   base64.URLEncoding.EncodeToString(plaintext),
    47  		AdditionalAuthenticatedData: base64.URLEncoding.EncodeToString(additionalData),
    48  	}
    49  
    50  	resp, err := a.secretLock.Encrypt(a.keyURI, req)
    51  	if err != nil {
    52  		return nil, err
    53  	}
    54  
    55  	ct, err := base64.URLEncoding.DecodeString(resp.Ciphertext)
    56  	if err != nil {
    57  		return nil, err
    58  	}
    59  
    60  	return ct, nil
    61  }
    62  
    63  // Decrypt LocalAEAD decrypts the data and verified the additional data.
    64  func (a *LocalAEAD) Decrypt(ciphertext, additionalData []byte) ([]byte, error) {
    65  	req := &secretlock.DecryptRequest{
    66  		Ciphertext:                  base64.URLEncoding.EncodeToString(ciphertext),
    67  		AdditionalAuthenticatedData: base64.URLEncoding.EncodeToString(additionalData),
    68  	}
    69  
    70  	resp, err := a.secretLock.Decrypt(a.keyURI, req)
    71  	if err != nil {
    72  		return nil, err
    73  	}
    74  
    75  	pt, err := base64.URLEncoding.DecodeString(resp.Plaintext)
    76  	if err != nil {
    77  		return nil, err
    78  	}
    79  
    80  	return pt, nil
    81  }
    82  
    83  func trimPrefix(keyURI string) (string, error) {
    84  	re1 := regexp.MustCompile(`[a-zA-Z0-9-_]+://`)
    85  	loc := re1.FindStringIndex(keyURI)
    86  
    87  	if len(loc) == 0 || loc[0] > 0 {
    88  		return "", errors.New("keyURI must have a prefix in form 'prefixname://'")
    89  	}
    90  
    91  	if loc[1] == len(keyURI) {
    92  		return "", errors.New("keyURI can't consist only from a prefix")
    93  	}
    94  
    95  	return keyURI[loc[1]:], nil
    96  }