11fa2f5a1c7c4376164ee52fc457490f0fe94f38
[platform/core/security/device-certificate-manager-backend.git] / src / dummy-backend / dummycryptobackendcontext.cpp
1 /******************************************************************
2  *
3  * Copyright 2017 - 2019 Samsung Electronics All Rights Reserved.
4  *
5  * Author: Jaroslaw Pelczar <j.pelczar@samsung.com>
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  ******************************************************************/
20
21 #include "dummycryptobackendcontext.h"
22 #include <mbedtls/pk.h>
23 #include <mbedtls/ctr_drbg.h>
24 #include <iostream>
25 #include "log.h"
26 #include <string>
27
28 extern "C" {
29         extern size_t dummy_rootca_rsa_key_size;
30         extern char dummy_rootca_rsa_key[];
31         extern size_t dummy_rootca_rsa_cert_size;
32         extern char dummy_rootca_rsa_cert[];
33         extern size_t dummy_rootca_ecdsa_key_size;
34         extern char dummy_rootca_ecdsa_key[];
35         extern size_t dummy_rootca_ecdsa_cert_size;
36         extern char dummy_rootca_ecdsa_cert[];
37 }
38
39 dummy_crypto_backend_context::dummy_crypto_backend_context(const std::string& keyType) {
40         if(keyType.empty() || keyType == "RSA") {
41                 fKey = CRYPTO_KEY_TYPE_RSA;
42         } else if(keyType == "ECDSA") {
43                 fKey = CRYPTO_KEY_TYPE_ECDSA;
44         } else {
45                 throw std::invalid_argument("Unsupported key type");
46         }
47
48         mbedtls_entropy_init( &fEntropy );
49         mbedtls_ctr_drbg_init( &fCtrDrbg );
50
51         int ret = mbedtls_ctr_drbg_seed( &fCtrDrbg,
52                         mbedtls_entropy_func,
53                         &fEntropy,
54                         (const unsigned char *)this,
55                         sizeof(dummy_crypto_backend_context) );
56
57         if(!ret) {
58                 LOGE("Can't seed entropy source");
59                 mbedtls_ctr_drbg_free( &fCtrDrbg );
60                 mbedtls_entropy_free( &fEntropy );
61                 throw std::runtime_error("seed failure");
62         }
63 }
64
65 dummy_crypto_backend_context::~dummy_crypto_backend_context() {
66         mbedtls_ctr_drbg_free( &fCtrDrbg );
67         mbedtls_entropy_free( &fEntropy );
68 }
69
70 int dummy_crypto_backend_context::request_certificate_chain(std::string& mutable_chain)
71 {
72         if(fKey == CRYPTO_KEY_TYPE_RSA) {
73                 mutable_chain.assign(dummy_rootca_rsa_cert, dummy_rootca_rsa_cert_size);
74         } else {
75                 mutable_chain.assign(dummy_rootca_ecdsa_cert, dummy_rootca_ecdsa_cert_size);
76         }
77
78         return 0;
79 }
80
81 int dummy_crypto_backend_context::sign_crypto_data(MessageDigestType digestType,
82                 const std::string& dataToSign,
83                 std::string& digestResult)
84 {
85         int error;
86
87         mbedtls_pk_context pk;
88         mbedtls_pk_init(&pk);
89
90         if(fKey == CRYPTO_KEY_TYPE_RSA) {
91                 error = mbedtls_pk_parse_key(&pk,
92                         (const unsigned char *)dummy_rootca_rsa_key,
93                         dummy_rootca_rsa_key_size + 1, // Include 0 byte for PEM
94                         nullptr, 0);
95
96         } else {
97                 error = mbedtls_pk_parse_key(&pk,
98                         (const unsigned char *)dummy_rootca_ecdsa_key,
99                         dummy_rootca_ecdsa_key_size + 1, // Include 0 byte for PEM
100                         nullptr, 0);
101         }
102
103         if(error != 0) {
104                 LOGE("Can't parse private key");
105                 mbedtls_pk_free(&pk);
106                 return error;
107         }
108
109         size_t sig_len = 0;
110
111         LOGD("Maximum digest size is " << MBEDTLS_MPI_MAX_SIZE);
112
113         char* output = (char*)malloc(MBEDTLS_MPI_MAX_SIZE);
114
115         if (!output) {
116                 LOGE("Can't allocate output buffer for signing");
117                 error = -1;
118                 mbedtls_pk_free(&pk);
119                 return error;
120         }
121
122         error = mbedtls_pk_sign(&pk,
123                         static_cast<mbedtls_md_type_t>(digestType),
124                         (const unsigned char *)dataToSign.c_str(),
125                         dataToSign.size(),
126                         (unsigned char *)output,
127                         &sig_len,
128                         &mbedtls_ctr_drbg_random,
129                         &fCtrDrbg);
130
131         if(error != 0) {
132                 LOGE("Signature generation failed");
133         } else {
134                 LOGD("Signature size is " << sig_len);
135                 digestResult = std::string(output, sig_len);
136         }
137
138         mbedtls_pk_free(&pk);
139         free(output);
140
141         return error;
142 }
143
144 CryptoKeyType dummy_crypto_backend_context::dummy_crypto_backend_context::key_type()
145 {
146         return fKey;
147 }
148
149 unsigned int dummy_crypto_backend_context::key_length()
150 {
151         size_t keyLength = 0;
152
153         mbedtls_pk_context pk;
154         mbedtls_pk_init(&pk);
155
156         if(fKey == CRYPTO_KEY_TYPE_RSA) {
157                 int error = mbedtls_pk_parse_key(&pk,
158                                 (const unsigned char *)dummy_rootca_rsa_key,
159                                 dummy_rootca_rsa_key_size + 1, // Include 0 byte for PEM
160                                 nullptr, 0);
161
162                 assert(error == 0);
163                 assert(mbedtls_pk_get_type(&pk) == MBEDTLS_PK_RSA);
164                 (void)error;
165         } else {
166                 int error = mbedtls_pk_parse_key(&pk,
167                                 (const unsigned char *)dummy_rootca_ecdsa_key,
168                                 dummy_rootca_ecdsa_key_size + 1, // Include 0 byte for PEM
169                                 nullptr, 0);
170
171                 assert(error == 0);
172                 assert(mbedtls_pk_get_type(&pk) == MBEDTLS_PK_ECKEY);
173                 (void)error;
174         }
175
176         keyLength = mbedtls_pk_get_bitlen(&pk);
177         mbedtls_pk_free(&pk);
178
179         assert(UINT_MAX >= keyLength);
180
181         return keyLength;
182 }