Browse Source

fmt

pull/7481/head
chrislu 3 weeks ago
parent
commit
615de0dbf2
  1. 54
      weed/s3api/s3api_object_handlers.go

54
weed/s3api/s3api_object_handlers.go

@ -418,7 +418,7 @@ func (s3a *S3ApiServer) GetObjectHandler(w http.ResponseWriter, r *http.Request)
// Detect SSE encryption type // Detect SSE encryption type
primarySSEType := s3a.detectPrimarySSEType(objectEntryForSSE) primarySSEType := s3a.detectPrimarySSEType(objectEntryForSSE)
// Stream directly from volume servers with SSE support // Stream directly from volume servers with SSE support
err = s3a.streamFromVolumeServersWithSSE(w, r, objectEntryForSSE, primarySSEType) err = s3a.streamFromVolumeServersWithSSE(w, r, objectEntryForSSE, primarySSEType)
if err != nil { if err != nil {
@ -582,16 +582,16 @@ func (s3a *S3ApiServer) streamFromVolumeServersWithSSE(w http.ResponseWriter, r
if sseType == "" || sseType == "None" { if sseType == "" || sseType == "None" {
return s3a.streamFromVolumeServers(w, r, entry, sseType) return s3a.streamFromVolumeServers(w, r, entry, sseType)
} }
glog.V(2).Infof("streamFromVolumeServersWithSSE: Handling %s encrypted object", sseType) glog.V(2).Infof("streamFromVolumeServersWithSSE: Handling %s encrypted object", sseType)
// Add SSE response headers before streaming // Add SSE response headers before streaming
s3a.addSSEResponseHeadersFromEntry(w, r, entry, sseType) s3a.addSSEResponseHeadersFromEntry(w, r, entry, sseType)
// For encrypted objects, we need to stream encrypted data through a decryption wrapper // For encrypted objects, we need to stream encrypted data through a decryption wrapper
// Create a pipe: encrypted data goes into pipe writer, decrypted data comes from pipe reader // Create a pipe: encrypted data goes into pipe writer, decrypted data comes from pipe reader
pipeReader, pipeWriter := io.Pipe() pipeReader, pipeWriter := io.Pipe()
// Start goroutine to stream encrypted data from volume servers to pipe // Start goroutine to stream encrypted data from volume servers to pipe
encryptedStreamErr := make(chan error, 1) encryptedStreamErr := make(chan error, 1)
go func() { go func() {
@ -599,11 +599,11 @@ func (s3a *S3ApiServer) streamFromVolumeServersWithSSE(w http.ResponseWriter, r
err := s3a.streamFromVolumeServers(&pipeWriterWrapper{pipeWriter}, r, entry, sseType) err := s3a.streamFromVolumeServers(&pipeWriterWrapper{pipeWriter}, r, entry, sseType)
encryptedStreamErr <- err encryptedStreamErr <- err
}() }()
// Create decrypted reader based on SSE type // Create decrypted reader based on SSE type
var decryptedReader io.Reader var decryptedReader io.Reader
var decryptErr error var decryptErr error
switch sseType { switch sseType {
case s3_constants.SSETypeC: case s3_constants.SSETypeC:
decryptedReader, decryptErr = s3a.createSSECDecryptedReaderFromEntry(r, pipeReader, entry) decryptedReader, decryptErr = s3a.createSSECDecryptedReaderFromEntry(r, pipeReader, entry)
@ -614,21 +614,21 @@ func (s3a *S3ApiServer) streamFromVolumeServersWithSSE(w http.ResponseWriter, r
default: default:
decryptErr = fmt.Errorf("unsupported SSE type: %s", sseType) decryptErr = fmt.Errorf("unsupported SSE type: %s", sseType)
} }
if decryptErr != nil { if decryptErr != nil {
pipeReader.Close() pipeReader.Close()
return fmt.Errorf("failed to create decrypted reader for %s: %v", sseType, decryptErr) return fmt.Errorf("failed to create decrypted reader for %s: %v", sseType, decryptErr)
} }
// Stream decrypted data to response // Stream decrypted data to response
buf := make([]byte, 128*1024) buf := make([]byte, 128*1024)
_, copyErr := io.CopyBuffer(w, decryptedReader, buf) _, copyErr := io.CopyBuffer(w, decryptedReader, buf)
// Check if encrypted streaming had errors // Check if encrypted streaming had errors
if streamErr := <-encryptedStreamErr; streamErr != nil { if streamErr := <-encryptedStreamErr; streamErr != nil {
return fmt.Errorf("encrypted stream error: %v", streamErr) return fmt.Errorf("encrypted stream error: %v", streamErr)
} }
return copyErr return copyErr
} }
@ -637,7 +637,7 @@ func (s3a *S3ApiServer) addSSEResponseHeadersFromEntry(w http.ResponseWriter, r
if entry == nil || entry.Extended == nil { if entry == nil || entry.Extended == nil {
return return
} }
switch sseType { switch sseType {
case s3_constants.SSETypeC: case s3_constants.SSETypeC:
// SSE-C: Echo back algorithm and key MD5 // SSE-C: Echo back algorithm and key MD5
@ -647,7 +647,7 @@ func (s3a *S3ApiServer) addSSEResponseHeadersFromEntry(w http.ResponseWriter, r
if keyMD5, exists := entry.Extended[s3_constants.AmzServerSideEncryptionCustomerKeyMD5]; exists { if keyMD5, exists := entry.Extended[s3_constants.AmzServerSideEncryptionCustomerKeyMD5]; exists {
w.Header().Set(s3_constants.AmzServerSideEncryptionCustomerKeyMD5, string(keyMD5)) w.Header().Set(s3_constants.AmzServerSideEncryptionCustomerKeyMD5, string(keyMD5))
} }
case s3_constants.SSETypeKMS: case s3_constants.SSETypeKMS:
// SSE-KMS: Return algorithm and key ID // SSE-KMS: Return algorithm and key ID
w.Header().Set(s3_constants.AmzServerSideEncryption, "aws:kms") w.Header().Set(s3_constants.AmzServerSideEncryption, "aws:kms")
@ -660,7 +660,7 @@ func (s3a *S3ApiServer) addSSEResponseHeadersFromEntry(w http.ResponseWriter, r
} }
} }
} }
case s3_constants.SSETypeS3: case s3_constants.SSETypeS3:
// SSE-S3: Return algorithm // SSE-S3: Return algorithm
w.Header().Set(s3_constants.AmzServerSideEncryption, s3_constants.SSEAlgorithmAES256) w.Header().Set(s3_constants.AmzServerSideEncryption, s3_constants.SSEAlgorithmAES256)
@ -688,11 +688,11 @@ func (s3a *S3ApiServer) createSSECDecryptedReaderFromEntry(r *http.Request, encr
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to parse SSE-C headers: %w", err) return nil, fmt.Errorf("failed to parse SSE-C headers: %w", err)
} }
if customerKey == nil { if customerKey == nil {
return nil, fmt.Errorf("SSE-C key required but not provided") return nil, fmt.Errorf("SSE-C key required but not provided")
} }
// Validate key MD5 from entry metadata // Validate key MD5 from entry metadata
if entry.Extended != nil { if entry.Extended != nil {
storedKeyMD5 := string(entry.Extended[s3_constants.AmzServerSideEncryptionCustomerKeyMD5]) storedKeyMD5 := string(entry.Extended[s3_constants.AmzServerSideEncryptionCustomerKeyMD5])
@ -700,18 +700,18 @@ func (s3a *S3ApiServer) createSSECDecryptedReaderFromEntry(r *http.Request, encr
return nil, fmt.Errorf("SSE-C key mismatch") return nil, fmt.Errorf("SSE-C key mismatch")
} }
} }
// Get IV from entry metadata // Get IV from entry metadata
ivBase64 := string(entry.Extended[s3_constants.SeaweedFSSSEIVHeader]) ivBase64 := string(entry.Extended[s3_constants.SeaweedFSSSEIVHeader])
if ivBase64 == "" { if ivBase64 == "" {
return nil, fmt.Errorf("SSE-C IV not found in metadata") return nil, fmt.Errorf("SSE-C IV not found in metadata")
} }
iv, err := base64.StdEncoding.DecodeString(ivBase64) iv, err := base64.StdEncoding.DecodeString(ivBase64)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to decode IV: %w", err) return nil, fmt.Errorf("failed to decode IV: %w", err)
} }
// Create decrypted reader // Create decrypted reader
return CreateSSECDecryptedReader(encryptedReader, customerKey, iv) return CreateSSECDecryptedReader(encryptedReader, customerKey, iv)
} }
@ -722,22 +722,22 @@ func (s3a *S3ApiServer) createSSEKMSDecryptedReaderFromEntry(r *http.Request, en
if entry.Extended == nil { if entry.Extended == nil {
return nil, fmt.Errorf("no extended metadata found") return nil, fmt.Errorf("no extended metadata found")
} }
kmsMetadataB64, exists := entry.Extended[s3_constants.SeaweedFSSSEKMSKeyHeader] kmsMetadataB64, exists := entry.Extended[s3_constants.SeaweedFSSSEKMSKeyHeader]
if !exists { if !exists {
return nil, fmt.Errorf("SSE-KMS metadata not found") return nil, fmt.Errorf("SSE-KMS metadata not found")
} }
kmsMetadataBytes, err := base64.StdEncoding.DecodeString(string(kmsMetadataB64)) kmsMetadataBytes, err := base64.StdEncoding.DecodeString(string(kmsMetadataB64))
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to decode SSE-KMS metadata: %w", err) return nil, fmt.Errorf("failed to decode SSE-KMS metadata: %w", err)
} }
sseKMSKey, err := DeserializeSSEKMSMetadata(kmsMetadataBytes) sseKMSKey, err := DeserializeSSEKMSMetadata(kmsMetadataBytes)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to deserialize SSE-KMS metadata: %w", err) return nil, fmt.Errorf("failed to deserialize SSE-KMS metadata: %w", err)
} }
// Create decrypted reader // Create decrypted reader
return CreateSSEKMSDecryptedReader(encryptedReader, sseKMSKey) return CreateSSEKMSDecryptedReader(encryptedReader, sseKMSKey)
} }
@ -748,24 +748,24 @@ func (s3a *S3ApiServer) createSSES3DecryptedReaderFromEntry(r *http.Request, enc
if entry.Extended == nil { if entry.Extended == nil {
return nil, fmt.Errorf("no extended metadata found") return nil, fmt.Errorf("no extended metadata found")
} }
keyData, exists := entry.Extended[s3_constants.SeaweedFSSSES3Key] keyData, exists := entry.Extended[s3_constants.SeaweedFSSSES3Key]
if !exists { if !exists {
return nil, fmt.Errorf("SSE-S3 metadata not found") return nil, fmt.Errorf("SSE-S3 metadata not found")
} }
keyManager := GetSSES3KeyManager() keyManager := GetSSES3KeyManager()
sseS3Key, err := DeserializeSSES3Metadata(keyData, keyManager) sseS3Key, err := DeserializeSSES3Metadata(keyData, keyManager)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to deserialize SSE-S3 metadata: %w", err) return nil, fmt.Errorf("failed to deserialize SSE-S3 metadata: %w", err)
} }
// Get IV // Get IV
iv, err := GetSSES3IV(entry, sseS3Key, keyManager) iv, err := GetSSES3IV(entry, sseS3Key, keyManager)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to get SSE-S3 IV: %w", err) return nil, fmt.Errorf("failed to get SSE-S3 IV: %w", err)
} }
// Create decrypted reader // Create decrypted reader
return CreateSSES3DecryptedReader(encryptedReader, sseS3Key, iv) return CreateSSES3DecryptedReader(encryptedReader, sseS3Key, iv)
} }

Loading…
Cancel
Save