Merge "Add of config for copier"
[oom/platform/cert-service.git] / trustStoreMerger / src / main / java / org / onap / oom / truststoremerger / 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.truststoremerger.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.truststoremerger.api.ExitableException;
31 import org.onap.oom.truststoremerger.merger.exception.AliasConflictException;
32 import org.onap.oom.truststoremerger.merger.exception.LoadTruststoreException;
33 import org.onap.oom.truststoremerger.merger.exception.MissingTruststoreException;
34 import org.onap.oom.truststoremerger.merger.exception.TruststoreDataOperationException;
35 import org.onap.oom.truststoremerger.merger.exception.WriteTruststoreFileException;
36 import org.onap.oom.truststoremerger.merger.model.certificate.CertificateWithAlias;
37 import org.onap.oom.truststoremerger.merger.model.certificate.CertificateWithAliasFactory;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
40
41 public final class JavaTruststore extends Truststore {
42
43     private static final Logger LOGGER = LoggerFactory.getLogger(JavaTruststore.class);
44
45     private final CertificateWithAliasFactory factory = new CertificateWithAliasFactory();
46     private final KeyStore keyStore;
47     private final String password;
48
49
50     private JavaTruststore(KeyStore keyStore, File storeFile, String password) {
51         super(storeFile);
52         this.keyStore = keyStore;
53         this.password = password;
54     }
55
56     public static JavaTruststore createWithLoadingFile(KeyStore keyStore, File storeFile, String password)
57         throws LoadTruststoreException {
58         JavaTruststore javaTruststore = new JavaTruststore(keyStore, storeFile, password);
59         javaTruststore.loadFile();
60         return javaTruststore;
61     }
62
63     public List<CertificateWithAlias> getCertificates() throws ExitableException {
64         LOGGER.debug("Attempt to read certificates from file: {}", storeFile.getPath());
65         List<String> aliases = getTruststoreAliases();
66         if (aliases.isEmpty()) {
67             throw new MissingTruststoreException("Missing certificate aliases in file: " + storeFile.getPath());
68         }
69         return getWrappedCertificates(aliases);
70     }
71
72     public void addCertificates(List<CertificateWithAlias> certificatesWithAliases)
73         throws ExitableException {
74         LOGGER.debug("Attempt to add certificates for saving to file");
75         if (getTruststoreAliases().isEmpty()) {
76             throw new MissingTruststoreException("Missing certificate aliases in file: " + storeFile.getPath());
77         }
78         for (CertificateWithAlias certificate : certificatesWithAliases) {
79             addCertificate(certificate);
80         }
81     }
82
83     public void saveFile() throws WriteTruststoreFileException {
84         LOGGER.debug("Attempt to save file: {}", storeFile.getPath());
85         try (FileOutputStream outputStream = new FileOutputStream(storeFile)) {
86             keyStore.store(outputStream, this.password.toCharArray());
87         } catch (Exception e) {
88             LOGGER.error("Cannot write truststore file");
89             throw new WriteTruststoreFileException(e);
90         }
91     }
92
93     private void loadFile() throws LoadTruststoreException {
94         try {
95             keyStore.load(new FileInputStream(storeFile), this.password.toCharArray());
96         } catch (Exception e) {
97             LOGGER.error("Cannot load file: {}", storeFile.getPath());
98             throw new LoadTruststoreException(e);
99         }
100     }
101
102     private void addCertificate(CertificateWithAlias certificate)
103         throws TruststoreDataOperationException, AliasConflictException {
104         if (hasAliasConflict(certificate)) {
105             LOGGER.error("Alias conflict detected");
106             throw new AliasConflictException("Alias conflict detected. Alias conflicted: " + certificate.getAlias());
107         }
108         try {
109             keyStore.setCertificateEntry(certificate.getAlias(), certificate.getCertificate());
110         } catch (KeyStoreException e) {
111             LOGGER.error("Cannot merge certificate with alias: {}", certificate.getAlias());
112             throw new TruststoreDataOperationException(e);
113         }
114     }
115
116     private boolean hasAliasConflict(CertificateWithAlias certificate) throws TruststoreDataOperationException {
117         try {
118             return keyStore.containsAlias(certificate.getAlias());
119         } catch (KeyStoreException e) {
120             LOGGER.error("Cannot check alias conflict");
121             throw new TruststoreDataOperationException(e);
122         }
123     }
124
125     private List<CertificateWithAlias> getWrappedCertificates(List<String> aliases)
126         throws TruststoreDataOperationException {
127
128         List<CertificateWithAlias> certificateWrapped = new ArrayList<>();
129
130         for (String alias : aliases) {
131             certificateWrapped.add(createWrappedCertificate(alias));
132         }
133         return certificateWrapped;
134     }
135
136     private CertificateWithAlias createWrappedCertificate(String alias) throws TruststoreDataOperationException {
137         try {
138             return factory.createCertificateWithAlias(keyStore.getCertificate(alias), alias);
139         } catch (KeyStoreException e) {
140             LOGGER.warn("Cannot get certificate with alias: {} ", alias);
141             throw new TruststoreDataOperationException(e);
142         }
143     }
144
145     private List<String> getTruststoreAliases() throws TruststoreDataOperationException {
146         try {
147             List<String> aliases = Collections.list(keyStore.aliases());
148             return getFilteredAlias(aliases);
149         } catch (KeyStoreException e) {
150             LOGGER.warn("Cannot read truststore aliases");
151             throw new TruststoreDataOperationException(e);
152         }
153     }
154
155     private List<String> getFilteredAlias(List<String> aliases) throws KeyStoreException {
156         List<String> filteredAlias = new ArrayList<>();
157         for (String alias : aliases) {
158             if (keyStore.isCertificateEntry(alias)) {
159                 filteredAlias.add(alias);
160             }
161         }
162         return filteredAlias;
163     }
164
165 }