private void ConstructOutputBufferChunk(int dataLen)
{
// if the input wasn't sufficient to fill the buffer, size it
// down to make the subseqent hashing/computations easier since
// they don't take any length arguments
if (dataLen > 0 && dataLen < _inputBuffer.Length)
{
var temp = new byte[dataLen];
Buffer.BlockCopy(_inputBuffer, 0, temp, 0, dataLen);
_inputBuffer = temp;
}
var chunkHeader = new StringBuilder();
// variable-length size of the embedded chunk data in hex
chunkHeader.Append(dataLen.ToString("X", CultureInfo.InvariantCulture));
const string nonsigExtension = "";
// signature-extension
var chunkStringToSign =
CHUNK_STRING_TO_SIGN_PREFIX + "\n" +
HeaderSigningResult.ISO8601DateTime + "\n" +
HeaderSigningResult.Scope + "\n" +
PreviousChunkSignature + "\n" +
AWSSDKUtils.ToHex(AWS4Signer.ComputeHash(nonsigExtension), true) + "\n" +
(dataLen > 0
? AWSSDKUtils.ToHex(AWS4Signer.ComputeHash(_inputBuffer), true)
: AWS4Signer.EmptyBodySha256);
var chunkSignature = AWSSDKUtils.ToHex(AWS4Signer.SignBlob(HeaderSigningResult.SigningKey, chunkStringToSign), true);
PreviousChunkSignature = chunkSignature;
chunkHeader.Append(nonsigExtension + CHUNK_SIGNATURE_HEADER + chunkSignature);
chunkHeader.Append(CLRF);
try
{
var header = Encoding.UTF8.GetBytes(chunkHeader.ToString());
var trailer = Encoding.UTF8.GetBytes(CLRF);
var writePos = 0;
Buffer.BlockCopy(header, 0, _outputBuffer, writePos, header.Length);
writePos += header.Length;
if (dataLen > 0)
{
Buffer.BlockCopy(_inputBuffer, 0, _outputBuffer, writePos, dataLen);
writePos += dataLen;
}
Buffer.BlockCopy(trailer, 0, _outputBuffer, writePos, trailer.Length);
_outputBufferPos = 0;
_outputBufferDataLen = header.Length + dataLen + trailer.Length;
}
catch (Exception e)
{
throw new AmazonClientException("Unable to sign the chunked data. " + e.Message, e);
}
}