Refactor logging to use slf4j
[iotivity.git] / cloud / account / src / main / java / org / iotivity / cloud / accountserver / resources / credprov / crl / CrlManager.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.crl;
23
24 import static org.iotivity.cloud.accountserver.resources.credprov.cert.CertificateConstants.ACCOUNT_DB_MANAGER;
25 import static org.iotivity.cloud.accountserver.resources.credprov.cert.CertificateConstants.CERTIFICATE_FACTORY;
26 import static org.iotivity.cloud.accountserver.resources.credprov.cert.CertificateConstants.DER;
27 import static org.iotivity.cloud.accountserver.resources.credprov.cert.CertificateConstants.NEXT_UPDATE_INTERVAL;
28 import static org.iotivity.cloud.accountserver.x509.crl.CrlIssuer.CRL_ISSUER;
29
30 import java.io.ByteArrayInputStream;
31 import java.io.IOException;
32 import java.security.cert.CRLException;
33 import java.security.cert.X509CRL;
34 import java.text.ParseException;
35 import java.text.SimpleDateFormat;
36 import java.util.ArrayList;
37 import java.util.Calendar;
38 import java.util.Collections;
39 import java.util.Date;
40 import java.util.HashMap;
41 import java.util.Map;
42
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
45 import org.bouncycastle.operator.OperatorCreationException;
46 import org.bson.types.Binary;
47 import org.iotivity.cloud.accountserver.Constants;
48 import org.iotivity.cloud.accountserver.db.CRLTable;
49 import org.iotivity.cloud.accountserver.util.TypeCastingManager;
50 import org.iotivity.cloud.base.exception.ServerException;
51
52 /**
53  * Class is used to manage CRLs. It helps to create, update CRLS, revoke
54  * certificates.
55  */
56 public final class CrlManager {
57     private final static Logger                 Log             = LoggerFactory.getLogger(CrlManager.class);
58
59     /**
60      * Casting manager for working with CRLTable in mongo db
61      */
62     private static TypeCastingManager<CRLTable> castingManager  = new TypeCastingManager<>();
63
64     /**
65      * X509 CRL presentation.
66      */
67     private X509CRL                             x509CRL;
68
69     /**
70      * Static manager for CRLs.
71      */
72     public static final CrlManager              CRL_MANAGER    = new CrlManager();
73
74     /**
75      * Private constructor to make this class non-instantiable.
76      */
77     private CrlManager() {
78         try {
79             Calendar calendar = Calendar.getInstance();
80             Date thisUpdate = calendar.getTime();
81             calendar.add(Calendar.DAY_OF_MONTH,
82                     Integer.parseInt(NEXT_UPDATE_INTERVAL));
83             byte[] data = CRL_ISSUER.generate(thisUpdate, calendar.getTime(),
84                     Collections.emptyList());
85             ACCOUNT_DB_MANAGER.insertRecord(Constants.CRL_TABLE,
86                     castingManager.convertObjectToMap(
87                             new CRLTable(thisUpdate, new Binary(data))));
88             setX509CRL(data);
89         } catch (CRLException | IOException | OperatorCreationException e) {
90             Log.error(e.getMessage());
91         }
92     }
93
94     /**
95      * Revokes specified serial numbers. Puts them to database.
96      *
97      * @param serialNumbers
98      *            specified var args serial numbers from 0.
99      */
100     public void revoke(String... serialNumbers)
101             throws CRLException, IOException, OperatorCreationException {
102         if (x509CRL != null) {
103             update(x509CRL.getThisUpdate(),
104                     CRL_ISSUER.generate(x509CRL.getThisUpdate(),
105                             x509CRL.getNextUpdate(),
106                             x509CRL.getRevokedCertificates(), serialNumbers));
107         }
108     }
109
110     /**
111      * Checks last update less than crl this update and returns response
112      * payload, including this update, next update, and CRL in DER encoding.
113      */
114     Map<String, Object> getPayload(String lastUpdate)
115             throws ServerException.PreconditionFailedException, CRLException {
116         if (checkLastUpdate(lastUpdate) && x509CRL != null) {
117             Map<String, Object> responsePayload = new HashMap<>();
118             responsePayload.put(Constants.REQ_THIS_UPDATE,
119                     new SimpleDateFormat("yyyyMMddHHmmss")
120                             .format(x509CRL.getThisUpdate()));
121             responsePayload.put(Constants.REQ_NEXT_UPDATE,
122                     new SimpleDateFormat("yyyyMMddHHmmss")
123                             .format(x509CRL.getNextUpdate()));
124             responsePayload.put(Constants.REQ_CRL,
125                     new CRL(DER, x509CRL.getEncoded()));
126             return responsePayload;
127         }
128         return Collections.emptyMap();
129     }
130
131     /**
132      * Checks if last update is before CRL this update.
133      *
134      * @param lastUpdate
135      *            specified last update;
136      * @return true if before and false - otherwise.
137      */
138     private boolean checkLastUpdate(String lastUpdate) {
139         boolean checkCondition = false;
140         try {
141             if (x509CRL != null) {
142                 checkCondition = new SimpleDateFormat("yyyyMMddHHmmss")
143                         .parse(lastUpdate).before(x509CRL.getThisUpdate());
144             }
145         } catch (ParseException e) {
146             Log.error(e.getMessage());
147         }
148         return checkCondition;
149     }
150
151     /**
152      * Updates CRLTable with specified this update and binary CRL data.
153      */
154     void update(Date thisUpdate, byte[] data) throws CRLException {
155         ArrayList<HashMap<String, Object>> crlList = ACCOUNT_DB_MANAGER
156                 .selectRecord(Constants.CRL_TABLE, new HashMap<>());
157         if (crlList != null && !crlList.isEmpty()) {
158             CRLTable crlTable = castingManager
159                     .convertMaptoObject(crlList.get(0), new CRLTable());
160             crlTable.setThisUpdate(thisUpdate);
161             crlTable.setBinaryData(new Binary(data));
162             ACCOUNT_DB_MANAGER.updateRecord(Constants.CRL_TABLE,
163                     castingManager.convertObjectToMap(crlTable));
164             setX509CRL(data);
165         }
166     }
167
168     /**
169      * Updates currect x509 CRL state by parsing specified data.
170      */
171     private void setX509CRL(byte[] data) throws CRLException {
172         x509CRL = (X509CRL) CERTIFICATE_FACTORY
173                 .generateCRL(new ByteArrayInputStream(data));
174     }
175
176     /**
177      * Utility class for CBOR Crl presentation.
178      */
179     private static final class CRL {
180
181         private final String encoding;
182
183         private final byte[] data;
184
185         CRL(String encoding, byte[] data) {
186             this.encoding = encoding;
187             this.data = data;
188         }
189
190         public String getEncoding() {
191             return encoding;
192         }
193
194         public byte[] getData() {
195             return data;
196         }
197     }
198 }