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));
}
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;
}
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));
}
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;
}
Aggregations