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 }