statistical defects fixed
[iotivity.git] / cloud / account / src / main / java / org / iotivity / cloud / accountserver / resources / credprov / crl / CrlResource.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.BASE_64;
25 import static org.iotivity.cloud.accountserver.resources.credprov.crl.CrlManager.CRL_MANAGER;
26
27 import java.io.IOException;
28 import java.security.cert.CRLException;
29 import java.text.ParseException;
30 import java.text.SimpleDateFormat;
31 import java.util.Arrays;
32 import java.util.Date;
33 import java.util.HashMap;
34 import java.util.List;
35 import java.util.Map;
36
37 import org.bouncycastle.operator.OperatorCreationException;
38 import org.bouncycastle.util.encoders.Base64;
39 import org.bouncycastle.util.encoders.DecoderException;
40 import org.iotivity.cloud.accountserver.Constants;
41 import org.iotivity.cloud.base.device.Device;
42 import org.iotivity.cloud.base.exception.ServerException;
43 import org.iotivity.cloud.base.protocols.IRequest;
44 import org.iotivity.cloud.base.protocols.IResponse;
45 import org.iotivity.cloud.base.protocols.MessageBuilder;
46 import org.iotivity.cloud.base.protocols.enums.ContentFormat;
47 import org.iotivity.cloud.base.protocols.enums.ResponseStatus;
48 import org.iotivity.cloud.base.resource.Resource;
49 import org.iotivity.cloud.util.Cbor;
50 import org.iotivity.cloud.util.Log;
51
52 /**
53  * Class is used working with POST and GET requests and handles CRL requests.
54  */
55 public class CrlResource extends Resource {
56
57     /**
58      * CBOR container with help of map presentation.
59      */
60     private static final Cbor<Map<String, Object>> MAP_CBOR = new Cbor<>();
61
62     /**
63      * Creates resource for handling CRL requests(GET and POST)
64      */
65     public CrlResource() {
66         super(Arrays.asList(Constants.PREFIX_OIC, Constants.CREDPROV_URI,
67                 Constants.REQ_CRL));
68
69     }
70
71     @Override
72     public void onDefaultRequestReceived(Device srcDevice, IRequest request)
73             throws ServerException {
74         IResponse response;
75         switch (request.getMethod()) {
76             case POST:
77                 response = handlePostRequest(request);
78                 break;
79             case GET:
80                 response = handleGetRequest(request);
81                 break;
82             default:
83                 response = MessageBuilder.createResponse(request,
84                         ResponseStatus.BAD_REQUEST);
85         }
86         srcDevice.sendResponse(response);
87     }
88
89     /**
90      * Method handles GET requests with specified format: GET
91      * /oic/credprov/crl?lu=20170701000000 Checks if “lu” value is not after the
92      * latest update. If so, response with the latest CRL, otherwise response
93      * error (e.g. 4.04 Not Found) And response of next format: 2.05 CONTENTS {
94      * “tu” : “20160711000000”, “nu” : “20161011000000”, “crl” : { “encoding” :
95      * “oic.sec.encoding.base64”, “data” : “<Base64 encoded CRL Binary>” } }
96      */
97     private IResponse handleGetRequest(IRequest request)
98             throws ServerException {
99         HashMap<String, List<String>> queryData = request.getUriQueryMap();
100         IResponse iResponse = MessageBuilder.createResponse(request,
101                 ResponseStatus.NOT_FOUND);
102         if (queryData != null) {
103             List<String> lastUpdateList = queryData
104                     .get(Constants.REQ_LAST_UPDATE);
105             if (lastUpdateList != null && !lastUpdateList.isEmpty()) {
106                 try {
107                     Map<String, Object> payload = CRL_MANAGER
108                             .getPayload(lastUpdateList.get(0));
109                     if (!payload.isEmpty()) {
110                         iResponse = MessageBuilder.createResponse(request,
111                                 ResponseStatus.CONTENT,
112                                 ContentFormat.APPLICATION_CBOR,
113                                 MAP_CBOR.encodingPayloadToCbor(payload));
114                     }
115                 } catch (CRLException e) {
116                     Log.e(e.getMessage());
117                 }
118             }
119         }
120         return iResponse;
121     }
122
123     /**
124      * Handles POST requests of next formats: POST /oic/credprov/crl { “tu” :
125      * “20160727000000”, “nu” : “20161027000000”, “rcsn” : “123456” } AND POST
126      * /oic/credprov/crl { “tu” : “20160727000000”, “nu” : “20161027000000”,
127      * “crl” : { “encoding” : “oic.sec.encoding.base64”, “data” : “<Base64
128      * encoded New CRL Binary>” } } And responds back with 2.04 CHANGED if
129      * everything is ok, and PRECONDITION_FAILED - otherwise
130      */
131     private IResponse handlePostRequest(IRequest request)
132             throws ServerException {
133         byte[] requestPayload = request.getPayload();
134         IResponse response = MessageBuilder.createResponse(request,
135                 ResponseStatus.PRECONDITION_FAILED);
136         if (requestPayload != null) {
137             Map<String, Object> payloadData = MAP_CBOR
138                     .parsePayloadFromCbor(request.getPayload(), HashMap.class);
139             if (payloadData != null) {
140                 Object thisUpdate = payloadData.get(Constants.REQ_THIS_UPDATE);
141                 Object nextUpdate = payloadData.get(Constants.REQ_NEXT_UPDATE);
142                 if (thisUpdate != null && thisUpdate instanceof String
143                         && nextUpdate != null && nextUpdate instanceof String) {
144                     Date thisUpdateDate;
145                     try {
146                         thisUpdateDate = new SimpleDateFormat("yyyyMMddHHmmss")
147                                 .parse(thisUpdate.toString());
148                         Object reqSerialNumber = payloadData
149                                 .get(Constants.REQ_SERIAL_NUMBER);
150                         Object crl = payloadData.get(Constants.REQ_CRL);
151                         if (reqSerialNumber != null
152                                 && reqSerialNumber instanceof List) {
153                             CRL_MANAGER.revoke(((List<String>) reqSerialNumber)
154                                     .toArray(new String[] {}));
155                             response = MessageBuilder.createResponse(request,
156                                     ResponseStatus.CHANGED);
157                         } else if (crl != null && crl instanceof Map) {
158                             Object encoding = ((Map<String, Object>) crl)
159                                     .get(Constants.ENCODING);
160                             Object crlData = ((Map<String, Object>) crl)
161                                     .get(Constants.DATA);
162                             if (encoding != null && encoding instanceof String
163                                     && crlData != null
164                                     && crlData instanceof byte[]) {
165                                 try {
166                                     if (encoding.equals(BASE_64)) {
167                                         crlData = Base64
168                                                 .decode((byte[]) crlData);
169                                     }
170                                     CRL_MANAGER.update(thisUpdateDate,
171                                             (byte[]) crlData);
172                                     response = MessageBuilder.createResponse(
173                                             request, ResponseStatus.CHANGED);
174                                 } catch (DecoderException e) {
175                                     Log.e(e.getMessage() + e.getClass());
176                                 }
177                             }
178                         }
179                     } catch (CRLException | IOException
180                             | OperatorCreationException | ParseException e) {
181                         Log.e(e.getMessage() + e.getClass());
182                     }
183                 }
184             }
185         }
186         return response;
187     }
188 }