Mass removal of all Tabs (Style Warnings)
[aaf/authz.git] / cadi / aaf / src / test / java / org / onap / aaf / cadi / cm / test / JU_Factory.java
1 /*******************************************************************************
2  * ============LICENSE_START====================================================
3  * * org.onap.aaf
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
10  * *
11  *  *      http://www.apache.org/licenses/LICENSE-2.0
12  * *
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====================================================
19  * *
20  * *
21  ******************************************************************************/
22
23 package org.onap.aaf.cadi.cm.test;
24
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;
32
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;
38
39 import java.io.BufferedReader;
40 import java.io.File;
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;
57
58 import javax.crypto.Cipher;
59
60 import org.onap.aaf.cadi.configure.CertException;
61 import org.onap.aaf.cadi.configure.Factory;
62 import org.onap.aaf.cadi.configure.Factory.Base64InputStream;
63 import org.onap.aaf.cadi.configure.Factory.StripperInputStream;
64 import org.onap.aaf.misc.env.Env;
65 import org.onap.aaf.misc.env.LogTarget;
66 import org.onap.aaf.misc.env.TimeTaken;
67 import org.onap.aaf.misc.env.Trans;
68
69 public class JU_Factory {
70
71     private static final String message = "The quick brown fox jumps over the lazy dog.";
72     private static final String subjectDNText = "subjectDN";
73     private static final String certText = "Some text that might be included in a certificate";
74     private static final String resourceDirName = "src/test/resources";
75
76     private File resourceDir;
77     private File publicKeyFile;
78     private File privateKeyFile;
79     private File certFile;
80
81     @Mock private Trans transMock;
82     @Mock private TimeTaken timeTakenMock;
83     @Mock private LogTarget logTargetMock;
84     @Mock private X509Certificate x509CertMock;
85     @Mock private Certificate certMock;
86     @Mock private Principal subjectDN;
87
88
89     @Before
90     public void setup() throws CertificateEncodingException {
91         MockitoAnnotations.initMocks(this);
92
93         resourceDir = new File(resourceDirName);
94         resourceDir.mkdirs();
95         publicKeyFile = new File(resourceDirName, "/publicKey");
96         privateKeyFile = new File(resourceDirName, "/privateKey");
97         publicKeyFile.delete();
98         privateKeyFile.delete();
99
100         certFile = new File(resourceDirName + "/exampleCertificate.cer");
101
102         when(transMock.start(anyString(), anyInt())).thenReturn(timeTakenMock);
103         when(transMock.debug()).thenReturn(logTargetMock);
104
105         when(subjectDN.toString()).thenReturn(subjectDNText);
106
107         when(x509CertMock.getSubjectDN()).thenReturn(subjectDN);
108         when(x509CertMock.getEncoded()).thenReturn(certText.getBytes());
109
110         when(certMock.getEncoded()).thenReturn(certText.getBytes());
111     }
112
113     @After
114     public void tearDown() {
115         publicKeyFile = new File(resourceDirName, "/publicKey");
116         privateKeyFile = new File(resourceDirName, "/privateKey");
117         publicKeyFile.delete();
118         privateKeyFile.delete();
119     }
120
121     @Test
122     public void generateKeyPairTest() throws Exception {
123         // This instatiation isn't actually necessary, but it gets coverage
124         Cipher encryptor = Factory.pkCipher();
125         Cipher decryptor = Factory.pkCipher();
126
127         KeyPair kp1 = Factory.generateKeyPair(transMock);
128         encryptor = Factory.pkCipher(kp1.getPublic(), true);
129         decryptor = Factory.pkCipher(kp1.getPrivate(), false);
130         byte[] encrypedMessage1 = encryptor.doFinal(message.getBytes(StandardCharsets.UTF_8));
131         String output1 = new String(decryptor.doFinal(encrypedMessage1));
132         assertThat(output1, is(message));
133
134         // coverage
135         when(transMock.start("Generate KeyPair", Env.SUB)).thenReturn(null);
136         KeyPair kp2 = Factory.generateKeyPair(transMock);
137         encryptor = Factory.pkCipher(kp2.getPublic(), true);
138         decryptor = Factory.pkCipher(kp2.getPrivate(), false);
139         byte[] encrypedMessage2 = encryptor.doFinal(message.getBytes(StandardCharsets.UTF_8));
140         String output2 = new String(decryptor.doFinal(encrypedMessage2));
141         assertThat(output2, is(message));
142
143         KeyPair kp3 = Factory.generateKeyPair(null);
144         encryptor = Factory.pkCipher(kp3.getPublic(), true);
145         decryptor = Factory.pkCipher(kp3.getPrivate(), false);
146         byte[] encrypedMessage3 = encryptor.doFinal(message.getBytes(StandardCharsets.UTF_8));
147         String output3 = new String(decryptor.doFinal(encrypedMessage3));
148         assertThat(output3, is(message));
149     }
150
151     @Test
152     public void keyStringManipTest() throws Exception {
153         KeyPair kp = Factory.generateKeyPair(transMock);
154
155         String publicKeyString = Factory.toString(transMock, kp.getPublic());
156         String privateKeyString = Factory.toString(transMock, kp.getPrivate());
157
158         assertThat(publicKeyString.startsWith("-----BEGIN PUBLIC KEY-----"), is(true));
159         assertThat(publicKeyString.endsWith("-----END PUBLIC KEY-----\n"), is(true));
160
161         assertThat(privateKeyString.startsWith("-----BEGIN PRIVATE KEY-----"), is(true));
162         assertThat(privateKeyString.endsWith("-----END PRIVATE KEY-----\n"), is(true));
163
164         PublicKey publicKey = Factory.toPublicKey(transMock, publicKeyString);
165         PrivateKey privateKey = Factory.toPrivateKey(transMock, privateKeyString);
166
167         Cipher encryptor = Factory.pkCipher(publicKey, true);
168         Cipher decryptor = Factory.pkCipher(privateKey, false);
169         byte[] encrypedMessage = encryptor.doFinal(message.getBytes(StandardCharsets.UTF_8));
170         String output = new String(decryptor.doFinal(encrypedMessage));
171         assertThat(output, is(message));
172     }
173
174     @Test
175     public void keyFileManipTest() throws Exception {
176         KeyPair kp = Factory.generateKeyPair(transMock);
177
178         String privateKeyString = Factory.toString(transMock, kp.getPrivate());
179         writeToFile(privateKeyFile, privateKeyString, "Header:this line has a header");
180
181         PublicKey publicKey = kp.getPublic();
182         PrivateKey privateKey = Factory.toPrivateKey(transMock, privateKeyFile);
183
184         Cipher encryptor = Factory.pkCipher(publicKey, true);
185         Cipher decryptor = Factory.pkCipher(privateKey, false);
186         byte[] encrypedMessage = encryptor.doFinal(message.getBytes(StandardCharsets.UTF_8));
187         String output = new String(decryptor.doFinal(encrypedMessage));
188         assertThat(output, is(message));
189     }
190
191     @Test
192     public void certToStringTest() throws IOException, CertException, CertificateEncodingException {
193         String certString;
194         when(logTargetMock.isLoggable()).thenReturn(true);
195
196         certString = Factory.toString(transMock, x509CertMock);
197         assertThat(certString.startsWith("-----BEGIN CERTIFICATE-----"), is(true));
198         assertThat(certString.endsWith("-----END CERTIFICATE-----\n"), is(true));
199
200         certString = Factory.toString(transMock, certMock);
201         assertThat(certString.startsWith("-----BEGIN CERTIFICATE-----"), is(true));
202         assertThat(certString.endsWith("-----END CERTIFICATE-----\n"), is(true));
203
204         try {
205             certString = Factory.toString(transMock, (Certificate)null);
206             fail("Should have thrown an exception");
207         } catch (CertException e) {
208             assertThat(e.getMessage(), is("Certificate not built"));
209         }
210
211         when(certMock.getEncoded()).thenThrow(new CertificateEncodingException());
212         try {
213             certString = Factory.toString(transMock, certMock);
214             fail("Should have thrown an exception");
215         } catch (CertException e) {
216         }
217
218         // coverage
219         when(logTargetMock.isLoggable()).thenReturn(false);
220         certString = Factory.toString(transMock, x509CertMock);
221     }
222
223     @Test
224     public void toX509Test() throws CertificateException, IOException, CertException {
225         String output;
226         Collection<? extends Certificate> certs;
227         when(logTargetMock.isLoggable()).thenReturn(true);
228
229         String certString = readFromFile(certFile, false);
230
231         certs = Factory.toX509Certificate(certString);
232         // Contrived way of getting a Certificate out of a Collection
233         output = Factory.toString(transMock, certs.toArray(new Certificate[0])[0]);
234         assertThat(output, is(certString));
235
236         certs = Factory.toX509Certificate(transMock, certFile);
237         // Contrived way of getting a Certificate out of a Collection
238         output = Factory.toString(transMock, certs.toArray(new Certificate[0])[0]);
239         assertThat(output, is(certString));
240
241         List<String> certStrings = new ArrayList<>();
242         certStrings.add(certString);
243         certStrings.add(certString);
244         certs = Factory.toX509Certificate(certStrings);
245         // Contrived way of getting a Certificate out of a Collection
246         // it doesn't matter which one we get - they're the same
247         output = Factory.toString(transMock, certs.toArray(new Certificate[0])[0]);
248         assertThat(output, is(certString));
249     }
250
251     @Test
252     public void stripperTest() throws Exception {
253         KeyPair kp = Factory.generateKeyPair(transMock);
254         String privateKeyString = Factory.toString(transMock, kp.getPrivate());
255         writeToFile(privateKeyFile, privateKeyString, "Header:this line has a header");
256
257         StripperInputStream stripper = new StripperInputStream(privateKeyFile);
258
259         String expected = cleanupString(privateKeyString);
260         byte[] buffer = new byte[10000];
261         stripper.read(buffer);
262         String output = new String(buffer, 0, expected.length());
263         assertThat(output, is(expected));
264         stripper.close();
265
266         // coverage
267         stripper = new StripperInputStream(new FileInputStream(privateKeyFile));
268         stripper.close();
269         stripper = new StripperInputStream(new BufferedReader(new FileReader(privateKeyFile)));
270         stripper.close();
271         stripper.close();  // also coverage...
272     }
273
274     @Test
275     public void binaryTest() throws IOException {
276         String output = new String(Factory.binary(certFile));
277         String expected = readFromFile(certFile, true);
278         assertThat(output, is(expected));
279     }
280
281     @Test
282     public void signatureTest() throws Exception {
283         KeyPair kp = Factory.generateKeyPair(transMock);
284         String signedString = "Something that needs signing";
285         byte[] signedBytes = Factory.sign(transMock, signedString.getBytes(), kp.getPrivate());
286         String output = Factory.toSignatureString(signedBytes);
287         assertThat(output.startsWith("-----BEGIN SIGNATURE-----"), is(true));
288         assertThat(output.endsWith("-----END SIGNATURE-----\n"), is(true));
289         assertThat(Factory.verify(transMock, signedString.getBytes(), signedBytes, kp.getPublic()), is(true));
290     }
291
292     @Test
293     public void base64ISTest() throws Exception {
294         KeyPair kp = Factory.generateKeyPair(transMock);
295
296         String privateKeyString = Factory.toString(transMock, kp.getPrivate());
297         String cleaned = cleanupString(privateKeyString);
298         writeToFile(privateKeyFile, cleaned, null);
299         Base64InputStream b64is = new Base64InputStream(privateKeyFile);
300         byte[] buffer = new byte[10000];
301         b64is.read(buffer);
302         b64is.close();
303
304         FileInputStream fis = new FileInputStream(privateKeyFile);
305         b64is = new Base64InputStream(fis);
306         b64is.close();
307         fis.close();
308     }
309
310     @Test
311     public void getSecurityProviderTest() throws CertException {
312         String[][] params = {
313                 {"test", "test"},
314                 {"test", "test"},
315         };
316         assertThat(Factory.getSecurityProvider("PKCS12", params), is(nullValue()));
317     }
318
319     private String cleanupString(String str) {
320         String[] lines = str.split("\n", 0);
321         List<String> rawLines = new ArrayList<>();
322         for (int i = 0; i < lines.length - 2; i++) {
323             rawLines.add(lines[i + 1]);
324         }
325         return join("", rawLines);
326     }
327
328     /**
329      * Note: String.join is not part of JDK 7, which is what we compile to for CADI
330      */
331     private String join(String delim, List<String> rawLines) {
332         StringBuilder sb = new StringBuilder();
333         boolean first = true;
334         for(String s : rawLines) {
335             if(first) {
336                 first = false;
337             } else {
338                 sb.append(delim);
339             }
340             sb.append(s);
341         }
342         return sb.toString();
343     }
344
345     private void writeToFile(File file, String contents, String header) throws Exception {
346         PrintWriter writer = new PrintWriter(file, "UTF-8");
347         if (header != null) {
348             writer.println(header);
349         }
350         writer.println(contents);
351         writer.close();
352     }
353
354     private String readFromFile(File file, boolean addCR) throws IOException {
355         BufferedReader br = new BufferedReader(new FileReader(file));
356         StringBuilder sb = new StringBuilder();
357         String line;
358         while ((line = br.readLine()) != null) {
359             String lineEnd = (addCR) ? "\r\n" : "\n";
360             sb.append(line + lineEnd);
361         }
362         br.close();
363         return sb.toString();
364     }
365
366 }