001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */
019:
020: package org.apache.harmony.tools.keytool.tests;
021:
022: import java.io.File;
023: import java.math.BigInteger;
024: import java.security.InvalidKeyException;
025: import java.security.Key;
026: import java.security.KeyStore;
027: import java.security.NoSuchAlgorithmException;
028: import java.security.PrivateKey;
029: import java.security.cert.X509Certificate;
030: import java.util.Arrays;
031: import java.util.Date;
032:
033: import javax.crypto.Cipher;
034: import javax.security.auth.x500.X500Principal;
035:
036: import junit.framework.TestCase;
037:
038: import org.apache.harmony.tools.keytool.KeytoolException;
039: import org.apache.harmony.tools.keytool.Main;
040: import org.apache.harmony.tools.toolutils.KeyStoreLoaderSaver;
041:
042: /**
043: * Tests "-genkey" option of Keytool.
044: */
045: public class GenKeyTest extends TestCase {
046: /**
047: * Test method for generation of a key pair and wrapping it into a a
048: * certificate (self-signed or signed with another certificate from the
049: * store) with method 'KeyCertGenerator.genKey(KeytoolParameters)'
050: */
051: public void testGenKey_keyPair() throws Exception {
052:
053: // need to create keystore in a temporary directory
054: String tempDir = System.getProperty("java.io.tmpdir")
055: + File.separatorChar;
056: String keyStorePath = tempDir + "GenKeyTestTemporaryFile";
057:
058: File keyStoreFile = new File(keyStorePath);
059: // Quit if such file exists for some reason.
060: if (keyStoreFile.exists()) {
061: assertTrue(
062: "Cannot delete a temporary file " + keyStorePath,
063: keyStoreFile.delete());
064: }
065: // The file will be created by the KeyStoreLoaderSaver,
066: // delete it when exiting.
067:
068: // normal parameters //
069: // parameters for key pair with self-signed cerificate generation
070: String[] selfSignedArgs = TestUtils.genKeySelfSignedArgs;
071: String[] genKeyNoIssuerArgs = new String[selfSignedArgs.length];
072: System.arraycopy(selfSignedArgs, 0, genKeyNoIssuerArgs, 0,
073: selfSignedArgs.length);
074: // set keystore
075: genKeyNoIssuerArgs[2] = keyStorePath;
076: // set distinguished name
077: genKeyNoIssuerArgs[18] = "CN=selfSigned";
078:
079: // parameters to create a key pair with certificate signed by just
080: // generated certificate and key pair
081: // +4 will contain "-issuer" and "-issuerpass" options and their
082: // values (2+2)
083: String[] genKeyIssuerArgs = new String[selfSignedArgs.length + 4];
084: System.arraycopy(selfSignedArgs, 0, genKeyIssuerArgs, 0,
085: selfSignedArgs.length);
086: // "-issuer alias -issuerpass 321321"
087: genKeyIssuerArgs[genKeyIssuerArgs.length - 4] = "-issuer";
088: genKeyIssuerArgs[genKeyIssuerArgs.length - 3] = genKeyNoIssuerArgs[8];
089: genKeyIssuerArgs[genKeyIssuerArgs.length - 2] = "-issuerpass";
090: genKeyIssuerArgs[genKeyIssuerArgs.length - 1] = TestUtils.keyPass;
091: // set keystore
092: genKeyIssuerArgs[2] = keyStorePath;
093: // set alias
094: genKeyIssuerArgs[8] = "issued";
095:
096: try {
097: // Firstly generate a self-signed cert
098: String[] args = genKeyNoIssuerArgs;
099: String errMsgPrefix = "Self-signed cert generation: ";
100: for (int p = 0; p < 2; p++) {
101: if (p == 1) {
102: // secondly generate a cert, signed by an issuer
103: args = genKeyIssuerArgs;
104: errMsgPrefix = "Issued cert generation: ";
105: }
106:
107: // current alias
108: String curAlias = args[8];
109:
110: // run Keytool with given arguments
111: Main.run(args);
112:
113: // read the result
114: KeyStore keyStore = KeyStoreLoaderSaver.loadStore(
115: keyStorePath, args[6], TestUtils.ksPass
116: .toCharArray(), null);
117: // check the result
118: assertTrue(errMsgPrefix + "alias " + curAlias
119: + " does not exist in keystore", keyStore
120: .containsAlias(curAlias));
121: assertTrue(errMsgPrefix + "alias " + curAlias
122: + " is not a key entry", keyStore
123: .isKeyEntry(curAlias));
124: Key key = keyStore.getKey(curAlias, TestUtils.keyPass
125: .toCharArray());
126: // check if alg = "RSA"
127: assertEquals(errMsgPrefix
128: + "unexpected key algorithm. ", args[14], key
129: .getAlgorithm().toUpperCase());
130: X509Certificate cert = (X509Certificate) keyStore
131: .getCertificate(curAlias);
132: X500Principal prnc = cert.getSubjectX500Principal();
133: // check if the name = "CN=CN,OU=OU,O=O,L=L,ST=ST,C=C"
134: assertEquals(errMsgPrefix + "unexpected name. ",
135: args[18], prnc.getName());
136: X500Principal issuerPrnc = cert
137: .getIssuerX500Principal();
138: // if generated self-signed certificate
139: if (p == 0) {
140: // check if the issuer and subject equal
141: assertEquals(errMsgPrefix
142: + "unexpected principal. ", prnc,
143: issuerPrnc);
144: cert.verify(cert.getPublicKey());
145: } else { // if signed with certificate chain
146: // check if issuer name is "CN=selfSigned"
147: assertEquals(errMsgPrefix
148: + "unexpected issuer name. ",
149: genKeyNoIssuerArgs[18], issuerPrnc
150: .getName());
151: cert.verify(keyStore.getCertificate(
152: genKeyNoIssuerArgs[8]).getPublicKey());
153: }
154:
155: // check validity period
156: // 86400000 milliseconds in one day
157: long curPlusValidity = System.currentTimeMillis()
158: + 86400000 * (new Integer(args[20])).intValue();
159: // 300000 ms is 5 minutes
160: cert.checkValidity(new Date(curPlusValidity - 300000));
161:
162: assertEquals(errMsgPrefix
163: + "unexpected serial number. ", new BigInteger(
164: args[24]), cert.getSerialNumber());
165: assertEquals(errMsgPrefix + "unexpected version. ",
166: new Integer(args[22]).intValue(), cert
167: .getVersion());
168:
169: // Encrypt data with the private key and decrypt
170: // it with the certificate.
171: PrivateKey privateKey = (PrivateKey) keyStore.getKey(
172: curAlias, TestUtils.keyPass.toCharArray());
173: Cipher cipher = Cipher.getInstance("RSA");
174: cipher.init(Cipher.ENCRYPT_MODE, privateKey);
175: byte[] clearText = "Betty Botter bought some butter"
176: .getBytes();
177: byte[] cipherText = cipher.doFinal(clearText);
178: cipher.init(Cipher.DECRYPT_MODE, cert);
179: byte[] decrypted = cipher.doFinal(cipherText);
180: assertTrue(errMsgPrefix
181: + "unexpected decryption result. ", Arrays
182: .equals(clearText, decrypted));
183: }
184:
185: // remove the added entries
186: genKeyNoIssuerArgs[0] = "-delete";
187: Main.run(genKeyNoIssuerArgs);
188: genKeyNoIssuerArgs[0] = "-genkey";
189:
190: genKeyIssuerArgs[0] = "-delete";
191: Main.run(genKeyIssuerArgs);
192: genKeyIssuerArgs[0] = "-genkey";
193:
194: // bad parameters //
195: // error message
196: String excNotThrown = TestUtils.excNotThrown;
197:
198: // bad key size
199: args = genKeyNoIssuerArgs;
200: String keySize = args[12];
201: args[12] = "1";
202: try {
203: Main.run(args);
204: fail(excNotThrown);
205: } catch (IllegalArgumentException ok) {
206: }
207: // set normal key size back
208: args[12] = keySize;
209:
210: // bad key algorithm
211: String keyAlg = args[14];
212: args[14] = "badKeyAlg";
213: try {
214: Main.run(args);
215: fail(excNotThrown);
216: } catch (NoSuchAlgorithmException ok) {
217: }
218: // set normal key algorithm back
219: args[14] = keyAlg;
220:
221: // bad signature algorithm
222: String sigAlg = args[16];
223: args[16] = "badSigAlg";
224: try {
225: Main.run(args);
226: fail(excNotThrown);
227: } catch (NoSuchAlgorithmException ok) {
228: }
229:
230: // normal but incompatible signature algorithm
231: args[16] = "SHA1withDSA";
232: try {
233: Main.run(args);
234: fail(excNotThrown);
235: } catch (InvalidKeyException ok) {
236: }
237: // set compatible signature algorithm back
238: args[16] = sigAlg;
239:
240: // try to sign with issuer with bad parameters
241: args = genKeyIssuerArgs;
242:
243: // bad issuer alias
244: String issuerAlias = args[26];
245: args[26] = "badIssuerAlias";
246: try {
247: Main.run(args);
248: fail(excNotThrown);
249: } catch (KeytoolException ok) {
250: }
251: // set normal issuer alias back
252: args[26] = issuerAlias;
253: } finally {
254: keyStoreFile.delete();
255: }
256: }
257: }
|