Search in sources :

Example 1 with KMSEncryptionMaterials

use of com.amazonaws.services.s3.model.KMSEncryptionMaterials in project aws-sdk-android by aws-amplify.

the class ContentCryptoMaterial method fromObjectMetadata0.

/**
 * @return a non-null content crypto material.
 */
private static ContentCryptoMaterial fromObjectMetadata0(ObjectMetadata metadata, EncryptionMaterialsAccessor kekMaterialAccessor, Provider securityProvider, long[] range, ExtraMaterialsDescription extra, boolean keyWrapExpected, AWSKMSClient kms) {
    // CEK and IV
    final Map<String, String> userMeta = metadata.getUserMetadata();
    String b64key = userMeta.get(Headers.CRYPTO_KEY_V2);
    if (b64key == null) {
        b64key = userMeta.get(Headers.CRYPTO_KEY);
        if (b64key == null) {
            throw new AmazonClientException("Content encrypting key not found.");
        }
    }
    final byte[] cekWrapped = Base64.decode(b64key);
    byte[] iv = Base64.decode(userMeta.get(Headers.CRYPTO_IV));
    if (cekWrapped == null || iv == null) {
        throw new AmazonClientException("Content encrypting key or IV not found.");
    }
    // Material description
    final String matdescStr = userMeta.get(Headers.MATERIALS_DESCRIPTION);
    final String keyWrapAlgo = userMeta.get(Headers.CRYPTO_KEYWRAP_ALGORITHM);
    final boolean isKMS = isKMSKeyWrapped(keyWrapAlgo);
    final Map<String, String> core = matdescFromJson(matdescStr);
    final Map<String, String> merged = isKMS || extra == null ? core : extra.mergeInto(core);
    final EncryptionMaterials materials;
    if (isKMS) {
        materials = new KMSEncryptionMaterials(core.get(KMSEncryptionMaterials.CUSTOMER_MASTER_KEY_ID));
        materials.addDescriptions(core);
    } else {
        materials = kekMaterialAccessor == null ? null : kekMaterialAccessor.getEncryptionMaterials(merged);
        if (materials == null) {
            throw new AmazonClientException("Unable to retrieve the client encryption materials");
        }
    }
    // CEK algorithm
    final String cekAlgo = userMeta.get(Headers.CRYPTO_CEK_ALGORITHM);
    final boolean isRangeGet = range != null;
    // The content crypto scheme may vary depending on whether
    // it is a range get operation
    final ContentCryptoScheme contentCryptoScheme = ContentCryptoScheme.fromCEKAlgo(cekAlgo, isRangeGet);
    if (isRangeGet) {
        // Adjust the IV as needed
        iv = contentCryptoScheme.adjustIV(iv, range[0]);
    } else {
        // Validate the tag length supported
        final int tagLenExpected = contentCryptoScheme.getTagLengthInBits();
        if (tagLenExpected > 0) {
            final String s = userMeta.get(Headers.CRYPTO_TAG_LENGTH);
            final int tagLenActual = Integer.parseInt(s);
            if (tagLenExpected != tagLenActual) {
                throw new AmazonClientException("Unsupported tag length: " + tagLenActual + ", expected: " + tagLenExpected);
            }
        }
    }
    // Unwrap or decrypt the CEK
    if (keyWrapExpected && keyWrapAlgo == null) {
        throw newKeyWrapException();
    }
    final SecretKey cek = cek(cekWrapped, keyWrapAlgo, materials, securityProvider, contentCryptoScheme, kms);
    return new ContentCryptoMaterial(merged, cekWrapped, keyWrapAlgo, contentCryptoScheme.createCipherLite(cek, iv, Cipher.DECRYPT_MODE, securityProvider));
}
Also used : SecretKey(javax.crypto.SecretKey) KMSEncryptionMaterials(com.amazonaws.services.s3.model.KMSEncryptionMaterials) EncryptionMaterials(com.amazonaws.services.s3.model.EncryptionMaterials) AmazonClientException(com.amazonaws.AmazonClientException) KMSEncryptionMaterials(com.amazonaws.services.s3.model.KMSEncryptionMaterials)

Example 2 with KMSEncryptionMaterials

use of com.amazonaws.services.s3.model.KMSEncryptionMaterials in project aws-sdk-android by aws-amplify.

the class ContentCryptoMaterial method recreate.

