use of com.amazonaws.services.s3.AmazonS3EncryptionClient.USER_AGENT in project aws-sdk-android by aws-amplify.
the class S3CryptoModuleBase method completeMultipartUploadSecurely.
@Override
public CompleteMultipartUploadResult completeMultipartUploadSecurely(CompleteMultipartUploadRequest req) {
appendUserAgent(req, USER_AGENT);
final String uploadId = req.getUploadId();
final T uploadContext = multipartUploadContexts.get(uploadId);
if (uploadContext != null && !uploadContext.hasFinalPartBeenSeen()) {
throw new AmazonClientException("Unable to complete an encrypted multipart upload without being told which part was the last. " + "Without knowing which part was the last, the encrypted data in Amazon S3 is incomplete and corrupt.");
}
final CompleteMultipartUploadResult result = s3.completeMultipartUpload(req);
// after the whole upload has completed correctly.
if (uploadContext != null && cryptoConfig.getStorageMode() == InstructionFile) {
// Put the instruction file into S3
s3.putObject(createInstructionPutRequest(uploadContext.getBucketName(), uploadContext.getKey(), uploadContext.getContentCryptoMaterial()));
}
multipartUploadContexts.remove(uploadId);
return result;
}
use of com.amazonaws.services.s3.AmazonS3EncryptionClient.USER_AGENT in project aws-sdk-android by aws-amplify.
the class S3CryptoModuleBase method uploadPartSecurely.
/**
* {@inheritDoc}
*
* <p>
* <b>NOTE:</b> Because the encryption process requires context from
* previous blocks, parts uploaded with the AmazonS3EncryptionClient (as
* opposed to the normal AmazonS3Client) must be uploaded serially, and in
* order. Otherwise, the previous encryption context isn't available to use
* when encrypting the current part.
*/
@Override
public UploadPartResult uploadPartSecurely(UploadPartRequest req) {
appendUserAgent(req, USER_AGENT);
final int blockSize = contentCryptoScheme.getBlockSizeInBytes();
final boolean isLastPart = req.isLastPart();
final String uploadId = req.getUploadId();
final long partSize = req.getPartSize();
final boolean partSizeMultipleOfCipherBlockSize = 0 == (partSize % blockSize);
if (!isLastPart && !partSizeMultipleOfCipherBlockSize) {
throw new AmazonClientException("Invalid part size: part sizes for encrypted multipart uploads must be multiples " + "of the cipher block size (" + blockSize + ") with the exception of the last part.");
}
final T uploadContext = multipartUploadContexts.get(uploadId);
if (uploadContext == null) {
throw new AmazonClientException("No client-side information available on upload ID " + uploadId);
}
final UploadPartResult result;
// Checks the parts are uploaded in series
uploadContext.beginPartUpload(req.getPartNumber());
final CipherLite cipherLite = cipherLiteForNextPart(uploadContext);
final File fileOrig = req.getFile();
final InputStream isOrig = req.getInputStream();
SdkFilterInputStream isCurr = null;
try {
final CipherLiteInputStream clis = newMultipartS3CipherInputStream(req, cipherLite);
// so the clis will be closed (in the finally block below) upon
isCurr = clis;
// unexpected failure should we opened a file undereath
isCurr = wrapForMultipart(clis, partSize);
req.setInputStream(isCurr);
// Treat all encryption requests as input stream upload requests,
// not as file upload requests.
req.setFile(null);
req.setFileOffset(0);
// 16-byte mac
if (isLastPart) {
// We only change the size of the last part
final long lastPartSize = computeLastPartSize(req);
if (lastPartSize > -1) {
req.setPartSize(lastPartSize);
}
if (uploadContext.hasFinalPartBeenSeen()) {
throw new AmazonClientException("This part was specified as the last part in a multipart upload, but a previous part was already marked as the last part. " + "Only the last part of the upload should be marked as the last part.");
}
}
result = s3.uploadPart(req);
} finally {
cleanupDataSource(req, fileOrig, isOrig, isCurr, log);
uploadContext.endPartUpload();
}
if (isLastPart) {
uploadContext.setHasFinalPartBeenSeen(true);
}
updateUploadContext(uploadContext, isCurr);
return result;
}
use of com.amazonaws.services.s3.AmazonS3EncryptionClient.USER_AGENT in project aws-sdk-android by aws-amplify.
the class S3CryptoModuleBase method initiateMultipartUploadSecurely.
@Override
public InitiateMultipartUploadResult initiateMultipartUploadSecurely(InitiateMultipartUploadRequest req) {
appendUserAgent(req, USER_AGENT);
// Generate a one-time use symmetric key and initialize a cipher to
// encrypt object data
final ContentCryptoMaterial cekMaterial = createContentCryptoMaterial(req);
if (cryptoConfig.getStorageMode() == ObjectMetadata) {
ObjectMetadata metadata = req.getObjectMetadata();
if (metadata == null) {
metadata = new ObjectMetadata();
}
// Store encryption info in metadata
req.setObjectMetadata(updateMetadataWithContentCryptoMaterial(metadata, null, cekMaterial));
}
final InitiateMultipartUploadResult result = s3.initiateMultipartUpload(req);
final T uploadContext = newUploadContext(req, cekMaterial);
if (req instanceof MaterialsDescriptionProvider) {
final MaterialsDescriptionProvider p = (MaterialsDescriptionProvider) req;
uploadContext.setMaterialsDescription(p.getMaterialsDescription());
}
multipartUploadContexts.put(result.getUploadId(), uploadContext);
return result;
}
use of com.amazonaws.services.s3.AmazonS3EncryptionClient.USER_AGENT in project aws-sdk-android by aws-amplify.
the class AmazonS3EncryptionClient method deleteObject.
@Override
public void deleteObject(DeleteObjectRequest req) {
req.getRequestClientOptions().appendUserAgent(USER_AGENT);
// Delete the object
super.deleteObject(req);
// If it exists, delete the instruction file.
InstructionFileId ifid = new S3ObjectId(req.getBucketName(), req.getKey()).instructionFileId();
DeleteObjectRequest instructionDeleteRequest = (DeleteObjectRequest) req.clone();
instructionDeleteRequest.withBucketName(ifid.getBucket()).withKey(ifid.getKey());
super.deleteObject(instructionDeleteRequest);
}
use of com.amazonaws.services.s3.AmazonS3EncryptionClient.USER_AGENT in project aws-sdk-android by aws-amplify.
the class S3CryptoModuleAE method getObjectSecurely.
@Override
public S3Object getObjectSecurely(GetObjectRequest req) {
appendUserAgent(req, USER_AGENT);
// Adjust the crypto range to retrieve all of the cipher blocks needed to contain the user's desired
// range of bytes.
final long[] desiredRange = req.getRange();
if (isStrict() && (desiredRange != null || req.getPartNumber() != null)) {
throw new SecurityException("Range get and getting a part are not allowed in strict crypto mode");
}
final long[] adjustedCryptoRange = getAdjustedCryptoRange(desiredRange);
if (adjustedCryptoRange != null) {
req.setRange(adjustedCryptoRange[0], adjustedCryptoRange[1]);
}
// Get the object from S3
final S3Object retrieved = s3.getObject(req);
// would return null, so we simply return null as well.
if (retrieved == null) {
return null;
}
String suffix = null;
if (req instanceof EncryptedGetObjectRequest) {
final EncryptedGetObjectRequest ereq = (EncryptedGetObjectRequest) req;
suffix = ereq.getInstructionFileSuffix();
}
try {
return suffix == null || suffix.trim().isEmpty() ? decipher(req, desiredRange, adjustedCryptoRange, retrieved) : decipherWithInstFileSuffix(req, desiredRange, adjustedCryptoRange, retrieved, suffix);
} catch (final RuntimeException ex) {
// If we're unable to set up the decryption, make sure we close the
// HTTP connection
closeQuietly(retrieved, log);
throw ex;
} catch (final Error error) {
closeQuietly(retrieved, log);
throw error;
}
}
Aggregations