Encryption Instructions store the encryption crdentials
        /// <summary>
        /// Updates the request where the input stream contains the encrypted object contents.
        /// </summary>
        /// <param name="request"></param>
        private void GenerateEncryptedUploadPartRequest(UploadPartRequest request)
        {
            string uploadID = request.UploadId;

            UploadPartEncryptionContext contextForEncryption = currentMultiPartUploadKeys[uploadID];

            byte[] envelopeKey = contextForEncryption.EnvelopeKey;
            byte[] IV          = contextForEncryption.NextIV;

            EncryptionInstructions instructions = new EncryptionInstructions(EncryptionMaterials.EmptyMaterialsDescription, envelopeKey, IV);

            if (request.IsLastPart == false)
            {
                if (contextForEncryption.IsFinalPart == true)
                {
                    throw new AmazonClientException("Last part has already been processed, cannot upload this as the last part");
                }

                if (request.PartNumber < contextForEncryption.PartNumber)
                {
                    throw new AmazonClientException("Upload Parts must in correct sequence");
                }

                request.InputStream             = EncryptionUtils.EncryptUploadPartRequestUsingInstructions(request.InputStream, instructions);
                contextForEncryption.PartNumber = request.PartNumber;
            }
            else
            {
                request.InputStream = EncryptionUtils.EncryptRequestUsingInstruction(request.InputStream, instructions);
                contextForEncryption.IsFinalPart = true;
            }
            request.RequestState.Add(S3CryptoStream, request.InputStream);
        }
Exemple #2
0
        //wrap encrypted stream into AESDecriptionStream wrapper
        internal static Stream DecryptStream(Stream encryptedStream, EncryptionInstructions encryptionInstructions)
        {
            AESDecryptionStream aesDecryptStream;

            aesDecryptStream = new AESDecryptionStream(encryptedStream, encryptionInstructions.EnvelopeKey, encryptionInstructions.InitializationVector);
            return(aesDecryptStream);
        }
        /// <summary>
        /// Updates object where the object input stream contains the decrypted contents.
        /// </summary>
        /// <param name="objectResponse">
        /// The getObject response whose contents are to be decrypted.
        /// </param>
        private void DecryptObjectUsingMetadata(GetObjectResponse objectResponse)
        {
            // Create an instruction object from the object metadata
            EncryptionInstructions instructions = EncryptionUtils.BuildInstructionsFromObjectMetadata(objectResponse, this.encryptionMaterials);

            // Decrypt the object with the instruction
            EncryptionUtils.DecryptObjectUsingInstructions(objectResponse, instructions);
        }
        /// <summary>
        /// Updates object where the object input stream contains the decrypted contents.
        /// </summary>
        /// <param name="instructionFileResponse">
        /// The getObject response of InstructionFile.
        /// </param>
        /// <param name="response">
        /// The getObject response whose contents are to be decrypted.
        /// </param>
        private void DecryptObjectUsingInstructionFile(GetObjectResponse response, GetObjectResponse instructionFileResponse)
        {
            // Create an instruction object from the instruction file response
            EncryptionInstructions instructions = EncryptionUtils.BuildInstructionsUsingInstructionFile(instructionFileResponse, this.encryptionMaterials);

            // Decrypt the object with the instructions
            EncryptionUtils.DecryptObjectUsingInstructions(response, instructions);
        }
