df9699aead6bf2802a4dc289f13cddbcc3450b4e
[oom/platform/cert-service.git] / certService / src / test / java / org / onap / oom / 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.oom.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.asn1.x509.GeneralName;
56 import org.bouncycastle.jce.provider.BouncyCastleProvider;
57 import org.junit.jupiter.api.Assertions;
58 import org.junit.jupiter.api.BeforeEach;
59 import org.junit.jupiter.api.Test;
60 import org.mockito.Mock;
61 import org.onap.oom.certservice.certification.configuration.model.Authentication;
62 import org.onap.oom.certservice.certification.configuration.model.Cmpv2Server;
63 import org.onap.oom.certservice.certification.model.CsrModel;
64 import org.onap.oom.certservice.cmpv2client.exceptions.CmpClientException;
65 import org.onap.oom.certservice.cmpv2client.exceptions.CmpServerException;
66 import org.onap.oom.certservice.cmpv2client.impl.CmpClientImpl;
67 import org.onap.oom.certservice.cmpv2client.model.Cmpv2CertificationModel;
68
69 class Cmpv2ClientTest {
70
71     static {
72         Security.addProvider(new BouncyCastleProvider());
73     }
74
75     private CsrModel csrModel;
76     private Cmpv2Server server;
77     private Date notBefore;
78     private Date notAfter;
79     private X500Name dn;
80
81     @Mock
82     X509Certificate cert;
83
84     @Mock
85     CloseableHttpClient httpClient;
86
87     @Mock
88     CloseableHttpResponse httpResponse;
89
90     @Mock
91     HttpEntity httpEntity;
92
93     private static KeyPair keyPair;
94
95     @BeforeEach
96     void setUp()
97             throws NoSuchProviderException, NoSuchAlgorithmException, IOException,
98             InvalidKeySpecException {
99         keyPair = loadKeyPair();
100         dn = new X500NameBuilder()
101                 .addRDN(BCStyle.O, "TestOrganization")
102                 .build();
103         initMocks(this);
104     }
105
106     public KeyPair loadKeyPair()
107             throws IOException, NoSuchAlgorithmException, InvalidKeySpecException,
108             NoSuchProviderException {
109
110         final InputStream privateInputStream = this.getClass().getResourceAsStream("/privateKey");
111         final InputStream publicInputStream = this.getClass().getResourceAsStream("/publicKey");
112         BufferedInputStream bis = new BufferedInputStream(privateInputStream);
113         byte[] privateBytes = IOUtils.toByteArray(bis);
114         bis = new BufferedInputStream(publicInputStream);
115         byte[] publicBytes = IOUtils.toByteArray(bis);
116
117         KeyFactory keyFactory = KeyFactory.getInstance("RSA", BouncyCastleProvider.PROVIDER_NAME);
118         X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(publicBytes);
119         PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);
120
121         PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(privateBytes);
122         PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec);
123
124         return new KeyPair(publicKey, privateKey);
125     }
126
127     @Test
128     void shouldReturnValidPkiMessageWhenCreateCertificateRequestMessageMethodCalledWithValidCsr()
129             throws Exception {
130         // given
131         Date beforeDate = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").parse("2019/11/11 12:00:00");
132         Date afterDate = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").parse("2020/11/11 12:00:00");
133         setCsrModelAndServerValues(
134                 "mypassword",
135                 "senderKID",
136                 "http://127.0.0.1/ejbca/publicweb/cmp/cmp",
137                 beforeDate,
138                 afterDate);
139         when(httpClient.execute(any())).thenReturn(httpResponse);
140         when(httpResponse.getEntity()).thenReturn(httpEntity);
141
142         try (final InputStream is =
143                      this.getClass().getResourceAsStream("/ReturnedSuccessPKIMessageWithCertificateFile");
144              BufferedInputStream bis = new BufferedInputStream(is)) {
145
146             byte[] ba = IOUtils.toByteArray(bis);
147             doAnswer(
148                     invocation -> {
149                         OutputStream os = (ByteArrayOutputStream) invocation.getArguments()[0];
150                         os.write(ba);
151                         return null;
152                     })
153                     .when(httpEntity)
154                     .writeTo(any(OutputStream.class));
155         }
156         CmpClientImpl cmpClient = spy(new CmpClientImpl(httpClient));
157         // when
158         Cmpv2CertificationModel cmpClientResult =
159                 cmpClient.createCertificate(csrModel, server, notBefore, notAfter);
160         // then
161         assertNotNull(cmpClientResult);
162     }
163
164     @Test
165     void
166     shouldThrowCmpClientExceptionWhenCreateCertificateRequestMessageMethodCalledWithWrongProtectedBytesInResponse()
167             throws Exception {
168         // given
169         Date beforeDate = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").parse("2019/11/11 12:00:00");
170         Date afterDate = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").parse("2020/11/11 12:00:00");
171         setCsrModelAndServerValues(
172                 "password",
173                 "senderKID",
174                 "http://127.0.0.1/ejbca/publicweb/cmp/cmp",
175                 beforeDate,
176                 afterDate);
177         when(httpClient.execute(any())).thenReturn(httpResponse);
178         when(httpResponse.getEntity()).thenReturn(httpEntity);
179
180         try (final InputStream is =
181                      this.getClass().getResourceAsStream("/ReturnedSuccessPKIMessageWithCertificateFile");
182              BufferedInputStream bis = new BufferedInputStream(is)) {
183
184             byte[] ba = IOUtils.toByteArray(bis);
185             doAnswer(
186                     invocation -> {
187                         OutputStream os = (ByteArrayOutputStream) invocation.getArguments()[0];
188                         os.write(ba);
189                         return null;
190                     })
191                     .when(httpEntity)
192                     .writeTo(any(OutputStream.class));
193         }
194         CmpClientImpl cmpClient = spy(new CmpClientImpl(httpClient));
195         // then
196         Assertions.assertThrows(
197                 CmpClientException.class,
198                 () -> cmpClient.createCertificate(csrModel, server, notBefore, notAfter));
199     }
200
201     @Test
202     void shouldThrowCmpClientExceptionWithPkiErrorExceptionWhenCmpClientCalledWithBadPassword()
203             throws Exception {
204         // given
205         Date beforeDate = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").parse("2019/11/11 12:00:00");
206         Date afterDate = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").parse("2020/11/11 12:00:00");
207         setCsrModelAndServerValues(
208                 "password",
209                 "senderKID",
210                 "http://127.0.0.1/ejbca/publicweb/cmp/cmp",
211                 beforeDate,
212                 afterDate);
213         when(httpClient.execute(any())).thenReturn(httpResponse);
214         when(httpResponse.getEntity()).thenReturn(httpEntity);
215
216         try (final InputStream is =
217                      this.getClass().getResourceAsStream("/ReturnedFailurePKIMessageBadPassword");
218              BufferedInputStream bis = new BufferedInputStream(is)) {
219
220             byte[] ba = IOUtils.toByteArray(bis);
221             doAnswer(
222                     invocation -> {
223                         OutputStream os = (ByteArrayOutputStream) invocation.getArguments()[0];
224                         os.write(ba);
225                         return null;
226                     })
227                     .when(httpEntity)
228                     .writeTo(any(OutputStream.class));
229         }
230         CmpClientImpl cmpClient = spy(new CmpClientImpl(httpClient));
231
232         // then
233         Assertions.assertThrows(
234                 CmpServerException.class,
235                 () -> cmpClient.createCertificate(csrModel, server, notBefore, notAfter));
236     }
237
238     @Test
239     void shouldThrowIllegalArgumentExceptionWhencreateCertificateCalledWithInvalidCsr()
240             throws ParseException {
241         // given
242         Date beforeDate = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").parse("2020/11/11 12:00:00");
243         Date afterDate = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").parse("2019/11/11 12:00:00");
244         setCsrModelAndServerValues(
245                 "password",
246                 "senderKID",
247                 "http://127.0.0.1/ejbca/publicweb/cmp/cmp",
248                 beforeDate,
249                 afterDate);
250         CmpClientImpl cmpClient = new CmpClientImpl(httpClient);
251         // then
252         Assertions.assertThrows(
253                 IllegalArgumentException.class,
254                 () -> cmpClient.createCertificate(csrModel, server, notBefore, notAfter));
255     }
256
257     @Test
258     void shouldThrowIoExceptionWhenCreateCertificateCalledWithNoServerAvailable()
259             throws IOException, ParseException {
260         // given
261         Date beforeDate = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").parse("2019/11/11 12:00:00");
262         Date afterDate = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").parse("2020/11/11 12:00:00");
263         setCsrModelAndServerValues(
264                 "myPassword",
265                 "sender",
266                 "http://127.0.0.1/ejbca/publicweb/cmp/cmpTest",
267                 beforeDate,
268                 afterDate);
269         when(httpClient.execute(any())).thenThrow(IOException.class);
270         CmpClientImpl cmpClient = spy(new CmpClientImpl(httpClient));
271         // then
272         Assertions.assertThrows(
273                 CmpClientException.class,
274                 () -> cmpClient.createCertificate(csrModel, server, notBefore, notAfter));
275     }
276
277     private void setCsrModelAndServerValues(String iak, String rv, String externalCaUrl, Date notBefore, Date notAfter) {
278         csrModel = new CsrModel(null, dn, keyPair.getPrivate(), keyPair.getPublic(), new GeneralName[0]);
279
280         Authentication authentication = new Authentication();
281         authentication.setIak(iak);
282         authentication.setRv(rv);
283         server = new Cmpv2Server();
284         server.setAuthentication(authentication);
285         server.setUrl(externalCaUrl);
286         server.setIssuerDN(dn);
287         this.notBefore = notBefore;
288         this.notAfter = notAfter;
289     }
290 }