|
|
@ -772,12 +772,14 @@ func (s3a *S3ApiServer) createLookupFileIdFunction() func(context.Context, strin |
|
|
} |
|
|
} |
|
|
if locs, found := resp.LocationsMap[vid]; found { |
|
|
if locs, found := resp.LocationsMap[vid]; found { |
|
|
for _, loc := range locs.Locations { |
|
|
for _, loc := range locs.Locations { |
|
|
// Ensure URL has http:// scheme prefix for proper URL parsing
|
|
|
|
|
|
urls = append(urls, "http://"+loc.Url) |
|
|
|
|
|
|
|
|
// Build complete URL with volume server address and fileId
|
|
|
|
|
|
// Format: http://host:port/volumeId,fileId
|
|
|
|
|
|
urls = append(urls, "http://"+loc.Url+"/"+fileId) |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
return nil |
|
|
return nil |
|
|
}) |
|
|
}) |
|
|
|
|
|
glog.V(3).Infof("createLookupFileIdFunction: fileId=%s, resolved urls=%v", fileId, urls) |
|
|
return urls, err |
|
|
return urls, err |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
@ -1224,20 +1226,14 @@ func (s3a *S3ApiServer) decryptSSECChunkView(ctx context.Context, fileChunk *fil |
|
|
|
|
|
|
|
|
// Decrypt with CTR IV offset adjustment
|
|
|
// Decrypt with CTR IV offset adjustment
|
|
|
// CTR mode: IV for block N = base_IV + (N / 16)
|
|
|
// CTR mode: IV for block N = base_IV + (N / 16)
|
|
|
// PartOffset in metadata distinguishes single-part vs multipart:
|
|
|
|
|
|
// - Single-part: PartOffset = 0 for all chunks (one encrypted stream starting at 0)
|
|
|
|
|
|
// - Multipart: PartOffset = chunk position within part during upload
|
|
|
|
|
|
var ivOffset int64 |
|
|
|
|
|
if ssecMetadata.PartOffset == 0 { |
|
|
|
|
|
// Single-part upload: use absolute file position
|
|
|
|
|
|
ivOffset = chunkView.ViewOffset |
|
|
|
|
|
} else { |
|
|
|
|
|
// Multipart upload: use position within the part's encrypted stream
|
|
|
|
|
|
// After assembly, chunk.Offset is in final file, so we calculate position within part
|
|
|
|
|
|
ivOffset = chunkView.ViewOffset - fileChunk.Offset |
|
|
|
|
|
} |
|
|
|
|
|
glog.V(3).Infof("decryptSSECChunkView: chunk=%s, fileChunk.Offset=%d, chunkView.ViewOffset=%d, chunkView.ViewSize=%d, metadata.PartOffset=%d, ivOffset=%d", |
|
|
|
|
|
chunkView.FileId, fileChunk.Offset, chunkView.ViewOffset, chunkView.ViewSize, ssecMetadata.PartOffset, ivOffset) |
|
|
|
|
|
|
|
|
// PartOffset stores the position within the encrypted stream (which always starts at 0)
|
|
|
|
|
|
// After multipart assembly, fileChunk.Offset is the position in the final file
|
|
|
|
|
|
// Formula: ivOffset = PartOffset + (ViewOffset - fileChunk.Offset)
|
|
|
|
|
|
// - PartOffset: where this chunk is in its encrypted stream
|
|
|
|
|
|
// - (ViewOffset - fileChunk.Offset): offset within this chunk
|
|
|
|
|
|
ivOffset := ssecMetadata.PartOffset + (chunkView.ViewOffset - fileChunk.Offset) |
|
|
|
|
|
glog.V(3).Infof("decryptSSECChunkView: chunk=%s, fileChunk.Offset=%d, chunkView.ViewOffset=%d, metadata.PartOffset=%d, ivOffset=%d", |
|
|
|
|
|
chunkView.FileId, fileChunk.Offset, chunkView.ViewOffset, ssecMetadata.PartOffset, ivOffset) |
|
|
adjustedIV := adjustCTRIV(chunkIV, ivOffset) |
|
|
adjustedIV := adjustCTRIV(chunkIV, ivOffset) |
|
|
return CreateSSECDecryptedReader(encryptedReader, customerKey, adjustedIV) |
|
|
return CreateSSECDecryptedReader(encryptedReader, customerKey, adjustedIV) |
|
|
} |
|
|
} |
|
|
@ -1265,18 +1261,10 @@ func (s3a *S3ApiServer) decryptSSEKMSChunkView(ctx context.Context, fileChunk *f |
|
|
return nil, fmt.Errorf("failed to fetch chunk data: %w", err) |
|
|
return nil, fmt.Errorf("failed to fetch chunk data: %w", err) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Decrypt with CTR IV offset adjustment
|
|
|
|
|
|
// ChunkOffset in KMS metadata distinguishes single-part vs multipart (same logic as SSE-C)
|
|
|
|
|
|
// - Single-part: ChunkOffset = 0 for all chunks (one encrypted stream starting at 0)
|
|
|
|
|
|
// - Multipart: ChunkOffset = chunk position within part during upload
|
|
|
|
|
|
var ivOffset int64 |
|
|
|
|
|
if sseKMSKey.ChunkOffset == 0 { |
|
|
|
|
|
// Single-part upload: use absolute file position
|
|
|
|
|
|
ivOffset = chunkView.ViewOffset |
|
|
|
|
|
} else { |
|
|
|
|
|
// Multipart upload: use position within the part's encrypted stream
|
|
|
|
|
|
ivOffset = chunkView.ViewOffset - fileChunk.Offset |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// Decrypt with CTR IV offset adjustment (same logic as SSE-C)
|
|
|
|
|
|
// ChunkOffset stores the position within the encrypted stream (which always starts at 0)
|
|
|
|
|
|
// Formula: ivOffset = ChunkOffset + (ViewOffset - fileChunk.Offset)
|
|
|
|
|
|
ivOffset := sseKMSKey.ChunkOffset + (chunkView.ViewOffset - fileChunk.Offset) |
|
|
adjustedIV := adjustCTRIV(sseKMSKey.IV, ivOffset) |
|
|
adjustedIV := adjustCTRIV(sseKMSKey.IV, ivOffset) |
|
|
adjustedKey := &SSEKMSKey{ |
|
|
adjustedKey := &SSEKMSKey{ |
|
|
KeyID: sseKMSKey.KeyID, |
|
|
KeyID: sseKMSKey.KeyID, |
|
|
|