1 /*******************************************************************************
2 * ============LICENSE_START====================================================
4 * * ===========================================================================
5 * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
6 * * ===========================================================================
7 * * Licensed under the Apache License, Version 2.0 (the "License");
8 * * you may not use this file except in compliance with the License.
9 * * You may obtain a copy of the License at
11 * * http://www.apache.org/licenses/LICENSE-2.0
13 * * Unless required by applicable law or agreed to in writing, software
14 * * distributed under the License is distributed on an "AS IS" BASIS,
15 * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * * See the License for the specific language governing permissions and
17 * * limitations under the License.
18 * * ============LICENSE_END====================================================
21 ******************************************************************************/
23 package org.onap.aaf.cadi.cm.test;
25 import static org.junit.Assert.assertThat;
26 import static org.junit.Assert.fail;
27 import static org.hamcrest.CoreMatchers.is;
28 import static org.hamcrest.CoreMatchers.nullValue;
29 import static org.mockito.Mockito.when;
30 import static org.mockito.Mockito.anyInt;
31 import static org.mockito.Mockito.anyString;
33 import org.junit.After;
34 import org.junit.Before;
35 import org.junit.Test;
36 import org.mockito.Mock;
37 import org.mockito.MockitoAnnotations;
39 import java.io.BufferedReader;
41 import java.io.FileInputStream;
42 import java.io.FileReader;
43 import java.io.IOException;
44 import java.io.PrintWriter;
45 import java.nio.charset.StandardCharsets;
46 import java.security.cert.Certificate;
47 import java.security.cert.CertificateEncodingException;
48 import java.security.cert.CertificateException;
49 import java.security.cert.X509Certificate;
50 import java.security.KeyPair;
51 import java.security.Principal;
52 import java.security.PrivateKey;
53 import java.security.PublicKey;
54 import java.util.ArrayList;
55 import java.util.Collection;
56 import java.util.List;
58 import javax.crypto.Cipher;
60 import org.onap.aaf.cadi.cm.CertException;
61 import org.onap.aaf.cadi.cm.Factory;
62 import org.onap.aaf.cadi.cm.Factory.Base64InputStream;
63 import org.onap.aaf.cadi.cm.Factory.StripperInputStream;
65 import org.onap.aaf.misc.env.Env;
66 import org.onap.aaf.misc.env.LogTarget;
67 import org.onap.aaf.misc.env.TimeTaken;
68 import org.onap.aaf.misc.env.Trans;
70 public class JU_Factory {
72 private static final String message = "The quick brown fox jumps over the lazy dog.";
73 private static final String subjectDNText = "subjectDN";
74 private static final String certText = "Some text that might be included in a certificate";
75 private static final String resourceDirName = "src/test/resources";
77 private File resourceDir;
78 private File publicKeyFile;
79 private File privateKeyFile;
80 private File certFile;
82 @Mock private Trans transMock;
83 @Mock private TimeTaken timeTakenMock;
84 @Mock private LogTarget logTargetMock;
85 @Mock private X509Certificate x509CertMock;
86 @Mock private Certificate certMock;
87 @Mock private Principal subjectDN;
91 public void setup() throws CertificateEncodingException {
92 MockitoAnnotations.initMocks(this);
94 resourceDir = new File(resourceDirName);
96 publicKeyFile = new File(resourceDirName, "/publicKey");
97 privateKeyFile = new File(resourceDirName, "/privateKey");
98 publicKeyFile.delete();
99 privateKeyFile.delete();
101 certFile = new File(resourceDirName + "/exampleCertificate.cer");
103 when(transMock.start(anyString(), anyInt())).thenReturn(timeTakenMock);
104 when(transMock.debug()).thenReturn(logTargetMock);
106 when(subjectDN.toString()).thenReturn(subjectDNText);
108 when(x509CertMock.getSubjectDN()).thenReturn(subjectDN);
109 when(x509CertMock.getEncoded()).thenReturn(certText.getBytes());
111 when(certMock.getEncoded()).thenReturn(certText.getBytes());
115 public void tearDown() {
116 publicKeyFile = new File(resourceDirName, "/publicKey");
117 privateKeyFile = new File(resourceDirName, "/privateKey");
118 publicKeyFile.delete();
119 privateKeyFile.delete();
123 public void generateKeyPairTest() throws Exception {
124 // This instatiation isn't actually necessary, but it gets coverage
125 Cipher encryptor = Factory.pkCipher();
126 Cipher decryptor = Factory.pkCipher();
128 KeyPair kp1 = Factory.generateKeyPair(transMock);
129 encryptor = Factory.pkCipher(kp1.getPublic(), true);
130 decryptor = Factory.pkCipher(kp1.getPrivate(), false);
131 byte[] encrypedMessage1 = encryptor.doFinal(message.getBytes(StandardCharsets.UTF_8));
132 String output1 = new String(decryptor.doFinal(encrypedMessage1));
133 assertThat(output1, is(message));
136 when(transMock.start("Generate KeyPair", Env.SUB)).thenReturn(null);
137 KeyPair kp2 = Factory.generateKeyPair(transMock);
138 encryptor = Factory.pkCipher(kp2.getPublic(), true);
139 decryptor = Factory.pkCipher(kp2.getPrivate(), false);
140 byte[] encrypedMessage2 = encryptor.doFinal(message.getBytes(StandardCharsets.UTF_8));
141 String output2 = new String(decryptor.doFinal(encrypedMessage2));
142 assertThat(output2, is(message));
144 KeyPair kp3 = Factory.generateKeyPair(null);
145 encryptor = Factory.pkCipher(kp3.getPublic(), true);
146 decryptor = Factory.pkCipher(kp3.getPrivate(), false);
147 byte[] encrypedMessage3 = encryptor.doFinal(message.getBytes(StandardCharsets.UTF_8));
148 String output3 = new String(decryptor.doFinal(encrypedMessage3));
149 assertThat(output3, is(message));
153 public void keyStringManipTest() throws Exception {
154 KeyPair kp = Factory.generateKeyPair(transMock);
156 String publicKeyString = Factory.toString(transMock, kp.getPublic());
157 String privateKeyString = Factory.toString(transMock, kp.getPrivate());
159 assertThat(publicKeyString.startsWith("-----BEGIN PUBLIC KEY-----"), is(true));
160 assertThat(publicKeyString.endsWith("-----END PUBLIC KEY-----\n"), is(true));
162 assertThat(privateKeyString.startsWith("-----BEGIN PRIVATE KEY-----"), is(true));
163 assertThat(privateKeyString.endsWith("-----END PRIVATE KEY-----\n"), is(true));
165 PublicKey publicKey = Factory.toPublicKey(transMock, cleanupString(publicKeyString));
166 PrivateKey privateKey = Factory.toPrivateKey(transMock, cleanupString(privateKeyString));
168 Cipher encryptor = Factory.pkCipher(publicKey, true);
169 Cipher decryptor = Factory.pkCipher(privateKey, false);
170 byte[] encrypedMessage = encryptor.doFinal(message.getBytes(StandardCharsets.UTF_8));
171 String output = new String(decryptor.doFinal(encrypedMessage));
172 assertThat(output, is(message));
176 public void keyFileManipTest() throws Exception {
177 KeyPair kp = Factory.generateKeyPair(transMock);
179 String privateKeyString = Factory.toString(transMock, kp.getPrivate());
180 writeToFile(privateKeyFile, privateKeyString, "Header:this line has a header");
182 PublicKey publicKey = kp.getPublic();
183 PrivateKey privateKey = Factory.toPrivateKey(transMock, privateKeyFile);
185 Cipher encryptor = Factory.pkCipher(publicKey, true);
186 Cipher decryptor = Factory.pkCipher(privateKey, false);
187 byte[] encrypedMessage = encryptor.doFinal(message.getBytes(StandardCharsets.UTF_8));
188 String output = new String(decryptor.doFinal(encrypedMessage));
189 assertThat(output, is(message));
193 public void certToStringTest() throws IOException, CertException, CertificateEncodingException {
195 when(logTargetMock.isLoggable()).thenReturn(true);
197 certString = Factory.toString(transMock, x509CertMock);
198 assertThat(certString.startsWith("-----BEGIN CERTIFICATE-----"), is(true));
199 assertThat(certString.endsWith("-----END CERTIFICATE-----\n"), is(true));
201 certString = Factory.toString(transMock, certMock);
202 assertThat(certString.startsWith("-----BEGIN CERTIFICATE-----"), is(true));
203 assertThat(certString.endsWith("-----END CERTIFICATE-----\n"), is(true));
206 certString = Factory.toString(transMock, (Certificate)null);
207 fail("Should have thrown an exception");
208 } catch (CertException e) {
209 assertThat(e.getMessage(), is("Certificate not built"));
212 when(certMock.getEncoded()).thenThrow(new CertificateEncodingException());
214 certString = Factory.toString(transMock, certMock);
215 fail("Should have thrown an exception");
216 } catch (CertException e) {
220 when(logTargetMock.isLoggable()).thenReturn(false);
221 certString = Factory.toString(transMock, x509CertMock);
225 public void toX509Test() throws CertificateException, IOException, CertException {
227 Collection<? extends Certificate> certs;
228 when(logTargetMock.isLoggable()).thenReturn(true);
230 String certString = readFromFile(certFile, false);
232 certs = Factory.toX509Certificate(certString);
233 // Contrived way of getting a Certificate out of a Collection
234 output = Factory.toString(transMock, certs.toArray(new Certificate[0])[0]);
235 assertThat(output, is(certString));
237 certs = Factory.toX509Certificate(transMock, certFile);
238 // Contrived way of getting a Certificate out of a Collection
239 output = Factory.toString(transMock, certs.toArray(new Certificate[0])[0]);
240 assertThat(output, is(certString));
242 List<String> certStrings = new ArrayList<String>();
243 certStrings.add(certString);
244 certStrings.add(certString);
245 certs = Factory.toX509Certificate(certStrings);
246 // Contrived way of getting a Certificate out of a Collection
247 // it doesn't matter which one we get - they're the same
248 output = Factory.toString(transMock, certs.toArray(new Certificate[0])[0]);
249 assertThat(output, is(certString));
253 public void stripperTest() throws Exception {
254 KeyPair kp = Factory.generateKeyPair(transMock);
255 String privateKeyString = Factory.toString(transMock, kp.getPrivate());
256 writeToFile(privateKeyFile, privateKeyString, "Header:this line has a header");
258 StripperInputStream stripper = new StripperInputStream(privateKeyFile);
260 String expected = cleanupString(privateKeyString);
261 byte[] buffer = new byte[10000];
262 stripper.read(buffer);
263 String output = new String(buffer, 0, expected.length());
264 assertThat(output, is(expected));
268 stripper = new StripperInputStream(new FileInputStream(privateKeyFile));
270 stripper = new StripperInputStream(new BufferedReader(new FileReader(privateKeyFile)));
272 stripper.close(); // also coverage...
276 public void binaryTest() throws IOException {
277 String output = new String(Factory.binary(certFile));
278 String expected = readFromFile(certFile, true);
279 assertThat(output, is(expected));
283 public void signatureTest() throws Exception {
284 KeyPair kp = Factory.generateKeyPair(transMock);
285 String signedString = "Something that needs signing";
286 byte[] signedBytes = Factory.sign(transMock, signedString.getBytes(), kp.getPrivate());
287 String output = Factory.toSignatureString(signedBytes);
288 assertThat(output.startsWith("-----BEGIN SIGNATURE-----"), is(true));
289 assertThat(output.endsWith("-----END SIGNATURE-----\n"), is(true));
290 assertThat(Factory.verify(transMock, signedString.getBytes(), signedBytes, kp.getPublic()), is(true));
294 public void base64ISTest() throws Exception {
295 KeyPair kp = Factory.generateKeyPair(transMock);
297 String privateKeyString = Factory.toString(transMock, kp.getPrivate());
298 String cleaned = cleanupString(privateKeyString);
299 writeToFile(privateKeyFile, cleaned, null);
300 Base64InputStream b64is = new Base64InputStream(privateKeyFile);
301 byte[] buffer = new byte[10000];
305 FileInputStream fis = new FileInputStream(privateKeyFile);
306 b64is = new Base64InputStream(fis);
312 public void getSecurityProviderTest() throws CertException {
313 String[][] params = {
317 assertThat(Factory.getSecurityProvider("PKCS12", params), is(nullValue()));
320 private String cleanupString(String str) {
321 String[] lines = str.split("\n", 0);
322 List<String> rawLines = new ArrayList<String>();
323 for (int i = 0; i < lines.length - 2; i++) {
324 rawLines.add(lines[i + 1]);
326 return join("", rawLines);
330 * Note: String.join is not part of JDK 7, which is what we compile to for CADI
332 private String join(String delim, List<String> rawLines) {
333 StringBuilder sb = new StringBuilder();
334 boolean first = true;
335 for(String s : rawLines) {
343 return sb.toString();
346 private void writeToFile(File file, String contents, String header) throws Exception {
347 PrintWriter writer = new PrintWriter(file, "UTF-8");
348 if (header != null) {
349 writer.println(header);
351 writer.println(contents);
355 private String readFromFile(File file, boolean addCR) throws IOException {
356 BufferedReader br = new BufferedReader(new FileReader(file));
357 StringBuilder sb = new StringBuilder();
359 while ((line = br.readLine()) != null) {
360 String lineEnd = (addCR) ? "\r\n" : "\n";
361 sb.append(line + lineEnd);
364 return sb.toString();