/* * Copyright 2011 Licel LLC. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.licel.jcardsim.crypto; import java.math.BigInteger; import java.security.SecureRandom; import javacard.security.CryptoException; import javacard.security.DSAKey; import javacard.security.KeyBuilder; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.KeyGenerationParameters; import org.bouncycastle.crypto.params.DSAKeyGenerationParameters; import org.bouncycastle.crypto.params.DSAKeyParameters; import org.bouncycastle.crypto.params.DSAParameters; import org.bouncycastle.crypto.params.DSAValidationParameters; /** * Base class for <code>DSAPublicKeyImpl/DSAPrivateKeyImpl</code> * on BouncyCastle CryptoAPI. * @see DSAKey */ public class DSAKeyImpl extends KeyImpl implements DSAKey { protected ByteContainer p = new ByteContainer(); protected ByteContainer q = new ByteContainer(); protected ByteContainer g = new ByteContainer(); protected boolean isPrivate; /** * Construct not-initialized dsa key * @param keyType - key type * @param keySize - key size in bits * @see javacard.security.KeyPair * @see KeyBuilder */ public DSAKeyImpl(byte keyType, short keySize) { this.size = keySize; type = keyType; } /** * Construct and initialize dsa key with DSAKeyParameters. * Use in KeyPairImpl * @see javacard.security.KeyPair * @see DSAKeyParameters * @param params key params from BouncyCastle API */ public DSAKeyImpl(DSAKeyParameters params) { this(params.isPrivate() ? KeyBuilder.TYPE_DSA_PRIVATE : KeyBuilder.TYPE_DSA_PUBLIC, (short) params.getParameters().getP().bitLength()); setParameters(params); } public void setParameters(CipherParameters params){ p.setBigInteger(((DSAKeyParameters)params).getParameters().getP()); q.setBigInteger(((DSAKeyParameters)params).getParameters().getQ()); g.setBigInteger(((DSAKeyParameters)params).getParameters().getG()); } public void clearKey() { p.clear(); q.clear(); g.clear(); } public boolean isInitialized() { return (p.isInitialized() && q.isInitialized() && g.isInitialized()); } public void setP(byte[] buffer, short offset, short length) throws CryptoException { p.setBytes(buffer, offset, length); } public void setQ(byte[] buffer, short offset, short length) throws CryptoException { q.setBytes(buffer, offset, length); } public void setG(byte[] buffer, short offset, short length) throws CryptoException { g.setBytes(buffer, offset, length); } public short getP(byte[] buffer, short offset) { return p.getBytes(buffer, offset); } public short getQ(byte[] buffer, short offset) { return q.getBytes(buffer, offset); } public short getG(byte[] buffer, short offset) { return g.getBytes(buffer, offset); } /** * Get <code>DSAKeyParameters</code> * @return parameters for use with BouncyCastle API * @see DSAKeyParameters */ public CipherParameters getParameters() { if (!isInitialized()) { CryptoException.throwIt(CryptoException.UNINITIALIZED_KEY); } return new DSAKeyParameters(isPrivate, new DSAParameters(p.getBigInteger(), q.getBigInteger(), g.getBigInteger())); } /** * Get * <code>DSAKeyGenerationParameters</code> * * @param rnd Secure Random Generator * @return parameters for use with BouncyCastle API */ public KeyGenerationParameters getKeyGenerationParameters(SecureRandom rnd) { if (isInitialized()) { return new DSAKeyGenerationParameters(rnd, new DSAParameters(p.getBigInteger(), q.getBigInteger(), g.getBigInteger())); } return getDefaultKeyGenerationParameters(size, rnd); } /** * Get DSA KeyGeneration Defaults Parameters * {@link http://docs.oracle.com/javase/6/docs/technotes/guides/security/StandardNames.html#alg} * * @param keySize key size in bits * @param rnd Secure Random Generator */ static KeyGenerationParameters getDefaultKeyGenerationParameters(short keySize, SecureRandom rnd) { BigInteger p = null; BigInteger q = null; BigInteger g = null; BigInteger seed = null; short counter = 0; switch (keySize) { case 512: counter = 123; p = new BigInteger("fca682ce8e12caba26efccf7110e526db078b05edecbcd1eb4a208f3" + "ae1617ae01f35b91a47e6df63413c5e12ed0899bcd132acd50d99151" + "bdc43ee737592e17", 16); q = new BigInteger("962eddcc369cba8ebb260ee6b6a126d9346e38c5", 16); g = new BigInteger("678471b27a9cf44ee91a49c5147db1a9aaf244f05a434d6486931d2d" + "14271b9e35030b71fd73da179069b32e2935630e1c2062354d0da20a" + "6c416e50be794ca4", 16); seed = new BigInteger("b869c82b35d70e1b1ff91b28e37a62ecdc34409b", 16); break; case 768: counter = 263; p = new BigInteger("e9e642599d355f37c97ffd3567120b8e25c9cd43e927b3a9670fbec5" + "d890141922d2c3b3ad2480093799869d1e846aab49fab0ad26d2ce6a" + "22219d470bce7d777d4a21fbe9c270b57f607002f3cef8393694cf45" + "ee3688c11a8c56ab127a3daf", 16); q = new BigInteger("9cdbd84c9f1ac2f38d0f80f42ab952e7338bf511", 16); g = new BigInteger("30470ad5a005fb14ce2d9dcd87e38bc7d1b1c5facbaecbe95f190aa7" + "a31d23c4dbbcbe06174544401a5b2c020965d8c2bd2171d366844577" + "1f74ba084d2029d83c1c158547f3a9f1a2715be23d51ae4d3e5a1f6a" + "7064f316933a346d3f529252", 16); seed = new BigInteger("77d0f8c4dad15eb8c4f2f8d6726cefd96d5bb399", 16); break; case 1024: counter = 92; p = new BigInteger("fd7f53811d75122952df4a9c2eece4e7f611b7523cef4400c31e3f80" + "b6512669455d402251fb593d8d58fabfc5f5ba30f6cb9b556cd7813b" + "801d346ff26660b76b9950a5a49f9fe8047b1022c24fbba9d7feb7c6" + "1bf83b57e7c6a8a6150f04fb83f6d3c51ec3023554135a169132f675" + "f3ae2b61d72aeff22203199dd14801c7", 16); q = new BigInteger("9760508f15230bccb292b982a2eb840bf0581cf5", 16); g = new BigInteger("f7e1a085d69b3ddecbbcab5c36b857b97994afbbfa3aea82f9574c0b" + "3d0782675159578ebad4594fe67107108180b449167123e84c281613" + "b7cf09328cc8a6e13c167a8b547c8d28e0a3ae1e2bb3a675916ea37f" + "0bfa213562f1fb627a01243bcca4f1bea8519089a883dfe15ae59f06" + "928b665e807b552564014c3bfecf492a", 16); seed = new BigInteger("8d5155894229d5e689ee01e6018a237e2cae64cd", 16); break; default: CryptoException.throwIt(CryptoException.ILLEGAL_VALUE); break; } return new DSAKeyGenerationParameters(rnd, new DSAParameters(p, q, g, new DSAValidationParameters(seed.toByteArray(), counter))); } }