Add scheme encryption test db generator
[platform/core/security/key-manager.git] / tests / encryption-scheme / scheme-test.cpp
1 /*
2  *  Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
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  * @file       scheme-test.cpp
18  * @author     Krzysztof Jackiewicz (k.jackiewicz@samsung.com)
19  * @version    1.0
20  */
21 #include <scheme-test.h>
22
23 #include <sys/smack.h>
24 #include <sys/types.h>
25 #include <unistd.h>
26
27 #include <fstream>
28 #include <stdexcept>
29
30 #include <smack-access.h>
31
32 using namespace CKM;
33 using namespace std;
34
35 namespace {
36 const uid_t UID = 7654;
37 const gid_t GID = 7654;
38 const char* const DBPASS = "db-pass";
39 const char* const LABEL = "my-label";
40 const string TEST_DATA_STR = "test-data";
41 RawBuffer TEST_DATA(TEST_DATA_STR.begin(), TEST_DATA_STR.end());
42 const Password TEST_PASS = "custom user password";
43
44 enum {
45     NO_PASS = 0,
46     PASS = 1
47 };
48
49 enum {
50     NO_EXP = 0,
51     EXP = 1
52 };
53
54 // [password][exportable]
55 Policy policy[2][2] = {
56         {{ Password(), false }, { Password(), true }},
57         {{ TEST_PASS,  false }, { TEST_PASS,  true }},
58 };
59
60 struct Group {
61     enum {
62         KEY_PAIR,
63         CERT_CHAIN,
64         SINGLE_ITEM
65     } type;
66     Items items;
67 };
68
69 Group GROUPS[] = {
70     // Data
71     { Group::SINGLE_ITEM, {
72             Item("data-alias1", DataType::BINARY_DATA,  policy[NO_PASS][EXP])
73     }},
74     { Group::SINGLE_ITEM, {
75             Item("data-alias2", DataType::BINARY_DATA,  policy[PASS][EXP])
76     }},
77
78     // RSA keys
79     { Group::KEY_PAIR, {
80             Item("key-rsa-alias-prv1", DataType::KEY_RSA_PRIVATE,  policy[NO_PASS][NO_EXP]),
81             Item("key-rsa-alias-pub1", DataType::KEY_RSA_PUBLIC,   policy[NO_PASS][NO_EXP])
82     }},
83     { Group::KEY_PAIR, {
84             Item("key-rsa-alias-prv2", DataType::KEY_RSA_PRIVATE,  policy[NO_PASS][EXP]),
85             Item("key-rsa-alias-pub2", DataType::KEY_RSA_PUBLIC,   policy[NO_PASS][EXP]),
86     }},
87     { Group::KEY_PAIR, {
88             Item("key-rsa-alias-prv3", DataType::KEY_RSA_PRIVATE,  policy[PASS][NO_EXP]),
89             Item("key-rsa-alias-pub3", DataType::KEY_RSA_PUBLIC,   policy[PASS][NO_EXP]),
90     }},
91     { Group::KEY_PAIR, {
92             Item("key-rsa-alias-prv4", DataType::KEY_RSA_PRIVATE,  policy[PASS][EXP]),
93             Item("key-rsa-alias-pub4", DataType::KEY_RSA_PUBLIC,   policy[PASS][EXP]),
94     }},
95     // different policies
96     { Group::KEY_PAIR, {
97             Item("key-rsa-alias-prv5", DataType::KEY_RSA_PRIVATE,  policy[PASS][NO_EXP]),
98             Item("key-rsa-alias-pub5", DataType::KEY_RSA_PUBLIC,   policy[NO_PASS][EXP]),
99     }},
100
101     // AES
102     { Group::SINGLE_ITEM, {
103             Item("key-aes-alias1",     DataType::KEY_AES,          policy[NO_PASS][NO_EXP]),
104     }},
105     { Group::SINGLE_ITEM, {
106             Item("key-aes-alias2",     DataType::KEY_AES,          policy[NO_PASS][EXP]),
107     }},
108     { Group::SINGLE_ITEM, {
109             Item("key-aes-alias3",     DataType::KEY_AES,          policy[PASS][NO_EXP]),
110     }},
111     { Group::SINGLE_ITEM, {
112             Item("key-aes-alias4",     DataType::KEY_AES,          policy[PASS][EXP]),
113     }},
114
115     // Certificates
116     { Group::CERT_CHAIN, {
117             Item("cert-root-alias1",   DataType::CERTIFICATE,      policy[NO_PASS][NO_EXP]),
118             Item("cert-im-ca-alias1",  DataType::CERTIFICATE,      policy[NO_PASS][NO_EXP]),
119             Item("cert-leaf-alias1",   DataType::CERTIFICATE,      policy[NO_PASS][NO_EXP]),
120     }},
121     { Group::CERT_CHAIN, {
122             Item("cert-root-alias2",   DataType::CERTIFICATE,      policy[NO_PASS][EXP]),
123             Item("cert-im-ca-alias2",  DataType::CERTIFICATE,      policy[NO_PASS][EXP]),
124             Item("cert-leaf-alias2",   DataType::CERTIFICATE,      policy[NO_PASS][EXP]),
125     }},
126     { Group::CERT_CHAIN, {
127             Item("cert-root-alias3",   DataType::CERTIFICATE,      policy[PASS][NO_EXP]),
128             Item("cert-im-ca-alias3",  DataType::CERTIFICATE,      policy[PASS][NO_EXP]),
129             Item("cert-leaf-alias3",   DataType::CERTIFICATE,      policy[PASS][NO_EXP]),
130     }},
131     { Group::CERT_CHAIN, {
132             Item("cert-root-alias4",   DataType::CERTIFICATE,      policy[PASS][EXP]),
133             Item("cert-im-ca-alias4",  DataType::CERTIFICATE,      policy[PASS][EXP]),
134             Item("cert-leaf-alias4",   DataType::CERTIFICATE,      policy[PASS][EXP]),
135     }},
136
137     // PKCS
138     { Group::SINGLE_ITEM, {
139             Item("pkcs-alias1",        DataType::CHAIN_CERT_0,     policy[NO_PASS][NO_EXP]),
140     }},
141     { Group::SINGLE_ITEM, {
142             Item("pkcs-alias2",        DataType::CHAIN_CERT_0,     policy[NO_PASS][EXP]),
143     }},
144     { Group::SINGLE_ITEM, {
145             Item("pkcs-alias3",        DataType::CHAIN_CERT_0,     policy[PASS][NO_EXP]),
146     }},
147     { Group::SINGLE_ITEM, {
148             Item("pkcs-alias4",        DataType::CHAIN_CERT_0,     policy[PASS][EXP]),
149     }},
150 };
151
152 const size_t CHAIN_SIZE = 3;
153
154 // TEST_ROOT_CA, expires 2035
155 std::string TEST_ROOT_CA =
156     "-----BEGIN CERTIFICATE-----\n"
157     "MIIDnzCCAoegAwIBAgIJAMH/ADkC5YSTMA0GCSqGSIb3DQEBBQUAMGYxCzAJBgNV\n"
158     "BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMQ0wCwYDVQQKDARBQ01FMRAwDgYD\n"
159     "VQQLDAdUZXN0aW5nMSEwHwYDVQQDDBhUZXN0IHJvb3QgY2EgY2VydGlmaWNhdGUw\n"
160     "HhcNMTQxMjMwMTcyMTUyWhcNMjQxMjI3MTcyMTUyWjBmMQswCQYDVQQGEwJBVTET\n"
161     "MBEGA1UECAwKU29tZS1TdGF0ZTENMAsGA1UECgwEQUNNRTEQMA4GA1UECwwHVGVz\n"
162     "dGluZzEhMB8GA1UEAwwYVGVzdCByb290IGNhIGNlcnRpZmljYXRlMIIBIjANBgkq\n"
163     "hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0EJRdUtd2th0vTVF7QxvDKzyFCF3w9vC\n"
164     "9IDE/Yr12w+a9jd0s7/eG96qTHIYffS3B7x2MB+d4n+SR3W0qmYh7xk8qfEgH3da\n"
165     "eDoV59IZ9r543KM+g8jm6KffYGX1bIJVVY5OhBRbO9nY6byYpd5kbCIUB6dCf7/W\n"
166     "rQl1aIdLGFIegAzPGFPXDcU6F192686x54bxt/itMX4agHJ9ZC/rrTBIZghVsjJo\n"
167     "5/AH5WZpasv8sfrGiiohAxtieoYoJkv5MOYP4/2lPlOY+Cgw1Yoz+HHv31AllgFs\n"
168     "BquBb/kJVmCCNsAOcnvQzTZUsW/TXz9G2nwRdqI1nSy2JvVjZGsqGQIDAQABo1Aw\n"
169     "TjAdBgNVHQ4EFgQUt6pkzFt1PZlfYRL/HGnufF4frdwwHwYDVR0jBBgwFoAUt6pk\n"
170     "zFt1PZlfYRL/HGnufF4frdwwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOC\n"
171     "AQEAld7Qwq0cdzDQ51w1RVLwTR8Oy25PB3rzwEHcSGJmdqlMi3xOdaz80S1R1BBX\n"
172     "ldvGBG5Tn0vT7xSuhmSgI2/HnBpy9ocHVOmhtNB4473NieEpfTYrnGXrFxu46Wus\n"
173     "9m/ZnugcQ2G6C54A/NFtvgLmaC8uH8M7gKdS6uYUwJFQEofkjmd4UpOYSqmcRXhS\n"
174     "Jzd5FYFWkJhKJYp3nlENSOD8CUFFVGekm05nFN2gRVc/qaqQkEX77+XYvhodLRsV\n"
175     "qMn7nf7taidDKLO2T4bhujztnTYOhhaXKgPy7AtZ28N2wvX96VyAPB/vrchGmyBK\n"
176     "kOg11TpPdNDkhb1J4ZCh2gupDg==\n"
177     "-----END CERTIFICATE-----\n";
178
179 // TEST_IM_CA, signed by TEST_ROOT_CA, expires 2035
180 std::string TEST_IM_CA =
181     "-----BEGIN CERTIFICATE-----\n"
182     "MIIDljCCAn6gAwIBAgICEAAwDQYJKoZIhvcNAQEFBQAwZjELMAkGA1UEBhMCQVUx\n"
183     "EzARBgNVBAgMClNvbWUtU3RhdGUxDTALBgNVBAoMBEFDTUUxEDAOBgNVBAsMB1Rl\n"
184     "c3RpbmcxITAfBgNVBAMMGFRlc3Qgcm9vdCBjYSBjZXJ0aWZpY2F0ZTAeFw0xNTAx\n"
185     "MTYxNjQ1MzRaFw0zNTAxMTExNjQ1MzRaMGQxCzAJBgNVBAYTAkFVMRMwEQYDVQQI\n"
186     "DApTb21lLVN0YXRlMQ0wCwYDVQQKDARBQ01FMRAwDgYDVQQLDAdUZXN0aW5nMR8w\n"
187     "HQYDVQQDDBZUZXN0IElNIENBIGNlcnRpZmljYXRlMIIBIjANBgkqhkiG9w0BAQEF\n"
188     "AAOCAQ8AMIIBCgKCAQEAzmBF78qClgoKfnLAncMXZwZ14TW+5kags1+QCYeg3c7j\n"
189     "L9+RvDxIaX2tKf1sukJcwQfYqUlQkwt+58LMOb2ORtkpj8Or6WCWCZ0BzneT8ug7\n"
190     "nxJT4m9+bohMF0JoKjjB2H4KNMHamLIwUxRKt6nyfk81kVhJOi2vzzxd+UCPi6Pc\n"
191     "UAbJNH48eNgOIg55nyFovVzYj8GIo/9GvHJj83PPa/KlJZ+Z1qZASZZ/VYorplVT\n"
192     "thsHXKfejhFy5YJ9t7n/vyAQsyBsagZsvX19xnH41fbYXHKf8UbXG23rNaZlchs6\n"
193     "XJVLQdzOpj3WTj/lCocVHqLaZISLhNQ3aI7kUBUdiwIDAQABo1AwTjAdBgNVHQ4E\n"
194     "FgQUoCYNaCBP4jl/3SYQuK8Ka+6i3QEwHwYDVR0jBBgwFoAUt6pkzFt1PZlfYRL/\n"
195     "HGnufF4frdwwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAjRzWiD97\n"
196     "Htv4Kxpm3P+C+xP9AEteCJfO+7p8MWgtWEJOknJyt55zeKS2JwZIq57KcbqD8U7v\n"
197     "vAUx1ymtUhlFPFd7J1mJ3pou+3aFYmGShYhGHpbrmUwjp7HVP588jrW1NoZVHdMc\n"
198     "4OgJWFrViXeu9+maIcekjMB/+9Y0dUgQuK5ZuT5H/Jwet7Th/o9uufTUZjBzRvrB\n"
199     "pbXgQpqgME2av4Q/6LuldPCTHLtWXgFUU2R+yCGmuGilvhFJnKoQryAbYnIQNWE8\n"
200     "SLoHQ9s1i7Zyb7HU6UAaqMOz15LBkyAqtNyJcO2p7Q/p5YK0xfD4xisI5qXucqVm\n"
201     "F2obL5qJSTN/RQ==\n"
202     "-----END CERTIFICATE-----\n";
203
204 // TEST_LEAF, signed by TEST_IM_CA, expires 2035
205 std::string TEST_LEAF =
206     "-----BEGIN CERTIFICATE-----\n"
207     "MIIDOzCCAiMCAQEwDQYJKoZIhvcNAQEFBQAwZDELMAkGA1UEBhMCQVUxEzARBgNV\n"
208     "BAgMClNvbWUtU3RhdGUxDTALBgNVBAoMBEFDTUUxEDAOBgNVBAsMB1Rlc3Rpbmcx\n"
209     "HzAdBgNVBAMMFlRlc3QgSU0gQ0EgY2VydGlmaWNhdGUwHhcNMTUwMTE2MTY0ODE0\n"
210     "WhcNMzUwMTExMTY0ODE0WjBjMQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1T\n"
211     "dGF0ZTENMAsGA1UECgwEQUNNRTEQMA4GA1UECwwHVGVzdGluZzEeMBwGA1UEAwwV\n"
212     "VGVzdCBsZWFmIGNlcnRpZmljYXRlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB\n"
213     "CgKCAQEAzTdDIa2tDmRxFnIgiG+mBz8GoSVODs0ImNQGbqj+pLhBOFRH8fsah4Jl\n"
214     "z5YF9KwhMVLknnHGFLE/Nb7Ac35kEzhMQMpTRxohW83oxw3eZ8zN/FBoKqg4qHRq\n"
215     "QR8kS10YXTgrBR0ex/Vp+OUKEw6h7yL2r4Tpvrn9/qHwsxtLxqWbDIVf1O9b1Lfc\n"
216     "bllYMdmV5E62yN5tcwrDP8gvHjFnVeLzrG8wTpc9FR90/0Jkfp5jAJcArOBLrT0E\n"
217     "4VRqs+4HuwT8jAwFAmNnc7IYX5qSjtSWkmmHe73K/lzB+OiI0JEc/3eWUTWqwTSk\n"
218     "4tNCiQGBKJ39LXPTBBJdzmxVH7CUDQIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQAp\n"
219     "UdDOGu3hNiG+Vn10aQ6B1ZmOj3t+45gUV3sC+y8hB8EK1g4P5Ke9bVDts0T5eOnj\n"
220     "CSc+6VoND5O4adI0IFFRFljHNVnvjeosHfUZNnowsmA2ptQBtC1g5ZKRvKXlkC5/\n"
221     "i5BGgRqPFA7y9WB9Y05MrJHf3E+Oz/RBsLeeNiNN+rF5X1vYExvGHpo0M0zS0ze9\n"
222     "HtC0aOy8ocsTrQkf3ceHTAXx2i8ftoSSD4klojtWFpWMrNQa52F7wB9nU6FfKRuF\n"
223     "Zj/T1JkYXKkEwZU6nAR2jdZp3EP9xj3o15V/tyFcXHx6l8NTxn4cJb+Xe4VquQJz\n"
224     "6ON7PVe0ABN/AlwVQiFE\n"
225     "-----END CERTIFICATE-----\n";
226 } // namespace anonymous
227
228
229 SchemeTest::SchemeTest() : m_userChanged(false) {
230     m_control = Control::create();
231     m_mgr = Manager::create();
232
233     SmackAccess sa;
234     sa.add("System", LABEL, "rwx");
235     sa.add(LABEL, "System", "rwx");
236     sa.add(LABEL, "System::Run", "x");
237     sa.apply();
238 }
239
240 SchemeTest::~SchemeTest() {
241     try {
242         SwitchToRoot();
243     } catch (...) {}
244 }
245
246 void SchemeTest::SwitchToUser() {
247     if (m_userChanged)
248         return;
249
250     if(CKM_API_SUCCESS != m_control->unlockUserKey(UID, DBPASS))
251         throw runtime_error("unlockUserKey failed");
252
253     // get calling label
254     char* label = NULL;
255     if (smack_new_label_from_self(&label) <= 0)
256         throw runtime_error("smack_new_label_from_self failed");
257
258     m_origLabel = string(label);
259     free(label);
260
261     if(0 > smack_set_label_for_self(LABEL))
262         throw runtime_error("smack_set_label_for_self failed");
263
264     if(0 > setegid(GID))
265         throw runtime_error("setegid failed");
266
267     if(0 > seteuid(UID))
268         throw runtime_error("seteuid failed");
269
270     m_userChanged = true;
271 }
272
273 void SchemeTest::SwitchToRoot() {
274     if (!m_userChanged)
275         return;
276
277     if(0 > seteuid(0))
278         throw runtime_error("seteuid failed");
279     if(0 > setegid(0))
280         throw runtime_error("setegid failed");
281
282     if(0 > smack_set_label_for_self(m_origLabel.c_str()))
283         throw runtime_error("smack_set_label_for_self failed");
284
285     if(m_control->lockUserKey(UID) != CKM_API_SUCCESS)
286         throw runtime_error("lockUserKey failed");
287 }
288
289 void SchemeTest::FillDb() {
290     // pkcs
291     ifstream is("/usr/share/ckm-db-test/encryption-scheme.p12");
292     if(!is)
293         throw runtime_error("Failed to read pkcs");
294     istreambuf_iterator<char> begin(is), end;
295     RawBuffer pkcsBuffer(begin, end);
296     auto pkcs = PKCS12::create(pkcsBuffer, Password());
297     if(pkcs->empty())
298         throw runtime_error("Empty pkcs");
299
300     SwitchToUser();
301
302     // certificates
303     RawBuffer rootCaBuffer(TEST_ROOT_CA.begin(), TEST_ROOT_CA.end());
304     CertificateShPtr rootCa = CKM::Certificate::create(rootCaBuffer, CKM::DataFormat::FORM_PEM);
305     RawBuffer imCaBuffer(TEST_IM_CA.begin(), TEST_IM_CA.end());
306     CertificateShPtr imCa = CKM::Certificate::create(imCaBuffer, CKM::DataFormat::FORM_PEM);
307     RawBuffer leafBuffer(TEST_LEAF.begin(), TEST_LEAF.end());
308     CertificateShPtr leaf = CKM::Certificate::create(leafBuffer, CKM::DataFormat::FORM_PEM);
309
310     for(const auto& g:GROUPS) {
311         switch (g.type) {
312         case Group::KEY_PAIR:
313             if(g.items.size() != 2)
314                 throw runtime_error("Wrong number of keys");
315             if( g.items[0].type != DataType::KEY_RSA_PRIVATE ||
316                 g.items[1].type != DataType::KEY_RSA_PUBLIC)
317                 throw runtime_error("Invalid item type");
318
319             if(CKM_API_SUCCESS != m_mgr->createKeyPairRSA(1024,
320                                                           g.items[0].alias,
321                                                           g.items[1].alias,
322                                                           g.items[0].policy,
323                                                           g.items[1].policy))
324                 throw runtime_error("createKeyPair failed");
325             break;
326
327         case Group::CERT_CHAIN:
328             if(g.items.size() != CHAIN_SIZE)
329                 throw runtime_error("Wrong number of certificates");
330             if( g.items[0].type != DataType::CERTIFICATE ||
331                 g.items[1].type != DataType::CERTIFICATE ||
332                 g.items[2].type != DataType::CERTIFICATE)
333                 throw runtime_error("Invalid item type");
334
335             if(CKM_API_SUCCESS != m_mgr->saveCertificate(g.items[0].alias, rootCa, g.items[0].policy))
336                 throw runtime_error("saveCertificate failed");
337             if(CKM_API_SUCCESS != m_mgr->saveCertificate(g.items[1].alias, imCa, g.items[1].policy))
338                 throw runtime_error("saveCertificate failed");
339             if(CKM_API_SUCCESS != m_mgr->saveCertificate(g.items[2].alias, leaf, g.items[2].policy))
340                 throw runtime_error("saveCertificate failed");
341             break;
342
343         default:
344             for(const auto& i:g.items) {
345                 switch (i.type) {
346                 case DataType::BINARY_DATA:
347                     if(CKM_API_SUCCESS != m_mgr->saveData(i.alias, TEST_DATA, i.policy))
348                         throw runtime_error("saveData failed");
349                     break;
350
351                 case DataType::KEY_AES:
352                     if(CKM_API_SUCCESS != m_mgr->createKeyAES(256, i.alias, i.policy))
353                         throw runtime_error("createKeyAES failed");
354                     break;
355
356                 case DataType::CHAIN_CERT_0:    // PKCS
357                     if(CKM_API_SUCCESS != m_mgr->savePKCS12(i.alias, pkcs, i.policy, i.policy))
358                         throw runtime_error("savePkcs12 failed");
359                     break;
360
361                 default:
362                     throw runtime_error("unsupported data type");
363                 }
364             }
365             break;
366         }
367     }
368 }