github.com/rclone/rclone@v1.66.1-0.20240517100346-7b89735ae726/backend/oracleobjectstorage/byok.go (about) 1 //go:build !plan9 && !solaris && !js 2 3 package oracleobjectstorage 4 5 import ( 6 "crypto/sha256" 7 "encoding/base64" 8 "errors" 9 "fmt" 10 "os" 11 "strings" 12 13 "github.com/oracle/oci-go-sdk/v65/common" 14 "github.com/oracle/oci-go-sdk/v65/objectstorage" 15 ) 16 17 const ( 18 sseDefaultAlgorithm = "AES256" 19 ) 20 21 func getSha256(p []byte) []byte { 22 h := sha256.New() 23 h.Write(p) 24 return h.Sum(nil) 25 } 26 27 func validateSSECustomerKeyOptions(opt *Options) error { 28 if opt.SSEKMSKeyID != "" && (opt.SSECustomerKeyFile != "" || opt.SSECustomerKey != "") { 29 return errors.New("oos: can't use vault sse_kms_key_id and local sse_customer_key at the same time") 30 } 31 if opt.SSECustomerKey != "" && opt.SSECustomerKeyFile != "" { 32 return errors.New("oos: can't use sse_customer_key and sse_customer_key_file at the same time") 33 } 34 if opt.SSEKMSKeyID != "" { 35 return nil 36 } 37 err := populateSSECustomerKeys(opt) 38 if err != nil { 39 return err 40 } 41 return nil 42 } 43 44 func populateSSECustomerKeys(opt *Options) error { 45 if opt.SSECustomerKeyFile != "" { 46 // Reads the base64-encoded AES key data from the specified file and computes its SHA256 checksum 47 data, err := os.ReadFile(expandPath(opt.SSECustomerKeyFile)) 48 if err != nil { 49 return fmt.Errorf("oos: error reading sse_customer_key_file: %v", err) 50 } 51 opt.SSECustomerKey = strings.TrimSpace(string(data)) 52 } 53 if opt.SSECustomerKey != "" { 54 decoded, err := base64.StdEncoding.DecodeString(opt.SSECustomerKey) 55 if err != nil { 56 return fmt.Errorf("oos: Could not decode sse_customer_key_file: %w", err) 57 } 58 sha256Checksum := base64.StdEncoding.EncodeToString(getSha256(decoded)) 59 if opt.SSECustomerKeySha256 == "" { 60 opt.SSECustomerKeySha256 = sha256Checksum 61 } else { 62 if opt.SSECustomerKeySha256 != sha256Checksum { 63 return fmt.Errorf("the computed SHA256 checksum "+ 64 "(%v) of the key doesn't match the config entry sse_customer_key_sha256=(%v)", 65 sha256Checksum, opt.SSECustomerKeySha256) 66 } 67 } 68 if opt.SSECustomerAlgorithm == "" { 69 opt.SSECustomerAlgorithm = sseDefaultAlgorithm 70 } 71 } 72 return nil 73 } 74 75 // https://docs.oracle.com/en-us/iaas/Content/Object/Tasks/usingyourencryptionkeys.htm 76 func useBYOKPutObject(fs *Fs, request *objectstorage.PutObjectRequest) { 77 if fs.opt.SSEKMSKeyID != "" { 78 request.OpcSseKmsKeyId = common.String(fs.opt.SSEKMSKeyID) 79 } 80 if fs.opt.SSECustomerAlgorithm != "" { 81 request.OpcSseCustomerAlgorithm = common.String(fs.opt.SSECustomerAlgorithm) 82 } 83 if fs.opt.SSECustomerKey != "" { 84 request.OpcSseCustomerKey = common.String(fs.opt.SSECustomerKey) 85 } 86 if fs.opt.SSECustomerKeySha256 != "" { 87 request.OpcSseCustomerKeySha256 = common.String(fs.opt.SSECustomerKeySha256) 88 } 89 } 90 91 func useBYOKHeadObject(fs *Fs, request *objectstorage.HeadObjectRequest) { 92 if fs.opt.SSECustomerAlgorithm != "" { 93 request.OpcSseCustomerAlgorithm = common.String(fs.opt.SSECustomerAlgorithm) 94 } 95 if fs.opt.SSECustomerKey != "" { 96 request.OpcSseCustomerKey = common.String(fs.opt.SSECustomerKey) 97 } 98 if fs.opt.SSECustomerKeySha256 != "" { 99 request.OpcSseCustomerKeySha256 = common.String(fs.opt.SSECustomerKeySha256) 100 } 101 } 102 103 func useBYOKGetObject(fs *Fs, request *objectstorage.GetObjectRequest) { 104 if fs.opt.SSECustomerAlgorithm != "" { 105 request.OpcSseCustomerAlgorithm = common.String(fs.opt.SSECustomerAlgorithm) 106 } 107 if fs.opt.SSECustomerKey != "" { 108 request.OpcSseCustomerKey = common.String(fs.opt.SSECustomerKey) 109 } 110 if fs.opt.SSECustomerKeySha256 != "" { 111 request.OpcSseCustomerKeySha256 = common.String(fs.opt.SSECustomerKeySha256) 112 } 113 } 114 115 func useBYOKCopyObject(fs *Fs, request *objectstorage.CopyObjectRequest) { 116 if fs.opt.SSEKMSKeyID != "" { 117 request.OpcSseKmsKeyId = common.String(fs.opt.SSEKMSKeyID) 118 } 119 if fs.opt.SSECustomerAlgorithm != "" { 120 request.OpcSseCustomerAlgorithm = common.String(fs.opt.SSECustomerAlgorithm) 121 } 122 if fs.opt.SSECustomerKey != "" { 123 request.OpcSseCustomerKey = common.String(fs.opt.SSECustomerKey) 124 } 125 if fs.opt.SSECustomerKeySha256 != "" { 126 request.OpcSseCustomerKeySha256 = common.String(fs.opt.SSECustomerKeySha256) 127 } 128 }