Exemple #5
0
        /// <summary>
        /// Returns an updated stream where the stream contains the encrypted object contents.
        /// The specified instruction will be used to encrypt data.
        /// </summary>
        /// <param name="toBeEncrypted">
        /// The stream whose contents are to be encrypted.
        /// </param>
        /// <param name="instructions">
        /// The instruction that will be used to encrypt the object data.
        /// </param>
        /// <returns>
        /// Encrypted stream, i.e input stream wrapped into encrypted stream
        /// </returns>
        internal static Stream EncryptRequestUsingInstruction(Stream toBeEncrypted, EncryptionInstructions instructions)
        {
            //wrap input stream into AESEncryptionPutObjectStream wrapper
            AESEncryptionPutObjectStream aesEStream;

            aesEStream = new AESEncryptionPutObjectStream(toBeEncrypted, instructions.EnvelopeKey, instructions.InitializationVector);
            return(aesEStream);
        }
        /// <summary>
        /// Updates the request where the metadata contains encryption information
        /// and the input stream contains the encrypted object contents.
        /// </summary>
        /// <param name="putObjectRequest">
        /// The request whose contents are to be encrypted.
        /// </param>
        private void GenerateEncryptedObjectRequestUsingMetadata(PutObjectRequest putObjectRequest)
        {
            // Create instruction
            EncryptionInstructions instructions = EncryptionUtils.GenerateInstructions(this.encryptionMaterials);

            EncryptionUtils.AddUnencryptedContentLengthToMetadata(putObjectRequest);

            // Encrypt the object data with the instruction
            putObjectRequest.InputStream = EncryptionUtils.EncryptRequestUsingInstruction(putObjectRequest.InputStream, instructions);

            // Update the metadata
            EncryptionUtils.UpdateMetadataWithEncryptionInstructions(putObjectRequest, instructions);
        }
        /// <summary>
        /// Updates the request where the instruction file contains encryption information
        /// and the input stream contains the encrypted object contents.
        /// </summary>
        /// <param name="putObjectRequest"></param>
        private void GenerateEncryptedObjectRequestUsingInstructionFile(PutObjectRequest putObjectRequest)
        {
            // Create instruction
            EncryptionInstructions instructions = EncryptionUtils.GenerateInstructions(this.encryptionMaterials);

            EncryptionUtils.AddUnencryptedContentLengthToMetadata(putObjectRequest);

            // Encrypt the object data with the instruction
            putObjectRequest.InputStream = EncryptionUtils.EncryptRequestUsingInstruction(putObjectRequest.InputStream, instructions);

            // Create request for uploading instruction file
            PutObjectRequest instructionFileRequest = EncryptionUtils.CreateInstructionFileRequest(putObjectRequest, instructions);

            S3ClientForInstructionFile.PutObject(instructionFileRequest);
        }
        /// <summary>
        /// Update the request's ObjectMetadata with the necessary information for decrypting the object.
        /// </summary>
        /// <param name="request">
        /// AmazonWebServiceRequest  encrypted using the given instruction
        /// </param>
        /// <param name="instructions">
        /// Non-null instruction used to encrypt the data in this AmazonWebServiceRequest .
        /// </param>
        /// <param name="useV2Metadata">
        /// If true use V2 metadata format, otherwise use V1.
        /// </param>
        internal static void UpdateMetadataWithEncryptionInstructions(
            AmazonWebServiceRequest request, EncryptionInstructions instructions,
            bool useV2Metadata)
        {
            byte[] keyBytesToStoreInMetadata = instructions.EncryptedEnvelopeKey;
            string base64EncodedEnvelopeKey  = Convert.ToBase64String(keyBytesToStoreInMetadata);

            byte[] IVToStoreInMetadata = instructions.InitializationVector;
            string base64EncodedIV     = Convert.ToBase64String(IVToStoreInMetadata);

            MetadataCollection metadata = null;

            var putObjectRequest = request as PutObjectRequest;

            if (putObjectRequest != null)
            {
                metadata = putObjectRequest.Metadata;
            }

            var initiateMultipartrequest = request as InitiateMultipartUploadRequest;

            if (initiateMultipartrequest != null)
            {
                metadata = initiateMultipartrequest.Metadata;
            }

            if (metadata != null)
            {
                if (useV2Metadata)
                {
                    metadata.Add(XAmzKeyV2, base64EncodedEnvelopeKey);
                    metadata.Add(XAmzWrapAlg, XAmzWrapAlgValue);
                    metadata.Add(XAmzCEKAlg, XAmzCEKAlgValue);
                }
                else
                {
                    metadata.Add(XAmzKey, base64EncodedEnvelopeKey);
                }

                metadata.Add(XAmzIV, base64EncodedIV);
                metadata.Add(XAmzMatDesc, JsonMapper.ToJson(instructions.MaterialsDescription));
            }
        }
        /// <summary>
        /// Performs encryption for PutObject and MultiPartUpload,
        /// also adding encryption information to object metadata or
        /// instruction file
        /// </summary>
        /// <param name="request">AmazonWebServiceRequest on which encryption is performed </param>
        protected override void ProcessPreRequestHandlers(AmazonWebServiceRequest request)
        {
            base.ProcessPreRequestHandlers(request);

            var putObjectRequest = request as PutObjectRequest;

            if (putObjectRequest != null)
            {
                if (this.amazonS3CryptoConfig.StorageMode == CryptoStorageMode.InstructionFile)
                {
                    GenerateEncryptedObjectRequestUsingInstructionFile(putObjectRequest);
                }
                else
                {
                    GenerateEncryptedObjectRequestUsingMetadata(putObjectRequest);
                }
            }

            var initiateMultiPartRequest = request as InitiateMultipartUploadRequest;

            if (initiateMultiPartRequest != null)
            {
                EncryptionInstructions instructions = EncryptionUtils.GenerateInstructions(this.encryptionMaterials);

                if (this.amazonS3CryptoConfig.StorageMode == CryptoStorageMode.ObjectMetadata)
                {
                    EncryptionUtils.UpdateMetadataWithEncryptionInstructions(initiateMultiPartRequest, instructions);
                }

                initiateMultiPartRequest.EnvelopeKey = instructions.EnvelopeKey;
                initiateMultiPartRequest.IV          = instructions.InitializationVector;
            }

            var uploadPartRequest = request as UploadPartRequest;

            if (uploadPartRequest != null)
            {
                GenerateEncryptedUploadPartRequest(uploadPartRequest);
            }
        }
