Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/security/pkcs11/P11RSAKeyFactory.java
38919 views
/*1* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.security.pkcs11;2627import java.math.BigInteger;2829import java.security.*;30import java.security.interfaces.*;31import java.security.spec.*;3233import sun.security.rsa.RSAPublicKeyImpl;34import static sun.security.pkcs11.TemplateManager.*;35import sun.security.pkcs11.wrapper.*;36import static sun.security.pkcs11.wrapper.PKCS11Constants.*;3738import sun.security.rsa.RSAKeyFactory;3940/**41* RSA KeyFactory implementation.42*43* @author Andreas Sterbenz44* @since 1.545*/46final class P11RSAKeyFactory extends P11KeyFactory {4748P11RSAKeyFactory(Token token, String algorithm) {49super(token, algorithm);50}5152PublicKey implTranslatePublicKey(PublicKey key) throws InvalidKeyException {53try {54if (key instanceof RSAPublicKey) {55RSAPublicKey rsaKey = (RSAPublicKey)key;56return generatePublic(57rsaKey.getModulus(),58rsaKey.getPublicExponent()59);60} else if ("X.509".equals(key.getFormat())) {61// let SunRsaSign provider parse for us, then recurse62byte[] encoded = key.getEncoded();63key = RSAPublicKeyImpl.newKey(encoded);64return implTranslatePublicKey(key);65} else {66throw new InvalidKeyException("PublicKey must be instance "67+ "of RSAPublicKey or have X.509 encoding");68}69} catch (PKCS11Exception e) {70throw new InvalidKeyException("Could not create RSA public key", e);71}72}7374PrivateKey implTranslatePrivateKey(PrivateKey key)75throws InvalidKeyException {76try {77if (key instanceof RSAPrivateCrtKey) {78RSAPrivateCrtKey rsaKey = (RSAPrivateCrtKey)key;79return generatePrivate(80rsaKey.getModulus(),81rsaKey.getPublicExponent(),82rsaKey.getPrivateExponent(),83rsaKey.getPrimeP(),84rsaKey.getPrimeQ(),85rsaKey.getPrimeExponentP(),86rsaKey.getPrimeExponentQ(),87rsaKey.getCrtCoefficient()88);89} else if (key instanceof RSAPrivateKey) {90RSAPrivateKey rsaKey = (RSAPrivateKey)key;91return generatePrivate(92rsaKey.getModulus(),93rsaKey.getPrivateExponent()94);95} else if ("PKCS#8".equals(key.getFormat())) {96// let SunRsaSign provider parse for us, then recurse97byte[] encoded = key.getEncoded();98key = sun.security.rsa.RSAPrivateCrtKeyImpl.newKey(encoded);99return implTranslatePrivateKey(key);100} else {101throw new InvalidKeyException("Private key must be instance "102+ "of RSAPrivate(Crt)Key or have PKCS#8 encoding");103}104} catch (PKCS11Exception e) {105throw new InvalidKeyException("Could not create RSA private key", e);106}107}108109// see JCA spec110protected PublicKey engineGeneratePublic(KeySpec keySpec)111throws InvalidKeySpecException {112token.ensureValid();113if (keySpec instanceof X509EncodedKeySpec) {114try {115byte[] encoded = ((X509EncodedKeySpec)keySpec).getEncoded();116PublicKey key = RSAPublicKeyImpl.newKey(encoded);117return implTranslatePublicKey(key);118} catch (InvalidKeyException e) {119throw new InvalidKeySpecException120("Could not create RSA public key", e);121}122}123if (keySpec instanceof RSAPublicKeySpec == false) {124throw new InvalidKeySpecException("Only RSAPublicKeySpec and "125+ "X509EncodedKeySpec supported for RSA public keys");126}127try {128RSAPublicKeySpec rs = (RSAPublicKeySpec)keySpec;129return generatePublic(130rs.getModulus(),131rs.getPublicExponent()132);133} catch (PKCS11Exception | InvalidKeyException e) {134throw new InvalidKeySpecException135("Could not create RSA public key", e);136}137}138139// see JCA spec140protected PrivateKey engineGeneratePrivate(KeySpec keySpec)141throws InvalidKeySpecException {142token.ensureValid();143if (keySpec instanceof PKCS8EncodedKeySpec) {144try {145byte[] encoded = ((PKCS8EncodedKeySpec)keySpec).getEncoded();146PrivateKey key =147sun.security.rsa.RSAPrivateCrtKeyImpl.newKey(encoded);148return implTranslatePrivateKey(key);149} catch (GeneralSecurityException e) {150throw new InvalidKeySpecException151("Could not create RSA private key", e);152}153}154try {155if (keySpec instanceof RSAPrivateCrtKeySpec) {156RSAPrivateCrtKeySpec rs = (RSAPrivateCrtKeySpec)keySpec;157return generatePrivate(158rs.getModulus(),159rs.getPublicExponent(),160rs.getPrivateExponent(),161rs.getPrimeP(),162rs.getPrimeQ(),163rs.getPrimeExponentP(),164rs.getPrimeExponentQ(),165rs.getCrtCoefficient()166);167} else if (keySpec instanceof RSAPrivateKeySpec) {168RSAPrivateKeySpec rs = (RSAPrivateKeySpec)keySpec;169return generatePrivate(170rs.getModulus(),171rs.getPrivateExponent()172);173} else {174throw new InvalidKeySpecException("Only RSAPrivate(Crt)KeySpec "175+ "and PKCS8EncodedKeySpec supported for RSA private keys");176}177} catch (PKCS11Exception | InvalidKeyException e) {178throw new InvalidKeySpecException179("Could not create RSA private key", e);180}181}182183private PublicKey generatePublic(BigInteger n, BigInteger e)184throws PKCS11Exception, InvalidKeyException {185RSAKeyFactory.checkKeyLengths(n.bitLength(), e, -1, 64 * 1024);186CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {187new CK_ATTRIBUTE(CKA_CLASS, CKO_PUBLIC_KEY),188new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_RSA),189new CK_ATTRIBUTE(CKA_MODULUS, n),190new CK_ATTRIBUTE(CKA_PUBLIC_EXPONENT, e),191};192attributes = token.getAttributes193(O_IMPORT, CKO_PUBLIC_KEY, CKK_RSA, attributes);194Session session = null;195try {196session = token.getObjSession();197long keyID = token.p11.C_CreateObject(session.id(), attributes);198return P11Key.publicKey199(session, keyID, "RSA", n.bitLength(), attributes);200} finally {201token.releaseSession(session);202}203}204205private PrivateKey generatePrivate(BigInteger n, BigInteger d)206throws PKCS11Exception, InvalidKeyException {207RSAKeyFactory.checkKeyLengths(n.bitLength(), null, -1, 64 * 1024);208CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {209new CK_ATTRIBUTE(CKA_CLASS, CKO_PRIVATE_KEY),210new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_RSA),211new CK_ATTRIBUTE(CKA_MODULUS, n),212new CK_ATTRIBUTE(CKA_PRIVATE_EXPONENT, d),213};214attributes = token.getAttributes215(O_IMPORT, CKO_PRIVATE_KEY, CKK_RSA, attributes);216Session session = null;217try {218session = token.getObjSession();219long keyID = token.p11.C_CreateObject(session.id(), attributes);220return P11Key.privateKey221(session, keyID, "RSA", n.bitLength(), attributes);222} finally {223token.releaseSession(session);224}225}226227private PrivateKey generatePrivate(BigInteger n, BigInteger e,228BigInteger d, BigInteger p, BigInteger q, BigInteger pe,229BigInteger qe, BigInteger coeff) throws PKCS11Exception,230InvalidKeyException {231RSAKeyFactory.checkKeyLengths(n.bitLength(), e, -1, 64 * 1024);232CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {233new CK_ATTRIBUTE(CKA_CLASS, CKO_PRIVATE_KEY),234new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_RSA),235new CK_ATTRIBUTE(CKA_MODULUS, n),236new CK_ATTRIBUTE(CKA_PUBLIC_EXPONENT, e),237new CK_ATTRIBUTE(CKA_PRIVATE_EXPONENT, d),238new CK_ATTRIBUTE(CKA_PRIME_1, p),239new CK_ATTRIBUTE(CKA_PRIME_2, q),240new CK_ATTRIBUTE(CKA_EXPONENT_1, pe),241new CK_ATTRIBUTE(CKA_EXPONENT_2, qe),242new CK_ATTRIBUTE(CKA_COEFFICIENT, coeff),243};244attributes = token.getAttributes245(O_IMPORT, CKO_PRIVATE_KEY, CKK_RSA, attributes);246Session session = null;247try {248session = token.getObjSession();249long keyID = token.p11.C_CreateObject(session.id(), attributes);250return P11Key.privateKey251(session, keyID, "RSA", n.bitLength(), attributes);252} finally {253token.releaseSession(session);254}255}256257<T extends KeySpec> T implGetPublicKeySpec(P11Key key, Class<T> keySpec,258Session[] session) throws PKCS11Exception, InvalidKeySpecException {259if (RSAPublicKeySpec.class.isAssignableFrom(keySpec)) {260session[0] = token.getObjSession();261CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {262new CK_ATTRIBUTE(CKA_MODULUS),263new CK_ATTRIBUTE(CKA_PUBLIC_EXPONENT),264};265long keyID = key.getKeyID();266try {267token.p11.C_GetAttributeValue(session[0].id(), keyID, attributes);268} finally {269key.releaseKeyID();270}271KeySpec spec = new RSAPublicKeySpec(272attributes[0].getBigInteger(),273attributes[1].getBigInteger()274);275return keySpec.cast(spec);276} else { // X.509 handled in superclass277throw new InvalidKeySpecException("Only RSAPublicKeySpec and "278+ "X509EncodedKeySpec supported for RSA public keys");279}280}281282<T extends KeySpec> T implGetPrivateKeySpec(P11Key key, Class<T> keySpec,283Session[] session) throws PKCS11Exception, InvalidKeySpecException {284if (RSAPrivateCrtKeySpec.class.isAssignableFrom(keySpec)) {285session[0] = token.getObjSession();286CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {287new CK_ATTRIBUTE(CKA_MODULUS),288new CK_ATTRIBUTE(CKA_PUBLIC_EXPONENT),289new CK_ATTRIBUTE(CKA_PRIVATE_EXPONENT),290new CK_ATTRIBUTE(CKA_PRIME_1),291new CK_ATTRIBUTE(CKA_PRIME_2),292new CK_ATTRIBUTE(CKA_EXPONENT_1),293new CK_ATTRIBUTE(CKA_EXPONENT_2),294new CK_ATTRIBUTE(CKA_COEFFICIENT),295};296long keyID = key.getKeyID();297try {298token.p11.C_GetAttributeValue(session[0].id(), keyID, attributes);299} finally {300key.releaseKeyID();301}302303KeySpec spec = new RSAPrivateCrtKeySpec(304attributes[0].getBigInteger(),305attributes[1].getBigInteger(),306attributes[2].getBigInteger(),307attributes[3].getBigInteger(),308attributes[4].getBigInteger(),309attributes[5].getBigInteger(),310attributes[6].getBigInteger(),311attributes[7].getBigInteger()312);313return keySpec.cast(spec);314} else if (RSAPrivateKeySpec.class.isAssignableFrom(keySpec)) {315session[0] = token.getObjSession();316CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {317new CK_ATTRIBUTE(CKA_MODULUS),318new CK_ATTRIBUTE(CKA_PRIVATE_EXPONENT),319};320long keyID = key.getKeyID();321try {322token.p11.C_GetAttributeValue(session[0].id(), keyID, attributes);323} finally {324key.releaseKeyID();325}326327KeySpec spec = new RSAPrivateKeySpec(328attributes[0].getBigInteger(),329attributes[1].getBigInteger()330);331return keySpec.cast(spec);332} else { // PKCS#8 handled in superclass333throw new InvalidKeySpecException("Only RSAPrivate(Crt)KeySpec "334+ "and PKCS8EncodedKeySpec supported for RSA private keys");335}336}337338KeyFactory implGetSoftwareFactory() throws GeneralSecurityException {339return KeyFactory.getInstance("RSA", P11Util.getSunRsaSignProvider());340}341342}343344345