/**
 * Recreates a new content crypto material from the current material given a
 * new KEK material-descriptions. The purpose is to re-encrypt the CEK under
 * a different KEK.
 *
 * Note network calls are involved if the CEK has been or is to be protected
 * by KMS.
 *
 * @param newKEKMatDesc
 *            material descriptions for the new KEK; never null
 * @param accessor
 *            used to retrieve the KEK given the corresponding material
 *            description
 * @param targetScheme
 *            the target crypto scheme to be used for key wrapping, etc.
 * @param p
 *            optional security provider; null means to use the default.
 * @throws SecurityException
 *             if the old and new material description are the same; or if
 *             the old and new KEK are the same
 */
ContentCryptoMaterial recreate(Map<String, String> newKEKMatDesc, EncryptionMaterialsAccessor accessor, S3CryptoScheme targetScheme, Provider p, AWSKMSClient kms, AmazonWebServiceRequest req) {
    if (!usesKMSKey() && newKEKMatDesc.equals(kekMaterialsDescription)) {
        throw new SecurityException("Material description of the new KEK must differ from the current one");
    }
    final EncryptionMaterials origKEK;
    if (usesKMSKey()) {
        origKEK = new KMSEncryptionMaterials(kekMaterialsDescription.get(KMSEncryptionMaterials.CUSTOMER_MASTER_KEY_ID));
    } else {
        origKEK = accessor.getEncryptionMaterials(kekMaterialsDescription);
    }
    final EncryptionMaterials newKEK = accessor.getEncryptionMaterials(newKEKMatDesc);
    if (newKEK == null) {
        throw new AmazonClientException("No material available with the description " + newKEKMatDesc + " from the encryption material provider");
    }
    final SecretKey cek = cek(encryptedCEK, keyWrappingAlgorithm, origKEK, p, getContentCryptoScheme(), kms);
    final ContentCryptoMaterial output = create(cek, cipherLite.getIV(), newKEK, // must use same content crypto scheme
    getContentCryptoScheme(), targetScheme, p, kms, req);
    if (Arrays.equals(output.encryptedCEK, encryptedCEK)) {
        throw new SecurityException("The new KEK must differ from the original");
    }
    return output;
}
Also used : SecretKey(javax.crypto.SecretKey) KMSEncryptionMaterials(com.amazonaws.services.s3.model.KMSEncryptionMaterials) EncryptionMaterials(com.amazonaws.services.s3.model.EncryptionMaterials) AmazonClientException(com.amazonaws.AmazonClientException) KMSEncryptionMaterials(com.amazonaws.services.s3.model.KMSEncryptionMaterials)

Example 3 with KMSEncryptionMaterials

use of com.amazonaws.services.s3.model.KMSEncryptionMaterials in project aws-sdk-android by aws-amplify.

the class ContentCryptoMaterial method fromInstructionFile0.

/**
 * @return a non-null content crypto material.
 */
private static ContentCryptoMaterial fromInstructionFile0(Map<String, String> instFile, EncryptionMaterialsAccessor kekMaterialAccessor, Provider securityProvider, long[] range, ExtraMaterialsDescription extra, boolean keyWrapExpected, AWSKMSClient kms) {
    // CEK and IV
    String b64key = instFile.get(Headers.CRYPTO_KEY_V2);
    if (b64key == null) {
        b64key = instFile.get(Headers.CRYPTO_KEY);
        if (b64key == null) {
            throw new AmazonClientException("Content encrypting key not found.");
        }
    }
    final byte[] cekWrapped = Base64.decode(b64key);
    byte[] iv = Base64.decode(instFile.get(Headers.CRYPTO_IV));
    if (cekWrapped == null || iv == null) {
        throw new AmazonClientException("Necessary encryption info not found in the instruction file " + instFile);
    }
    final String keyWrapAlgo = instFile.get(Headers.CRYPTO_KEYWRAP_ALGORITHM);
    final boolean isKMS = isKMSKeyWrapped(keyWrapAlgo);
    // Material description
    final String matdescStr = instFile.get(Headers.MATERIALS_DESCRIPTION);
    final Map<String, String> core = matdescFromJson(matdescStr);
    final Map<String, String> merged = extra == null || isKMS ? core : extra.mergeInto(core);
    EncryptionMaterials materials;
    if (isKMS) {
        materials = new KMSEncryptionMaterials(core.get(KMSEncryptionMaterials.CUSTOMER_MASTER_KEY_ID));
        materials.addDescriptions(core);
    } else {
        materials = kekMaterialAccessor == null ? null : kekMaterialAccessor.getEncryptionMaterials(merged);
        if (materials == null) {
            throw new AmazonClientException("Unable to retrieve the encryption materials that originally " + "encrypted object corresponding to instruction file " + instFile);
        }
    }
    // CEK algorithm
    final String cekAlgo = instFile.get(Headers.CRYPTO_CEK_ALGORITHM);
    final boolean isRangeGet = range != null;
    // The content crypto scheme may vary depending on whether
    // it is a range get operation
    final ContentCryptoScheme contentCryptoScheme = ContentCryptoScheme.fromCEKAlgo(cekAlgo, isRangeGet);
    if (isRangeGet) {
        // Adjust the IV as needed
        iv = contentCryptoScheme.adjustIV(iv, range[0]);
    } else {
        // Validate the tag length supported
        final int tagLenExpected = contentCryptoScheme.getTagLengthInBits();
        if (tagLenExpected > 0) {
            final String s = instFile.get(Headers.CRYPTO_TAG_LENGTH);
            final int tagLenActual = Integer.parseInt(s);
            if (tagLenExpected != tagLenActual) {
                throw new AmazonClientException("Unsupported tag length: " + tagLenActual + ", expected: " + tagLenExpected);
            }
        }
    }
    // Unwrap or decrypt the CEK
    if (keyWrapExpected && keyWrapAlgo == null) {
        throw newKeyWrapException();
    }
    final SecretKey cek = cek(cekWrapped, keyWrapAlgo, materials, securityProvider, contentCryptoScheme, kms);
    return new ContentCryptoMaterial(merged, cekWrapped, keyWrapAlgo, contentCryptoScheme.createCipherLite(cek, iv, Cipher.DECRYPT_MODE, securityProvider));
}
Also used : SecretKey(javax.crypto.SecretKey) KMSEncryptionMaterials(com.amazonaws.services.s3.model.KMSEncryptionMaterials) EncryptionMaterials(com.amazonaws.services.s3.model.EncryptionMaterials) AmazonClientException(com.amazonaws.AmazonClientException) KMSEncryptionMaterials(com.amazonaws.services.s3.model.KMSEncryptionMaterials)

