2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2021 Nordix Foundation
4 * ================================================================================
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 * SPDX-License-Identifier: Apache-2.0
17 * ============LICENSE_END=========================================================
20 package org.openecomp.sdc.be.plugins.etsi.nfv.nsd.security;
22 import static org.hamcrest.MatcherAssert.assertThat;
23 import static org.hamcrest.Matchers.hasSize;
24 import static org.hamcrest.Matchers.is;
25 import static org.hamcrest.Matchers.nullValue;
26 import static org.junit.jupiter.api.Assertions.assertThrows;
27 import static org.mockito.ArgumentMatchers.any;
28 import static org.mockito.ArgumentMatchers.eq;
29 import static org.mockito.Mockito.when;
30 import static org.openecomp.sdc.be.plugins.etsi.nfv.nsd.security.NsdCsarEtsiOption2Signer.SDC_NSD_CERT_NAME;
31 import static org.openecomp.sdc.be.plugins.etsi.nfv.nsd.security.NsdCsarEtsiOption2Signer.SIGNATURE_EXTENSION;
32 import static org.openecomp.sdc.be.plugins.etsi.nfv.nsd.security.exception.NsdSignatureExceptionSupplier.certificateNotConfigured;
33 import static org.openecomp.sdc.be.plugins.etsi.nfv.nsd.security.exception.NsdSignatureExceptionSupplier.invalidCertificate;
34 import static org.openecomp.sdc.be.plugins.etsi.nfv.nsd.security.exception.NsdSignatureExceptionSupplier.unableToCreateSignature;
36 import java.nio.charset.StandardCharsets;
37 import java.util.Optional;
38 import org.junit.jupiter.api.Assertions;
39 import org.junit.jupiter.api.BeforeEach;
40 import org.junit.jupiter.api.Test;
41 import org.mockito.InjectMocks;
42 import org.mockito.Mock;
43 import org.mockito.MockitoAnnotations;
44 import org.openecomp.sdc.be.csar.security.api.CertificateManager;
45 import org.openecomp.sdc.be.csar.security.api.CmsContentSigner;
46 import org.openecomp.sdc.be.csar.security.api.model.CertificateInfo;
47 import org.openecomp.sdc.be.csar.security.exception.CmsSignatureException;
48 import org.openecomp.sdc.be.plugins.etsi.nfv.nsd.model.NsdCsar;
49 import org.openecomp.sdc.be.plugins.etsi.nfv.nsd.security.exception.NsdSignatureException;
50 import org.springframework.core.env.Environment;
52 class NsdCsarEtsiOption2SignerTest {
54 private static final String CERT_NAME = "nsdCert";
57 private CertificateManager certificateManager;
59 private CmsContentSigner cmsContentSigner;
61 private Environment environment;
63 private CertificateInfo certificateInfo;
65 private NsdCsarEtsiOption2Signer nsdCsarEtsiOption2Signer;
69 MockitoAnnotations.openMocks(this);
70 when(environment.getProperty(SDC_NSD_CERT_NAME)).thenReturn(CERT_NAME);
71 when(certificateManager.getCertificate(CERT_NAME)).thenReturn(Optional.of(certificateInfo));
72 when(certificateInfo.isValid()).thenReturn(true);
76 void signNsdTest() throws NsdSignatureException, CmsSignatureException {
77 final NsdCsar nsdCsar = new NsdCsar("");
78 nsdCsar.addFile("aFile", "aFile".getBytes(StandardCharsets.UTF_8));
79 final byte[] aFileSigned = "aFileSigned".getBytes(StandardCharsets.UTF_8);
80 when(cmsContentSigner.signData(eq("aFile".getBytes(StandardCharsets.UTF_8)), any(), any())).thenReturn(
82 final String aFileSignedPemString = "aFileSignedPemString";
83 when(cmsContentSigner.formatToPemSignature(aFileSigned)).thenReturn(aFileSignedPemString);
84 nsdCsarEtsiOption2Signer.signArtifacts(nsdCsar);
85 assertThat("The NSD CSAR should contain the original file and its signature",
86 nsdCsar.getFileMap().keySet(), hasSize(2));
87 assertThat("The signed file should be as expected",
88 nsdCsar.getFile("aFile" + SIGNATURE_EXTENSION), is(aFileSignedPemString.getBytes(StandardCharsets.UTF_8)));
92 void dontCreateNsdManifestSignatureFileTest() throws NsdSignatureException {
93 final NsdCsar nsdCsar = new NsdCsar("nsdCsar");
94 nsdCsar.addFile(nsdCsar.getManifestPath(), "manifest".getBytes(StandardCharsets.UTF_8));
95 nsdCsarEtsiOption2Signer.signArtifacts(nsdCsar);
96 assertThat("The NSD CSAR should contain only the original file",
97 nsdCsar.getFileMap().keySet(), hasSize(1));
98 assertThat("The NSD CSAR should not contain the manifest signature file",
99 nsdCsar.getFile(nsdCsar.getManifestPath() + SIGNATURE_EXTENSION), is(nullValue()));
103 void signEmptyNsdTest() throws NsdSignatureException {
104 final NsdCsar nsdCsar = new NsdCsar("");
105 nsdCsarEtsiOption2Signer.signArtifacts(nsdCsar);
106 assertThat("The NSD CSAR should continue empty", nsdCsar.isEmpty(), is(true));
110 void signNsdNoCertificateTest() {
111 when(certificateManager.getCertificate(CERT_NAME)).thenReturn(Optional.empty());
112 final NsdCsar nsdCsar = new NsdCsar("");
113 nsdCsar.addFile("anyFile", "anyFile".getBytes());
114 final NsdSignatureException actualException = assertThrows(NsdSignatureException.class,
115 () -> nsdCsarEtsiOption2Signer.signArtifacts(nsdCsar));
116 assertThat(actualException.getMessage(), is(certificateNotConfigured().getMessage()));
120 void signWholeNoCertificateTest() {
121 when(certificateManager.getCertificate(CERT_NAME)).thenReturn(Optional.empty());
122 final NsdSignatureException actualException =
123 Assertions.assertThrows(NsdSignatureException.class,
124 () -> nsdCsarEtsiOption2Signer.sign(new byte[]{}));
125 assertThat(actualException.getMessage(), is(certificateNotConfigured().getMessage()));
129 void signWithInvalidCertificateTest() {
130 when(certificateInfo.isValid()).thenReturn(false);
131 final NsdSignatureException actualException =
132 Assertions.assertThrows(NsdSignatureException.class,
133 () -> nsdCsarEtsiOption2Signer.sign(new byte[]{}));
134 assertThat(actualException.getMessage(), is(invalidCertificate(null).getMessage()));
138 void signWholeFileTest() throws NsdSignatureException, CmsSignatureException {
139 final byte[] nsdCsarBytes = "nsdCsarBytes".getBytes(StandardCharsets.UTF_8);
140 final NsdCsar nsdCsar = new NsdCsar("");
141 nsdCsar.addFile("aFile", "aFile".getBytes(StandardCharsets.UTF_8));
142 final byte[] nsdCsarBytesSigned = "nsdCsarBytesSigned".getBytes(StandardCharsets.UTF_8);
143 when(cmsContentSigner.signData(eq(nsdCsarBytes), any(), any())).thenReturn(nsdCsarBytesSigned);
144 final String nsdCsarBytesSignedPemString = "nsdCsarBytesSignedPemString";
145 when(cmsContentSigner.formatToPemSignature(nsdCsarBytesSigned)).thenReturn(nsdCsarBytesSignedPemString);
146 final byte[] actualNsdSignedCsar = nsdCsarEtsiOption2Signer.sign(nsdCsarBytes);
147 assertThat("Signature should be as expected",
148 actualNsdSignedCsar, is(nsdCsarBytesSignedPemString.getBytes(StandardCharsets.UTF_8)));
152 void signatureCreationErrorTest() throws CmsSignatureException {
153 final byte[] nsdCsarBytes = "nsdCsarBytes".getBytes(StandardCharsets.UTF_8);
154 final NsdCsar nsdCsar = new NsdCsar("");
155 nsdCsar.addFile("aFile", "aFile".getBytes(StandardCharsets.UTF_8));
156 when(cmsContentSigner.signData(eq(nsdCsarBytes), any(), any()))
157 .thenThrow(new CmsSignatureException(null, null));
158 final NsdSignatureException actualException = assertThrows(NsdSignatureException.class,
159 () -> nsdCsarEtsiOption2Signer.sign(nsdCsarBytes));
160 assertThat(actualException.getMessage(), is(unableToCreateSignature(null).getMessage()));
164 void getSigningCertificateTest() {
165 when(certificateManager.getCertificate(CERT_NAME)).thenReturn(Optional.empty());
166 Optional<CertificateInfo> signingCertificate = nsdCsarEtsiOption2Signer.getSigningCertificate();
167 assertThat("Certificate should not be present", signingCertificate.isEmpty(), is(true));
168 when(certificateManager.getCertificate(CERT_NAME)).thenReturn(Optional.of(certificateInfo));
169 signingCertificate = nsdCsarEtsiOption2Signer.getSigningCertificate();
170 assertThat("Certificate should be present", signingCertificate.isPresent(), is(true));
171 assertThat("Certificate should be as expected", signingCertificate.get(), is(certificateInfo));
175 void isCertificateConfiguredTest() {
176 when(certificateManager.getCertificate(CERT_NAME)).thenReturn(Optional.empty());
177 boolean isCertificateConfigured = nsdCsarEtsiOption2Signer.isCertificateConfigured();
178 assertThat("Certificate should not be configured", isCertificateConfigured, is(false));
179 when(certificateManager.getCertificate(CERT_NAME)).thenReturn(Optional.of(certificateInfo));
180 isCertificateConfigured = nsdCsarEtsiOption2Signer.isCertificateConfigured();
181 assertThat("Certificate should be configured", isCertificateConfigured, is(true));