Exemple #10
0
 /// <summary>
 /// Returns an updated input stream where the input stream contains the encrypted object contents.
 /// The specified instruction will be used to encrypt data.
 /// </summary>
 /// <param name="toBeEncrypted">
 /// The stream whose contents are to be encrypted.
 /// </param>
 /// <param name="instructions">
 /// The instruction that will be used to encrypt the object data.
 /// </param>
 /// <returns>
 /// Encrypted stream, i.e input stream wrapped into encrypted stream
 /// </returns>
 internal static Stream EncryptUploadPartRequestUsingInstructions(Stream toBeEncrypted, EncryptionInstructions instructions)
 {
     //wrap input stream into AESEncryptionStreamForUploadPart wrapper
     AESEncryptionUploadPartStream aesEStream;
     aesEStream = new AESEncryptionUploadPartStream(toBeEncrypted, instructions.EnvelopeKey, instructions.InitializationVector);
     return aesEStream;
 }
Exemple #11
0
        /// <summary>
        /// Returns an updated stream where the stream contains the encrypted object contents.
        /// The specified instruction will be used to encrypt data.
        /// </summary>
        /// <param name="toBeEncrypted">
        /// The stream whose contents are to be encrypted.
        /// </param>
        /// <param name="instructions">
        /// The instruction that will be used to encrypt the object data.
        /// </param>
        /// <returns>
        /// Encrypted stream, i.e input stream wrapped into encrypted stream
        /// </returns>
        internal static Stream EncryptRequestUsingInstruction(Stream toBeEncrypted, EncryptionInstructions instructions)
        {
            //wrap input stream into AESEncryptionPutObjectStream wrapper
            AESEncryptionPutObjectStream aesEStream;
            aesEStream = new AESEncryptionPutObjectStream(toBeEncrypted, instructions.EnvelopeKey, instructions.InitializationVector);
            return aesEStream;

        }
