提交 c55e0542 编写于 作者: W weijun

6879539: enable empty password support for pkcs12 keystore

Reviewed-by: vinnie, weijun
Contributed-by: NFlorian Weimer <fweimer@bfk.de>
上级 7df0a39e
......@@ -55,9 +55,12 @@ final class PBEKey implements SecretKey {
// Should allow an empty password.
passwd = new char[0];
}
for (int i=0; i<passwd.length; i++) {
if ((passwd[i] < '\u0020') || (passwd[i] > '\u007E')) {
throw new InvalidKeySpecException("Password is not ASCII");
// Accept "\0" to signify "zero-length password with no terminator".
if (!(passwd.length == 1 && passwd[0] == 0)) {
for (int i=0; i<passwd.length; i++) {
if ((passwd[i] < '\u0020') || (passwd[i] > '\u007E')) {
throw new InvalidKeySpecException("Password is not ASCII");
}
}
}
this.key = new byte[passwd.length];
......
......@@ -60,11 +60,16 @@ final class PKCS12PBECipherCore {
static byte[] derive(char[] chars, byte[] salt,
int ic, int n, int type) {
// Add in trailing NULL terminator.
// Add in trailing NULL terminator. Special case:
// no terminator if password is "\0".
int length = chars.length*2;
if (length != 0) {
if (length == 2 && chars[0] == 0) {
chars = new char[0];
length = 0;
} else {
length += 2;
}
byte[] passwd = new byte[length];
for (int i = 0, j = 0; i < chars.length; i++, j+=2) {
passwd[j] = (byte) ((chars[i] >>> 8) & 0xFF);
......@@ -133,6 +138,9 @@ final class PKCS12PBECipherCore {
}
private static void concat(byte[] src, byte[] dst, int start, int len) {
if (src.length == 0) {
return;
}
int loop = len / src.length;
int off, i;
for (i = 0, off = 0; i < loop; i++, off += src.length)
......
......@@ -253,11 +253,25 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
}
try {
// Use JCE
SecretKey skey = getPBEKey(password);
Cipher cipher = Cipher.getInstance(algOid.toString());
cipher.init(Cipher.DECRYPT_MODE, skey, algParams);
byte[] privateKeyInfo = cipher.doFinal(encryptedKey);
byte[] privateKeyInfo;
while (true) {
try {
// Use JCE
SecretKey skey = getPBEKey(password);
Cipher cipher = Cipher.getInstance(algOid.toString());
cipher.init(Cipher.DECRYPT_MODE, skey, algParams);
privateKeyInfo = cipher.doFinal(encryptedKey);
break;
} catch (Exception e) {
if (password.length == 0) {
// Retry using an empty password
// without a NULL terminator.
password = new char[1];
continue;
}
throw e;
}
}
PKCS8EncodedKeySpec kspec = new PKCS8EncodedKeySpec(privateKeyInfo);
......@@ -1251,16 +1265,24 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
ObjectIdentifier algOid = in.getOID();
AlgorithmParameters algParams = parseAlgParameters(in);
try {
// Use JCE
SecretKey skey = getPBEKey(password);
Cipher cipher = Cipher.getInstance(algOid.toString());
cipher.init(Cipher.DECRYPT_MODE, skey, algParams);
safeContentsData = cipher.doFinal(safeContentsData);
} catch (Exception e) {
throw new IOException("failed to decrypt safe"
+ " contents entry: " + e, e);
while (true) {
try {
// Use JCE
SecretKey skey = getPBEKey(password);
Cipher cipher = Cipher.getInstance(algOid.toString());
cipher.init(Cipher.DECRYPT_MODE, skey, algParams);
safeContentsData = cipher.doFinal(safeContentsData);
break;
} catch (Exception e) {
if (password.length == 0) {
// Retry using an empty password
// without a NULL terminator.
password = new char[1];
continue;
}
throw new IOException(
"failed to decrypt safe contents entry: " + e, e);
}
}
} else {
throw new IOException("public key protected PKCS12" +
......
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册