001: package org.bouncycastle.jce.provider.test;
002:
003: import java.io.ByteArrayInputStream;
004: import java.math.BigInteger;
005: import java.security.InvalidKeyException;
006: import java.security.KeyPair;
007: import java.security.KeyPairGenerator;
008: import java.security.KeyStore;
009: import java.security.PrivateKey;
010: import java.security.PublicKey;
011: import java.security.Security;
012: import java.security.SignatureException;
013: import java.security.cert.Certificate;
014: import java.security.cert.X509Certificate;
015: import java.util.Date;
016:
017: import org.bouncycastle.asn1.ASN1InputStream;
018: import org.bouncycastle.asn1.ASN1Sequence;
019: import org.bouncycastle.asn1.x9.X9ECParameters;
020: import org.bouncycastle.jce.X509Principal;
021: import org.bouncycastle.jce.provider.BouncyCastleProvider;
022: import org.bouncycastle.jce.provider.JCEECPrivateKey;
023: import org.bouncycastle.jce.provider.JCEECPublicKey;
024: import org.bouncycastle.jce.spec.ECParameterSpec;
025: import org.bouncycastle.math.ec.ECCurve;
026: import org.bouncycastle.util.encoders.Hex;
027: import org.bouncycastle.util.test.SimpleTest;
028: import org.bouncycastle.x509.X509V3CertificateGenerator;
029:
030: public class ECEncodingTest extends SimpleTest {
031: public String getName() {
032: return "ECEncodingTest";
033: }
034:
035: /** J.4.7 An Example with m = 304 */
036: private int m = 304;
037:
038: /** f = 010000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000807 */
039: private int k1 = 1;
040: private int k2 = 2;
041: private int k3 = 11;
042: private byte hexa[] = { (byte) 0xFD, 0x0D, 0x69, 0x31, 0x49,
043: (byte) 0xA1, 0x18, (byte) 0xF6, 0x51, (byte) 0xE6,
044: (byte) 0xDC, (byte) 0xE6, (byte) 0x80, 0x20, (byte) 0x85,
045: 0x37, 0x7E, 0x5F, (byte) 0x88, 0x2D, 0x1B, 0x51, 0x0B,
046: 0x44, 0x16, 0x00, 0x74, (byte) 0xC1, 0x28, (byte) 0x80,
047: 0x78, 0x36, 0x5A, 0x03, (byte) 0x96, (byte) 0xC8,
048: (byte) 0xE6, (byte) 0x81 };
049: private byte hexb[] = { (byte) 0xBD, (byte) 0xDB, (byte) 0x97,
050: (byte) 0xE5, (byte) 0x55, (byte) 0xA5, (byte) 0x0A,
051: (byte) 0x90, (byte) 0x8E, (byte) 0x43, (byte) 0xB0,
052: (byte) 0x1C, (byte) 0x79, (byte) 0x8E, (byte) 0xA5,
053: (byte) 0xDA, (byte) 0xA6, (byte) 0x78, (byte) 0x8F,
054: (byte) 0x1E, (byte) 0xA2, (byte) 0x79, (byte) 0x4E,
055: (byte) 0xFC, (byte) 0xF5, (byte) 0x71, (byte) 0x66,
056: (byte) 0xB8, (byte) 0xC1, (byte) 0x40, (byte) 0x39,
057: (byte) 0x60, (byte) 0x1E, (byte) 0x55, (byte) 0x82,
058: (byte) 0x73, (byte) 0x40, (byte) 0xBE };
059: private BigInteger a = new BigInteger(1, hexa);
060: private BigInteger b = new BigInteger(1, hexb);
061:
062: /** Base point G (with point compression) */
063: private byte enc[] = { 0x02, 0x19, 0x7B, 0x07, (byte) 0x84, 0x5E,
064: (byte) 0x9B, (byte) 0xE2, (byte) 0xD9, 0x6A, (byte) 0xDB,
065: 0x0F, 0x5F, 0x3C, 0x7F, 0x2C, (byte) 0xFF, (byte) 0xBD,
066: 0x7A, 0x3E, (byte) 0xB8, (byte) 0xB6, (byte) 0xFE,
067: (byte) 0xC3, 0x5C, 0x7F, (byte) 0xD6, 0x7F, 0x26,
068: (byte) 0xDD, (byte) 0xF6, 0x28, 0x5A, 0x64, 0x4F, 0x74,
069: 0x0A, 0x26, 0x14 };
070:
071: private void testPointCompression() throws Exception {
072: ECCurve curve = new ECCurve.F2m(m, k1, k2, k3, a, b);
073: curve.decodePoint(enc);
074:
075: int ks[] = new int[3];
076: ks[0] = k3;
077: ks[1] = k2;
078: ks[2] = k1;
079: }
080:
081: public void performTest() throws Exception {
082: byte[] ecParams = Hex
083: .decode("3081C8020101302806072A8648CE3D0101021D00D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF303C041C68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43041C2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B0439040D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD021D00D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F020101");
084: testParams(ecParams, true);
085:
086: testParams(ecParams, false);
087:
088: ecParams = Hex
089: .decode("3081C8020101302806072A8648CE3D0101021D00D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF303C041C56E6C7E4F11A7B4B961A4DCB5BD282EB22E42E9BCBE3E7B361F18012041C4BE3E7B361F18012F2353D22975E02D8D05D2C6F3342DD8F57D4C76F0439048D127A0C27E0DE207ED3B7FB98F83C8BD5A2A57C827F4B97874DEB2C1BAEB0C006958CE61BB1FC81F5389E288CB3E86E2ED91FB47B08FCCA021D00D7C134AA264366862A18302575D11A5F7AABFBA3D897FF5CA727AF53020101");
090: testParams(ecParams, true);
091:
092: testParams(ecParams, false);
093:
094: ecParams = Hex
095: .decode("30820142020101303c06072a8648ce3d0101023100fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff3066043100fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000fffffffc043100b3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed19d2a85c8edd3ec2aef046104aa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab73617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f023100ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973020101");
096: testParams(ecParams, true);
097:
098: testParams(ecParams, false);
099:
100: testPointCompression();
101: }
102:
103: private void testParams(byte[] ecParameterEncoded, boolean compress)
104: throws Exception {
105: String keyStorePass = "myPass";
106: ASN1InputStream in = new ASN1InputStream(
107: new ByteArrayInputStream(ecParameterEncoded));
108: X9ECParameters params = new X9ECParameters((ASN1Sequence) in
109: .readObject());
110: KeyPair kp = null;
111: boolean success = false;
112: while (!success) {
113: KeyPairGenerator kpg = KeyPairGenerator
114: .getInstance("ECDSA");
115: kpg.initialize(new ECParameterSpec(params.getCurve(),
116: params.getG(), params.getN(), params.getH(), params
117: .getSeed()));
118: kp = kpg.generateKeyPair();
119: // The very old Problem... we need a certificate chain to
120: // save a private key...
121: JCEECPublicKey pubKey = (JCEECPublicKey) kp.getPublic();
122: if (!compress) {
123: pubKey.setPointFormat("UNCOMPRESSED");
124: }
125: byte[] x = pubKey.getQ().getX().toBigInteger()
126: .toByteArray();
127: byte[] y = pubKey.getQ().getY().toBigInteger()
128: .toByteArray();
129: if (x.length == y.length) {
130: success = true;
131: }
132: }
133:
134: // The very old Problem... we need a certificate chain to
135: // save a private key...
136:
137: Certificate[] chain = new Certificate[] { generateSelfSignedSoftECCert(
138: kp, compress) };
139:
140: KeyStore keyStore = KeyStore.getInstance("BKS");
141: keyStore.load(null, keyStorePass.toCharArray());
142:
143: keyStore.setCertificateEntry("ECCert", chain[0]);
144:
145: JCEECPrivateKey privateECKey = (JCEECPrivateKey) kp
146: .getPrivate();
147: keyStore.setKeyEntry("ECPrivKey", privateECKey, keyStorePass
148: .toCharArray(), chain);
149:
150: // Test ec sign / verify
151: JCEECPublicKey pub = (JCEECPublicKey) kp.getPublic();
152: String oldPrivateKey = new String(Hex.encode(privateECKey
153: .getEncoded()));
154: String oldPublicKey = new String(Hex.encode(pub.getEncoded()));
155: JCEECPrivateKey newKey = (JCEECPrivateKey) keyStore.getKey(
156: "ECPrivKey", keyStorePass.toCharArray());
157: JCEECPublicKey newPubKey = (JCEECPublicKey) keyStore
158: .getCertificate("ECCert").getPublicKey();
159: if (!compress) {
160: newKey.setPointFormat("UNCOMPRESSED");
161: newPubKey.setPointFormat("UNCOMPRESSED");
162: }
163:
164: String newPrivateKey = new String(Hex.encode(newKey
165: .getEncoded()));
166: String newPublicKey = new String(Hex.encode(newPubKey
167: .getEncoded()));
168:
169: if (!oldPrivateKey.equals(newPrivateKey)) {
170: fail("failed private key comparison");
171: }
172:
173: if (!oldPublicKey.equals(newPublicKey)) {
174: fail("failed public key comparison");
175: }
176: }
177:
178: /**
179: * Create a self signed cert for our software emulation
180: *
181: * @param kp
182: * is the keypair for our certificate
183: * @return a self signed cert for our software emulation
184: * @throws InvalidKeyException
185: * on error
186: * @throws SignatureException
187: * on error
188: */
189: private X509Certificate generateSelfSignedSoftECCert(KeyPair kp,
190: boolean compress) throws InvalidKeyException,
191: SignatureException {
192: X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();
193: JCEECPrivateKey privECKey = (JCEECPrivateKey) kp.getPrivate();
194: JCEECPublicKey pubECKey = (JCEECPublicKey) kp.getPublic();
195: if (!compress) {
196: privECKey.setPointFormat("UNCOMPRESSED");
197: pubECKey.setPointFormat("UNCOMPRESSED");
198: }
199: certGen.setSignatureAlgorithm("ECDSAwithSHA1");
200: certGen.setSerialNumber(BigInteger.valueOf(1));
201: certGen.setIssuerDN(new X509Principal(
202: "CN=Software emul (EC Cert)"));
203: certGen.setNotBefore(new Date(
204: System.currentTimeMillis() - 50000));
205: certGen.setNotAfter(new Date(
206: System.currentTimeMillis() + 50000000));
207: certGen.setSubjectDN(new X509Principal(
208: "CN=Software emul (EC Cert)"));
209: certGen.setPublicKey((PublicKey) pubECKey);
210:
211: return certGen.generateX509Certificate((PrivateKey) privECKey);
212: }
213:
214: public static void main(String[] args) {
215: Security.addProvider(new BouncyCastleProvider());
216:
217: runTest(new ECEncodingTest());
218: }
219: }
|