Exemple #12
0
 /// <summary>
 /// Updates object where the object
 /// input stream contains the decrypted contents.
 /// </summary>
 /// <param name="response">
 /// The getObject response whose contents are to be decrypted.
 /// </param>
 /// <param name="instructions">
 /// The instruction that will be used to encrypt the object data.
 /// </param>
 internal static void DecryptObjectUsingInstructions(GetObjectResponse response, EncryptionInstructions instructions)
 {
     response.ResponseStream = DecryptStream(response.ResponseStream, instructions);
 }
        /// <summary>
        /// Performs decryption of data by getting encryption information
        /// from object metadata or instruction file.
        /// </summary>
        /// <param name="response">AmazonWebServiceResponse on which decryption is performed</param>
        /// <param name="request">IRequest</param>
        /// <param name="webResponseData">IWebResponseData</param>
        protected override void ProcessResponseHandlers(AmazonWebServiceResponse response, IRequest request, IWebResponseData webResponseData)
        {
            base.ProcessResponseHandlers(response, request, webResponseData);

            var initiateMultiPartUploadRequest = request.OriginalRequest as InitiateMultipartUploadRequest;
            var initiateMultiPartResponse = response as InitiateMultipartUploadResponse;
            if (initiateMultiPartResponse != null)
            {
                byte[] envelopeKey = initiateMultiPartUploadRequest.EnvelopeKey;
                byte[] iv = initiateMultiPartUploadRequest.IV;

                UploadPartEncryptionContext contextForEncryption = new UploadPartEncryptionContext();
                contextForEncryption.EnvelopeKey = envelopeKey;
                contextForEncryption.NextIV = iv;
                contextForEncryption.FirstIV = iv;
                contextForEncryption.PartNumber = 0;

                //Add context for encryption of next part
                currentMultiPartUploadKeys.Add(initiateMultiPartResponse.UploadId, contextForEncryption);
            }

            var uploadPartRequest = request.OriginalRequest as UploadPartRequest;
            var uploadPartResponse = response as UploadPartResponse;
            if (uploadPartResponse != null)
            {
                string uploadID = uploadPartRequest.UploadId;
                UploadPartEncryptionContext encryptedUploadedContext = null;

                if (!currentMultiPartUploadKeys.TryGetValue(uploadID, out encryptedUploadedContext))
                    throw new AmazonS3Exception("encryption context for multi part upload not found");

                if (uploadPartRequest.IsLastPart == false)
                {
                    object stream = null;

                    if (!uploadPartRequest.RequestState.TryGetValue(S3CryptoStream, out stream))
                        throw new AmazonS3Exception("cannot retrieve S3 crypto stream from request state, hence cannot get Initialization vector for next uploadPart ");

                    var encryptionStream = stream as AESEncryptionUploadPartStream;
                    encryptedUploadedContext.NextIV = encryptionStream.InitializationVector;
                }

            }

            var getObjectResponse = response as GetObjectResponse;
            if (getObjectResponse != null)
            {
                if (EncryptionUtils.IsEncryptionInfoInMetadata(getObjectResponse) == true)
                {
                    DecryptObjectUsingMetadata(getObjectResponse);
                }
                else
                {
                    GetObjectResponse instructionFileResponse = null;
                    try
                    {
                        GetObjectRequest instructionFileRequest = EncryptionUtils.GetInstructionFileRequest(getObjectResponse);
                        instructionFileResponse = S3ClientForInstructionFile.GetObject(instructionFileRequest);
                    }
                    catch (AmazonServiceException ace)
                    {
                        throw new AmazonServiceException(string.Format(CultureInfo.InvariantCulture, "Unable to decrypt data for object {0} in bucket {1}",
                            getObjectResponse.Key, getObjectResponse.BucketName), ace);
                    }

                    if (EncryptionUtils.IsEncryptionInfoInInstructionFile(instructionFileResponse) == true)
                    {
                        DecryptObjectUsingInstructionFile(getObjectResponse, instructionFileResponse);
                    }
                }
            }

            var completeMultiPartUploadRequest = request.OriginalRequest as CompleteMultipartUploadRequest;
            var completeMultipartUploadResponse = response as CompleteMultipartUploadResponse;
            if (completeMultipartUploadResponse != null)
            {
                if (amazonS3CryptoConfig.StorageMode == CryptoStorageMode.InstructionFile)
                {
                    UploadPartEncryptionContext context = currentMultiPartUploadKeys[completeMultiPartUploadRequest.UploadId];
                    byte[] envelopeKey = context.EnvelopeKey;
                    byte[] iv = context.FirstIV;
                    byte[] encryptedEnvelopeKey = EncryptionUtils.EncryptEnvelopeKey(envelopeKey, this.encryptionMaterials);
                    EncryptionInstructions instructions = new EncryptionInstructions(EncryptionMaterials.EmptyMaterialsDescription, envelopeKey, encryptedEnvelopeKey, iv);

                    PutObjectRequest instructionFileRequest = EncryptionUtils.CreateInstructionFileRequest(completeMultiPartUploadRequest, instructions);

                    S3ClientForInstructionFile.PutObject(instructionFileRequest);
                }

                //Clear Context data since encryption is completed
                currentMultiPartUploadKeys.Clear();
            }
        }
        /// <summary>
        /// Updates the request where the input stream contains the encrypted object contents.
        /// </summary>
        /// <param name="request"></param>
        private void GenerateEncryptedUploadPartRequest(UploadPartRequest request)
        {
            string uploadID = request.UploadId;

            UploadPartEncryptionContext contextForEncryption = currentMultiPartUploadKeys[uploadID];
            byte[] envelopeKey = contextForEncryption.EnvelopeKey;
            byte[] IV = contextForEncryption.NextIV;

            EncryptionInstructions instructions = new EncryptionInstructions(EncryptionMaterials.EmptyMaterialsDescription, envelopeKey, IV);

            if (request.IsLastPart == false)
            {
                if (contextForEncryption.IsFinalPart == true)
                    throw new AmazonClientException("Last part has already been processed, cannot upload this as the last part");

                if (request.PartNumber < contextForEncryption.PartNumber)
                    throw new AmazonClientException("Upload Parts must in correct sequence");

                request.InputStream = EncryptionUtils.EncryptUploadPartRequestUsingInstructions(request.InputStream, instructions);
                contextForEncryption.PartNumber = request.PartNumber;
            }
            else
            {
                request.InputStream = EncryptionUtils.EncryptRequestUsingInstruction(request.InputStream, instructions);
                contextForEncryption.IsFinalPart = true;
            }
            request.RequestState.Add(S3CryptoStream, request.InputStream);
        }
