001: /*
002: * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package sun.security.pkcs11;
027:
028: import java.math.BigInteger;
029:
030: import java.security.*;
031: import java.security.interfaces.*;
032: import java.security.spec.*;
033:
034: import static sun.security.pkcs11.TemplateManager.*;
035: import sun.security.pkcs11.wrapper.*;
036: import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
037:
038: /**
039: * DSA KeyFactory implemenation.
040: *
041: * @author Andreas Sterbenz
042: * @version 1.12, 05/05/07
043: * @since 1.5
044: */
045: final class P11DSAKeyFactory extends P11KeyFactory {
046:
047: P11DSAKeyFactory(Token token, String algorithm) {
048: super (token, algorithm);
049: }
050:
051: PublicKey implTranslatePublicKey(PublicKey key)
052: throws InvalidKeyException {
053: try {
054: if (key instanceof DSAPublicKey) {
055: DSAPublicKey dsaKey = (DSAPublicKey) key;
056: DSAParams params = dsaKey.getParams();
057: return generatePublic(dsaKey.getY(), params.getP(),
058: params.getQ(), params.getG());
059: } else if ("X.509".equals(key.getFormat())) {
060: // let Sun provider parse for us, then recurse
061: byte[] encoded = key.getEncoded();
062: key = new sun.security.provider.DSAPublicKey(encoded);
063: return implTranslatePublicKey(key);
064: } else {
065: throw new InvalidKeyException(
066: "PublicKey must be instance "
067: + "of DSAPublicKey or have X.509 encoding");
068: }
069: } catch (PKCS11Exception e) {
070: throw new InvalidKeyException(
071: "Could not create DSA public key", e);
072: }
073: }
074:
075: PrivateKey implTranslatePrivateKey(PrivateKey key)
076: throws InvalidKeyException {
077: try {
078: if (key instanceof DSAPrivateKey) {
079: DSAPrivateKey dsaKey = (DSAPrivateKey) key;
080: DSAParams params = dsaKey.getParams();
081: return generatePrivate(dsaKey.getX(), params.getP(),
082: params.getQ(), params.getG());
083: } else if ("PKCS#8".equals(key.getFormat())) {
084: // let Sun provider parse for us, then recurse
085: byte[] encoded = key.getEncoded();
086: key = new sun.security.provider.DSAPrivateKey(encoded);
087: return implTranslatePrivateKey(key);
088: } else {
089: throw new InvalidKeyException(
090: "PrivateKey must be instance "
091: + "of DSAPrivateKey or have PKCS#8 encoding");
092: }
093: } catch (PKCS11Exception e) {
094: throw new InvalidKeyException(
095: "Could not create DSA private key", e);
096: }
097: }
098:
099: // see JCA spec
100: protected PublicKey engineGeneratePublic(KeySpec keySpec)
101: throws InvalidKeySpecException {
102: token.ensureValid();
103: if (keySpec instanceof X509EncodedKeySpec) {
104: try {
105: byte[] encoded = ((X509EncodedKeySpec) keySpec)
106: .getEncoded();
107: PublicKey key = new sun.security.provider.DSAPublicKey(
108: encoded);
109: return implTranslatePublicKey(key);
110: } catch (InvalidKeyException e) {
111: throw new InvalidKeySpecException(
112: "Could not create DSA public key", e);
113: }
114: }
115: if (keySpec instanceof DSAPublicKeySpec == false) {
116: throw new InvalidKeySpecException(
117: "Only DSAPublicKeySpec and "
118: + "X509EncodedKeySpec supported for DSA public keys");
119: }
120: try {
121: DSAPublicKeySpec ds = (DSAPublicKeySpec) keySpec;
122: return generatePublic(ds.getY(), ds.getP(), ds.getQ(), ds
123: .getG());
124: } catch (PKCS11Exception e) {
125: throw new InvalidKeySpecException(
126: "Could not create DSA public key", e);
127: }
128: }
129:
130: // see JCA spec
131: protected PrivateKey engineGeneratePrivate(KeySpec keySpec)
132: throws InvalidKeySpecException {
133: token.ensureValid();
134: if (keySpec instanceof PKCS8EncodedKeySpec) {
135: try {
136: byte[] encoded = ((PKCS8EncodedKeySpec) keySpec)
137: .getEncoded();
138: PrivateKey key = new sun.security.provider.DSAPrivateKey(
139: encoded);
140: return implTranslatePrivateKey(key);
141: } catch (GeneralSecurityException e) {
142: throw new InvalidKeySpecException(
143: "Could not create DSA private key", e);
144: }
145: }
146: if (keySpec instanceof DSAPrivateKeySpec == false) {
147: throw new InvalidKeySpecException(
148: "Only DSAPrivateKeySpec and "
149: + "PKCS8EncodedKeySpec supported for DSA private keys");
150: }
151: try {
152: DSAPrivateKeySpec ds = (DSAPrivateKeySpec) keySpec;
153: return generatePrivate(ds.getX(), ds.getP(), ds.getQ(), ds
154: .getG());
155: } catch (PKCS11Exception e) {
156: throw new InvalidKeySpecException(
157: "Could not create DSA private key", e);
158: }
159: }
160:
161: private PublicKey generatePublic(BigInteger y, BigInteger p,
162: BigInteger q, BigInteger g) throws PKCS11Exception {
163: CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
164: new CK_ATTRIBUTE(CKA_CLASS, CKO_PUBLIC_KEY),
165: new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_DSA),
166: new CK_ATTRIBUTE(CKA_VALUE, y),
167: new CK_ATTRIBUTE(CKA_PRIME, p),
168: new CK_ATTRIBUTE(CKA_SUBPRIME, q),
169: new CK_ATTRIBUTE(CKA_BASE, g), };
170: attributes = token.getAttributes(O_IMPORT, CKO_PUBLIC_KEY,
171: CKK_DSA, attributes);
172: Session session = null;
173: try {
174: session = token.getObjSession();
175: long keyID = token.p11.C_CreateObject(session.id(),
176: attributes);
177: return P11Key.publicKey(session, keyID, "DSA", p
178: .bitLength(), attributes);
179: } finally {
180: token.releaseSession(session);
181: }
182: }
183:
184: private PrivateKey generatePrivate(BigInteger x, BigInteger p,
185: BigInteger q, BigInteger g) throws PKCS11Exception {
186: CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
187: new CK_ATTRIBUTE(CKA_CLASS, CKO_PRIVATE_KEY),
188: new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_DSA),
189: new CK_ATTRIBUTE(CKA_VALUE, x),
190: new CK_ATTRIBUTE(CKA_PRIME, p),
191: new CK_ATTRIBUTE(CKA_SUBPRIME, q),
192: new CK_ATTRIBUTE(CKA_BASE, g), };
193: attributes = token.getAttributes(O_IMPORT, CKO_PRIVATE_KEY,
194: CKK_DSA, attributes);
195: Session session = null;
196: try {
197: session = token.getObjSession();
198: long keyID = token.p11.C_CreateObject(session.id(),
199: attributes);
200: return P11Key.privateKey(session, keyID, "DSA", p
201: .bitLength(), attributes);
202: } finally {
203: token.releaseSession(session);
204: }
205: }
206:
207: KeySpec implGetPublicKeySpec(P11Key key, Class keySpec,
208: Session[] session) throws PKCS11Exception,
209: InvalidKeySpecException {
210: if (DSAPublicKeySpec.class.isAssignableFrom(keySpec)) {
211: session[0] = token.getObjSession();
212: CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
213: new CK_ATTRIBUTE(CKA_VALUE),
214: new CK_ATTRIBUTE(CKA_PRIME),
215: new CK_ATTRIBUTE(CKA_SUBPRIME),
216: new CK_ATTRIBUTE(CKA_BASE), };
217: token.p11.C_GetAttributeValue(session[0].id(), key.keyID,
218: attributes);
219: KeySpec spec = new DSAPublicKeySpec(attributes[0]
220: .getBigInteger(), attributes[1].getBigInteger(),
221: attributes[2].getBigInteger(), attributes[3]
222: .getBigInteger());
223: return spec;
224: } else { // X.509 handled in superclass
225: throw new InvalidKeySpecException(
226: "Only DSAPublicKeySpec and "
227: + "X509EncodedKeySpec supported for DSA public keys");
228: }
229: }
230:
231: KeySpec implGetPrivateKeySpec(P11Key key, Class keySpec,
232: Session[] session) throws PKCS11Exception,
233: InvalidKeySpecException {
234: if (DSAPrivateKeySpec.class.isAssignableFrom(keySpec)) {
235: session[0] = token.getObjSession();
236: CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
237: new CK_ATTRIBUTE(CKA_VALUE),
238: new CK_ATTRIBUTE(CKA_PRIME),
239: new CK_ATTRIBUTE(CKA_SUBPRIME),
240: new CK_ATTRIBUTE(CKA_BASE), };
241: token.p11.C_GetAttributeValue(session[0].id(), key.keyID,
242: attributes);
243: KeySpec spec = new DSAPrivateKeySpec(attributes[0]
244: .getBigInteger(), attributes[1].getBigInteger(),
245: attributes[2].getBigInteger(), attributes[3]
246: .getBigInteger());
247: return spec;
248: } else { // PKCS#8 handled in superclass
249: throw new InvalidKeySpecException(
250: "Only DSAPrivateKeySpec "
251: + "and PKCS8EncodedKeySpec supported for DSA private keys");
252: }
253: }
254:
255: KeyFactory implGetSoftwareFactory() throws GeneralSecurityException {
256: return KeyFactory.getInstance("DSA", P11Util.getSunProvider());
257: }
258:
259: }
|