Merge "Add INFO.yaml file"
[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.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;
64
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;
69
70 public class JU_Factory {
71
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";
76
77         private File resourceDir;
78         private File publicKeyFile;
79         private File privateKeyFile;
80         private File certFile;
81
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;
88
89
90         @Before
91         public void setup() throws CertificateEncodingException {
92                 MockitoAnnotations.initMocks(this);
93
94                 resourceDir = new File(resourceDirName);
95                 resourceDir.mkdirs();
96                 publicKeyFile = new File(resourceDirName, "/publicKey");
97                 privateKeyFile = new File(resourceDirName, "/privateKey");
98                 publicKeyFile.delete();
99                 privateKeyFile.delete();
100
101                 certFile = new File(resourceDirName + "/exampleCertificate.cer");
102
103                 when(transMock.start(anyString(), anyInt())).thenReturn(timeTakenMock);
104                 when(transMock.debug()).thenReturn(logTargetMock);
105
106                 when(subjectDN.toString()).thenReturn(subjectDNText);
107
108                 when(x509CertMock.getSubjectDN()).thenReturn(subjectDN);
109                 when(x509CertMock.getEncoded()).thenReturn(certText.getBytes());
110
111                 when(certMock.getEncoded()).thenReturn(certText.getBytes());
112         }
113
114         @After
115         public void tearDown() {
116                 publicKeyFile = new File(resourceDirName, "/publicKey");
117                 privateKeyFile = new File(resourceDirName, "/privateKey");
118                 publicKeyFile.delete();
119                 privateKeyFile.delete();
120         }
121
122         @Test
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();
127
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));
134
135                 // coverage
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));
143
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));
150         }
151
152         @Test
153         public void keyStringManipTest() throws Exception {
154                 KeyPair kp = Factory.generateKeyPair(transMock);
155
156                 String publicKeyString = Factory.toString(transMock, kp.getPublic());
157                 String privateKeyString = Factory.toString(transMock, kp.getPrivate());
158
159                 assertThat(publicKeyString.startsWith("-----BEGIN PUBLIC KEY-----"), is(true));
160                 assertThat(publicKeyString.endsWith("-----END PUBLIC KEY-----\n"), is(true));
161
162                 assertThat(privateKeyString.startsWith("-----BEGIN PRIVATE KEY-----"), is(true));
163                 assertThat(privateKeyString.endsWith("-----END PRIVATE KEY-----\n"), is(true));
164
165                 PublicKey publicKey = Factory.toPublicKey(transMock, cleanupString(publicKeyString));
166                 PrivateKey privateKey = Factory.toPrivateKey(transMock, cleanupString(privateKeyString));
167
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));
173         }
174
175         @Test
176         public void keyFileManipTest() throws Exception {
177                 KeyPair kp = Factory.generateKeyPair(transMock);
178
179                 String privateKeyString = Factory.toString(transMock, kp.getPrivate());
180                 writeToFile(privateKeyFile, privateKeyString, "Header:this line has a header");
181
182                 PublicKey publicKey = kp.getPublic();
183                 PrivateKey privateKey = Factory.toPrivateKey(transMock, privateKeyFile);
184
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));
190         }
191
192         @Test
193         public void certToStringTest() throws IOException, CertException, CertificateEncodingException {
194                 String certString;
195                 when(logTargetMock.isLoggable()).thenReturn(true);
196
197                 certString = Factory.toString(transMock, x509CertMock);
198                 assertThat(certString.startsWith("-----BEGIN CERTIFICATE-----"), is(true));
199                 assertThat(certString.endsWith("-----END CERTIFICATE-----\n"), is(true));
200
201                 certString = Factory.toString(transMock, certMock);
202                 assertThat(certString.startsWith("-----BEGIN CERTIFICATE-----"), is(true));
203                 assertThat(certString.endsWith("-----END CERTIFICATE-----\n"), is(true));
204
205                 try {
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"));
210                 }
211
212                 when(certMock.getEncoded()).thenThrow(new CertificateEncodingException());
213                 try {
214                         certString = Factory.toString(transMock, certMock);
215                         fail("Should have thrown an exception");
216                 } catch (CertException e) {
217                 }
218
219                 // coverage
220                 when(logTargetMock.isLoggable()).thenReturn(false);
221                 certString = Factory.toString(transMock, x509CertMock);
222         }
223
224         @Test
225         public void toX509Test() throws CertificateException, IOException, CertException {
226                 String output;
227                 Collection<? extends Certificate> certs;
228                 when(logTargetMock.isLoggable()).thenReturn(true);
229
230                 String certString = readFromFile(certFile, false);
231
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));
236
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));
241
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));
250         }
251
252         @Test
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");
257
258                 StripperInputStream stripper = new StripperInputStream(privateKeyFile);
259
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));
265                 stripper.close();
266
267                 // coverage
268                 stripper = new StripperInputStream(new FileInputStream(privateKeyFile));
269                 stripper.close();
270                 stripper = new StripperInputStream(new BufferedReader(new FileReader(privateKeyFile)));
271                 stripper.close();
272                 stripper.close();  // also coverage...
273         }
274
275         @Test
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));
280         }
281
282         @Test
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));
291         }
292
293         @Test
294         public void base64ISTest() throws Exception {
295                 KeyPair kp = Factory.generateKeyPair(transMock);
296
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];
302                 b64is.read(buffer);
303                 b64is.close();
304
305                 FileInputStream fis = new FileInputStream(privateKeyFile);
306                 b64is = new Base64InputStream(fis);
307                 b64is.close();
308                 fis.close();
309         }
310
311         @Test
312         public void getSecurityProviderTest() throws CertException {
313                 String[][] params = {
314                                 {"test", "test"},
315                                 {"test", "test"},
316                 };
317                 assertThat(Factory.getSecurityProvider("PKCS12", params), is(nullValue()));
318         }
319
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]);
325                 }
326                 return join("", rawLines);
327         }
328
329         /**
330          * Note: String.join is not part of JDK 7, which is what we compile to for CADI
331          */
332         private String join(String delim, List<String> rawLines) {
333                 StringBuilder sb = new StringBuilder();
334                 boolean first = true;
335                 for(String s : rawLines) {
336                         if(first) {
337                                 first = false;
338                         } else {
339                                 sb.append(delim);
340                         }
341                         sb.append(s);
342                 }
343                 return sb.toString();
344         }
345
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);
350                 }
351                 writer.println(contents);
352                 writer.close();
353         }
354
355         private String readFromFile(File file, boolean addCR) throws IOException {
356                 BufferedReader br = new BufferedReader(new FileReader(file));
357                 StringBuilder sb = new StringBuilder();
358                 String line;
359                 while ((line = br.readLine()) != null) {
360                         String lineEnd = (addCR) ? "\r\n" : "\n";
361                         sb.append(line + lineEnd);
362                 }
363                 br.close();
364                 return sb.toString();
365         }
366
367 }