Exemple #15
0
        internal static PutObjectRequest CreateInstructionFileRequest(AmazonWebServiceRequest request, EncryptionInstructions instructions)
        {
            byte[] keyBytesToStoreInInstructionFile = instructions.EncryptedEnvelopeKey;
            string base64EncodedEnvelopeKey = Convert.ToBase64String(keyBytesToStoreInInstructionFile);

            byte[] IVToStoreInInstructionFile = instructions.InitializationVector;
            string base64EncodedIV = Convert.ToBase64String(IVToStoreInInstructionFile);

            JsonData jsonData = new JsonData();
            jsonData["EncryptedEnvelopeKey"] = base64EncodedEnvelopeKey;
            jsonData["IV"] = base64EncodedIV;

            string credentials = jsonData.ToJson();

            var putObjectRequest = request as PutObjectRequest;
            if (putObjectRequest != null)
            {
                PutObjectRequest requestforInstructionFile = new PutObjectRequest()
                {
                    BucketName = putObjectRequest.BucketName,
                    Key = putObjectRequest.Key + instructionfileSuffix,
                    ContentBody = credentials
                };
                requestforInstructionFile.Metadata.Add(instructionFileInfo, "");
                return requestforInstructionFile;
            }

            var completeMultiPartRequest = request as CompleteMultipartUploadRequest;
            if (completeMultiPartRequest != null)
            {
                PutObjectRequest requestforInstructionFile = new PutObjectRequest()
                {
                    BucketName = completeMultiPartRequest.BucketName,
                    Key = completeMultiPartRequest.Key + instructionfileSuffix,
                    ContentBody = credentials
                };
                requestforInstructionFile.Metadata.Add(instructionFileInfo, "");
                return requestforInstructionFile;
            }

            else
                return null;
        }
