05bda54bf41b8919d5aa4f2e6b5e326f3c89fef7
[oom/platform/cert-service.git] / certService / src / test / java / org / onap / aaf / certservice / cmpv2client / Cmpv2ClientTest.java
1 /*
2  * Copyright (C) 2019 Ericsson Software Technology AB. All rights reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License
15  */
16
17 package org.onap.aaf.certservice.cmpv2client;
18
19 import static org.junit.jupiter.api.Assertions.assertNotNull;
20 import static org.mockito.ArgumentMatchers.any;
21 import static org.mockito.Mockito.doAnswer;
22 import static org.mockito.Mockito.spy;
23 import static org.mockito.Mockito.when;
24 import static org.mockito.MockitoAnnotations.initMocks;
25
26 import java.io.BufferedInputStream;
27 import java.io.ByteArrayOutputStream;
28 import java.io.IOException;
29 import java.io.InputStream;
30 import java.io.OutputStream;
31 import java.security.KeyFactory;
32 import java.security.KeyPair;
33 import java.security.NoSuchAlgorithmException;
34 import java.security.NoSuchProviderException;
35 import java.security.PrivateKey;
36 import java.security.PublicKey;
37 import java.security.Security;
38 import java.security.cert.X509Certificate;
39 import java.security.spec.InvalidKeySpecException;
40 import java.security.spec.PKCS8EncodedKeySpec;
41 import java.security.spec.X509EncodedKeySpec;
42 import java.text.ParseException;
43 import java.text.SimpleDateFormat;
44 import java.util.Collections;
45 import java.util.Date;
46 import java.util.List;
47
48 import org.apache.commons.io.IOUtils;
49 import org.apache.http.HttpEntity;
50 import org.apache.http.client.methods.CloseableHttpResponse;
51 import org.apache.http.impl.client.CloseableHttpClient;
52 import org.bouncycastle.asn1.x500.X500Name;
53 import org.bouncycastle.asn1.x500.X500NameBuilder;
54 import org.bouncycastle.asn1.x500.style.BCStyle;
55 import org.bouncycastle.jce.provider.BouncyCastleProvider;
56 import org.junit.jupiter.api.Assertions;
57 import org.junit.jupiter.api.BeforeEach;
58 import org.junit.jupiter.api.Test;
59 import org.mockito.Mock;
60 import org.onap.aaf.certservice.certification.configuration.model.Authentication;
61 import org.onap.aaf.certservice.certification.configuration.model.Cmpv2Server;
62 import org.onap.aaf.certservice.certification.model.CsrModel;
63 import org.onap.aaf.certservice.cmpv2client.exceptions.CmpClientException;
64 import org.onap.aaf.certservice.cmpv2client.impl.CmpClientImpl;
65 import org.onap.aaf.certservice.cmpv2client.model.Cmpv2CertificationModel;
66
67 class Cmpv2ClientTest {
68
69     static {
70         Security.addProvider(new BouncyCastleProvider());
71     }
72
73     private CsrModel csrModel;
74     private Cmpv2Server server;
75     private Date notBefore;
76     private Date notAfter;
77     private X500Name dn;
78
79     @Mock
80     X509Certificate cert;
81
82     @Mock
83     CloseableHttpClient httpClient;
84
85     @Mock
86     CloseableHttpResponse httpResponse;
87
88     @Mock
89     HttpEntity httpEntity;
90
91     private static KeyPair keyPair;
92
93     @BeforeEach
94     void setUp()
95             throws NoSuchProviderException, NoSuchAlgorithmException, IOException,
96             InvalidKeySpecException {
97         keyPair = loadKeyPair();
98         dn = new X500NameBuilder()
99                 .addRDN(BCStyle.O, "TestOrganization")
100                 .build();
101         initMocks(this);
102     }
103
104     public KeyPair loadKeyPair()
105             throws IOException, NoSuchAlgorithmException, InvalidKeySpecException,
106             NoSuchProviderException {
107
108         final InputStream privateInputStream = this.getClass().getResourceAsStream("/privateKey");
109         final InputStream publicInputStream = this.getClass().getResourceAsStream("/publicKey");
110         BufferedInputStream bis = new BufferedInputStream(privateInputStream);
111         byte[] privateBytes = IOUtils.toByteArray(bis);
112         bis = new BufferedInputStream(publicInputStream);
113         byte[] publicBytes = IOUtils.toByteArray(bis);
114
115         KeyFactory keyFactory = KeyFactory.getInstance("RSA", BouncyCastleProvider.PROVIDER_NAME);
116         X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(publicBytes);
117         PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);
118
119         PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(privateBytes);
120         PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec);
121
122         return new KeyPair(publicKey, privateKey);
123     }
124
125     @Test
126     void shouldReturnValidPkiMessageWhenCreateCertificateRequestMessageMethodCalledWithValidCsr()
127             throws Exception {
128         // given
129         Date beforeDate = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").parse("2019/11/11 12:00:00");
130         Date afterDate = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").parse("2020/11/11 12:00:00");
131         setCsrModelAndServerValues(
132                 "mypassword",
133                 "senderKID",
134                 "http://127.0.0.1/ejbca/publicweb/cmp/cmp",
135                 beforeDate,
136                 afterDate);
137         when(httpClient.execute(any())).thenReturn(httpResponse);
138         when(httpResponse.getEntity()).thenReturn(httpEntity);
139
140         try (final InputStream is =
141                      this.getClass().getResourceAsStream("/ReturnedSuccessPKIMessageWithCertificateFile");
142              BufferedInputStream bis = new BufferedInputStream(is)) {
143
144             byte[] ba = IOUtils.toByteArray(bis);
145             doAnswer(
146                     invocation -> {
147                         OutputStream os = (ByteArrayOutputStream) invocation.getArguments()[0];
148                         os.write(ba);
149                         return null;
150                     })
151                     .when(httpEntity)
152                     .writeTo(any(OutputStream.class));
153         }
154         CmpClientImpl cmpClient = spy(new CmpClientImpl(httpClient));
155         // when
156         Cmpv2CertificationModel cmpClientResult =
157                 cmpClient.createCertificate(csrModel, server, notBefore, notAfter);
158         // then
159         assertNotNull(cmpClientResult);
160     }
161
162     @Test
163     void
164     shouldThrowCmpClientExceptionWhenCreateCertificateRequestMessageMethodCalledWithWrongProtectedBytesInResponse()
165             throws Exception {
166         // given
167         Date beforeDate = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").parse("2019/11/11 12:00:00");
168         Date afterDate = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").parse("2020/11/11 12:00:00");
169         setCsrModelAndServerValues(
170                 "password",
171                 "senderKID",
172                 "http://127.0.0.1/ejbca/publicweb/cmp/cmp",
173                 beforeDate,
174                 afterDate);
175         when(httpClient.execute(any())).thenReturn(httpResponse);
176         when(httpResponse.getEntity()).thenReturn(httpEntity);
177
178         try (final InputStream is =
179                      this.getClass().getResourceAsStream("/ReturnedSuccessPKIMessageWithCertificateFile");
180              BufferedInputStream bis = new BufferedInputStream(is)) {
181
182             byte[] ba = IOUtils.toByteArray(bis);
183             doAnswer(
184                     invocation -> {
185                         OutputStream os = (ByteArrayOutputStream) invocation.getArguments()[0];
186                         os.write(ba);
187                         return null;
188                     })
189                     .when(httpEntity)
190                     .writeTo(any(OutputStream.class));
191         }
192         CmpClientImpl cmpClient = spy(new CmpClientImpl(httpClient));
193         // then
194         Assertions.assertThrows(
195                 CmpClientException.class,
196                 () -> cmpClient.createCertificate(csrModel, server, notBefore, notAfter));
197     }
198
199     @Test
200     void shouldThrowCmpClientExceptionWithPkiErrorExceptionWhenCmpClientCalledWithBadPassword()
201             throws Exception {
202         // given
203         Date beforeDate = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").parse("2019/11/11 12:00:00");
204         Date afterDate = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").parse("2020/11/11 12:00:00");
205         setCsrModelAndServerValues(
206                 "password",
207                 "senderKID",
208                 "http://127.0.0.1/ejbca/publicweb/cmp/cmp",
209                 beforeDate,
210                 afterDate);
211         when(httpClient.execute(any())).thenReturn(httpResponse);
212         when(httpResponse.getEntity()).thenReturn(httpEntity);
213
214         try (final InputStream is =
215                      this.getClass().getResourceAsStream("/ReturnedFailurePKIMessageBadPassword");
216              BufferedInputStream bis = new BufferedInputStream(is)) {
217
218             byte[] ba = IOUtils.toByteArray(bis);
219             doAnswer(
220                     invocation -> {
221                         OutputStream os = (ByteArrayOutputStream) invocation.getArguments()[0];
222                         os.write(ba);
223                         return null;
224                     })
225                     .when(httpEntity)
226                     .writeTo(any(OutputStream.class));
227         }
228         CmpClientImpl cmpClient = spy(new CmpClientImpl(httpClient));
229
230         // then
231         Assertions.assertThrows(
232                 CmpClientException.class,
233                 () -> cmpClient.createCertificate(csrModel, server, notBefore, notAfter));
234     }
235
236     @Test
237     void shouldThrowIllegalArgumentExceptionWhencreateCertificateCalledWithInvalidCsr()
238             throws ParseException {
239         // given
240         Date beforeDate = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").parse("2020/11/11 12:00:00");
241         Date afterDate = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").parse("2019/11/11 12:00:00");
242         setCsrModelAndServerValues(
243                 "password",
244                 "senderKID",
245                 "http://127.0.0.1/ejbca/publicweb/cmp/cmp",
246                 beforeDate,
247                 afterDate);
248         CmpClientImpl cmpClient = new CmpClientImpl(httpClient);
249         // then
250         Assertions.assertThrows(
251                 IllegalArgumentException.class,
252                 () -> cmpClient.createCertificate(csrModel, server, notBefore, notAfter));
253     }
254
255     @Test
256     void shouldThrowIoExceptionWhenCreateCertificateCalledWithNoServerAvailable()
257             throws IOException, ParseException {
258         // given
259         Date beforeDate = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").parse("2019/11/11 12:00:00");
260         Date afterDate = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").parse("2020/11/11 12:00:00");
261         setCsrModelAndServerValues(
262                 "myPassword",
263                 "sender",
264                 "http://127.0.0.1/ejbca/publicweb/cmp/cmpTest",
265                 beforeDate,
266                 afterDate);
267         when(httpClient.execute(any())).thenThrow(IOException.class);
268         CmpClientImpl cmpClient = spy(new CmpClientImpl(httpClient));
269         // then
270         Assertions.assertThrows(
271                 CmpClientException.class,
272                 () -> cmpClient.createCertificate(csrModel, server, notBefore, notAfter));
273     }
274
275     private void setCsrModelAndServerValues(String iak, String rv, String externalCaUrl, Date notBefore, Date notAfter) {
276         csrModel = new CsrModel(null, dn, keyPair.getPrivate(), keyPair.getPublic(), Collections.emptyList());
277
278         Authentication authentication = new Authentication();
279         authentication.setIak(iak);
280         authentication.setRv(rv);
281         server = new Cmpv2Server();
282         server.setAuthentication(authentication);
283         server.setUrl(externalCaUrl);
284         server.setIssuerDN(dn);
285         this.notBefore = notBefore;
286         this.notAfter = notAfter;
287     }
288 }