diff --git a/pom.xml b/pom.xml
index fd5dcd0..ae28ba3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,9 +6,14 @@
net.wedjaa.ansible.vault
vault-utilities
- 1.2.0
+ 1.3.0-SNAPSHOT
+
+ org.bouncycastle
+ bcprov-jdk15to18
+ 1.69
+
commons-io
commons-io
diff --git a/src/main/java/net/wedjaa/ansible/vault/crypto/VaultHandler.java b/src/main/java/net/wedjaa/ansible/vault/crypto/VaultHandler.java
index 382f05d..a4872e1 100644
--- a/src/main/java/net/wedjaa/ansible/vault/crypto/VaultHandler.java
+++ b/src/main/java/net/wedjaa/ansible/vault/crypto/VaultHandler.java
@@ -19,6 +19,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.security.Security;
import net.wedjaa.ansible.vault.crypto.data.Util;
import net.wedjaa.ansible.vault.crypto.data.VaultInfo;
@@ -37,9 +38,15 @@ public class VaultHandler
public final static String CHAR_ENCODING = "UTF-8";
+ private static synchronized void addBouncyCastleProvider() {
+ if( Security.getProvider("BC") == null ) {
+ Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
+ }
+ }
public static byte [] encrypt(byte [] cleartext, String password, String cypher) throws IOException
{
+ addBouncyCastleProvider();
CypherInterface cypherInstance = CypherFactory.getCypher(cypher);
byte [] vaultData = cypherInstance.encrypt(cleartext, password);
String vaultDataString = new String(vaultData);
@@ -71,7 +78,7 @@ public static void decrypt(InputStream encryptedVault, OutputStream decryptedVau
public static byte[] decrypt(byte[] encrypted, String password) throws IOException
{
-
+ addBouncyCastleProvider();
VaultInfo vaultInfo = Util.getVaultInfo(encrypted);
if ( !vaultInfo.isEncryptedVault() ) {
throw new IOException("File is not an Ansible Encrypted Vault");
diff --git a/src/main/java/net/wedjaa/ansible/vault/crypto/data/VaultContent.java b/src/main/java/net/wedjaa/ansible/vault/crypto/data/VaultContent.java
index 5d371b5..3c6fb23 100644
--- a/src/main/java/net/wedjaa/ansible/vault/crypto/data/VaultContent.java
+++ b/src/main/java/net/wedjaa/ansible/vault/crypto/data/VaultContent.java
@@ -75,7 +75,7 @@ private int[] getDataLengths(byte[] encodedData) throws IOException
int idx = 0;
int saltLen = 0;
- while (encodedData[idx] != '\n' && idx < encodedData.length)
+ while (idx < encodedData.length && encodedData[idx] != '\n')
{
saltLen++;
idx++;
@@ -89,7 +89,7 @@ private int[] getDataLengths(byte[] encodedData) throws IOException
result[0] = saltLen;
int hmacLen = 0;
- while (encodedData[idx] != '\n' && idx < encodedData.length)
+ while (idx < encodedData.length && encodedData[idx] != '\n')
{
hmacLen++;
idx++;
@@ -121,7 +121,7 @@ private byte[][] splitData(byte[] encodedData) throws IOException
int idx = 0;
int saltIdx = 0;
result[0] = new byte[partsLength[0]];
- while (encodedData[idx] != '\n' && idx < encodedData.length)
+ while (idx < encodedData.length && encodedData[idx] != '\n')
{
result[0][saltIdx++] = encodedData[idx++];
}
@@ -133,7 +133,7 @@ private byte[][] splitData(byte[] encodedData) throws IOException
}
int macIdx = 0;
result[1] = new byte[partsLength[1]];
- while (encodedData[idx] != '\n' && idx < encodedData.length)
+ while (idx < encodedData.length && encodedData[idx] != '\n')
{
result[1][macIdx++] = encodedData[idx++];
}
diff --git a/src/main/java/net/wedjaa/ansible/vault/crypto/data/VaultInfo.java b/src/main/java/net/wedjaa/ansible/vault/crypto/data/VaultInfo.java
index 4163432..39ad47a 100644
--- a/src/main/java/net/wedjaa/ansible/vault/crypto/data/VaultInfo.java
+++ b/src/main/java/net/wedjaa/ansible/vault/crypto/data/VaultInfo.java
@@ -54,7 +54,7 @@ public VaultInfo(String infoLine)
if ( infoParts[MAGIC_PART].equals(VAULT_MAGIC) ) {
validVault = true;
vaultVersion = infoParts[VERSION_PART];
- vaultCypher = infoParts[CYPHER_PART];
+ vaultCypher = infoParts[CYPHER_PART].trim();
}
}
}
diff --git a/src/main/java/net/wedjaa/ansible/vault/crypto/decoders/implementation/CypherAES256.java b/src/main/java/net/wedjaa/ansible/vault/crypto/decoders/implementation/CypherAES256.java
index 733a90f..27284e6 100644
--- a/src/main/java/net/wedjaa/ansible/vault/crypto/decoders/implementation/CypherAES256.java
+++ b/src/main/java/net/wedjaa/ansible/vault/crypto/decoders/implementation/CypherAES256.java
@@ -40,7 +40,7 @@ public class CypherAES256 implements CypherInterface
public final static String CHAR_ENCODING = "UTF-8";
public final static String KEYGEN_ALGO = "HmacSHA256";
public final static String CYPHER_KEY_ALGO = "AES";
- public static final String CYPHER_ALGO = "AES/CTR/NoPadding";
+ public static final String CYPHER_ALGO = "AES/CTR/PKCS7Padding"; // handle by BouncyCastle
private static final String JDK8_UPF_URL = "http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html";
private static final int SALT_LENGTH = 32;
@@ -122,7 +122,7 @@ public byte[] pad(byte[] cleartext) throws IOException
try
{
- int blockSize = Cipher.getInstance(CYPHER_ALGO).getBlockSize();
+ int blockSize = Cipher.getInstance(CYPHER_ALGO, "BC").getBlockSize();
logger.debug("Padding to block size: {}", blockSize);
int padding_length = (blockSize - (cleartext.length % blockSize));
if (padding_length == 0)
@@ -148,10 +148,9 @@ public byte[] decryptAES(byte[] cypher, byte[] key, byte[] iv) throws IOExceptio
IvParameterSpec ivSpec = new IvParameterSpec(iv);
try
{
- Cipher cipher = Cipher.getInstance(CYPHER_ALGO);
+ Cipher cipher = Cipher.getInstance(CYPHER_ALGO, "BC");
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
- byte[] decrypted = cipher.doFinal(cypher);
- return unpad(decrypted);
+ return cipher.doFinal(cypher);
}
catch (Exception ex)
{
@@ -165,7 +164,7 @@ public byte[] encryptAES(byte[] cleartext, byte[] key, byte[] iv) throws IOExcep
IvParameterSpec ivSpec = new IvParameterSpec(iv);
try
{
- Cipher cipher = Cipher.getInstance(CYPHER_ALGO);
+ Cipher cipher = Cipher.getInstance(CYPHER_ALGO, "BC");
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
byte[] encrypted = cipher.doFinal(cleartext);
return encrypted;
@@ -244,8 +243,6 @@ public byte[] encrypt(byte[] data, String password) throws IOException
byte[] iv = keys.getIv();
logger.debug("IV: {} - {}", iv.length, Util.hexit(iv, 100));
logger.debug("Original data length: {}", data.length);
- data = pad(data);
- logger.debug("Padded data length: {}", data.length);
byte[] encrypted = encryptAES(data, keys.getEncryptionKey(), keys.getIv());
byte[] hmacHash = calculateHMAC(keys.getHmacKey(), encrypted);
VaultContent vaultContent = new VaultContent(keys.getSalt(), hmacHash, encrypted);
diff --git a/src/test/resources/test-vault.yml b/src/test/resources/test-vault.yml
index a3ae003..561b7e3 100644
--- a/src/test/resources/test-vault.yml
+++ b/src/test/resources/test-vault.yml
@@ -1,12 +1,12 @@
$ANSIBLE_VAULT;1.1;AES256
-33643135356137353133373035376564316239633562363430636665373133376131633364633366
-3561306635333832356137313239643335303631323662330a303464373738373932333564353634
-31653666306337356665343736643136656264353534643139626333653630333235306430393832
-3231643966373262650a653664663237616138303932313663643939393539343734366662343365
-63376565643165386538326138396632333566356266333538636335396132316161313538396137
-66623032663537656636373164303763623538333665666466386562343934303735313135663030
-66616130346130303063663636306537613334663661616361636235666361613462373066363565
-34643665663030636333313237613861626665326462313239353532313535303264646361613734
-31333762343638316364363632653861356135336333356662303732633962336133343563396432
-39353065393238666334396232653034613263346566343639333163656633626436636364313932
-313436663431643964396366633264306633
+35313934363637313839333532346163363766626365633865613338386338623264303965613236
+3339323330346632316437396530393439353662376538610a353833323134643538343864306435
+64396461653430353636333763376161363039646662633631363637663131646231643432636531
+3833663937393065380a396331623064663465356138313934326630356465326330393439366563
+33326161643763393561353862626433633833386232363564656330373130613832396232393230
+39303537616366623462353164643063623935653030333061643530396131306561316134353564
+64356662646630623665643831306134653732353935336432333537633538656363653630383061
+61626262383761393236623664393563623561646661636463363466653731366364623462646532
+62666138363938323639356263336132316634626633376461623466643461336535626632356264
+35653834333239386630656236653865653536656132323965386537393337313931333561323131
+666435653932323731646164383065636236
\ No newline at end of file