gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

server-side.go (6469B)


      1 /*
      2  * MinIO Go Library for Amazon S3 Compatible Cloud Storage
      3  * Copyright 2018 MinIO, Inc.
      4  *
      5  * Licensed under the Apache License, Version 2.0 (the "License");
      6  * you may not use this file except in compliance with the License.
      7  * You may obtain a copy of the License at
      8  *
      9  *     http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  * Unless required by applicable law or agreed to in writing, software
     12  * distributed under the License is distributed on an "AS IS" BASIS,
     13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  * See the License for the specific language governing permissions and
     15  * limitations under the License.
     16  */
     17 
     18 package encrypt
     19 
     20 import (
     21 	"crypto/md5"
     22 	"encoding/base64"
     23 	"errors"
     24 	"net/http"
     25 
     26 	jsoniter "github.com/json-iterator/go"
     27 	"golang.org/x/crypto/argon2"
     28 )
     29 
     30 const (
     31 	// SseGenericHeader is the AWS SSE header used for SSE-S3 and SSE-KMS.
     32 	SseGenericHeader = "X-Amz-Server-Side-Encryption"
     33 
     34 	// SseKmsKeyID is the AWS SSE-KMS key id.
     35 	SseKmsKeyID = SseGenericHeader + "-Aws-Kms-Key-Id"
     36 	// SseEncryptionContext is the AWS SSE-KMS Encryption Context data.
     37 	SseEncryptionContext = SseGenericHeader + "-Context"
     38 
     39 	// SseCustomerAlgorithm is the AWS SSE-C algorithm HTTP header key.
     40 	SseCustomerAlgorithm = SseGenericHeader + "-Customer-Algorithm"
     41 	// SseCustomerKey is the AWS SSE-C encryption key HTTP header key.
     42 	SseCustomerKey = SseGenericHeader + "-Customer-Key"
     43 	// SseCustomerKeyMD5 is the AWS SSE-C encryption key MD5 HTTP header key.
     44 	SseCustomerKeyMD5 = SseGenericHeader + "-Customer-Key-MD5"
     45 
     46 	// SseCopyCustomerAlgorithm is the AWS SSE-C algorithm HTTP header key for CopyObject API.
     47 	SseCopyCustomerAlgorithm = "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Algorithm"
     48 	// SseCopyCustomerKey is the AWS SSE-C encryption key HTTP header key for CopyObject API.
     49 	SseCopyCustomerKey = "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key"
     50 	// SseCopyCustomerKeyMD5 is the AWS SSE-C encryption key MD5 HTTP header key for CopyObject API.
     51 	SseCopyCustomerKeyMD5 = "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key-MD5"
     52 )
     53 
     54 // PBKDF creates a SSE-C key from the provided password and salt.
     55 // PBKDF is a password-based key derivation function
     56 // which can be used to derive a high-entropy cryptographic
     57 // key from a low-entropy password and a salt.
     58 type PBKDF func(password, salt []byte) ServerSide
     59 
     60 // DefaultPBKDF is the default PBKDF. It uses Argon2id with the
     61 // recommended parameters from the RFC draft (1 pass, 64 MB memory, 4 threads).
     62 var DefaultPBKDF PBKDF = func(password, salt []byte) ServerSide {
     63 	sse := ssec{}
     64 	copy(sse[:], argon2.IDKey(password, salt, 1, 64*1024, 4, 32))
     65 	return sse
     66 }
     67 
     68 // Type is the server-side-encryption method. It represents one of
     69 // the following encryption methods:
     70 //   - SSE-C: server-side-encryption with customer provided keys
     71 //   - KMS:   server-side-encryption with managed keys
     72 //   - S3:    server-side-encryption using S3 storage encryption
     73 type Type string
     74 
     75 const (
     76 	// SSEC represents server-side-encryption with customer provided keys
     77 	SSEC Type = "SSE-C"
     78 	// KMS represents server-side-encryption with managed keys
     79 	KMS Type = "KMS"
     80 	// S3 represents server-side-encryption using S3 storage encryption
     81 	S3 Type = "S3"
     82 )
     83 
     84 // ServerSide is a form of S3 server-side-encryption.
     85 type ServerSide interface {
     86 	// Type returns the server-side-encryption method.
     87 	Type() Type
     88 
     89 	// Marshal adds encryption headers to the provided HTTP headers.
     90 	// It marks an HTTP request as server-side-encryption request
     91 	// and inserts the required data into the headers.
     92 	Marshal(h http.Header)
     93 }
     94 
     95 // NewSSE returns a server-side-encryption using S3 storage encryption.
     96 // Using SSE-S3 the server will encrypt the object with server-managed keys.
     97 func NewSSE() ServerSide { return s3{} }
     98 
     99 // NewSSEKMS returns a new server-side-encryption using SSE-KMS and the provided Key Id and context.
    100 func NewSSEKMS(keyID string, context interface{}) (ServerSide, error) {
    101 	if context == nil {
    102 		return kms{key: keyID, hasContext: false}, nil
    103 	}
    104 	json := jsoniter.ConfigCompatibleWithStandardLibrary
    105 	serializedContext, err := json.Marshal(context)
    106 	if err != nil {
    107 		return nil, err
    108 	}
    109 	return kms{key: keyID, context: serializedContext, hasContext: true}, nil
    110 }
    111 
    112 // NewSSEC returns a new server-side-encryption using SSE-C and the provided key.
    113 // The key must be 32 bytes long.
    114 func NewSSEC(key []byte) (ServerSide, error) {
    115 	if len(key) != 32 {
    116 		return nil, errors.New("encrypt: SSE-C key must be 256 bit long")
    117 	}
    118 	sse := ssec{}
    119 	copy(sse[:], key)
    120 	return sse, nil
    121 }
    122 
    123 // SSE transforms a SSE-C copy encryption into a SSE-C encryption.
    124 // It is the inverse of SSECopy(...).
    125 //
    126 // If the provided sse is no SSE-C copy encryption SSE returns
    127 // sse unmodified.
    128 func SSE(sse ServerSide) ServerSide {
    129 	if sse == nil || sse.Type() != SSEC {
    130 		return sse
    131 	}
    132 	if sse, ok := sse.(ssecCopy); ok {
    133 		return ssec(sse)
    134 	}
    135 	return sse
    136 }
    137 
    138 // SSECopy transforms a SSE-C encryption into a SSE-C copy
    139 // encryption. This is required for SSE-C key rotation or a SSE-C
    140 // copy where the source and the destination should be encrypted.
    141 //
    142 // If the provided sse is no SSE-C encryption SSECopy returns
    143 // sse unmodified.
    144 func SSECopy(sse ServerSide) ServerSide {
    145 	if sse == nil || sse.Type() != SSEC {
    146 		return sse
    147 	}
    148 	if sse, ok := sse.(ssec); ok {
    149 		return ssecCopy(sse)
    150 	}
    151 	return sse
    152 }
    153 
    154 type ssec [32]byte
    155 
    156 func (s ssec) Type() Type { return SSEC }
    157 
    158 func (s ssec) Marshal(h http.Header) {
    159 	keyMD5 := md5.Sum(s[:])
    160 	h.Set(SseCustomerAlgorithm, "AES256")
    161 	h.Set(SseCustomerKey, base64.StdEncoding.EncodeToString(s[:]))
    162 	h.Set(SseCustomerKeyMD5, base64.StdEncoding.EncodeToString(keyMD5[:]))
    163 }
    164 
    165 type ssecCopy [32]byte
    166 
    167 func (s ssecCopy) Type() Type { return SSEC }
    168 
    169 func (s ssecCopy) Marshal(h http.Header) {
    170 	keyMD5 := md5.Sum(s[:])
    171 	h.Set(SseCopyCustomerAlgorithm, "AES256")
    172 	h.Set(SseCopyCustomerKey, base64.StdEncoding.EncodeToString(s[:]))
    173 	h.Set(SseCopyCustomerKeyMD5, base64.StdEncoding.EncodeToString(keyMD5[:]))
    174 }
    175 
    176 type s3 struct{}
    177 
    178 func (s s3) Type() Type { return S3 }
    179 
    180 func (s s3) Marshal(h http.Header) { h.Set(SseGenericHeader, "AES256") }
    181 
    182 type kms struct {
    183 	key        string
    184 	context    []byte
    185 	hasContext bool
    186 }
    187 
    188 func (s kms) Type() Type { return KMS }
    189 
    190 func (s kms) Marshal(h http.Header) {
    191 	h.Set(SseGenericHeader, "aws:kms")
    192 	if s.key != "" {
    193 		h.Set(SseKmsKeyID, s.key)
    194 	}
    195 	if s.hasContext {
    196 		h.Set(SseEncryptionContext, base64.StdEncoding.EncodeToString(s.context))
    197 	}
    198 }