001: package org.bouncycastle.jce.provider.test;
002:
003: import org.bouncycastle.asn1.ASN1InputStream;
004: import org.bouncycastle.asn1.DERNull;
005: import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
006: import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
007: import org.bouncycastle.jce.ECPointUtil;
008: import org.bouncycastle.jce.interfaces.ConfigurableProvider;
009: import org.bouncycastle.jce.interfaces.ECPrivateKey;
010: import org.bouncycastle.jce.interfaces.ECPublicKey;
011: import org.bouncycastle.jce.provider.BouncyCastleProvider;
012: import org.bouncycastle.jce.spec.ECParameterSpec;
013: import org.bouncycastle.jce.spec.ECPrivateKeySpec;
014: import org.bouncycastle.jce.spec.ECPublicKeySpec;
015: import org.bouncycastle.math.ec.ECCurve;
016: import org.bouncycastle.util.encoders.Hex;
017: import org.bouncycastle.util.test.FixedSecureRandom;
018: import org.bouncycastle.util.test.SimpleTest;
019:
020: import java.math.BigInteger;
021: import java.security.KeyFactory;
022: import java.security.KeyPair;
023: import java.security.KeyPairGenerator;
024: import java.security.SecureRandom;
025: import java.security.Security;
026: import java.security.Signature;
027: import java.security.interfaces.ECKey;
028: import java.security.spec.ECFieldFp;
029: import java.security.spec.EllipticCurve;
030: import java.security.spec.PKCS8EncodedKeySpec;
031: import java.security.spec.X509EncodedKeySpec;
032:
033: public class ImplicitlyCaTest extends SimpleTest {
034: byte[] k1 = Hex.decode("d5014e4b60ef2ba8b6211b4062ba3224e0427dd3");
035: byte[] k2 = Hex
036: .decode("345e8d05c075c3a508df729a1685690e68fcfb8c8117847e89063bca1f85d968fd281540b6e13bd1af989a1fbf17e06462bf511f9d0b140fb48ac1b1baa5bded");
037:
038: SecureRandom random = new FixedSecureRandom(new byte[][] { k1, k2 });
039:
040: public void performTest() throws Exception {
041: testBCAPI();
042:
043: testJDKAPI();
044:
045: testKeyFactory();
046:
047: testBasicThreadLocal();
048: }
049:
050: private void testBCAPI() throws Exception {
051: KeyPairGenerator g = KeyPairGenerator
052: .getInstance("ECDSA", "BC");
053:
054: ECCurve curve = new ECCurve.Fp(
055: new BigInteger(
056: "883423532389192164791648750360308885314476597252960362792450860609699839"), // q
057: new BigInteger(
058: "7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc",
059: 16), // a
060: new BigInteger(
061: "6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a",
062: 16)); // b
063:
064: ECParameterSpec ecSpec = new ECParameterSpec(
065: curve,
066: curve
067: .decodePoint(Hex
068: .decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G
069: new BigInteger(
070: "883423532389192164791648750360308884807550341691627752275345424702807307")); // n
071:
072: ConfigurableProvider config = (ConfigurableProvider) Security
073: .getProvider("BC");
074:
075: config.setParameter(ConfigurableProvider.EC_IMPLICITLY_CA,
076: ecSpec);
077:
078: g.initialize(null, new SecureRandom());
079:
080: KeyPair p = g.generateKeyPair();
081:
082: ECPrivateKey sKey = (ECPrivateKey) p.getPrivate();
083: ECPublicKey vKey = (ECPublicKey) p.getPublic();
084:
085: testECDSA(sKey, vKey);
086:
087: testBCParamsAndQ(sKey, vKey);
088: testEC5Params(sKey, vKey);
089:
090: testEncoding(sKey, vKey);
091: }
092:
093: private void testKeyFactory() throws Exception {
094: KeyPairGenerator g = KeyPairGenerator
095: .getInstance("ECDSA", "BC");
096:
097: ECCurve curve = new ECCurve.Fp(
098: new BigInteger(
099: "883423532389192164791648750360308885314476597252960362792450860609699839"), // q
100: new BigInteger(
101: "7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc",
102: 16), // a
103: new BigInteger(
104: "6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a",
105: 16)); // b
106:
107: ECParameterSpec ecSpec = new ECParameterSpec(
108: curve,
109: curve
110: .decodePoint(Hex
111: .decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G
112: new BigInteger(
113: "883423532389192164791648750360308884807550341691627752275345424702807307")); // n
114:
115: ConfigurableProvider config = (ConfigurableProvider) Security
116: .getProvider("BC");
117:
118: config.setParameter(ConfigurableProvider.EC_IMPLICITLY_CA,
119: ecSpec);
120:
121: g.initialize(null, new SecureRandom());
122:
123: KeyPair p = g.generateKeyPair();
124:
125: ECPrivateKey sKey = (ECPrivateKey) p.getPrivate();
126: ECPublicKey vKey = (ECPublicKey) p.getPublic();
127:
128: KeyFactory fact = KeyFactory.getInstance("ECDSA", "BC");
129:
130: vKey = (ECPublicKey) fact.generatePublic(new ECPublicKeySpec(
131: vKey.getQ(), null));
132: sKey = (ECPrivateKey) fact
133: .generatePrivate(new ECPrivateKeySpec(sKey.getD(), null));
134:
135: testECDSA(sKey, vKey);
136:
137: testBCParamsAndQ(sKey, vKey);
138: testEC5Params(sKey, vKey);
139:
140: testEncoding(sKey, vKey);
141:
142: ECPublicKey vKey2 = (ECPublicKey) fact
143: .generatePublic(new ECPublicKeySpec(vKey.getQ(), ecSpec));
144: ECPrivateKey sKey2 = (ECPrivateKey) fact
145: .generatePrivate(new ECPrivateKeySpec(sKey.getD(),
146: ecSpec));
147:
148: if (!vKey.equals(vKey2) || vKey.hashCode() != vKey2.hashCode()) {
149: fail("private equals/hashCode failed");
150: }
151:
152: if (!sKey.equals(sKey2) || sKey.hashCode() != sKey2.hashCode()) {
153: fail("private equals/hashCode failed");
154: }
155: }
156:
157: private void testJDKAPI() throws Exception {
158: KeyPairGenerator g = KeyPairGenerator
159: .getInstance("ECDSA", "BC");
160:
161: EllipticCurve curve = new EllipticCurve(
162: new ECFieldFp(
163: new BigInteger(
164: "883423532389192164791648750360308885314476597252960362792450860609699839")), // q
165: new BigInteger(
166: "7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc",
167: 16), // a
168: new BigInteger(
169: "6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a",
170: 16)); // b
171:
172: java.security.spec.ECParameterSpec ecSpec = new java.security.spec.ECParameterSpec(
173: curve,
174: ECPointUtil
175: .decodePoint(
176: curve,
177: Hex
178: .decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G
179: new BigInteger(
180: "883423532389192164791648750360308884807550341691627752275345424702807307"), // n
181: 1); // h
182:
183: ConfigurableProvider config = (ConfigurableProvider) Security
184: .getProvider("BC");
185:
186: config.setParameter(ConfigurableProvider.EC_IMPLICITLY_CA,
187: ecSpec);
188:
189: g.initialize(null, new SecureRandom());
190:
191: KeyPair p = g.generateKeyPair();
192:
193: ECPrivateKey sKey = (ECPrivateKey) p.getPrivate();
194: ECPublicKey vKey = (ECPublicKey) p.getPublic();
195:
196: testECDSA(sKey, vKey);
197:
198: testBCParamsAndQ(sKey, vKey);
199: testEC5Params(sKey, vKey);
200:
201: testEncoding(sKey, vKey);
202: }
203:
204: private void testBasicThreadLocal() throws Exception {
205: KeyPairGenerator g = KeyPairGenerator
206: .getInstance("ECDSA", "BC");
207:
208: EllipticCurve curve = new EllipticCurve(
209: new ECFieldFp(
210: new BigInteger(
211: "883423532389192164791648750360308885314476597252960362792450860609699839")), // q
212: new BigInteger(
213: "7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc",
214: 16), // a
215: new BigInteger(
216: "6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a",
217: 16)); // b
218:
219: java.security.spec.ECParameterSpec ecSpec = new java.security.spec.ECParameterSpec(
220: curve,
221: ECPointUtil
222: .decodePoint(
223: curve,
224: Hex
225: .decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G
226: new BigInteger(
227: "883423532389192164791648750360308884807550341691627752275345424702807307"), // n
228: 1); // h
229:
230: ConfigurableProvider config = (ConfigurableProvider) Security
231: .getProvider("BC");
232:
233: config.setParameter(
234: ConfigurableProvider.THREAD_LOCAL_EC_IMPLICITLY_CA,
235: ecSpec);
236:
237: g.initialize(null, new SecureRandom());
238:
239: KeyPair p = g.generateKeyPair();
240:
241: ECPrivateKey sKey = (ECPrivateKey) p.getPrivate();
242: ECPublicKey vKey = (ECPublicKey) p.getPublic();
243:
244: testECDSA(sKey, vKey);
245:
246: testBCParamsAndQ(sKey, vKey);
247: testEC5Params(sKey, vKey);
248:
249: testEncoding(sKey, vKey);
250: }
251:
252: private void testECDSA(ECPrivateKey sKey, ECPublicKey vKey)
253: throws Exception {
254: byte[] data = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
255: Signature s = Signature.getInstance("ECDSA", "BC");
256:
257: s.initSign(sKey);
258:
259: s.update(data);
260:
261: byte[] sigBytes = s.sign();
262:
263: s = Signature.getInstance("ECDSA", "BC");
264:
265: s.initVerify(vKey);
266:
267: s.update(data);
268:
269: if (!s.verify(sigBytes)) {
270: fail("ECDSA verification failed");
271: }
272: }
273:
274: private void testEncoding(ECPrivateKey privKey, ECPublicKey pubKey)
275: throws Exception {
276: KeyFactory kFact = KeyFactory.getInstance("ECDSA", "BC");
277:
278: byte[] bytes = privKey.getEncoded();
279:
280: PrivateKeyInfo sInfo = PrivateKeyInfo
281: .getInstance(new ASN1InputStream(bytes).readObject());
282:
283: if (!sInfo.getAlgorithmId().getParameters().equals(
284: DERNull.INSTANCE)) {
285: fail("private key parameters wrong");
286: }
287:
288: ECPrivateKey sKey = (ECPrivateKey) kFact
289: .generatePrivate(new PKCS8EncodedKeySpec(bytes));
290:
291: if (!sKey.equals(privKey)) {
292: fail("private equals failed");
293: }
294:
295: if (sKey.hashCode() != privKey.hashCode()) {
296: fail("private hashCode failed");
297: }
298:
299: bytes = pubKey.getEncoded();
300:
301: SubjectPublicKeyInfo vInfo = SubjectPublicKeyInfo
302: .getInstance(new ASN1InputStream(bytes).readObject());
303:
304: if (!vInfo.getAlgorithmId().getParameters().equals(
305: DERNull.INSTANCE)) {
306: fail("public key parameters wrong");
307: }
308:
309: ECPublicKey vKey = (ECPublicKey) kFact
310: .generatePublic(new X509EncodedKeySpec(bytes));
311:
312: if (!vKey.equals(pubKey)
313: || vKey.hashCode() != pubKey.hashCode()) {
314: fail("public equals/hashCode failed");
315: }
316:
317: testBCParamsAndQ(sKey, vKey);
318: testEC5Params(sKey, vKey);
319:
320: testECDSA(sKey, vKey);
321: }
322:
323: private void testBCParamsAndQ(ECPrivateKey sKey, ECPublicKey vKey) {
324: if (sKey.getParameters() != null) {
325: fail("parameters exposed in private key");
326: }
327:
328: if (vKey.getParameters() != null) {
329: fail("parameters exposed in public key");
330: }
331:
332: if (vKey.getQ().getCurve() != null) {
333: fail("curve exposed in public point");
334: }
335: }
336:
337: private void testEC5Params(ECPrivateKey sKey, ECPublicKey vKey) {
338: java.security.interfaces.ECKey k = (java.security.interfaces.ECKey) sKey;
339:
340: if (k.getParams() != null) {
341: fail("parameters exposed in private key");
342: }
343:
344: k = (ECKey) vKey;
345: if (k.getParams() != null) {
346: fail("parameters exposed in public key");
347: }
348: }
349:
350: public String getName() {
351: return "ImplicitlyCA";
352: }
353:
354: public static void main(String[] args) {
355: Security.addProvider(new BouncyCastleProvider());
356:
357: runTest(new ImplicitlyCaTest());
358: }
359: }
|