summaryrefslogtreecommitdiffstats
path: root/csarvalidation/src/main/java
diff options
context:
space:
mode:
authorBogumil Zebek <bogumil.zebek@nokia.com>2019-04-17 07:56:27 +0200
committerZebek Bogumil <bogumil.zebek@nokia.com>2019-04-18 10:29:04 +0200
commit089d8c3fb0a277351a55371dff8c2b27bd3f4ed5 (patch)
tree4b5be25b0a4bd80ac6c413e481413fc2c55ea210 /csarvalidation/src/main/java
parent96fcbb323829e81abf746efc5f62763f277786b6 (diff)
Security TC op2
Change-Id: I247c1223b5731c8dbea1480ca88db1cff78cb633 Issue-ID: VNFSDK-342 Signed-off-by: Zebek Bogumil <bogumil.zebek@nokia.com>
Diffstat (limited to 'csarvalidation/src/main/java')
-rw-r--r--csarvalidation/src/main/java/org/onap/cvc/csar/CSARArchive.java68
-rw-r--r--csarvalidation/src/main/java/org/onap/cvc/csar/FileArchive.java215
-rw-r--r--csarvalidation/src/main/java/org/onap/cvc/csar/ZipFileContentValidator.java52
-rw-r--r--csarvalidation/src/main/java/org/onap/cvc/csar/cc/VTPValidateCSARBase.java17
-rw-r--r--csarvalidation/src/main/java/org/onap/cvc/csar/cc/sol004/VTPValidateCSARR787965.java82
-rw-r--r--csarvalidation/src/main/java/org/onap/cvc/csar/rsa/RSACertificateValidator.java43
-rw-r--r--csarvalidation/src/main/java/org/onap/cvc/csar/rsa/X509RsaCertification.java66
7 files changed, 489 insertions, 54 deletions
diff --git a/csarvalidation/src/main/java/org/onap/cvc/csar/CSARArchive.java b/csarvalidation/src/main/java/org/onap/cvc/csar/CSARArchive.java
index ed53fc8..448469d 100644
--- a/csarvalidation/src/main/java/org/onap/cvc/csar/CSARArchive.java
+++ b/csarvalidation/src/main/java/org/onap/cvc/csar/CSARArchive.java
@@ -15,23 +15,18 @@
*/
package org.onap.cvc.csar;
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
-import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.nio.file.Path;
-import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipInputStream;
+import java.util.Optional;
import org.apache.commons.io.FileUtils;
import org.yaml.snakeyaml.Yaml;
@@ -48,11 +43,11 @@ import com.fasterxml.jackson.databind.ObjectMapper;
public class CSARArchive implements AutoCloseable {
public static final String SOL0004_2_4_1 = "V2.4.1 (2018-02)";
-
public String getSOL004Version() {
return SOL0004_2_4_1;
}
+ private FileArchive.Workspace workspace;
protected Path tempDir;
public static final String TEMP_DIR = "/tmp";
@@ -124,6 +119,10 @@ public class CSARArchive implements AutoCloseable {
public static final String CSAR_Archive = "CSAR Archive";
+ public FileArchive.Workspace getWorkspace() {
+ return this.workspace;
+ }
+
public enum Mode {
WITH_TOSCA_META_DIR,
WITHOUT_TOSCA_META_DIR
@@ -260,7 +259,6 @@ public class CSARArchive implements AutoCloseable {
this.lineNumber = lineNo;
this.file = file;
- //this.message = "More than one file exists in the archive root for " + fileName + ", It should be only one. Files: " + files;
}
}
@@ -298,7 +296,6 @@ public class CSARArchive implements AutoCloseable {
this.message += ". " + message;
}
- this.file = file;
this.lineNumber = lineNo;
}
}
@@ -878,41 +875,6 @@ public class CSARArchive implements AutoCloseable {
this.manifest = manifest;
}
- private void unzip(String csarPath, Path destination) throws IOException {
- File csarFile = new File(csarPath);
-
- if (!csarFile.exists()) {
- throw new RuntimeException(csarPath + " does not exist");
- }
-
- try (ZipInputStream zipInputStream = new ZipInputStream(new BufferedInputStream(new FileInputStream(csarFile)))){
-
- ZipEntry entry;
- while ((entry = zipInputStream.getNextEntry()) != null) {
-
- File filePath = new File(destination + File.separator + entry.getName());
-
- if(entry.isDirectory()){
- filePath.mkdirs();
- } else {
- extract(zipInputStream, filePath);
- }
- }
- }
- }
-
- private void extract(ZipInputStream csar, File filePath) throws IOException {
- byte[] buffer = new byte[2048];
- try (FileOutputStream fos = new FileOutputStream(filePath);
- BufferedOutputStream bos = new BufferedOutputStream(fos, buffer.length)) {
-
- int len;
- while ((len = csar.read(buffer)) > 0) {
- bos.write(buffer, 0, len);
- }
- }
- }
-
public String getProductName() {
if (this.toscaMeta.getMode().equals(Mode.WITH_TOSCA_META_DIR)) {
@@ -1317,11 +1279,14 @@ public class CSARArchive implements AutoCloseable {
}
public void init(String csarPath) throws IOException {
- this.tempDir = Paths.get(TEMP_DIR + File.separator + System.currentTimeMillis());
- this.tempDir.toFile().mkdirs();
+ this.workspace = new FileArchive(TEMP_DIR).unpack(csarPath);
- this.unzip(csarPath, this.tempDir);
+ final Optional<Path> pathToCsarFolder = workspace.getPathToCsarFolder();
+ if (pathToCsarFolder.isPresent()) {
+ this.tempDir = pathToCsarFolder.get();
+ }
}
+
public void parse() throws IOException {
//Find out the mode of CSAR
this.setMode();
@@ -1338,7 +1303,10 @@ public class CSARArchive implements AutoCloseable {
public void cleanup() throws IOException {
//remove temp dir
- FileUtils.deleteDirectory(this.tempDir.toFile());
+ final Optional<Path> rootFolder = workspace.getRootFolder();
+ if(rootFolder.isPresent()) {
+ FileUtils.deleteDirectory(rootFolder.get().toFile());
+ }
}
public File getFileFromCsar(String path) {
@@ -1347,8 +1315,6 @@ public class CSARArchive implements AutoCloseable {
@Override
public void close() throws Exception {
- if(this.tempDir != null){
- cleanup();
- }
+ cleanup();
}
}
diff --git a/csarvalidation/src/main/java/org/onap/cvc/csar/FileArchive.java b/csarvalidation/src/main/java/org/onap/cvc/csar/FileArchive.java
new file mode 100644
index 0000000..86904b1
--- /dev/null
+++ b/csarvalidation/src/main/java/org/onap/cvc/csar/FileArchive.java
@@ -0,0 +1,215 @@
+/*
+ * Copyright 2019 Nokia
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.onap.cvc.csar;
+
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Optional;
+import java.util.stream.Stream;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+
+
+public class FileArchive {
+
+ private static final String ZIP_POSTFIX = "zip";
+ private static final String CSAR_POSTFIX = ".csar";
+ private static final String CERT_POSTFIX = ".cert";
+ private static final String CMS_POSTFIX = ".cms";
+ private final String tempDir;
+
+ FileArchive(String tempDir){
+ this.tempDir = tempDir;
+ }
+
+ Workspace unpack(String pathToFile) throws IOException {
+ File fileArchive = new File(pathToFile);
+ if (!fileArchive.exists()) {
+ throw new IllegalArgumentException(String.format("%s does not exist", fileArchive.getName()));
+ }
+
+ String path = String.format("%s%s%d", tempDir, File.separator, System.currentTimeMillis());
+ Optional<Path> workspaceFolderPath = createWorkspaceFolder(path);
+ if(workspaceFolderPath.isPresent()) {
+ final Path destination = workspaceFolderPath.get();
+ unzip(fileArchive, destination);
+
+ if (pathToFile.endsWith(ZIP_POSTFIX)) {
+ return createZipWorkspace(path, destination);
+ }else {
+ return Workspace.forCsar(destination);
+ }
+ }
+
+ return Workspace.empty();
+ }
+
+ private Workspace createZipWorkspace(String path, Path workspaceFolderPath) throws IOException {
+
+ Optional<Path> pathToCsarFile = findFile(workspaceFolderPath, CSAR_POSTFIX);
+ Optional<Path> pathToCertFile = findFile(workspaceFolderPath, CERT_POSTFIX);
+ Optional<Path> pathToCmsFile = findFile(workspaceFolderPath, CMS_POSTFIX);
+
+ Path workspaceCsarPath = new File(String.format("%s%scsar", path, File.separator)).toPath();
+ if (pathToCsarFile.isPresent()) {
+ final Path csarFilePath = pathToCsarFile.get();
+ unzip(csarFilePath.toFile(), workspaceCsarPath);
+
+ return Workspace.forZip(
+ workspaceFolderPath,
+ workspaceCsarPath,
+ pathToCertFile.orElse(null),
+ pathToCmsFile.orElse(null),
+ csarFilePath
+ );
+ }
+
+
+ return Workspace.forZip(workspaceFolderPath);
+ }
+
+ private Optional<Path> findFile(Path workspaceFolderPath, String filePostfix) throws IOException {
+ try(Stream<Path> files = Files.find(
+ workspaceFolderPath,
+ 1,
+ (p, b)->p.getFileName().toString().endsWith(filePostfix))){
+ return files.findFirst();
+ }
+ }
+
+ private Optional<Path> createWorkspaceFolder(String path) {
+ Path destination = Paths.get(path);
+ if(destination.toFile().mkdirs()){
+ return Optional.of(destination);
+ }
+
+ return Optional.empty();
+ }
+
+ private void unzip(File file, Path destination) throws IOException {
+
+ try (ZipInputStream zipInputStream = new ZipInputStream(new BufferedInputStream(new FileInputStream(file)))){
+
+ ZipEntry entry;
+ while ((entry = zipInputStream.getNextEntry()) != null) {
+
+ File filePath = new File(destination + File.separator + entry.getName());
+
+ if(entry.isDirectory()){
+ filePath.mkdirs();
+ } else {
+ extract(zipInputStream, filePath);
+ }
+ }
+ }
+ }
+
+ private void extract(ZipInputStream csar, File filePath) throws IOException {
+ byte[] buffer = new byte[2048];
+ try (FileOutputStream fos = new FileOutputStream(filePath);
+ BufferedOutputStream bos = new BufferedOutputStream(fos, buffer.length)) {
+
+ int len;
+ while ((len = csar.read(buffer)) > 0) {
+ bos.write(buffer, 0, len);
+ }
+ }
+ }
+
+ public static class Workspace{
+ private boolean isZip;
+ private Path rootFolder;
+ private Path pathToCsarFolder;
+ private Path certFile;
+ private Path cmsFile;
+ private Path csarFile;
+
+ private Workspace(boolean isZip, Path rootFolder,
+ Path pathToCsarFolder,
+ Path certFile, Path cmsFile,
+ Path csarFile) {
+ this.isZip = isZip;
+ this.rootFolder = rootFolder;
+ this.pathToCsarFolder = pathToCsarFolder;
+ this.certFile = certFile;
+ this.cmsFile = cmsFile;
+ this.csarFile = csarFile;
+ }
+
+ private Workspace() {
+ }
+
+ private Workspace(boolean isZip, Path rootFolder){
+ this.isZip = isZip;
+ this.rootFolder = rootFolder;
+ this.pathToCsarFolder = rootFolder;
+ }
+
+ static Workspace empty(){
+ return new Workspace();
+ }
+
+ static Workspace forCsar(Path workspaceFolder) {
+ return new Workspace(false, workspaceFolder);
+ }
+
+ static Workspace forZip(Path rootFolder) {
+ return new Workspace(true, rootFolder);
+ }
+
+
+ static Workspace forZip(Path rootFolder, Path pathToCsarWorkspace,
+ Path certFile, Path cmsFile, Path csarFile) {
+ return new Workspace(true, rootFolder, pathToCsarWorkspace, certFile, cmsFile, csarFile);
+ }
+
+ public boolean isZip() {
+ return isZip;
+ }
+
+ public Optional<Path> getPathToCsarFolder() {
+ return Optional.ofNullable(pathToCsarFolder);
+ }
+
+ public Optional<Path> getPathToCertFile() {
+ return Optional.ofNullable(certFile);
+ }
+
+ public Optional<Path> getRootFolder() {
+ return Optional.ofNullable(rootFolder);
+ }
+
+ public Optional<Path> getPathToCmsFile() {
+ return Optional.ofNullable(cmsFile);
+ }
+
+ public Optional<Path> getPathToCsarFile() {
+ return Optional.ofNullable(csarFile);
+ }
+ }
+
+}
diff --git a/csarvalidation/src/main/java/org/onap/cvc/csar/ZipFileContentValidator.java b/csarvalidation/src/main/java/org/onap/cvc/csar/ZipFileContentValidator.java
new file mode 100644
index 0000000..801d8cf
--- /dev/null
+++ b/csarvalidation/src/main/java/org/onap/cvc/csar/ZipFileContentValidator.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2019 Nokia
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.onap.cvc.csar;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ZipFileContentValidator {
+
+ public static class CSARErrorCertMissing extends CSARArchive.CSARError {
+ CSARErrorCertMissing() {
+ super("0x1008");
+ this.message = "Missing. Cert file is not available!";
+ }
+ }
+
+ public static class CSARErrorCMSMissing extends CSARArchive.CSARError {
+ CSARErrorCMSMissing() {
+ super("0x1009");
+ this.message = "Missing. CMS file is not available!";
+ }
+ }
+
+ public List<CSARArchive.CSARError> validate(FileArchive.Workspace workspace){
+ final ArrayList<CSARArchive.CSARError> retValue = new ArrayList<>();
+
+ if(!workspace.getPathToCertFile().isPresent()){
+ retValue.add(new CSARErrorCertMissing());
+ }
+
+ if(!workspace.getPathToCmsFile().isPresent()){
+ retValue.add(new CSARErrorCMSMissing());
+ }
+
+ return retValue;
+ }
+}
diff --git a/csarvalidation/src/main/java/org/onap/cvc/csar/cc/VTPValidateCSARBase.java b/csarvalidation/src/main/java/org/onap/cvc/csar/cc/VTPValidateCSARBase.java
index d879ff3..bd771e0 100644
--- a/csarvalidation/src/main/java/org/onap/cvc/csar/cc/VTPValidateCSARBase.java
+++ b/csarvalidation/src/main/java/org/onap/cvc/csar/cc/VTPValidateCSARBase.java
@@ -16,20 +16,24 @@
package org.onap.cvc.csar.cc;
-import java.util.ArrayList;
-import java.util.List;
-
import org.onap.cli.fw.cmd.OnapCommand;
import org.onap.cli.fw.error.OnapCommandException;
import org.onap.cli.fw.error.OnapCommandExecutionFailed;
import org.onap.cvc.csar.CSARArchive;
import org.onap.cvc.csar.CSARArchive.CSARError;
+import org.onap.cvc.csar.FileArchive;
+import org.onap.cvc.csar.ZipFileContentValidator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.util.ArrayList;
+import java.util.List;
+
public abstract class VTPValidateCSARBase extends OnapCommand {
protected static final Logger LOG = LoggerFactory.getLogger(VTPValidateCSARBase.class);
+ private final ZipFileContentValidator zipFileContentValidator = new ZipFileContentValidator();
+
protected abstract void validateCSAR(CSARArchive csar) throws Exception;
protected abstract String getVnfReqsNo();
@@ -43,7 +47,14 @@ public abstract class VTPValidateCSARBase extends OnapCommand {
//execute
try (CSARArchive csar = this.createArchiveInstance()){
+
csar.init(path);
+
+ FileArchive.Workspace workspace = csar.getWorkspace();
+ if(workspace.isZip()) {
+ errors.addAll(zipFileContentValidator.validate(workspace));
+ }
+
csar.parse();
errors.addAll(csar.getErrors());
diff --git a/csarvalidation/src/main/java/org/onap/cvc/csar/cc/sol004/VTPValidateCSARR787965.java b/csarvalidation/src/main/java/org/onap/cvc/csar/cc/sol004/VTPValidateCSARR787965.java
new file mode 100644
index 0000000..ede1b6c
--- /dev/null
+++ b/csarvalidation/src/main/java/org/onap/cvc/csar/cc/sol004/VTPValidateCSARR787965.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2019 Nokia
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.onap.cvc.csar.cc.sol004;
+
+
+import org.onap.cli.fw.error.OnapCommandException;
+import org.onap.cli.fw.schema.OnapCommandSchema;
+import org.onap.cvc.csar.CSARArchive;
+import org.onap.cvc.csar.FileArchive;
+import org.onap.cvc.csar.cc.VTPValidatePnfCSARBase;
+import org.onap.cvc.csar.rsa.RSACertificateValidator;
+import org.onap.cvc.csar.rsa.X509RsaCertification;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Base64;
+import java.util.Optional;
+
+@OnapCommandSchema(schema = "vtp-validate-csar-r787965.yaml")
+public class VTPValidateCSARR787965 extends VTPValidatePnfCSARBase {
+
+ private static final Logger LOG = LoggerFactory.getLogger(VTPValidateCSARR787965.class);
+
+ public static class CSARErrorInvalidSignature extends CSARArchive.CSARError {
+ CSARErrorInvalidSignature() {
+ super("0x3001");
+ this.message = "Invalid CSAR signature!";
+ }
+ }
+
+ @Override
+ protected void validateCSAR(CSARArchive csar) throws OnapCommandException {
+
+ try {
+ final RSACertificateValidator rsaCertificateValidator = new RSACertificateValidator(new X509RsaCertification());
+
+ FileArchive.Workspace workspace = csar.getWorkspace();
+ final Optional<Path> pathToCsarFile = workspace.getPathToCsarFile();
+ final Optional<Path> pathToCertFile = workspace.getPathToCertFile();
+ final Optional<Path> pathToCmsFile = workspace.getPathToCmsFile();
+
+ if (workspace.isZip() && pathToCsarFile.isPresent() && pathToCertFile.isPresent() && pathToCmsFile.isPresent()) {
+ byte[] csarContent = Files.readAllBytes(pathToCsarFile.get());
+ String signature = Base64.getEncoder().encodeToString(Files.readAllBytes(pathToCmsFile.get()));
+ String publicCertification = Base64.getEncoder().encodeToString(Files.readAllBytes(pathToCertFile.get()));
+
+ if (!rsaCertificateValidator.isValid(csarContent, signature, publicCertification)) {
+ this.errors.add(new CSARErrorInvalidSignature());
+ }
+ }
+
+ } catch (Exception e) {
+ LOG.error("Internal VTPValidateCSARR787965 command error", e);
+ throw new OnapCommandException("0x3000", "Internal VTPValidateCSARR787965 command error. See logs.");
+ }
+
+ }
+
+ @Override
+ protected String getVnfReqsNo() {
+ return "R787965";
+ }
+
+
+}
diff --git a/csarvalidation/src/main/java/org/onap/cvc/csar/rsa/RSACertificateValidator.java b/csarvalidation/src/main/java/org/onap/cvc/csar/rsa/RSACertificateValidator.java
new file mode 100644
index 0000000..022f697
--- /dev/null
+++ b/csarvalidation/src/main/java/org/onap/cvc/csar/rsa/RSACertificateValidator.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2019 Nokia
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.onap.cvc.csar.rsa;
+
+
+import java.security.PublicKey;
+
+public class RSACertificateValidator {
+
+ private final X509RsaCertification x509RsaCertification;
+
+ public RSACertificateValidator(X509RsaCertification x509RsaCertification) {
+ this.x509RsaCertification = x509RsaCertification;
+ }
+
+ public boolean isValid(byte [] content, String signature, String publicCertificateContent) throws Exception {
+
+ String publicCert = extractPublicKeyCertificate(publicCertificateContent);
+ final PublicKey publicKey = this.x509RsaCertification.generatePublicKey(publicCert);
+
+ return this.x509RsaCertification.verify(content,signature,publicKey);
+ }
+
+ private String extractPublicKeyCertificate(String publicCertificateContent) {
+ String publicCert = publicCertificateContent.replace("-----BEGIN CERTIFICATE-----\n", "");
+ return publicCert.replace("-----END CERTIFICATE-----\n", "");
+ }
+}
diff --git a/csarvalidation/src/main/java/org/onap/cvc/csar/rsa/X509RsaCertification.java b/csarvalidation/src/main/java/org/onap/cvc/csar/rsa/X509RsaCertification.java
new file mode 100644
index 0000000..8395221
--- /dev/null
+++ b/csarvalidation/src/main/java/org/onap/cvc/csar/rsa/X509RsaCertification.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2019 Nokia
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.onap.cvc.csar.rsa;
+
+import org.apache.commons.codec.binary.Base64;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.PublicKey;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+
+public class X509RsaCertification {
+
+ private static final Logger LOG = LoggerFactory.getLogger(X509RsaCertification.class);
+
+ PublicKey generatePublicKey(String cert) throws CertificateException {
+ byte[] encodedCert = cert.getBytes(StandardCharsets.UTF_8);
+ byte[] decodedCert = Base64.decodeBase64(encodedCert);
+ CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
+ InputStream in = new ByteArrayInputStream(decodedCert);
+ X509Certificate certificate = (X509Certificate) certFactory.generateCertificate(in);
+
+ LOG.info(String.format("Subject DN : %s", certificate.getSubjectDN().getName()));
+ LOG.info(String.format("Issuer : %s", certificate.getIssuerDN().getName()));
+ LOG.info(String.format("Not After: %s", certificate.getNotAfter()));
+ LOG.info(String.format("Not Before: %s", certificate.getNotBefore()));
+ LOG.info(String.format("version: %d", certificate.getVersion()));
+ LOG.info(String.format("serial number : %s", certificate.getSerialNumber()));
+
+ return certificate.getPublicKey();
+ }
+
+ boolean verify(byte[] content, String signature, PublicKey publicKey) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {
+ Signature publicSignature = Signature.getInstance("SHA256withRSA");
+ publicSignature.initVerify(publicKey);
+ publicSignature.update(content);
+
+ byte[] signatureBytes = java.util.Base64.getDecoder().decode(signature);
+
+ return publicSignature.verify(signatureBytes);
+ }
+}