001: package org.bouncycastle.jce.provider.test;
002:
003: import java.io.ByteArrayInputStream;
004: import java.io.ByteArrayOutputStream;
005: import java.math.BigInteger;
006: import java.security.KeyFactory;
007: import java.security.KeyPair;
008: import java.security.KeyPairGenerator;
009: import java.security.KeyStore;
010: import java.security.PrivateKey;
011: import java.security.PublicKey;
012: import java.security.SecureRandom;
013: import java.security.Security;
014: import java.security.cert.Certificate;
015: import java.security.cert.CertificateFactory;
016: import java.security.cert.X509Certificate;
017: import java.security.interfaces.RSAPrivateKey;
018: import java.security.interfaces.RSAPublicKey;
019: import java.security.spec.PKCS8EncodedKeySpec;
020: import java.security.spec.X509EncodedKeySpec;
021: import java.util.Date;
022: import java.util.Hashtable;
023: import java.util.Vector;
024:
025: import org.bouncycastle.jce.X509Principal;
026: import org.bouncycastle.x509.X509V3CertificateGenerator;
027: import org.bouncycastle.jce.provider.BouncyCastleProvider;
028: import org.bouncycastle.jce.spec.ECParameterSpec;
029: import org.bouncycastle.math.ec.ECCurve;
030: import org.bouncycastle.util.encoders.Hex;
031: import org.bouncycastle.util.test.SimpleTestResult;
032: import org.bouncycastle.util.test.Test;
033: import org.bouncycastle.util.test.TestResult;
034:
035: /**
036: * Exercise the various key stores, making sure we at least get back what we put in!
037: * <p>
038: * This tests both the BKS, and the UBER key store.
039: */
040: public class KeyStoreTest implements Test {
041: static char[] passwd = { 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o',
042: 'r', 'l', 'd' };
043:
044: public TestResult ecStoreTest(String storeName) {
045: ECCurve curve = new ECCurve.Fp(
046: new BigInteger(
047: "883423532389192164791648750360308885314476597252960362792450860609699839"), // q
048: new BigInteger(
049: "7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc",
050: 16), // a
051: new BigInteger(
052: "6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a",
053: 16)); // b
054:
055: ECParameterSpec ecSpec = new ECParameterSpec(
056: curve,
057: curve
058: .decodePoint(Hex
059: .decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G
060: new BigInteger(
061: "883423532389192164791648750360308884807550341691627752275345424702807307")); // n
062:
063: try {
064: KeyPairGenerator g = KeyPairGenerator.getInstance("ECDSA",
065: "BC");
066:
067: g.initialize(ecSpec, new SecureRandom());
068:
069: KeyPair keyPair = g.generateKeyPair();
070:
071: PublicKey pubKey = keyPair.getPublic();
072: PrivateKey privKey = keyPair.getPrivate();
073:
074: //
075: // distinguished name table.
076: //
077: Hashtable attrs = new Hashtable();
078: Vector order = new Vector();
079:
080: attrs.put(X509Principal.C, "AU");
081: attrs.put(X509Principal.O,
082: "The Legion of the Bouncy Castle");
083: attrs.put(X509Principal.L, "Melbourne");
084: attrs.put(X509Principal.ST, "Victoria");
085: attrs.put(X509Principal.E,
086: "feedback-crypto@bouncycastle.org");
087:
088: order.addElement(X509Principal.C);
089: order.addElement(X509Principal.O);
090: order.addElement(X509Principal.L);
091: order.addElement(X509Principal.ST);
092: order.addElement(X509Principal.E);
093:
094: //
095: // create the certificate - version 3
096: //
097: X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();
098:
099: certGen.setSerialNumber(BigInteger.valueOf(1));
100: certGen.setIssuerDN(new X509Principal(order, attrs));
101: certGen.setNotBefore(new Date(
102: System.currentTimeMillis() - 50000));
103: certGen.setNotAfter(new Date(
104: System.currentTimeMillis() + 50000));
105: certGen.setSubjectDN(new X509Principal(order, attrs));
106: certGen.setPublicKey(pubKey);
107: certGen.setSignatureAlgorithm("ECDSAwithSHA1");
108:
109: Certificate[] chain = new Certificate[1];
110:
111: try {
112: X509Certificate cert = certGen
113: .generateX509Certificate(privKey);
114:
115: cert.checkValidity(new Date());
116:
117: cert.verify(pubKey);
118:
119: ByteArrayInputStream bIn = new ByteArrayInputStream(
120: cert.getEncoded());
121: CertificateFactory fact = CertificateFactory
122: .getInstance("X.509", "BC");
123:
124: cert = (X509Certificate) fact.generateCertificate(bIn);
125:
126: chain[0] = cert;
127: } catch (Exception e) {
128: return new SimpleTestResult(false, getName()
129: + ": error generating cert - " + e.toString());
130: }
131:
132: KeyStore store = KeyStore.getInstance(storeName, "BC");
133:
134: store.load(null, null);
135:
136: store.setKeyEntry("private", privKey, passwd, chain);
137:
138: //
139: // write out and read back store
140: //
141: ByteArrayOutputStream bOut = new ByteArrayOutputStream();
142:
143: store.store(bOut, passwd);
144:
145: ByteArrayInputStream bIn = new ByteArrayInputStream(bOut
146: .toByteArray());
147:
148: //
149: // start with a new key store
150: //
151: store = KeyStore.getInstance(storeName, "BC");
152:
153: store.load(bIn, passwd);
154:
155: //
156: // load the private key
157: //
158: privKey = (PrivateKey) store.getKey("private", passwd);
159:
160: //
161: // double public key encoding test
162: //
163: byte[] pubEnc = pubKey.getEncoded();
164: KeyFactory keyFac = KeyFactory.getInstance(pubKey
165: .getAlgorithm(), "BC");
166: X509EncodedKeySpec pubX509 = new X509EncodedKeySpec(pubEnc);
167:
168: pubKey = (PublicKey) keyFac.generatePublic(pubX509);
169:
170: pubEnc = pubKey.getEncoded();
171: keyFac = KeyFactory
172: .getInstance(pubKey.getAlgorithm(), "BC");
173: pubX509 = new X509EncodedKeySpec(pubEnc);
174:
175: pubKey = (PublicKey) keyFac.generatePublic(pubX509);
176:
177: //
178: // double private key encoding test
179: //
180: byte[] privEnc = privKey.getEncoded();
181:
182: keyFac = KeyFactory.getInstance(privKey.getAlgorithm(),
183: "BC");
184:
185: PKCS8EncodedKeySpec privPKCS8 = new PKCS8EncodedKeySpec(
186: privEnc);
187: privKey = (PrivateKey) keyFac.generatePrivate(privPKCS8);
188:
189: keyFac = KeyFactory.getInstance(privKey.getAlgorithm(),
190: "BC");
191: privPKCS8 = new PKCS8EncodedKeySpec(privEnc);
192: privKey = (PrivateKey) keyFac.generatePrivate(privPKCS8);
193:
194: return new SimpleTestResult(true, getName() + ": Okay");
195: } catch (Exception e) {
196: return new SimpleTestResult(false, getName()
197: + ": error doing EC test - " + e.toString());
198: }
199: }
200:
201: public TestResult keyStoreTest(String storeName) {
202: try {
203: KeyStore store = KeyStore.getInstance(storeName, "BC");
204:
205: store.load(null, null);
206:
207: KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA",
208: "BC");
209:
210: gen.initialize(1024, new SecureRandom());
211:
212: KeyPair pair = gen.generateKeyPair();
213: RSAPrivateKey privKey = (RSAPrivateKey) pair.getPrivate();
214: RSAPublicKey pubKey = (RSAPublicKey) pair.getPublic();
215: BigInteger modulus = privKey.getModulus();
216: BigInteger privateExponent = privKey.getPrivateExponent();
217:
218: //
219: // distinguished name table.
220: //
221: Hashtable attrs = new Hashtable();
222:
223: attrs.put(X509Principal.C, "AU");
224: attrs.put(X509Principal.O,
225: "The Legion of the Bouncy Castle");
226: attrs.put(X509Principal.L, "Melbourne");
227: attrs.put(X509Principal.ST, "Victoria");
228: attrs.put(X509Principal.EmailAddress,
229: "feedback-crypto@bouncycastle.org");
230:
231: //
232: // extensions
233: //
234:
235: //
236: // create the certificate.
237: //
238: X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();
239:
240: certGen.setSerialNumber(BigInteger.valueOf(1));
241: certGen.setIssuerDN(new X509Principal(attrs));
242: certGen.setNotBefore(new Date(
243: System.currentTimeMillis() - 50000));
244: certGen.setNotAfter(new Date(
245: System.currentTimeMillis() + 50000));
246: certGen.setSubjectDN(new X509Principal(attrs));
247: certGen.setPublicKey(pubKey);
248: certGen.setSignatureAlgorithm("MD5WithRSAEncryption");
249:
250: Certificate[] chain = new Certificate[1];
251:
252: try {
253: X509Certificate cert = certGen
254: .generateX509Certificate(privKey);
255:
256: cert.checkValidity(new Date());
257:
258: cert.verify(pubKey);
259:
260: ByteArrayInputStream bIn = new ByteArrayInputStream(
261: cert.getEncoded());
262: CertificateFactory fact = CertificateFactory
263: .getInstance("X.509", "BC");
264:
265: cert = (X509Certificate) fact.generateCertificate(bIn);
266:
267: chain[0] = cert;
268: } catch (Exception e) {
269: return new SimpleTestResult(false, getName()
270: + ": error generating cert - " + e.toString());
271: }
272:
273: store.setKeyEntry("private", privKey, passwd, chain);
274:
275: //
276: // write out and read back store
277: //
278: ByteArrayOutputStream bOut = new ByteArrayOutputStream();
279:
280: store.store(bOut, passwd);
281:
282: ByteArrayInputStream bIn = new ByteArrayInputStream(bOut
283: .toByteArray());
284:
285: //
286: // start with a new key store
287: //
288: store = KeyStore.getInstance(storeName, "BC");
289:
290: store.load(bIn, passwd);
291:
292: //
293: // verify public key
294: //
295: privKey = (RSAPrivateKey) store.getKey("private", passwd);
296:
297: if (!privKey.getModulus().equals(modulus)) {
298: return new SimpleTestResult(false, getName()
299: + ": private key modulus wrong");
300: } else if (!privKey.getPrivateExponent().equals(
301: privateExponent)) {
302: return new SimpleTestResult(false, getName()
303: + ": private key exponent wrong");
304: }
305:
306: //
307: // verify certificate
308: //
309: Certificate cert = store.getCertificateChain("private")[0];
310:
311: cert.verify(pubKey);
312:
313: return new SimpleTestResult(true, getName() + ": Okay");
314: } catch (Exception e) {
315: return new SimpleTestResult(false, getName()
316: + ": exception - " + e.toString());
317: }
318: }
319:
320: public String getName() {
321: return "KeyStore";
322: }
323:
324: public TestResult perform() {
325: TestResult result = keyStoreTest("BKS");
326: if (!result.isSuccessful()) {
327: return result;
328: }
329:
330: result = keyStoreTest("UBER");
331:
332: if (!result.isSuccessful()) {
333: return result;
334: }
335:
336: result = ecStoreTest("BKS");
337:
338: if (!result.isSuccessful()) {
339: return result;
340: }
341:
342: return new SimpleTestResult(true, getName() + ": Okay");
343: }
344:
345: public static void main(String[] args) {
346: Security.addProvider(new BouncyCastleProvider());
347:
348: Test test = new KeyStoreTest();
349: TestResult result = test.perform();
350:
351: System.out.println(result.toString());
352: }
353: }
|