Merge "[OOM-CPMv2] Fix sonar issue"
[oom/platform/cert-service.git] / trustStoreMerger / src / main / java / org / onap / oom / certservice / postprocessor / merger / model / JavaTruststore.java
1 /*============LICENSE_START=======================================================
2  * oom-truststore-merger
3  * ================================================================================
4  * Copyright (C) 2020 Nokia. All rights reserved.
5  * ================================================================================
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  * ============LICENSE_END=========================================================
18  */
19
20 package org.onap.oom.certservice.postprocessor.merger.model;
21
22 import java.io.File;
23 import java.io.FileInputStream;
24 import java.io.FileOutputStream;
25 import java.security.KeyStore;
26 import java.security.KeyStoreException;
27 import java.util.ArrayList;
28 import java.util.Collections;
29 import java.util.List;
30 import org.onap.oom.certservice.postprocessor.merger.exception.AliasConflictException;
31 import org.onap.oom.certservice.postprocessor.merger.exception.LoadTruststoreException;
32 import org.onap.oom.certservice.postprocessor.merger.exception.MissingTruststoreException;
33 import org.onap.oom.certservice.postprocessor.merger.exception.TruststoreDataOperationException;
34 import org.onap.oom.certservice.postprocessor.merger.exception.WriteTruststoreFileException;
35 import org.onap.oom.certservice.postprocessor.api.ExitableException;
36 import org.onap.oom.certservice.postprocessor.common.FileTools;
37 import org.onap.oom.certservice.postprocessor.merger.model.certificate.CertificateWithAlias;
38 import org.onap.oom.certservice.postprocessor.merger.model.certificate.CertificateWithAliasFactory;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
41
42 public final class JavaTruststore extends Truststore {
43
44     private static final Logger LOGGER = LoggerFactory.getLogger(JavaTruststore.class);
45
46     private final CertificateWithAliasFactory factory = new CertificateWithAliasFactory();
47     private final KeyStore keyStore;
48     private final String password;
49
50
51     private JavaTruststore(KeyStore keyStore, File storeFile, String password) {
52         super(storeFile, new FileTools());
53         this.keyStore = keyStore;
54         this.password = password;
55     }
56
57     public static JavaTruststore createWithLoadingFile(KeyStore keyStore, File storeFile, String password)
58         throws LoadTruststoreException {
59         JavaTruststore javaTruststore = new JavaTruststore(keyStore, storeFile, password);
60         javaTruststore.loadFile();
61         return javaTruststore;
62     }
63
64     public List<CertificateWithAlias> getCertificates() throws ExitableException {
65         LOGGER.debug("Attempt to read certificates from file: {}", storeFile.getPath());
66         List<String> aliases = getTruststoreAliases();
67         if (aliases.isEmpty()) {
68             throw new MissingTruststoreException("Missing certificate aliases in file: " + storeFile.getPath());
69         }
70         return getWrappedCertificates(aliases);
71     }
72
73     public void addCertificates(List<CertificateWithAlias> certificatesWithAliases)
74         throws ExitableException {
75         LOGGER.debug("Attempt to add certificates for saving to file");
76         if (getTruststoreAliases().isEmpty()) {
77             throw new MissingTruststoreException("Missing certificate aliases in file: " + storeFile.getPath());
78         }
79         for (CertificateWithAlias certificate : certificatesWithAliases) {
80             addCertificate(certificate);
81         }
82     }
83
84     public void saveFile() throws WriteTruststoreFileException {
85         LOGGER.debug("Attempt to save file: {}", storeFile.getPath());
86         try (FileOutputStream outputStream = new FileOutputStream(storeFile)) {
87             keyStore.store(outputStream, this.password.toCharArray());
88         } catch (Exception e) {
89             LOGGER.error("Cannot write truststore file");
90             throw new WriteTruststoreFileException(e);
91         }
92     }
93
94     private void loadFile() throws LoadTruststoreException {
95         try {
96             keyStore.load(new FileInputStream(storeFile), this.password.toCharArray());
97         } catch (Exception e) {
98             LOGGER.error("Cannot load file: {}", storeFile.getPath());
99             throw new LoadTruststoreException(e);
100         }
101     }
102
103     private void addCertificate(CertificateWithAlias certificate)
104         throws TruststoreDataOperationException, AliasConflictException {
105         if (hasAliasConflict(certificate)) {
106             LOGGER.error("Alias conflict detected");
107             throw new AliasConflictException("Alias conflict detected. Alias conflicted: " + certificate.getAlias());
108         }
109         try {
110             keyStore.setCertificateEntry(certificate.getAlias(), certificate.getCertificate());
111         } catch (KeyStoreException e) {
112             LOGGER.error("Cannot merge certificate with alias: {}", certificate.getAlias());
113             throw new TruststoreDataOperationException(e);
114         }
115     }
116
117     private boolean hasAliasConflict(CertificateWithAlias certificate) throws TruststoreDataOperationException {
118         try {
119             return keyStore.containsAlias(certificate.getAlias());
120         } catch (KeyStoreException e) {
121             LOGGER.error("Cannot check alias conflict");
122             throw new TruststoreDataOperationException(e);
123         }
124     }
125
126     private List<CertificateWithAlias> getWrappedCertificates(List<String> aliases)
127         throws TruststoreDataOperationException {
128
129         List<CertificateWithAlias> certificateWrapped = new ArrayList<>();
130
131         for (String alias : aliases) {
132             certificateWrapped.add(createWrappedCertificate(alias));
133         }
134         return certificateWrapped;
135     }
136
137     private CertificateWithAlias createWrappedCertificate(String alias) throws TruststoreDataOperationException {
138         try {
139             return factory.createCertificateWithAlias(keyStore.getCertificate(alias), alias);
140         } catch (KeyStoreException e) {
141             LOGGER.warn("Cannot get certificate with alias: {} ", alias);
142             throw new TruststoreDataOperationException(e);
143         }
144     }
145
146     private List<String> getTruststoreAliases() throws TruststoreDataOperationException {
147         try {
148             List<String> aliases = Collections.list(keyStore.aliases());
149             return getFilteredAlias(aliases);
150         } catch (KeyStoreException e) {
151             LOGGER.warn("Cannot read truststore aliases");
152             throw new TruststoreDataOperationException(e);
153         }
154     }
155
156     private List<String> getFilteredAlias(List<String> aliases) throws KeyStoreException {
157         List<String> filteredAlias = new ArrayList<>();
158         for (String alias : aliases) {
159             if (keyStore.isCertificateEntry(alias)) {
160                 filteredAlias.add(alias);
161             }
162         }
163         return filteredAlias;
164     }
165
166 }