All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.amazonaws.encryptionsdk.CryptoOutputStream Maven / Gradle / Ivy

There is a newer version: 3.0.1
Show newest version
/*
 * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except
 * in compliance with the License. A copy of the License is located at
 * 
 * http://aws.amazon.com/apache2.0
 * 
 * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 */

package com.amazonaws.encryptionsdk;

import java.io.IOException;
import java.io.OutputStream;
import java.util.List;

import com.amazonaws.encryptionsdk.caching.CachingCryptoMaterialsManager;
import com.amazonaws.encryptionsdk.exception.BadCiphertextException;
import com.amazonaws.encryptionsdk.internal.MessageCryptoHandler;
import com.amazonaws.encryptionsdk.internal.Utils;

/**
 * A CryptoOutputStream is a subclass of java.io.OutputStream. It performs cryptographic
 * transformation of the bytes passing through it.
 * 
 * 

* The CryptoOutputStream wraps a provided OutputStream object and performs cryptographic * transformation of the bytes written to it. The transformed bytes are then written to the wrapped * OutputStream. It uses the cryptography handler provided during construction to invoke methods * that perform the cryptographic transformations. * *

* In short, writing to the CryptoOutputStream results in those bytes being cryptographically * transformed and written to the wrapped OutputStream. * *

* For example, if the crypto handler provides methods for decryption, the CryptoOutputStream will * decrypt the provided ciphertext bytes and write the plaintext bytes to the wrapped OutputStream. * *

* This class adheres strictly to the semantics, especially the failure semantics, of its ancestor * class java.io.OutputStream. This class overrides all the methods specified in its ancestor class. * *

* To instantiate an instance of this class, please see {@link AwsCrypto}. * * @param * The type of {@link MasterKey}s used to manipulate the data. */ public class CryptoOutputStream> extends OutputStream { private final OutputStream outputStream_; private final MessageCryptoHandler cryptoHandler_; /** * Constructs a CryptoOutputStream that wraps the provided OutputStream object. It performs * cryptographic transformation of the bytes written to it using the methods provided in the * provided CryptoHandler implementation. The transformed bytes are then written to the wrapped * OutputStream. * * @param outputStream * the outputStream object to be wrapped. * @param cryptoHandler * the cryptoHandler implementation that provides the methods to use in performing * cryptographic transformation of the bytes written to this stream. */ CryptoOutputStream(final OutputStream outputStream, final MessageCryptoHandler cryptoHandler) { outputStream_ = Utils.assertNonNull(outputStream, "outputStream"); cryptoHandler_ = Utils.assertNonNull(cryptoHandler, "cryptoHandler"); } /** * {@inheritDoc} * * @throws BadCiphertextException * This is thrown only during decryption if b contains invalid or corrupt * ciphertext. */ @Override public void write(final byte[] b) throws IllegalArgumentException, IOException, BadCiphertextException { if (b == null) { throw new IllegalArgumentException("b cannot be null"); } write(b, 0, b.length); } /** * {@inheritDoc} * * @throws BadCiphertextException * This is thrown only during decryption if b contains invalid or corrupt * ciphertext. */ @Override public void write(final byte[] b, final int off, final int len) throws IllegalArgumentException, IOException, BadCiphertextException { if (b == null) { throw new IllegalArgumentException("b cannot be null"); } if (len < 0 || off < 0) { throw new IllegalArgumentException(String.format("Invalid values for offset: %d and length: %d", off, len)); } final int outLen = cryptoHandler_.estimatePartialOutputSize(len); final byte[] outBytes = new byte[outLen]; int bytesWritten = cryptoHandler_.processBytes(b, off, len, outBytes, 0).getBytesWritten(); if (bytesWritten > 0) { outputStream_.write(outBytes, 0, bytesWritten); } } /** * {@inheritDoc} * * @throws BadCiphertextException * This is thrown only during decryption if b contains invalid or corrupt * ciphertext. */ @Override public void write(int b) throws IOException, BadCiphertextException { byte[] bArray = new byte[1]; bArray[0] = (byte) b; write(bArray, 0, 1); } /** * Closes this output stream and releases any system resources associated * with this stream. * *

* This method writes any final bytes to the underlying stream that complete * the cyptographic transformation of the written bytes. It also calls close * on the wrapped OutputStream. * * @throws IOException * if an I/O error occurs. * @throws BadCiphertextException * This is thrown only during decryption if b contains invalid * or corrupt ciphertext. */ @Override public void close() throws IOException, BadCiphertextException { final byte[] outBytes = new byte[cryptoHandler_.estimateFinalOutputSize()]; int finalLen = cryptoHandler_.doFinal(outBytes, 0); outputStream_.write(outBytes, 0, finalLen); outputStream_.close(); } /** * Sets an upper bound on the size of the input data. This method should be called before writing any data to the * stream. If this method is not called prior to writing data, performance may be reduced (notably, it will not * be possible to cache data keys when encrypting). * * Among other things, this size is used to enforce limits configured on the {@link CachingCryptoMaterialsManager}. * * If the size set here is exceeded, an exception will be thrown, and the encyption or decryption will fail. * * If this method is called multiple times, the smallest bound will be used. * * @param size Maximum input size. */ public void setMaxInputLength(long size) { cryptoHandler_.setMaxInputLength(size); } /** * Returns the result of the cryptographic operations including associate metadata. */ public CryptoResult, K> getCryptoResult() { if (!cryptoHandler_.getHeaders().isComplete()) { throw new IllegalStateException("Ciphertext headers not yet written to stream"); } //noinspection unchecked return new CryptoResult<>( this, (List) cryptoHandler_.getMasterKeys(), cryptoHandler_.getHeaders()); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy