1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
|
package s3crypto
import (
"fmt"
)
// CryptoRegistry is a collection of registries for configuring a decryption client with different key wrapping algorithms,
// content encryption algorithms, and padders.
type CryptoRegistry struct {
wrap map[string]WrapEntry
cek map[string]CEKEntry
padder map[string]Padder
}
// NewCryptoRegistry creates a new CryptoRegistry to which wrapping algorithms, content encryption ciphers, and
// padders can be registered for use with the DecryptionClientV2.
func NewCryptoRegistry() *CryptoRegistry {
return &CryptoRegistry{
wrap: map[string]WrapEntry{},
cek: map[string]CEKEntry{},
padder: map[string]Padder{},
}
}
// initCryptoRegistryFrom creates a CryptoRegistry from prepopulated values, this is used for the V1 client
func initCryptoRegistryFrom(wrapRegistry map[string]WrapEntry, cekRegistry map[string]CEKEntry, padderRegistry map[string]Padder) *CryptoRegistry {
cr := &CryptoRegistry{
wrap: wrapRegistry,
cek: cekRegistry,
padder: padderRegistry,
}
return cr
}
// GetWrap returns the WrapEntry identified by the given name. Returns false if the entry is not registered.
func (c CryptoRegistry) GetWrap(name string) (WrapEntry, bool) {
if c.wrap == nil {
return nil, false
}
entry, ok := c.wrap[name]
return entry, ok
}
// AddWrap registers the provided WrapEntry under the given name, returns an error if a WrapEntry is already present
// for the given name.
//
// This method should only be used if you need to register custom wrapping algorithms. Please see the following methods
// for helpers to register AWS provided algorithms:
//
// RegisterKMSContextWrapWithAnyCMK (kms+context)
// RegisterKMSContextWrapWithCMK (kms+context)
// RegisterKMSWrapWithAnyCMK (kms)
// RegisterKMSWrapWithCMK (kms)
func (c *CryptoRegistry) AddWrap(name string, entry WrapEntry) error {
if entry == nil {
return errNilWrapEntry
}
if _, ok := c.wrap[name]; ok {
return newErrDuplicateWrapEntry(name)
}
c.wrap[name] = entry
return nil
}
// RemoveWrap removes the WrapEntry identified by name. If the WrapEntry is not present returns false.
func (c *CryptoRegistry) RemoveWrap(name string) (WrapEntry, bool) {
if c.wrap == nil {
return nil, false
}
entry, ok := c.wrap[name]
if ok {
delete(c.wrap, name)
}
return entry, ok
}
// GetCEK returns the CEKEntry identified by the given name. Returns false if the entry is not registered.
func (c CryptoRegistry) GetCEK(name string) (CEKEntry, bool) {
if c.cek == nil {
return nil, false
}
entry, ok := c.cek[name]
return entry, ok
}
// AddCEK registers CEKEntry under the given name, returns an error if a CEKEntry is already present for the given name.
//
// This method should only be used if you need to register custom content encryption algorithms. Please see the following methods
// for helpers to register AWS provided algorithms:
//
// RegisterAESGCMContentCipher (AES/GCM)
// RegisterAESCBCContentCipher (AES/CBC)
func (c *CryptoRegistry) AddCEK(name string, entry CEKEntry) error {
if entry == nil {
return errNilCEKEntry
}
if _, ok := c.cek[name]; ok {
return newErrDuplicateCEKEntry(name)
}
c.cek[name] = entry
return nil
}
// RemoveCEK removes the CEKEntry identified by name. If the entry is not present returns false.
func (c *CryptoRegistry) RemoveCEK(name string) (CEKEntry, bool) {
if c.cek == nil {
return nil, false
}
entry, ok := c.cek[name]
if ok {
delete(c.cek, name)
}
return entry, ok
}
// GetPadder returns the Padder identified by name. If the Padder is not present, returns false.
func (c *CryptoRegistry) GetPadder(name string) (Padder, bool) {
if c.padder == nil {
return nil, false
}
entry, ok := c.padder[name]
return entry, ok
}
// AddPadder registers Padder under the given name, returns an error if a Padder is already present for the given name.
//
// This method should only be used to register custom padder implementations not provided by AWS.
func (c *CryptoRegistry) AddPadder(name string, padder Padder) error {
if padder == nil {
return errNilPadder
}
if _, ok := c.padder[name]; ok {
return newErrDuplicatePadderEntry(name)
}
c.padder[name] = padder
return nil
}
// RemovePadder removes the Padder identified by name. If the entry is not present returns false.
func (c *CryptoRegistry) RemovePadder(name string) (Padder, bool) {
if c.padder == nil {
return nil, false
}
padder, ok := c.padder[name]
if ok {
delete(c.padder, name)
}
return padder, ok
}
func (c CryptoRegistry) valid() error {
if len(c.wrap) == 0 {
return fmt.Errorf("at least one key wrapping algorithms must be provided")
}
if len(c.cek) == 0 {
return fmt.Errorf("at least one content decryption algorithms must be provided")
}
return nil
}
|