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