diff options
Diffstat (limited to 'vendor/aws/aws-sdk-php/src/Crypto/AesEncryptingStream.php')
-rw-r--r-- | vendor/aws/aws-sdk-php/src/Crypto/AesEncryptingStream.php | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/vendor/aws/aws-sdk-php/src/Crypto/AesEncryptingStream.php b/vendor/aws/aws-sdk-php/src/Crypto/AesEncryptingStream.php new file mode 100644 index 0000000..3b7c446 --- /dev/null +++ b/vendor/aws/aws-sdk-php/src/Crypto/AesEncryptingStream.php @@ -0,0 +1,151 @@ +<?php +namespace Aws\Crypto; + +use GuzzleHttp\Psr7\StreamDecoratorTrait; +use \LogicException; +use Psr\Http\Message\StreamInterface; +use Aws\Crypto\Cipher\CipherMethod; + +/** + * @internal Represents a stream of data to be encrypted with a passed cipher. + */ +class AesEncryptingStream implements AesStreamInterface +{ + const BLOCK_SIZE = 16; // 128 bits + + use StreamDecoratorTrait; + + /** + * @var string + */ + private $buffer = ''; + + /** + * @var CipherMethod + */ + private $cipherMethod; + + /** + * @var string + */ + private $key; + + /** + * @var StreamInterface + */ + private $stream; + + /** + * @param StreamInterface $plainText + * @param string $key + * @param CipherMethod $cipherMethod + */ + public function __construct( + StreamInterface $plainText, + $key, + CipherMethod $cipherMethod + ) { + $this->stream = $plainText; + $this->key = $key; + $this->cipherMethod = clone $cipherMethod; + } + + public function getOpenSslName() + { + return $this->cipherMethod->getOpenSslName(); + } + + public function getAesName() + { + return $this->cipherMethod->getAesName(); + } + + public function getCurrentIv() + { + return $this->cipherMethod->getCurrentIv(); + } + + public function getSize() + { + $plainTextSize = $this->stream->getSize(); + + if ($this->cipherMethod->requiresPadding() && $plainTextSize !== null) { + // PKCS7 padding requires that between 1 and self::BLOCK_SIZE be + // added to the plaintext to make it an even number of blocks. + $padding = self::BLOCK_SIZE - $plainTextSize % self::BLOCK_SIZE; + return $plainTextSize + $padding; + } + + return $plainTextSize; + } + + public function isWritable() + { + return false; + } + + public function read($length) + { + if ($length > strlen($this->buffer)) { + $this->buffer .= $this->encryptBlock( + (int) + self::BLOCK_SIZE * ceil(($length - strlen($this->buffer)) / self::BLOCK_SIZE) + ); + } + + $data = substr($this->buffer, 0, $length); + $this->buffer = substr($this->buffer, $length); + + return $data ? $data : ''; + } + + public function seek($offset, $whence = SEEK_SET) + { + if ($whence === SEEK_CUR) { + $offset = $this->tell() + $offset; + $whence = SEEK_SET; + } + + if ($whence === SEEK_SET) { + $this->buffer = ''; + $wholeBlockOffset + = (int) ($offset / self::BLOCK_SIZE) * self::BLOCK_SIZE; + $this->stream->seek($wholeBlockOffset); + $this->cipherMethod->seek($wholeBlockOffset); + $this->read($offset - $wholeBlockOffset); + } else { + throw new LogicException('Unrecognized whence.'); + } + } + + private function encryptBlock($length) + { + if ($this->stream->eof()) { + return ''; + } + + $plainText = ''; + do { + $plainText .= $this->stream->read((int) ($length - strlen($plainText))); + } while (strlen($plainText) < $length && !$this->stream->eof()); + + $options = OPENSSL_RAW_DATA; + if (!$this->stream->eof() + || $this->stream->getSize() !== $this->stream->tell() + ) { + $options |= OPENSSL_ZERO_PADDING; + } + + $cipherText = openssl_encrypt( + $plainText, + $this->cipherMethod->getOpenSslName(), + $this->key, + $options, + $this->cipherMethod->getCurrentIv() + ); + + $this->cipherMethod->update($cipherText); + + return $cipherText; + } +} |