提交 98cb588a 编写于 作者: V valeriep

6994008: PKCS11 should support "RSA" and "RSA/ECB/NoPadding" ciphers

Summary: Add support for RSA_X_509 mechanism and aliasing of "RSA" to "RSA/ECB/PKCS1Padding".
Reviewed-by: wetmore
上级 7595ee5b
/*
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -62,6 +62,11 @@ final class P11RSACipher extends CipherSpi {
// mode constant for public key decryption (verifying)
private final static int MODE_VERIFY = 4;
// padding type constant for NoPadding
private final static int PAD_NONE = 1;
// padding type constant for PKCS1Padding
private final static int PAD_PKCS1 = 2;
// token instance
private final Token token;
......@@ -77,6 +82,9 @@ final class P11RSACipher extends CipherSpi {
// mode, one of MODE_* above
private int mode;
// padding, one of PAD_* above
private int padType;
private byte[] buffer;
private int bufOfs;
......@@ -113,8 +121,10 @@ final class P11RSACipher extends CipherSpi {
protected void engineSetPadding(String padding)
throws NoSuchPaddingException {
String lowerPadding = padding.toLowerCase(Locale.ENGLISH);
if (lowerPadding.equals("pkcs1Padding")) {
// empty
if (lowerPadding.equals("pkcs1padding")) {
padType = PAD_PKCS1;
} else if (lowerPadding.equals("nopadding")) {
padType = PAD_NONE;
} else {
throw new NoSuchPaddingException("Unsupported padding " + padding);
}
......@@ -209,7 +219,8 @@ final class P11RSACipher extends CipherSpi {
int n = (p11Key.keyLength() + 7) >> 3;
outputSize = n;
buffer = new byte[n];
maxInputSize = encrypt ? (n - PKCS1_MIN_PADDING_LENGTH) : n;
maxInputSize = ((padType == PAD_PKCS1 && encrypt) ?
(n - PKCS1_MIN_PADDING_LENGTH) : n);
try {
initialize();
} catch (PKCS11Exception e) {
......
......@@ -627,8 +627,10 @@ public final class SunPKCS11 extends AuthProvider {
m(CKM_BLOWFISH_CBC));
// XXX RSA_X_509, RSA_OAEP not yet supported
d(CIP, "RSA/ECB/PKCS1Padding", P11RSACipher,
d(CIP, "RSA/ECB/PKCS1Padding", P11RSACipher, s("RSA"),
m(CKM_RSA_PKCS));
d(CIP, "RSA/ECB/NoPadding", P11RSACipher,
m(CKM_RSA_X_509));
d(SIG, "RawDSA", P11Signature, s("NONEwithDSA"),
m(CKM_DSA));
......
/*
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -23,7 +23,7 @@
/**
* @test
* @bug 4898468
* @bug 4898468 6994008
* @summary basic test for RSA cipher
* @author Andreas Sterbenz
* @library ..
......@@ -38,9 +38,12 @@ import javax.crypto.*;
public class TestRSACipher extends PKCS11Test {
private static final String[] RSA_ALGOS =
{ "RSA/ECB/PKCS1Padding", "RSA" };
public void main(Provider p) throws Exception {
try {
Cipher.getInstance("RSA/ECB/PKCS1Padding", p);
Cipher.getInstance(RSA_ALGOS[0], p);
} catch (GeneralSecurityException e) {
System.out.println("Not supported by provider, skipping");
return;
......@@ -55,57 +58,58 @@ public class TestRSACipher extends PKCS11Test {
b = new byte[16];
random.nextBytes(b);
Cipher c1 = Cipher.getInstance("RSA/ECB/PKCS1Padding", p);
Cipher c2 = Cipher.getInstance("RSA/ECB/PKCS1Padding", "SunJCE");
c1.init(Cipher.ENCRYPT_MODE, publicKey);
e = c1.doFinal(b);
c1.init(Cipher.DECRYPT_MODE, privateKey);
d = c1.doFinal(e);
match(b, d);
c2.init(Cipher.DECRYPT_MODE, privateKey);
d = c2.doFinal(e);
match(b, d);
for (String rsaAlgo: RSA_ALGOS) {
Cipher c1 = Cipher.getInstance(rsaAlgo, p);
Cipher c2 = Cipher.getInstance(rsaAlgo, "SunJCE");
// invalid data
c1.init(Cipher.DECRYPT_MODE, publicKey);
try {
c1.init(Cipher.ENCRYPT_MODE, publicKey);
e = c1.doFinal(b);
c1.init(Cipher.DECRYPT_MODE, privateKey);
d = c1.doFinal(e);
throw new Exception("completed call");
} catch (BadPaddingException ee) {
ee.printStackTrace();
}
c1.init(Cipher.ENCRYPT_MODE, privateKey);
e = c1.doFinal(b);
c1.init(Cipher.DECRYPT_MODE, publicKey);
d = c1.doFinal(e);
match(b, d);
c2.init(Cipher.DECRYPT_MODE, publicKey);
d = c2.doFinal(e);
match(b, d);
// reinit tests
c1.init(Cipher.ENCRYPT_MODE, privateKey);
c1.init(Cipher.ENCRYPT_MODE, privateKey);
e = c1.doFinal(b);
e = c1.doFinal(b);
c1.update(b);
c1.update(b);
c1.init(Cipher.ENCRYPT_MODE, privateKey);
e = c1.doFinal();
e = c1.doFinal();
c1.update(b);
e = c1.doFinal();
c1.update(new byte[256]);
try {
match(b, d);
c2.init(Cipher.DECRYPT_MODE, privateKey);
d = c2.doFinal(e);
match(b, d);
// invalid data
c1.init(Cipher.DECRYPT_MODE, publicKey);
try {
d = c1.doFinal(e);
throw new Exception("completed call");
} catch (BadPaddingException ee) {
ee.printStackTrace();
}
c1.init(Cipher.ENCRYPT_MODE, privateKey);
e = c1.doFinal(b);
c1.init(Cipher.DECRYPT_MODE, publicKey);
d = c1.doFinal(e);
match(b, d);
c2.init(Cipher.DECRYPT_MODE, publicKey);
d = c2.doFinal(e);
match(b, d);
// reinit tests
c1.init(Cipher.ENCRYPT_MODE, privateKey);
c1.init(Cipher.ENCRYPT_MODE, privateKey);
e = c1.doFinal(b);
e = c1.doFinal(b);
c1.update(b);
c1.update(b);
c1.init(Cipher.ENCRYPT_MODE, privateKey);
e = c1.doFinal();
e = c1.doFinal();
c1.update(b);
e = c1.doFinal();
throw new Exception("completed call");
} catch (IllegalBlockSizeException ee) {
System.out.println(ee);
}
c1.update(new byte[256]);
try {
e = c1.doFinal();
throw new Exception("completed call");
} catch (IllegalBlockSizeException ee) {
System.out.println(ee);
}
}
}
private static void match(byte[] b1, byte[] b2) throws Exception {
......
/*
* Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -23,7 +23,7 @@
/**
* @test
* @bug 6572331
* @bug 6572331 6994008
* @summary basic test for RSA cipher key wrapping functionality
* @author Valerie Peng
* @library ..
......@@ -38,47 +38,48 @@ import javax.crypto.spec.SecretKeySpec;
public class TestRSACipherWrap extends PKCS11Test {
private static final String RSA_ALGO = "RSA/ECB/PKCS1Padding";
private static final String[] RSA_ALGOS =
{ "RSA/ECB/PKCS1Padding", "RSA" };
public void main(Provider p) throws Exception {
try {
Cipher.getInstance(RSA_ALGO, p);
Cipher.getInstance(RSA_ALGOS[0], p);
} catch (GeneralSecurityException e) {
System.out.println("Not supported by provider, skipping");
System.out.println(RSA_ALGOS[0] + " unsupported, skipping");
return;
}
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", p);
kpg.initialize(1024);
KeyPair kp = kpg.generateKeyPair();
PublicKey publicKey = kp.getPublic();
PrivateKey privateKey = kp.getPrivate();
Cipher cipherPKCS11 = Cipher.getInstance(RSA_ALGO, p);
Cipher cipherJce = Cipher.getInstance(RSA_ALGO, "SunJCE");
for (String rsaAlgo: RSA_ALGOS) {
Cipher cipherPKCS11 = Cipher.getInstance(rsaAlgo, p);
Cipher cipherJce = Cipher.getInstance(rsaAlgo, "SunJCE");
String algos[] = {"AES", "RC2", "Blowfish"};
int keySizes[] = {128, 256};
String algos[] = {"AES", "RC2", "Blowfish"};
int keySizes[] = {128, 256};
for (int j = 0; j < algos.length; j++) {
String algorithm = algos[j];
KeyGenerator keygen =
for (int j = 0; j < algos.length; j++) {
String algorithm = algos[j];
KeyGenerator keygen =
KeyGenerator.getInstance(algorithm);
for (int i = 0; i < keySizes.length; i++) {
SecretKey secretKey = null;
System.out.print("Generate " + keySizes[i] + "-bit " +
for (int i = 0; i < keySizes.length; i++) {
SecretKey secretKey = null;
System.out.print("Generate " + keySizes[i] + "-bit " +
algorithm + " key using ");
try {
keygen.init(keySizes[i]);
secretKey = keygen.generateKey();
System.out.println(keygen.getProvider().getName());
} catch (InvalidParameterException ipe) {
secretKey = new SecretKeySpec(new byte[32], algorithm);
System.out.println("SecretKeySpec class");
try {
keygen.init(keySizes[i]);
secretKey = keygen.generateKey();
System.out.println(keygen.getProvider().getName());
} catch (InvalidParameterException ipe) {
secretKey = new SecretKeySpec(new byte[32], algorithm);
System.out.println("SecretKeySpec class");
}
test(kp, secretKey, cipherPKCS11, cipherJce);
test(kp, secretKey, cipherPKCS11, cipherPKCS11);
test(kp, secretKey, cipherJce, cipherPKCS11);
}
test(kp, secretKey, cipherPKCS11, cipherJce);
test(kp, secretKey, cipherPKCS11, cipherPKCS11);
test(kp, secretKey, cipherJce, cipherPKCS11);
}
}
}
......
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @bug 6994008
* @summary basic test for RSA/ECB/NoPadding cipher
* @author Valerie Peng
* @library ..
*/
import javax.crypto.*;
import java.io.*;
import javax.crypto.spec.SecretKeySpec;
import java.security.*;
import java.util.*;
public class TestRawRSACipher extends PKCS11Test {
public void main(Provider p) throws Exception {
try {
Cipher.getInstance("RSA/ECB/NoPadding", p);
} catch (GeneralSecurityException e) {
System.out.println("Not supported by provider, skipping");
return;
}
final int KEY_LEN = 1024;
KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA", p);
kpGen.initialize(KEY_LEN);
KeyPair kp = kpGen.generateKeyPair();
Random random = new Random();
byte[] plainText, cipherText, recoveredText;
plainText = new byte[KEY_LEN/8];
random.nextBytes(plainText);
plainText[0] = 0; // to ensure that it's less than modulus
Cipher c1 = Cipher.getInstance("RSA/ECB/NoPadding", p);
Cipher c2 = Cipher.getInstance("RSA/ECB/NoPadding", "SunJCE");
c1.init(Cipher.ENCRYPT_MODE, kp.getPublic());
c2.init(Cipher.DECRYPT_MODE, kp.getPrivate());
cipherText = c1.doFinal(plainText);
recoveredText = c2.doFinal(cipherText);
if (!Arrays.equals(plainText, recoveredText)) {
throw new RuntimeException("E/D Test against SunJCE Failed!");
}
c2.init(Cipher.ENCRYPT_MODE, kp.getPublic());
c1.init(Cipher.DECRYPT_MODE, kp.getPrivate());
cipherText = c2.doFinal(plainText);
recoveredText = c1.doFinal(cipherText);
if (!Arrays.equals(plainText, recoveredText)) {
throw new RuntimeException("D/E Test against SunJCE Failed!");
}
System.out.println("Test Passed");
}
public static void main(String[] args) throws Exception {
main(new TestRawRSACipher());
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册