Example 4 with KMSEncryptionMaterials

use of com.amazonaws.services.s3.model.KMSEncryptionMaterials in project aws-sdk-android by aws-amplify.

the class ContentCryptoMaterial method recreate.

/**
 * Recreates a new content crypto material from the current material given a
 * new KEK encryption materials. The purpose is to re-encrypt the CEK under
 * the new KEK.
 *
 * Note network calls are involved if the CEK has been or is to be protected
 * by KMS.
 *
 * @param newKEK
 *            encryption materials for the new KEK; must not be null
 * @param accessor
 *            used to retrieve the original KEK given the corresponding
 *            material description
 * @param targetScheme
 *            the target crypto scheme to use for recreating the content
 *            crypto material
 * @param p
 *            optional security provider; null means to use the default.
 * @throws SecurityException
 *             if the old and new material description are the same; or if
 *             the old and new KEK are the same
 */
ContentCryptoMaterial recreate(EncryptionMaterials newKEK, EncryptionMaterialsAccessor accessor, S3CryptoScheme targetScheme, Provider p, AWSKMSClient kms, AmazonWebServiceRequest req) {
    if (!usesKMSKey() && newKEK.getMaterialsDescription().equals(kekMaterialsDescription)) {
        throw new SecurityException("Material description of the new KEK must differ from the current one");
    }
    final EncryptionMaterials origKEK;
    if (usesKMSKey()) {
        origKEK = new KMSEncryptionMaterials(kekMaterialsDescription.get(KMSEncryptionMaterials.CUSTOMER_MASTER_KEY_ID));
    } else {
        origKEK = accessor.getEncryptionMaterials(kekMaterialsDescription);
    }
    final SecretKey cek = cek(encryptedCEK, keyWrappingAlgorithm, origKEK, p, getContentCryptoScheme(), kms);
    final ContentCryptoMaterial output = create(cek, cipherLite.getIV(), newKEK, // must use same content crypto scheme
    getContentCryptoScheme(), // target scheme used to recreate the content crypto material
    targetScheme, p, kms, req);
    if (Arrays.equals(output.encryptedCEK, encryptedCEK)) {
        throw new SecurityException("The new KEK must differ from the original");
    }
    return output;
}
Also used : SecretKey(javax.crypto.SecretKey) KMSEncryptionMaterials(com.amazonaws.services.s3.model.KMSEncryptionMaterials) EncryptionMaterials(com.amazonaws.services.s3.model.EncryptionMaterials) KMSEncryptionMaterials(com.amazonaws.services.s3.model.KMSEncryptionMaterials)

Aggregations

EncryptionMaterials (com.amazonaws.services.s3.model.EncryptionMaterials)4 KMSEncryptionMaterials (com.amazonaws.services.s3.model.KMSEncryptionMaterials)4 SecretKey (javax.crypto.SecretKey)4 AmazonClientException (com.amazonaws.AmazonClientException)3