0N/A/*
2362N/A * Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/Apackage sun.security.pkcs11;
0N/A
0N/Aimport java.math.BigInteger;
0N/A
0N/Aimport java.security.*;
0N/Aimport java.security.interfaces.*;
0N/Aimport java.security.spec.*;
0N/A
0N/Aimport static sun.security.pkcs11.TemplateManager.*;
0N/Aimport sun.security.pkcs11.wrapper.*;
0N/Aimport static sun.security.pkcs11.wrapper.PKCS11Constants.*;
0N/A
1111N/Aimport sun.security.rsa.RSAKeyFactory;
1111N/A
0N/A/**
0N/A * RSA KeyFactory implemenation.
0N/A *
0N/A * @author Andreas Sterbenz
0N/A * @since 1.5
0N/A */
0N/Afinal class P11RSAKeyFactory extends P11KeyFactory {
0N/A
0N/A P11RSAKeyFactory(Token token, String algorithm) {
0N/A super(token, algorithm);
0N/A }
0N/A
0N/A PublicKey implTranslatePublicKey(PublicKey key) throws InvalidKeyException {
0N/A try {
0N/A if (key instanceof RSAPublicKey) {
0N/A RSAPublicKey rsaKey = (RSAPublicKey)key;
0N/A return generatePublic(
0N/A rsaKey.getModulus(),
0N/A rsaKey.getPublicExponent()
0N/A );
0N/A } else if ("X.509".equals(key.getFormat())) {
0N/A // let SunRsaSign provider parse for us, then recurse
0N/A byte[] encoded = key.getEncoded();
0N/A key = new sun.security.rsa.RSAPublicKeyImpl(encoded);
0N/A return implTranslatePublicKey(key);
0N/A } else {
0N/A throw new InvalidKeyException("PublicKey must be instance "
0N/A + "of RSAPublicKey or have X.509 encoding");
0N/A }
0N/A } catch (PKCS11Exception e) {
0N/A throw new InvalidKeyException("Could not create RSA public key", e);
0N/A }
0N/A }
0N/A
0N/A PrivateKey implTranslatePrivateKey(PrivateKey key)
0N/A throws InvalidKeyException {
0N/A try {
0N/A if (key instanceof RSAPrivateCrtKey) {
0N/A RSAPrivateCrtKey rsaKey = (RSAPrivateCrtKey)key;
0N/A return generatePrivate(
0N/A rsaKey.getModulus(),
0N/A rsaKey.getPublicExponent(),
0N/A rsaKey.getPrivateExponent(),
0N/A rsaKey.getPrimeP(),
0N/A rsaKey.getPrimeQ(),
0N/A rsaKey.getPrimeExponentP(),
0N/A rsaKey.getPrimeExponentQ(),
0N/A rsaKey.getCrtCoefficient()
0N/A );
0N/A } else if (key instanceof RSAPrivateKey) {
0N/A RSAPrivateKey rsaKey = (RSAPrivateKey)key;
0N/A return generatePrivate(
0N/A rsaKey.getModulus(),
0N/A rsaKey.getPrivateExponent()
0N/A );
0N/A } else if ("PKCS#8".equals(key.getFormat())) {
0N/A // let SunRsaSign provider parse for us, then recurse
0N/A byte[] encoded = key.getEncoded();
0N/A key = sun.security.rsa.RSAPrivateCrtKeyImpl.newKey(encoded);
0N/A return implTranslatePrivateKey(key);
0N/A } else {
0N/A throw new InvalidKeyException("Private key must be instance "
0N/A + "of RSAPrivate(Crt)Key or have PKCS#8 encoding");
0N/A }
0N/A } catch (PKCS11Exception e) {
0N/A throw new InvalidKeyException("Could not create RSA private key", e);
0N/A }
0N/A }
0N/A
0N/A // see JCA spec
0N/A protected PublicKey engineGeneratePublic(KeySpec keySpec)
0N/A throws InvalidKeySpecException {
0N/A token.ensureValid();
0N/A if (keySpec instanceof X509EncodedKeySpec) {
0N/A try {
0N/A byte[] encoded = ((X509EncodedKeySpec)keySpec).getEncoded();
0N/A PublicKey key = new sun.security.rsa.RSAPublicKeyImpl(encoded);
0N/A return implTranslatePublicKey(key);
0N/A } catch (InvalidKeyException e) {
0N/A throw new InvalidKeySpecException
0N/A ("Could not create RSA public key", e);
0N/A }
0N/A }
0N/A if (keySpec instanceof RSAPublicKeySpec == false) {
0N/A throw new InvalidKeySpecException("Only RSAPublicKeySpec and "
0N/A + "X509EncodedKeySpec supported for RSA public keys");
0N/A }
0N/A try {
0N/A RSAPublicKeySpec rs = (RSAPublicKeySpec)keySpec;
0N/A return generatePublic(
0N/A rs.getModulus(),
0N/A rs.getPublicExponent()
0N/A );
0N/A } catch (PKCS11Exception e) {
0N/A throw new InvalidKeySpecException
0N/A ("Could not create RSA public key", e);
1111N/A } catch (InvalidKeyException e) {
1111N/A throw new InvalidKeySpecException
1111N/A ("Could not create RSA public key", e);
0N/A }
0N/A }
0N/A
0N/A // see JCA spec
0N/A protected PrivateKey engineGeneratePrivate(KeySpec keySpec)
0N/A throws InvalidKeySpecException {
0N/A token.ensureValid();
0N/A if (keySpec instanceof PKCS8EncodedKeySpec) {
0N/A try {
0N/A byte[] encoded = ((PKCS8EncodedKeySpec)keySpec).getEncoded();
0N/A PrivateKey key =
0N/A sun.security.rsa.RSAPrivateCrtKeyImpl.newKey(encoded);
0N/A return implTranslatePrivateKey(key);
0N/A } catch (GeneralSecurityException e) {
0N/A throw new InvalidKeySpecException
0N/A ("Could not create RSA private key", e);
0N/A }
0N/A }
0N/A try {
0N/A if (keySpec instanceof RSAPrivateCrtKeySpec) {
0N/A RSAPrivateCrtKeySpec rs = (RSAPrivateCrtKeySpec)keySpec;
0N/A return generatePrivate(
0N/A rs.getModulus(),
0N/A rs.getPublicExponent(),
0N/A rs.getPrivateExponent(),
0N/A rs.getPrimeP(),
0N/A rs.getPrimeQ(),
0N/A rs.getPrimeExponentP(),
0N/A rs.getPrimeExponentQ(),
0N/A rs.getCrtCoefficient()
0N/A );
0N/A } else if (keySpec instanceof RSAPrivateKeySpec) {
0N/A RSAPrivateKeySpec rs = (RSAPrivateKeySpec)keySpec;
0N/A return generatePrivate(
0N/A rs.getModulus(),
0N/A rs.getPrivateExponent()
0N/A );
0N/A } else {
0N/A throw new InvalidKeySpecException("Only RSAPrivate(Crt)KeySpec "
0N/A + "and PKCS8EncodedKeySpec supported for RSA private keys");
0N/A }
0N/A } catch (PKCS11Exception e) {
0N/A throw new InvalidKeySpecException
0N/A ("Could not create RSA private key", e);
1111N/A } catch (InvalidKeyException e) {
1111N/A throw new InvalidKeySpecException
1111N/A ("Could not create RSA private key", e);
0N/A }
0N/A }
0N/A
0N/A private PublicKey generatePublic(BigInteger n, BigInteger e)
1111N/A throws PKCS11Exception, InvalidKeyException {
1111N/A RSAKeyFactory.checkKeyLengths(n.bitLength(), e, -1, 64 * 1024);
0N/A CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
0N/A new CK_ATTRIBUTE(CKA_CLASS, CKO_PUBLIC_KEY),
0N/A new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_RSA),
0N/A new CK_ATTRIBUTE(CKA_MODULUS, n),
0N/A new CK_ATTRIBUTE(CKA_PUBLIC_EXPONENT, e),
0N/A };
0N/A attributes = token.getAttributes
0N/A (O_IMPORT, CKO_PUBLIC_KEY, CKK_RSA, attributes);
0N/A Session session = null;
0N/A try {
0N/A session = token.getObjSession();
0N/A long keyID = token.p11.C_CreateObject(session.id(), attributes);
0N/A return P11Key.publicKey
0N/A (session, keyID, "RSA", n.bitLength(), attributes);
0N/A } finally {
0N/A token.releaseSession(session);
0N/A }
0N/A }
0N/A
0N/A private PrivateKey generatePrivate(BigInteger n, BigInteger d)
1111N/A throws PKCS11Exception, InvalidKeyException {
1111N/A RSAKeyFactory.checkKeyLengths(n.bitLength(), null, -1, 64 * 1024);
0N/A CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
0N/A new CK_ATTRIBUTE(CKA_CLASS, CKO_PRIVATE_KEY),
0N/A new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_RSA),
0N/A new CK_ATTRIBUTE(CKA_MODULUS, n),
0N/A new CK_ATTRIBUTE(CKA_PRIVATE_EXPONENT, d),
0N/A };
0N/A attributes = token.getAttributes
0N/A (O_IMPORT, CKO_PRIVATE_KEY, CKK_RSA, attributes);
0N/A Session session = null;
0N/A try {
0N/A session = token.getObjSession();
0N/A long keyID = token.p11.C_CreateObject(session.id(), attributes);
0N/A return P11Key.privateKey
0N/A (session, keyID, "RSA", n.bitLength(), attributes);
0N/A } finally {
0N/A token.releaseSession(session);
0N/A }
0N/A }
0N/A
0N/A private PrivateKey generatePrivate(BigInteger n, BigInteger e,
0N/A BigInteger d, BigInteger p, BigInteger q, BigInteger pe,
1111N/A BigInteger qe, BigInteger coeff) throws PKCS11Exception,
1111N/A InvalidKeyException {
1111N/A RSAKeyFactory.checkKeyLengths(n.bitLength(), e, -1, 64 * 1024);
0N/A CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
0N/A new CK_ATTRIBUTE(CKA_CLASS, CKO_PRIVATE_KEY),
0N/A new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_RSA),
0N/A new CK_ATTRIBUTE(CKA_MODULUS, n),
0N/A new CK_ATTRIBUTE(CKA_PUBLIC_EXPONENT, e),
0N/A new CK_ATTRIBUTE(CKA_PRIVATE_EXPONENT, d),
0N/A new CK_ATTRIBUTE(CKA_PRIME_1, p),
0N/A new CK_ATTRIBUTE(CKA_PRIME_2, q),
0N/A new CK_ATTRIBUTE(CKA_EXPONENT_1, pe),
0N/A new CK_ATTRIBUTE(CKA_EXPONENT_2, qe),
0N/A new CK_ATTRIBUTE(CKA_COEFFICIENT, coeff),
0N/A };
0N/A attributes = token.getAttributes
0N/A (O_IMPORT, CKO_PRIVATE_KEY, CKK_RSA, attributes);
0N/A Session session = null;
0N/A try {
0N/A session = token.getObjSession();
0N/A long keyID = token.p11.C_CreateObject(session.id(), attributes);
0N/A return P11Key.privateKey
0N/A (session, keyID, "RSA", n.bitLength(), attributes);
0N/A } finally {
0N/A token.releaseSession(session);
0N/A }
0N/A }
0N/A
0N/A KeySpec implGetPublicKeySpec(P11Key key, Class keySpec, Session[] session)
0N/A throws PKCS11Exception, InvalidKeySpecException {
0N/A if (RSAPublicKeySpec.class.isAssignableFrom(keySpec)) {
0N/A session[0] = token.getObjSession();
0N/A CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
0N/A new CK_ATTRIBUTE(CKA_MODULUS),
0N/A new CK_ATTRIBUTE(CKA_PUBLIC_EXPONENT),
0N/A };
0N/A token.p11.C_GetAttributeValue(session[0].id(), key.keyID, attributes);
0N/A KeySpec spec = new RSAPublicKeySpec(
0N/A attributes[0].getBigInteger(),
0N/A attributes[1].getBigInteger()
0N/A );
0N/A return spec;
0N/A } else { // X.509 handled in superclass
0N/A throw new InvalidKeySpecException("Only RSAPublicKeySpec and "
0N/A + "X509EncodedKeySpec supported for RSA public keys");
0N/A }
0N/A }
0N/A
0N/A KeySpec implGetPrivateKeySpec(P11Key key, Class keySpec, Session[] session)
0N/A throws PKCS11Exception, InvalidKeySpecException {
0N/A if (RSAPrivateCrtKeySpec.class.isAssignableFrom(keySpec)) {
0N/A session[0] = token.getObjSession();
0N/A CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
0N/A new CK_ATTRIBUTE(CKA_MODULUS),
0N/A new CK_ATTRIBUTE(CKA_PUBLIC_EXPONENT),
0N/A new CK_ATTRIBUTE(CKA_PRIVATE_EXPONENT),
0N/A new CK_ATTRIBUTE(CKA_PRIME_1),
0N/A new CK_ATTRIBUTE(CKA_PRIME_2),
0N/A new CK_ATTRIBUTE(CKA_EXPONENT_1),
0N/A new CK_ATTRIBUTE(CKA_EXPONENT_2),
0N/A new CK_ATTRIBUTE(CKA_COEFFICIENT),
0N/A };
0N/A token.p11.C_GetAttributeValue(session[0].id(), key.keyID, attributes);
0N/A KeySpec spec = new RSAPrivateCrtKeySpec(
0N/A attributes[0].getBigInteger(),
0N/A attributes[1].getBigInteger(),
0N/A attributes[2].getBigInteger(),
0N/A attributes[3].getBigInteger(),
0N/A attributes[4].getBigInteger(),
0N/A attributes[5].getBigInteger(),
0N/A attributes[6].getBigInteger(),
0N/A attributes[7].getBigInteger()
0N/A );
0N/A return spec;
0N/A } else if (RSAPrivateKeySpec.class.isAssignableFrom(keySpec)) {
0N/A session[0] = token.getObjSession();
0N/A CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
0N/A new CK_ATTRIBUTE(CKA_MODULUS),
0N/A new CK_ATTRIBUTE(CKA_PRIVATE_EXPONENT),
0N/A };
0N/A token.p11.C_GetAttributeValue(session[0].id(), key.keyID, attributes);
0N/A KeySpec spec = new RSAPrivateKeySpec(
0N/A attributes[0].getBigInteger(),
0N/A attributes[1].getBigInteger()
0N/A );
0N/A return spec;
0N/A } else { // PKCS#8 handled in superclass
0N/A throw new InvalidKeySpecException("Only RSAPrivate(Crt)KeySpec "
0N/A + "and PKCS8EncodedKeySpec supported for RSA private keys");
0N/A }
0N/A }
0N/A
0N/A KeyFactory implGetSoftwareFactory() throws GeneralSecurityException {
0N/A return KeyFactory.getInstance("RSA", P11Util.getSunRsaSignProvider());
0N/A }
0N/A
0N/A}