Exemple #16
0
        /// <summary>
        /// Update the request's ObjectMetadata with the necessary information for decrypting the object.
        /// </summary>
        /// <param name="request">
        /// AmazonWebServiceRequest  encrypted using the given instruction
        /// </param>
        /// <param name="instructions">
        /// Non-null instruction used to encrypt the data in this AmazonWebServiceRequest .
        /// </param>
        internal static void UpdateMetadataWithEncryptionInstructions(AmazonWebServiceRequest request, EncryptionInstructions instructions)
        {
            byte[] keyBytesToStoreInMetadata = instructions.EncryptedEnvelopeKey;
            string base64EncodedEnvelopeKey = Convert.ToBase64String(keyBytesToStoreInMetadata);

            byte[] IVToStoreInMetadata = instructions.InitializationVector;
            string base64EncodedIV = Convert.ToBase64String(IVToStoreInMetadata);

            var putObjectRequest = request as PutObjectRequest;
            if (putObjectRequest != null)
            {
                MetadataCollection metadata = putObjectRequest.Metadata;
                metadata.Add(keyInMetadata, base64EncodedEnvelopeKey);
                metadata.Add(initVectorInMetadata, base64EncodedIV);

                Dictionary<string, string> materialsDescription = instructions.MaterialsDescription;
                if (materialsDescription.Count == 0)
                    metadata.Add(encryptionMaterialsDescription, "{}");

                putObjectRequest.Metadata = metadata;
            }

            var initiateMultipartrequest = request as InitiateMultipartUploadRequest;
            if (initiateMultipartrequest != null)
            {
                MetadataCollection metadata = initiateMultipartrequest.Metadata;
                metadata.Add(keyInMetadata, base64EncodedEnvelopeKey);
                metadata.Add(initVectorInMetadata, base64EncodedIV);

                Dictionary<string, string> materialsDescription = instructions.MaterialsDescription;
                if (materialsDescription.Count == 0)
                    metadata.Add(encryptionMaterialsDescription, "{}");

                initiateMultipartrequest.Metadata = metadata;
            }
        }
