Refactor logging to use slf4j
[iotivity.git] / cloud / account / src / main / java / org / iotivity / cloud / accountserver / resources / credprov / cert / CertificateStorage.java
1 /*
2  * //******************************************************************
3  * //
4  * // Copyright 2016 Samsung Electronics All Rights Reserved.
5  * //
6  * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
7  * //
8  * // Licensed under the Apache License, Version 2.0 (the "License");
9  * // you may not use this file except in compliance with the License.
10  * // You may obtain a copy of the License at
11  * //
12  * //      http://www.apache.org/licenses/LICENSE-2.0
13  * //
14  * // Unless required by applicable law or agreed to in writing, software
15  * // distributed under the License is distributed on an "AS IS" BASIS,
16  * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * // See the License for the specific language governing permissions and
18  * // limitations under the License.
19  * //
20  * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
21  */
22 package org.iotivity.cloud.accountserver.resources.credprov.cert;
23
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
26 import org.bouncycastle.asn1.x509.BasicConstraints;
27 import org.bouncycastle.asn1.x509.Extension;
28 import org.bouncycastle.jce.ECNamedCurveTable;
29 import org.bouncycastle.operator.OperatorCreationException;
30 import org.iotivity.cloud.accountserver.x509.cert.CertificateBuilder;
31 import org.iotivity.cloud.accountserver.x509.cert.CertificateExtension;
32
33 import java.io.FileInputStream;
34 import java.io.FileOutputStream;
35 import java.io.IOException;
36 import java.io.InputStream;
37 import java.nio.file.Files;
38 import java.nio.file.Paths;
39 import java.security.*;
40 import java.security.cert.Certificate;
41 import java.security.cert.X509Certificate;
42
43 import static org.iotivity.cloud.accountserver.resources.credprov.cert.CertificateConstants.*;
44
45 /**
46  * This class is used for loading and storing key store.
47  * Also it generates CA certificate and puts it to keystore.
48  */
49 public final class CertificateStorage {
50     private final static Logger Log     = LoggerFactory.getLogger(CertificateStorage.class);
51
52     /**
53      * This attribute is used to get password to kestore, that stores CA certificate info.
54      * Private key and certificate.
55      */
56     private static final String PASSWORD = PROPERTIES.getProperty("password");
57
58     /**
59      * Root private key is used for signing certificates ans CRLs.
60      */
61     public static PrivateKey ROOT_PRIVATE_KEY;
62
63     /**
64      * Root certificate, is used for isssuing low level certificates.
65      */
66     public static X509Certificate ROOT_CERTIFICATE;
67
68     /**
69      * Keystore object to save, retrieve ca private key and ca certificate from keystore.
70      */
71     private static KeyStore keyStore;
72
73     /**
74      * Private contructor to make this class non-instantiable.
75      */
76     private CertificateStorage() {
77         throw new AssertionError();
78     }
79
80     /**
81      * Loads keystore with null paramaters.
82      * Stores it empty version. Generates CA certificate and private key and
83      * saves it to key storage.
84      */
85     static void init() throws GeneralSecurityException, IOException, OperatorCreationException {
86         Files.createDirectories(Paths.get(KEYSTORE_DIR));
87         keyStore = KeyStore.getInstance(KEYSTORE_TYPE, SECURITY_PROVIDER);
88         keyStore.load(null, null);
89         generate();
90     }
91
92     /**
93      * Loads KeyStore intance from created keystore file and with default password.
94      *
95      * @return KeyStore instance.
96      */
97     static void load() throws GeneralSecurityException, IOException {
98         keyStore = KeyStore.getInstance(KEYSTORE_TYPE, SECURITY_PROVIDER);
99         try (InputStream inputStream = new FileInputStream(KEYSTORE_FILE)) {
100             keyStore.load(inputStream, PASSWORD.toCharArray());
101         } catch (IOException ioException) {
102             Log.error(ioException.getMessage());
103         }
104         ROOT_PRIVATE_KEY = (PrivateKey) keyStore.getKey(CA_ALIAS, PASSWORD.toCharArray());
105         ROOT_CERTIFICATE = (X509Certificate) keyStore.getCertificate(CA_ALIAS);
106     }
107
108     /**
109      * Generates CA X509Certificate and private key and stores it to key storage.
110      *
111      * @return certificate and private key
112      */
113     private static void generate() throws GeneralSecurityException,
114             OperatorCreationException, IOException {
115         if (ROOT_PRIVATE_KEY == null) {
116             KeyPairGenerator g = KeyPairGenerator.getInstance(KEY_GENERATOR_ALGORITHM, SECURITY_PROVIDER);
117             g.initialize(ECNamedCurveTable.getParameterSpec(CURVE), new SecureRandom());
118             KeyPair pair = g.generateKeyPair();
119             ROOT_PRIVATE_KEY = pair.getPrivate();
120             ROOT_CERTIFICATE = new CertificateBuilder(CA_ISSUER, pair.getPublic(),
121                     new CertificateExtension(Extension.basicConstraints, false,
122                             new BasicConstraints(true))).build();
123             keyStore.setCertificateEntry(CA_ALIAS, ROOT_CERTIFICATE);
124             keyStore.setKeyEntry(CA_ALIAS, ROOT_PRIVATE_KEY, PASSWORD.toCharArray(),
125                     new Certificate[]{ROOT_CERTIFICATE});
126             store();
127         }
128     }
129
130     /**
131      * Stores keyStore instance to default keystore file with default password.
132      */
133     private static void store() throws IOException, GeneralSecurityException {
134         try (FileOutputStream out = new FileOutputStream(KEYSTORE_FILE)) {
135             keyStore.store(out, PASSWORD.toCharArray());
136         } catch (IOException ioException) {
137             Log.error(ioException.getMessage());
138         }
139     }
140 }