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