Exemple #17
0
 //wrap encrypted stream into AESDecriptionStream wrapper
 internal static Stream DecryptStream(Stream encryptedStream, EncryptionInstructions encryptionInstructions)
 {
     AESDecryptionStream aesDecryptStream;
     aesDecryptStream = new AESDecryptionStream(encryptedStream, encryptionInstructions.EnvelopeKey, encryptionInstructions.InitializationVector);
     return aesDecryptStream;
 }
        /// <summary>
        /// Performs decryption of data by getting encryption information
        /// from object metadata or instruction file.
        /// </summary>
        /// <param name="response">AmazonWebServiceResponse on which decryption is performed</param>
        /// <param name="request">IRequest</param>
        /// <param name="webResponseData">IWebResponseData</param>
        protected override void ProcessResponseHandlers(AmazonWebServiceResponse response, IRequest request, IWebResponseData webResponseData)
        {
            base.ProcessResponseHandlers(response, request, webResponseData);

            var initiateMultiPartUploadRequest = request.OriginalRequest as InitiateMultipartUploadRequest;
            var initiateMultiPartResponse      = response as InitiateMultipartUploadResponse;

            if (initiateMultiPartResponse != null)
            {
                byte[] envelopeKey = initiateMultiPartUploadRequest.EnvelopeKey;
                byte[] iv          = initiateMultiPartUploadRequest.IV;

                UploadPartEncryptionContext contextForEncryption = new UploadPartEncryptionContext();
                contextForEncryption.EnvelopeKey = envelopeKey;
                contextForEncryption.NextIV      = iv;
                contextForEncryption.FirstIV     = iv;
                contextForEncryption.PartNumber  = 0;

                //Add context for encryption of next part
                currentMultiPartUploadKeys.Add(initiateMultiPartResponse.UploadId, contextForEncryption);
            }

            var uploadPartRequest  = request.OriginalRequest as UploadPartRequest;
            var uploadPartResponse = response as UploadPartResponse;

            if (uploadPartResponse != null)
            {
                string uploadID = uploadPartRequest.UploadId;
                UploadPartEncryptionContext encryptedUploadedContext = null;

                if (!currentMultiPartUploadKeys.TryGetValue(uploadID, out encryptedUploadedContext))
                {
                    throw new AmazonS3Exception("encryption context for multi part upload not found");
                }

                if (uploadPartRequest.IsLastPart == false)
                {
                    object stream = null;

                    if (!uploadPartRequest.RequestState.TryGetValue(S3CryptoStream, out stream))
                    {
                        throw new AmazonS3Exception("cannot retrieve S3 crypto stream from request state, hence cannot get Initialization vector for next uploadPart ");
                    }

                    var encryptionStream = stream as AESEncryptionUploadPartStream;
                    encryptedUploadedContext.NextIV = encryptionStream.InitializationVector;
                }
            }

            var getObjectResponse = response as GetObjectResponse;

            if (getObjectResponse != null)
            {
                if (EncryptionUtils.IsEncryptionInfoInMetadata(getObjectResponse) == true)
                {
                    DecryptObjectUsingMetadata(getObjectResponse);
                }
                else
                {
                    GetObjectResponse instructionFileResponse = null;
                    try
                    {
                        GetObjectRequest instructionFileRequest = EncryptionUtils.GetInstructionFileRequest(getObjectResponse);
                        instructionFileResponse = S3ClientForInstructionFile.GetObject(instructionFileRequest);
                    }
                    catch (AmazonServiceException ace)
                    {
                        throw new AmazonServiceException(string.Format(CultureInfo.InvariantCulture, "Unable to decrypt data for object {0} in bucket {1}",
                                                                       getObjectResponse.Key, getObjectResponse.BucketName), ace);
                    }

                    if (EncryptionUtils.IsEncryptionInfoInInstructionFile(instructionFileResponse) == true)
                    {
                        DecryptObjectUsingInstructionFile(getObjectResponse, instructionFileResponse);
                    }
                }
            }

            var completeMultiPartUploadRequest  = request.OriginalRequest as CompleteMultipartUploadRequest;
            var completeMultipartUploadResponse = response as CompleteMultipartUploadResponse;

            if (completeMultipartUploadResponse != null)
            {
                if (amazonS3CryptoConfig.StorageMode == CryptoStorageMode.InstructionFile)
                {
                    UploadPartEncryptionContext context = currentMultiPartUploadKeys[completeMultiPartUploadRequest.UploadId];
                    byte[] envelopeKey                  = context.EnvelopeKey;
                    byte[] iv                           = context.FirstIV;
                    byte[] encryptedEnvelopeKey         = EncryptionUtils.EncryptEnvelopeKey(envelopeKey, this.encryptionMaterials);
                    EncryptionInstructions instructions = new EncryptionInstructions(EncryptionMaterials.EmptyMaterialsDescription, envelopeKey, encryptedEnvelopeKey, iv);

                    PutObjectRequest instructionFileRequest = EncryptionUtils.CreateInstructionFileRequest(completeMultiPartUploadRequest, instructions);

                    S3ClientForInstructionFile.PutObject(instructionFileRequest);
                }

                //Clear Context data since encryption is completed
                currentMultiPartUploadKeys.Clear();
            }
        }
