Skip to content

Commit

Permalink
Added locks to encrypt/decrypt in truststore password obfuscation (#1968
Browse files Browse the repository at this point in the history
)

* Added locks to encrypt/decrypt in truststore password obfuscation

* Edited method comments
  • Loading branch information
tkyc authored Nov 18, 2022
1 parent 7f17532 commit 7c8cb7d
Showing 1 changed file with 30 additions and 21 deletions.
51 changes: 30 additions & 21 deletions src/main/java/com/microsoft/sqlserver/jdbc/SecureStringUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,11 @@ final class SecureStringUtil {
private Cipher decryptCipher;

/* singleton instance */
private static SecureStringUtil instance;
private static volatile SecureStringUtil instance;

private static final Lock LOCK = new ReentrantLock();
private static final Lock INSTANCE_LOCK = new ReentrantLock();
private static final Lock ENCRYPT_LOCK = new ReentrantLock();
private static final Lock DECRYPT_LOCK = new ReentrantLock();

/**
* Get reference to SecureStringUtil instance
Expand All @@ -57,13 +59,13 @@ final class SecureStringUtil {
*/
static SecureStringUtil getInstance() throws SQLServerException {
if (instance == null) {
LOCK.lock();
INSTANCE_LOCK.lock();
try {
if (instance == null) {
instance = new SecureStringUtil();
}
} finally {
LOCK.unlock();
INSTANCE_LOCK.unlock();
}
}
return instance;
Expand Down Expand Up @@ -101,18 +103,19 @@ private SecureStringUtil() throws SQLServerException {
* @return encrypted string
*
* @throws SQLServerException
* if error
* Throws an exception if the method fails to encrypt the character array
*/
byte[] getEncryptedBytes(char[] chars) throws SQLServerException {
if (chars == null)
return null;

byte[] iv = new byte[IV_LENGTH];
SecureRandom random = new SecureRandom();
random.nextBytes(iv);
GCMParameterSpec ivParamSpec = new GCMParameterSpec(TAG_LENGTH * 8, iv);

ENCRYPT_LOCK.lock();
try {
if (chars == null) {
return null;
}

byte[] iv = new byte[IV_LENGTH];
SecureRandom random = new SecureRandom();
random.nextBytes(iv);
GCMParameterSpec ivParamSpec = new GCMParameterSpec(TAG_LENGTH * 8, iv);
encryptCipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParamSpec);

byte[] cipherText = encryptCipher.doFinal(Util.charsToBytes(chars));
Expand All @@ -124,29 +127,34 @@ byte[] getEncryptedBytes(char[] chars) throws SQLServerException {
MessageFormat form = new MessageFormat(SQLServerException.getErrString("R_EncryptionFailed"));
Object[] msgArgs = {e.getMessage()};
throw new SQLServerException(this, form.format(msgArgs), null, 0, false);
} finally {
ENCRYPT_LOCK.unlock();
}
}

/**
* Get decrypted value of an encrypted string
*
* @param bytes
* The byte array to decrypt into a character array
*
* @return decrypted string
*
* @throws SQLServerException
* Throws an exception if the method fails to decrypt the byte array
*/
char[] getDecryptedChars(byte[] bytes) throws SQLServerException {
if (bytes == null)
return null;

byte[] iv = new byte[IV_LENGTH];
System.arraycopy(bytes, 0, iv, 0, IV_LENGTH);

GCMParameterSpec ivParamSpec = new GCMParameterSpec(TAG_LENGTH * 8, iv);

DECRYPT_LOCK.lock();
byte[] plainText = null;
try {
if (bytes == null) {
return null;
}

byte[] iv = new byte[IV_LENGTH];
System.arraycopy(bytes, 0, iv, 0, IV_LENGTH);

GCMParameterSpec ivParamSpec = new GCMParameterSpec(TAG_LENGTH * 8, iv);
decryptCipher.init(Cipher.DECRYPT_MODE, secretKey, ivParamSpec);

plainText = decryptCipher.doFinal(bytes, IV_LENGTH, bytes.length - IV_LENGTH);
Expand All @@ -159,6 +167,7 @@ char[] getDecryptedChars(byte[] bytes) throws SQLServerException {
if (plainText != null) {
Arrays.fill(plainText, (byte) 0);
}
DECRYPT_LOCK.unlock();
}
}
}

0 comments on commit 7c8cb7d

Please sign in to comment.