use of com.mongodb.client.model.vault.EncryptOptions in project mongo-java-driver by mongodb.
the class ClientEncryptionDataKeyAndDoubleEncryptionTest method testProvider.
@Test
public void testProvider() {
String keyAltName = format("%s_altname", providerName);
BsonBinary dataKeyId = clientEncryption.createDataKey(providerName, new DataKeyOptions().keyAltNames(singletonList(keyAltName)).masterKey(getMasterKey()));
assertEquals(4, dataKeyId.getType());
ArrayList<Document> dataKeys = client.getDatabase("keyvault").getCollection("datakeys").find(eq("_id", dataKeyId)).into(new ArrayList<>());
assertEquals(1, dataKeys.size());
Document dataKey = dataKeys.get(0);
assertEquals(providerName, dataKey.get("masterKey", new Document()).get("provider", ""));
String insertWriteConcern = commandListener.getCommandStartedEvent("insert").getCommand().getDocument("writeConcern", new BsonDocument()).getString("w", new BsonString("")).getValue();
assertEquals("majority", insertWriteConcern);
String stringToEncrypt = format("hello %s", providerName);
BsonBinary encrypted = clientEncryption.encrypt(new BsonString(stringToEncrypt), new EncryptOptions("AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic").keyId(dataKeyId));
assertEquals(6, encrypted.getType());
Document insertDocument = new Document("_id", providerName);
insertDocument.put("value", encrypted);
clientEncrypted.getDatabase("db").getCollection("coll").insertOne(insertDocument);
Document decryptedDocument = clientEncrypted.getDatabase("db").getCollection("coll").find(eq("_id", providerName)).first();
assertNotNull(decryptedDocument);
assertEquals(stringToEncrypt, decryptedDocument.get("value", ""));
BsonBinary encryptedKeyAltName = clientEncryption.encrypt(new BsonString(stringToEncrypt), new EncryptOptions("AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic").keyAltName(keyAltName));
assertEquals(encrypted, encryptedKeyAltName);
assertThrows(MongoClientException.class, () -> clientEncrypted.getDatabase("db").getCollection("coll").insertOne(new Document("encrypted_placeholder", encrypted)));
}
use of com.mongodb.client.model.vault.EncryptOptions in project mongo-java-driver by mongodb.
the class ClientSideEncryptionCorpusTest method testCorpus.
@Test
public void testCorpus() throws IOException, URISyntaxException {
// Step 5: Iterate over corpus
BsonDocument corpus = bsonDocumentFromPath("corpus.json");
BsonDocument corpusCopied = new BsonDocument();
for (String field : corpus.keySet()) {
if (!corpus.get(field).isDocument()) {
corpusCopied.append(field, corpus.get(field));
continue;
}
BsonDocument fieldDocument = corpus.getDocument(field).clone();
String kms = fieldDocument.getString("kms").getValue();
String abbreviatedAlgorithName = fieldDocument.getString("algo").getValue();
String method = fieldDocument.getString("method").getValue();
String identifier = fieldDocument.getString("identifier").getValue();
boolean allowed = fieldDocument.getBoolean("allowed").getValue();
BsonValue value = fieldDocument.get("value");
byte[] awsKeyId = Base64.getDecoder().decode("AWSAAAAAAAAAAAAAAAAAAA==");
byte[] azureKeyId = Base64.getDecoder().decode("AZUREAAAAAAAAAAAAAAAAA==");
byte[] gcpKeyId = Base64.getDecoder().decode("GCPAAAAAAAAAAAAAAAAAAA==");
byte[] kmipKeyId = Base64.getDecoder().decode("KMIPAAAAAAAAAAAAAAAAAA==");
byte[] localKeyId = Base64.getDecoder().decode("LOCALAAAAAAAAAAAAAAAAA==");
if (method.equals("auto")) {
corpusCopied.append(field, corpus.get(field));
continue;
}
if (!method.equals("explicit")) {
throw new UnsupportedOperationException("Unsupported method: " + method);
}
String fullAlgorithmName = "AEAD_AES_256_CBC_HMAC_SHA_512-";
if (abbreviatedAlgorithName.equals("rand")) {
fullAlgorithmName += "Random";
} else if (abbreviatedAlgorithName.equals("det")) {
fullAlgorithmName += "Deterministic";
} else {
throw new UnsupportedOperationException("Unsupported algorithm: " + abbreviatedAlgorithName);
}
EncryptOptions opts = new EncryptOptions(fullAlgorithmName);
if (identifier.equals("id")) {
switch(kms) {
case "aws":
opts.keyId(new BsonBinary(BsonBinarySubType.UUID_STANDARD, awsKeyId));
break;
case "azure":
opts.keyId(new BsonBinary(BsonBinarySubType.UUID_STANDARD, azureKeyId));
break;
case "gcp":
opts.keyId(new BsonBinary(BsonBinarySubType.UUID_STANDARD, gcpKeyId));
break;
case "kmip":
opts.keyId(new BsonBinary(BsonBinarySubType.UUID_STANDARD, kmipKeyId));
break;
case "local":
opts.keyId(new BsonBinary(BsonBinarySubType.UUID_STANDARD, localKeyId));
break;
default:
throw new UnsupportedOperationException("Unsupported provider: " + kms);
}
} else if (identifier.equals("altname")) {
opts.keyAltName(kms);
} else {
throw new UnsupportedOperationException("Unsupported identifier: " + identifier);
}
try {
BsonValue encryptedValue = clientEncryption.encrypt(value, opts);
fieldDocument.put("value", encryptedValue);
corpusCopied.append(field, fieldDocument);
} catch (MongoException e) {
if (allowed) {
throw e;
}
corpusCopied.append(field, fieldDocument);
}
}
// Step 6: insert corpusCopied
MongoCollection<BsonDocument> encryptedCollection = autoEncryptingClient.getDatabase("db").getCollection("coll", BsonDocument.class);
encryptedCollection.insertOne(corpusCopied);
// Step 7: check the auto decrypted document
BsonDocument corpusDecrypted = encryptedCollection.find(new BsonDocument()).first();
assertEquals(corpus, corpusDecrypted);
// Step 8: check the document with an unencrypted client
MongoCollection<BsonDocument> coll = client.getDatabase("db").getCollection("coll", BsonDocument.class);
BsonDocument corpusEncryptedActual = coll.find(new BsonDocument()).first();
BsonDocument corpusEncryptedExpected = bsonDocumentFromPath("corpus-encrypted.json");
for (String field : corpusEncryptedExpected.keySet()) {
if (field.equals("_id") || field.equals("altname_aws") || field.equals("altname_local")) {
continue;
}
boolean allowed = corpusEncryptedActual.getDocument(field).getBoolean("allowed").getValue();
String algorithm = corpusEncryptedActual.getDocument(field).getString("algo").getValue();
BsonValue actualValue = corpusEncryptedActual.getDocument(field).get("value");
BsonValue expectedValue = corpusEncryptedExpected.getDocument(field).get("value");
if (algorithm.equals("det")) {
assertEquals(actualValue, expectedValue);
} else if (algorithm.equals("rand")) {
if (allowed) {
assertNotEquals(actualValue, expectedValue);
}
} else {
throw new UnsupportedOperationException("Unsupported algorithm type: " + algorithm);
}
if (allowed) {
BsonValue decrypted = clientEncryption.decrypt(actualValue.asBinary());
assertEquals("Values should be equal for field " + field, clientEncryption.decrypt(expectedValue.asBinary()), decrypted);
} else {
assertEquals("Values should be equal for field " + field, expectedValue, actualValue);
}
}
}
use of com.mongodb.client.model.vault.EncryptOptions in project mongo-java-driver by mongodb.
the class ClientSideEncryptionExternalKeyVaultTest method testExternal.
@Test
public void testExternal() {
boolean authExceptionThrown = false;
MongoCollection<BsonDocument> coll = clientEncrypted.getDatabase("db").getCollection("coll", BsonDocument.class);
try {
coll.insertOne(new BsonDocument().append("encrypted", new BsonString("test")));
} catch (MongoSecurityException mse) {
authExceptionThrown = true;
}
assertEquals(authExceptionThrown, withExternalKeyVault);
EncryptOptions encryptOptions = new EncryptOptions("AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic").keyId(new BsonBinary(BsonBinarySubType.UUID_STANDARD, Base64.getDecoder().decode("LOCALAAAAAAAAAAAAAAAAA==")));
authExceptionThrown = false;
try {
clientEncryption.encrypt(new BsonString("test"), encryptOptions);
} catch (MongoSecurityException mse) {
authExceptionThrown = true;
}
assertEquals(authExceptionThrown, withExternalKeyVault);
}
use of com.mongodb.client.model.vault.EncryptOptions in project mongo-java-driver by mongodb.
the class ClientEncryptionDataKeyAndDoubleEncryptionTest method testProvider.
@Test
public void testProvider() {
String keyAltName = format("%s_altname", providerName);
BsonBinary dataKeyId = clientEncryption.createDataKey(providerName, new DataKeyOptions().keyAltNames(singletonList(keyAltName)).masterKey(getMasterKey()));
assertEquals(4, dataKeyId.getType());
ArrayList<Document> dataKeys = client.getDatabase("keyvault").getCollection("datakeys").find(eq("_id", dataKeyId)).into(new ArrayList<>());
assertEquals(1, dataKeys.size());
Document dataKey = dataKeys.get(0);
assertEquals(providerName, dataKey.get("masterKey", new Document()).get("provider", ""));
String insertWriteConcern = commandListener.getCommandStartedEvent("insert").getCommand().getDocument("writeConcern", new BsonDocument()).getString("w", new BsonString("")).getValue();
assertEquals("majority", insertWriteConcern);
String stringToEncrypt = format("hello %s", providerName);
BsonBinary encrypted = clientEncryption.encrypt(new BsonString(stringToEncrypt), new EncryptOptions("AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic").keyId(dataKeyId));
assertEquals(6, encrypted.getType());
Document insertDocument = new Document("_id", providerName);
insertDocument.put("value", encrypted);
clientEncrypted.getDatabase("db").getCollection("coll").insertOne(insertDocument);
Document decryptedDocument = clientEncrypted.getDatabase("db").getCollection("coll").find(eq("_id", providerName)).first();
assertNotNull(decryptedDocument);
assertEquals(stringToEncrypt, decryptedDocument.get("value", ""));
BsonBinary encryptedKeyAltName = clientEncryption.encrypt(new BsonString(stringToEncrypt), new EncryptOptions("AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic").keyAltName(keyAltName));
assertEquals(encrypted, encryptedKeyAltName);
assertThrows(MongoClientException.class, () -> clientEncrypted.getDatabase("db").getCollection("coll").insertOne(new Document("encrypted_placeholder", encrypted)));
}
use of com.mongodb.client.model.vault.EncryptOptions in project mongo-java-driver by mongodb.
the class ClientSideEncryptionCorpusTest method testCorpus.
@Test
public void testCorpus() throws IOException, URISyntaxException {
// Step 5: Iterate over corpus
BsonDocument corpus = bsonDocumentFromPath("corpus.json");
BsonDocument corpusCopied = new BsonDocument();
for (String field : corpus.keySet()) {
if (!corpus.get(field).isDocument()) {
corpusCopied.append(field, corpus.get(field));
continue;
}
BsonDocument fieldDocument = corpus.getDocument(field).clone();
String kms = fieldDocument.getString("kms").getValue();
String abbreviatedAlgorithName = fieldDocument.getString("algo").getValue();
String method = fieldDocument.getString("method").getValue();
String identifier = fieldDocument.getString("identifier").getValue();
boolean allowed = fieldDocument.getBoolean("allowed").getValue();
BsonValue value = fieldDocument.get("value");
byte[] awsKeyId = Base64.getDecoder().decode("AWSAAAAAAAAAAAAAAAAAAA==");
byte[] azureKeyId = Base64.getDecoder().decode("AZUREAAAAAAAAAAAAAAAAA==");
byte[] gcpKeyId = Base64.getDecoder().decode("GCPAAAAAAAAAAAAAAAAAAA==");
byte[] kmipKeyId = Base64.getDecoder().decode("KMIPAAAAAAAAAAAAAAAAAA==");
byte[] localKeyId = Base64.getDecoder().decode("LOCALAAAAAAAAAAAAAAAAA==");
if (method.equals("auto")) {
corpusCopied.append(field, corpus.get(field));
continue;
}
if (!method.equals("explicit")) {
throw new UnsupportedOperationException("Unsupported method: " + method);
}
String fullAlgorithmName = "AEAD_AES_256_CBC_HMAC_SHA_512-";
if (abbreviatedAlgorithName.equals("rand")) {
fullAlgorithmName += "Random";
} else if (abbreviatedAlgorithName.equals("det")) {
fullAlgorithmName += "Deterministic";
} else {
throw new UnsupportedOperationException("Unsupported algorithm: " + abbreviatedAlgorithName);
}
EncryptOptions opts = new EncryptOptions(fullAlgorithmName);
if (identifier.equals("id")) {
switch(kms) {
case "aws":
opts.keyId(new BsonBinary(BsonBinarySubType.UUID_STANDARD, awsKeyId));
break;
case "azure":
opts.keyId(new BsonBinary(BsonBinarySubType.UUID_STANDARD, azureKeyId));
break;
case "gcp":
opts.keyId(new BsonBinary(BsonBinarySubType.UUID_STANDARD, gcpKeyId));
break;
case "kmip":
opts.keyId(new BsonBinary(BsonBinarySubType.UUID_STANDARD, kmipKeyId));
break;
case "local":
opts.keyId(new BsonBinary(BsonBinarySubType.UUID_STANDARD, localKeyId));
break;
default:
throw new UnsupportedOperationException("Unsupported provider: " + kms);
}
} else if (identifier.equals("altname")) {
opts.keyAltName(kms);
} else {
throw new UnsupportedOperationException("Unsupported identifier: " + identifier);
}
try {
BsonValue encryptedValue = Mono.from(clientEncryption.encrypt(value, opts)).block(TIMEOUT_DURATION);
fieldDocument.put("value", encryptedValue);
corpusCopied.append(field, fieldDocument);
} catch (MongoException e) {
if (allowed) {
throw e;
}
corpusCopied.append(field, fieldDocument);
}
}
// Step 6: insert corpusCopied
MongoCollection<BsonDocument> encryptedCollection = autoEncryptingClient.getDatabase("db").getCollection("coll", BsonDocument.class);
Mono.from(encryptedCollection.insertOne(corpusCopied)).block(TIMEOUT_DURATION);
// Step 7: check the auto decrypted document
BsonDocument corpusDecrypted = Mono.from(encryptedCollection.find(new BsonDocument()).first()).block(TIMEOUT_DURATION);
assertEquals(corpus, corpusDecrypted);
// Step 8: check the document with an unencrypted client
MongoCollection<BsonDocument> coll = client.getDatabase("db").getCollection("coll", BsonDocument.class);
BsonDocument corpusEncryptedActual = Mono.from(coll.find(new BsonDocument()).first()).block(TIMEOUT_DURATION);
BsonDocument corpusEncryptedExpected = bsonDocumentFromPath("corpus-encrypted.json");
for (String field : corpusEncryptedExpected.keySet()) {
if (field.equals("_id") || field.equals("altname_aws") || field.equals("altname_local")) {
continue;
}
boolean allowed = corpusEncryptedActual.getDocument(field).getBoolean("allowed").getValue();
String algorithm = corpusEncryptedActual.getDocument(field).getString("algo").getValue();
BsonValue actualValue = corpusEncryptedActual.getDocument(field).get("value");
BsonValue expectedValue = corpusEncryptedExpected.getDocument(field).get("value");
if (algorithm.equals("det")) {
assertEquals(actualValue, expectedValue);
} else if (algorithm.equals("rand")) {
if (allowed) {
assertNotEquals(actualValue, expectedValue);
}
} else {
throw new UnsupportedOperationException("Unsupported algorithm type: " + algorithm);
}
if (allowed) {
BsonValue decrypted = Mono.from(clientEncryption.decrypt(actualValue.asBinary())).block(TIMEOUT_DURATION);
BsonValue expectedDecrypted = Mono.from(clientEncryption.decrypt(expectedValue.asBinary())).block(TIMEOUT_DURATION);
assertEquals("Values should be equal for field " + field, expectedDecrypted, decrypted);
} else {
assertEquals("Values should be equal for field " + field, expectedValue, actualValue);
}
}
}
Aggregations