Exemple #19
0
        /// <summary>
        /// Update the request's ObjectMetadata with the necessary information for decrypting the object.
        /// </summary>
        /// <param name="request">
        /// AmazonWebServiceRequest  encrypted using the given instruction
        /// </param>
        /// <param name="instructions">
        /// Non-null instruction used to encrypt the data in this AmazonWebServiceRequest .
        /// </param>
        internal static void UpdateMetadataWithEncryptionInstructions(AmazonWebServiceRequest request, EncryptionInstructions instructions)
        {
            byte[] keyBytesToStoreInMetadata = instructions.EncryptedEnvelopeKey;
            string base64EncodedEnvelopeKey  = Convert.ToBase64String(keyBytesToStoreInMetadata);

            byte[] IVToStoreInMetadata = instructions.InitializationVector;
            string base64EncodedIV     = Convert.ToBase64String(IVToStoreInMetadata);

            var putObjectRequest = request as PutObjectRequest;

            if (putObjectRequest != null)
            {
                MetadataCollection metadata = putObjectRequest.Metadata;
                metadata.Add(keyInMetadata, base64EncodedEnvelopeKey);
                metadata.Add(initVectorInMetadata, base64EncodedIV);

                Dictionary <string, string> materialsDescription = instructions.MaterialsDescription;
                if (materialsDescription.Count == 0)
                {
                    metadata.Add(encryptionMaterialsDescription, "{}");
                }

                putObjectRequest.Metadata = metadata;
            }

            var initiateMultipartrequest = request as InitiateMultipartUploadRequest;

            if (initiateMultipartrequest != null)
            {
                MetadataCollection metadata = initiateMultipartrequest.Metadata;
                metadata.Add(keyInMetadata, base64EncodedEnvelopeKey);
                metadata.Add(initVectorInMetadata, base64EncodedIV);

                Dictionary <string, string> materialsDescription = instructions.MaterialsDescription;
                if (materialsDescription.Count == 0)
                {
                    metadata.Add(encryptionMaterialsDescription, "{}");
                }

                initiateMultipartrequest.Metadata = metadata;
            }
        }
Exemple #20
0
        internal static PutObjectRequest CreateInstructionFileRequest(AmazonWebServiceRequest request, EncryptionInstructions instructions)
        {
            byte[] keyBytesToStoreInInstructionFile = instructions.EncryptedEnvelopeKey;
            string base64EncodedEnvelopeKey         = Convert.ToBase64String(keyBytesToStoreInInstructionFile);

            byte[] IVToStoreInInstructionFile = instructions.InitializationVector;
            string base64EncodedIV            = Convert.ToBase64String(IVToStoreInInstructionFile);

            JsonData jsonData = new JsonData();

            jsonData["EncryptedEnvelopeKey"] = base64EncodedEnvelopeKey;
            jsonData["IV"] = base64EncodedIV;

            string credentials = jsonData.ToJson();

            var putObjectRequest = request as PutObjectRequest;

            if (putObjectRequest != null)
            {
                PutObjectRequest requestforInstructionFile = new PutObjectRequest()
                {
                    BucketName  = putObjectRequest.BucketName,
                    Key         = putObjectRequest.Key + S3Constants.EncryptionInstructionfileSuffix,
                    ContentBody = credentials
                };
                requestforInstructionFile.Metadata.Add(instructionFileInfo, "");
                return(requestforInstructionFile);
            }

            var completeMultiPartRequest = request as CompleteMultipartUploadRequest;

            if (completeMultiPartRequest != null)
            {
                PutObjectRequest requestforInstructionFile = new PutObjectRequest()
                {
                    BucketName  = completeMultiPartRequest.BucketName,
                    Key         = completeMultiPartRequest.Key + S3Constants.EncryptionInstructionfileSuffix,
                    ContentBody = credentials
                };
                requestforInstructionFile.Metadata.Add(instructionFileInfo, "");
                return(requestforInstructionFile);
            }

            else
            {
                return(null);
            }
        }
Exemple #21
0
 /// <summary>
 /// Updates object where the object
 /// input stream contains the decrypted contents.
 /// </summary>
 /// <param name="response">
 /// The getObject response whose contents are to be decrypted.
 /// </param>
 /// <param name="instructions">
 /// The instruction that will be used to encrypt the object data.
 /// </param>
 internal static void DecryptObjectUsingInstructions(GetObjectResponse response, EncryptionInstructions instructions)
 {
     response.ResponseStream = DecryptStream(response.ResponseStream, instructions);
 }