Add rule for 'All devices apps' when access rule is empty.
[platform/core/connectivity/smartcard-service.git] / common / AccessControlList.cpp
1 /*
2  * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 /* standard library header */
18 #include <stdio.h>
19
20 /* SLP library header */
21
22 /* local header */
23 #include "Debug.h"
24 #include "AccessControlList.h"
25 #include "PKCS15.h"
26
27 namespace smartcard_service_api
28 {
29         const unsigned char all_se_apps[] = { 0x00, 0x00 };
30         const unsigned char default_se_app[] = { 0x00, 0x01 };
31         const unsigned char all_device_apps[] = { 0x00, 0x02 };
32
33         ByteArray AccessControlList::ALL_SE_APPS(ARRAY_AND_SIZE(all_se_apps));
34         ByteArray AccessControlList::DEFAULT_SE_APP(ARRAY_AND_SIZE(default_se_app));
35         ByteArray AccessControlList::ALL_DEVICE_APPS(ARRAY_AND_SIZE(all_device_apps));
36
37         AccessControlList::AccessControlList() : allGranted(false)
38         {
39         }
40
41         AccessControlList::~AccessControlList()
42         {
43                 releaseACL();
44         }
45
46         void AccessControlList::releaseACL()
47         {
48                 mapConditions.clear();
49                 allGranted = false;
50         }
51
52         AccessCondition &AccessControlList::getAccessCondition(const ByteArray &aid)
53         {
54                 map<ByteArray, AccessCondition>::iterator item;
55
56                 item = mapConditions.find(aid);
57                 if (item == mapConditions.end())
58                 {
59                         AccessCondition condition;
60                         pair<ByteArray, AccessCondition> temp(aid, condition);
61                         mapConditions.insert(temp);
62
63                         item = mapConditions.find(aid);
64                 }
65
66                 return item->second;
67         }
68
69         const AccessRule *AccessControlList::findAccessRule(const ByteArray &aid,
70                 const ByteArray &hash) const
71         {
72                 const AccessRule *result = NULL;
73                 map<ByteArray, AccessCondition>::const_iterator item;
74
75                 item = mapConditions.find(aid);
76                 if (item != mapConditions.end()) {
77                         result = item->second.getAccessRule(hash);
78                 }
79
80                 return result;
81         }
82
83         bool AccessControlList::isAuthorizedAccess(const ByteArray &aid,
84                 const ByteArray &certHash) const
85         {
86                 vector<ByteArray> hashes;
87
88                 hashes.push_back(certHash);
89
90                 return isAuthorizedAccess(aid, hashes);
91         }
92
93         bool AccessControlList::isAuthorizedAccess(const unsigned char *aidBuffer,
94                 unsigned int aidLength, const unsigned char *certHashBuffer,
95                 unsigned int certHashLength) const
96         {
97                 ByteArray aid(aidBuffer, aidLength);
98                 ByteArray certHash(certHashBuffer, certHashLength);
99
100                 return isAuthorizedAccess(aid, certHash);
101         }
102
103         bool AccessControlList::isAuthorizedAccess(const ByteArray &aid,
104                 const vector<ByteArray> &certHashes) const
105         {
106                 return isAuthorizedAccess(aid, certHashes, ByteArray::EMPTY);
107         }
108
109         bool AccessControlList::isAuthorizedAccess(const ByteArray &aid,
110                 const vector<ByteArray> &certHashes, const ByteArray &command) const
111         {
112                 bool result = allGranted;
113                 vector<ByteArray>::const_reverse_iterator item;
114                 const AccessRule *rule = NULL;
115
116                 if (result == true) {
117                         goto END;
118                 }
119
120                 /* Step A, find with aid and cert hashes */
121                 for (item = certHashes.rbegin(); item != certHashes.rend(); item++) {
122                         rule = findAccessRule(aid, *item);
123                         if (rule != NULL) {
124                                 if (command.isEmpty()) {
125                                         result = rule->isAuthorizedAccess();
126                                 } else {
127                                         result = rule->isAuthorizedAPDUAccess(command);
128                                 }
129                                 _INFO("rule found (%s): [%s:%s]", result ? "accept" : "deny", aid.toString().c_str(), (*item).toString().c_str());
130                                 goto END;
131                         }
132                 }
133
134                 /* Step B, find with aid and ALL_DEVICES_APPS */
135                 rule = findAccessRule(aid, ALL_DEVICE_APPS);
136                 if (rule != NULL) {
137                         if (command.isEmpty()) {
138                                 result = rule->isAuthorizedAccess();
139                         } else {
140                                 result = rule->isAuthorizedAPDUAccess(command);
141                         }
142                         _INFO("rule found (%s): [%s:%s]", result ? "accept" : "deny", aid.toString().c_str(), ALL_DEVICE_APPS.toString().c_str());
143                         goto END;
144                 }
145
146                 /* Step C, find with ALL_SE_APPS and hashes */
147                 for (item = certHashes.rbegin(); item != certHashes.rend(); item++) {
148                         rule = findAccessRule(ALL_SE_APPS, *item);
149                         if (rule != NULL) {
150                                 if (command.isEmpty()) {
151                                         result = rule->isAuthorizedAccess();
152                                 } else {
153                                         result = rule->isAuthorizedAPDUAccess(command);
154                                 }
155                                 _INFO("rule found (%s): [%s:%s]", result ? "accept" : "deny", "All SE Applications", (*item).toString().c_str());
156                                 goto END;
157                         }
158                 }
159
160                 /* Step D, find with ALL_SE_APPS and ALL_DEVICES_APPS */
161                 rule = findAccessRule(ALL_SE_APPS, ALL_DEVICE_APPS);
162                 if (rule != NULL) {
163                         if (command.isEmpty()) {
164                                 result = rule->isAuthorizedAccess();
165                         } else {
166                                 result = rule->isAuthorizedAPDUAccess(command);
167                         }
168                         _INFO("rule found (%s): [%s:%s]", result ? "accept" : "deny", "All SE Applications", "All device applications");
169                 }
170
171 END :
172                 return result;
173         }
174
175         bool AccessControlList::isAuthorizedNFCAccess(const ByteArray &aid,
176                 const vector<ByteArray> &certHashes) const
177         {
178                 bool result = allGranted;
179                 vector<ByteArray>::const_reverse_iterator item;
180                 const AccessRule *rule = NULL;
181
182                 if (result == true) {
183                         goto END;
184                 }
185
186                 /* Step A, find with aid and cert hashes */
187                 for (item = certHashes.rbegin(); item != certHashes.rend(); item++) {
188                         rule = findAccessRule(aid, *item);
189                         if (rule != NULL) {
190                                 result = rule->isAuthorizedNFCAccess();
191                                 _INFO("rule found (%s): [%s:%s]", result ? "accept" : "deny", aid.toString().c_str(), (*item).toString().c_str());
192                                 goto END;
193                         }
194                 }
195
196                 /* Step B, find with aid and ALL_DEVICES_APPS */
197                 rule = findAccessRule(aid, ALL_DEVICE_APPS);
198                 if (rule != NULL) {
199                         result = rule->isAuthorizedNFCAccess();
200                         _INFO("rule found (%s): [%s:%s]", result ? "accept" : "deny", aid.toString().c_str(), "All device applications");
201                         goto END;
202                 }
203
204                 /* Step C, find with ALL_SE_APPS and hashes */
205                 for (item = certHashes.rbegin(); item != certHashes.rend(); item++) {
206                         rule = findAccessRule(ALL_SE_APPS, *item);
207                         if (rule != NULL) {
208                                 result = rule->isAuthorizedNFCAccess();
209                                 _INFO("rule found (%s): [%s:%s]", result ? "accept" : "deny", "All SE Applications", (*item).toString().c_str());
210                                 goto END;
211                         }
212                 }
213
214                 /* Step D, find with ALL_SE_APPS and ALL_DEVICES_APPS */
215                 rule = findAccessRule(ALL_SE_APPS, ALL_DEVICE_APPS);
216                 if (rule != NULL) {
217                         result = rule->isAuthorizedNFCAccess();
218                         _INFO("rule found (%s): [%s:%s]", result ? "accept" : "deny", "All SE Applications", "All device applications");
219                 }
220
221 END :
222                 return result;
223         }
224 } /* namespace smartcard_service_api */