| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 | 
							- package kms
 
- import (
 
- 	"crypto/aes"
 
- 	"crypto/cipher"
 
- 	"crypto/rand"
 
- 	"crypto/sha256"
 
- 	"encoding/hex"
 
- 	"errors"
 
- 	"io"
 
- )
 
- var (
 
- 	errMalformedCiphertext = errors.New("malformed ciphertext")
 
- )
 
- type builtinSecret struct {
 
- 	BaseSecret
 
- }
 
- func init() {
 
- 	RegisterSecretProvider(SchemeBuiltin, SecretStatusAES256GCM, newBuiltinSecret)
 
- }
 
- func newBuiltinSecret(base BaseSecret, url, masterKey string) SecretProvider {
 
- 	return &builtinSecret{
 
- 		BaseSecret: base,
 
- 	}
 
- }
 
- func (s *builtinSecret) Name() string {
 
- 	return "Builtin"
 
- }
 
- func (s *builtinSecret) IsEncrypted() bool {
 
- 	return s.Status == SecretStatusAES256GCM
 
- }
 
- func (s *builtinSecret) deriveKey(key []byte) []byte {
 
- 	var combined []byte
 
- 	combined = append(combined, key...)
 
- 	if s.AdditionalData != "" {
 
- 		combined = append(combined, []byte(s.AdditionalData)...)
 
- 	}
 
- 	combined = append(combined, key...)
 
- 	hash := sha256.Sum256(combined)
 
- 	return hash[:]
 
- }
 
- func (s *builtinSecret) Encrypt() error {
 
- 	if s.Payload == "" {
 
- 		return ErrInvalidSecret
 
- 	}
 
- 	switch s.Status {
 
- 	case SecretStatusPlain:
 
- 		key := make([]byte, 32)
 
- 		if _, err := io.ReadFull(rand.Reader, key); err != nil {
 
- 			return err
 
- 		}
 
- 		block, err := aes.NewCipher(s.deriveKey(key))
 
- 		if err != nil {
 
- 			return err
 
- 		}
 
- 		gcm, err := cipher.NewGCM(block)
 
- 		if err != nil {
 
- 			return err
 
- 		}
 
- 		nonce := make([]byte, gcm.NonceSize())
 
- 		if _, err = io.ReadFull(rand.Reader, nonce); err != nil {
 
- 			return err
 
- 		}
 
- 		var aad []byte
 
- 		if s.AdditionalData != "" {
 
- 			aad = []byte(s.AdditionalData)
 
- 		}
 
- 		ciphertext := gcm.Seal(nonce, nonce, []byte(s.Payload), aad)
 
- 		s.Key = hex.EncodeToString(key)
 
- 		s.Payload = hex.EncodeToString(ciphertext)
 
- 		s.Status = SecretStatusAES256GCM
 
- 		return nil
 
- 	default:
 
- 		return ErrWrongSecretStatus
 
- 	}
 
- }
 
- func (s *builtinSecret) Decrypt() error {
 
- 	switch s.Status {
 
- 	case SecretStatusAES256GCM:
 
- 		encrypted, err := hex.DecodeString(s.Payload)
 
- 		if err != nil {
 
- 			return err
 
- 		}
 
- 		key, err := hex.DecodeString(s.Key)
 
- 		if err != nil {
 
- 			return err
 
- 		}
 
- 		block, err := aes.NewCipher(s.deriveKey(key))
 
- 		if err != nil {
 
- 			return err
 
- 		}
 
- 		gcm, err := cipher.NewGCM(block)
 
- 		if err != nil {
 
- 			return err
 
- 		}
 
- 		nonceSize := gcm.NonceSize()
 
- 		if len(encrypted) < nonceSize {
 
- 			return errMalformedCiphertext
 
- 		}
 
- 		nonce, ciphertext := encrypted[:nonceSize], encrypted[nonceSize:]
 
- 		var aad []byte
 
- 		if s.AdditionalData != "" {
 
- 			aad = []byte(s.AdditionalData)
 
- 		}
 
- 		plaintext, err := gcm.Open(nil, nonce, ciphertext, aad)
 
- 		if err != nil {
 
- 			return err
 
- 		}
 
- 		s.Status = SecretStatusPlain
 
- 		s.Payload = string(plaintext)
 
- 		s.Key = ""
 
- 		s.AdditionalData = ""
 
- 		return nil
 
- 	default:
 
- 		return ErrWrongSecretStatus
 
- 	}
 
- }
 
- func (s *builtinSecret) Clone() SecretProvider {
 
- 	baseSecret := BaseSecret{
 
- 		Status:         s.Status,
 
- 		Payload:        s.Payload,
 
- 		Key:            s.Key,
 
- 		AdditionalData: s.AdditionalData,
 
- 		Mode:           s.Mode,
 
- 	}
 
- 	return newBuiltinSecret(baseSecret, "", "")
 
- }
 
 
  |