2 * certification service
4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd All Rights Reserved
6 * Contact: Kidong Kim <kd0228.kim@samsung.com>
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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.
25 #include <openssl/pkcs12.h>
26 #include <openssl/pem.h>
27 #include <libxml/parser.h>
28 #include <libxml/tree.h>
30 #include "orig/cert-service.h"
31 #include "orig/cert-service-util.h"
32 #include "orig/cert-service-debug.h"
35 #define CERT_BODY_PREFIX "-----BEGIN CERTIFICATE-----"
36 #define CERT_BODY_SUFIX "-----END CERTIFICATE-----"
37 #define ICERT_BODY_PREFIX "-----BEGIN TRUSTED CERTIFICATE-----"
38 #define ICERT_BODY_SUFIX "-----END TRUSTED CERTIFICATE-----"
40 static int base64DecodeTable[256] = {
41 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 0 ~ 15
42 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 16 ~ 31
43 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, // 32 ~ 47
44 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, // 48 ~ 63
45 -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, // 64 ~ 79
46 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, // 80 ~ 95
47 -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, // 96 ~ 111
48 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, // 112 ~ 127
49 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 128 ~ 143
50 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 144 ~ 159
51 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 160 ~ 175
52 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 176 ~ 191
53 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 192 ~ 207
54 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 208 ~ 223
55 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 224 ~ 239
56 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 // 240 ~ 255
59 static int cert_svc_util_base64_decode(const unsigned char *in, int inLen, unsigned char *out, int* outLen)
61 int ret = CERT_SVC_ERR_NO_ERROR;
62 int inputLen = 0, i = 0, j = 0, tail = 0;
63 const unsigned char *cur = NULL;
64 unsigned char tmpBuf[4];
66 if((in == NULL) || (inLen < 1)) {
67 SLOGE("[ERR][%s] Check your parameter.", __func__);
68 ret = CERT_SVC_ERR_INVALID_PARAMETER;
74 memset(tmpBuf, 0x00, 4);
78 for(j = 0; j < 4; j++) {
84 tmpBuf[j] = (unsigned char)base64DecodeTable[(int)cur[j]];
87 out[i++] = ((tmpBuf[0] & 0x3f) << 2) + ((tmpBuf[1] & 0x30) >> 4);
88 out[i++] = ((tmpBuf[1] & 0x0f) << 4) + ((tmpBuf[2] & 0x3c) >> 2);
89 out[i++] = ((tmpBuf[2] & 0x03) << 6) + (tmpBuf[3] & 0x3f);
94 memset(tmpBuf, 0x00, 4);
105 static int cert_svc_util_get_file_size(const char* filepath, unsigned long int* length)
107 int ret = CERT_SVC_ERR_NO_ERROR;
110 if(!(fp_in = fopen(filepath, "r"))) {
111 SLOGE("[ERR][%s] Fail to open file, [%s]", __func__, filepath);
112 ret = CERT_SVC_ERR_FILE_IO;
116 fseek(fp_in, 0L, SEEK_END);
117 (*length) = ftell(fp_in);
126 int get_content_into_buf_PEM(unsigned char* content, cert_svc_mem_buff* cert)
128 int ret = CERT_SVC_ERR_NO_ERROR;
129 char *startPEM, *endPEM;
130 unsigned char* original = NULL;
132 unsigned char* decoded = NULL;
137 ret = CERT_SVC_ERR_INVALID_PARAMETER;
140 startPEM = strstr((const char *)content, CERT_BODY_PREFIX);
141 startPEM = (startPEM) ? startPEM + strlen(CERT_BODY_PREFIX) : NULL;
142 endPEM = strstr((const char *)content, CERT_BODY_SUFIX);
143 if(!startPEM || !endPEM) {
144 startPEM = strstr((const char *)content, ICERT_BODY_PREFIX);
145 startPEM = (startPEM) ? startPEM + strlen(ICERT_BODY_PREFIX) : NULL;
146 endPEM = strstr((const char *)content, ICERT_BODY_SUFIX);
148 if(!startPEM || !endPEM) {
149 ret = CERT_SVC_ERR_UNKNOWN_ERROR;
155 size = (long)endPEM - (long)startPEM;
158 if(!(original = (unsigned char *)malloc(sizeof(unsigned char) * (size + 1)))) {
159 SLOGE("[ERR][%s] Fail to allocate memory.", __func__);
160 ret = CERT_SVC_ERR_MEMORY_ALLOCATION;
163 memset(original, 0x00, (size + 1));
165 for(i = 0, j = 0; i < size; i++) {
166 if(startPEM[i] != '\n')
167 original[j++] = startPEM[i];
170 size = strlen((char *)original);
171 decodedSize = ((size / 4) * 3) + 1;
173 if(!(decoded = (unsigned char *)malloc(sizeof(unsigned char) * decodedSize))) {
174 SLOGE("[ERR][%s] Fail to allocate memory.", __func__);
175 ret = CERT_SVC_ERR_MEMORY_ALLOCATION;
178 memset(decoded, 0x00, decodedSize);
179 if((ret = cert_svc_util_base64_decode(original, size, decoded, &decodedSize)) != CERT_SVC_ERR_NO_ERROR) {
180 SLOGE("[ERR][%s] Fail to base64 decode.", __func__);
182 ret = CERT_SVC_ERR_INVALID_OPERATION;
186 cert->data = decoded;
187 cert->size = decodedSize;
195 int get_content_into_buf_DER(unsigned char* content, cert_svc_mem_buff* cert)
197 int ret = CERT_SVC_ERR_NO_ERROR;
198 unsigned char* certData = NULL;
200 certData = (unsigned char*)malloc(sizeof(unsigned char) * (cert->size));
201 if(certData == NULL) {
202 SLOGE("[ERR][%s] Fail to allocate memory.", __func__);
203 ret = CERT_SVC_ERR_MEMORY_ALLOCATION;
207 memcpy(certData, content, cert->size);
208 cert->data = certData;
215 /* The dark side of cert-svc. */
216 int cert_svc_util_get_extension(const char* filePath, cert_svc_mem_buff* certBuf) {
217 int ret = CERT_SVC_ERR_NO_ERROR;
221 if ((in = fopen(filePath, "r")) == NULL) {
222 SLOGE("[ERR] Error opening file %s", filePath);
223 ret = CERT_SVC_ERR_FILE_IO;
227 if ((x = PEM_read_X509(in, NULL, NULL, NULL)) != NULL) {
228 strncpy(certBuf->type, "PEM", sizeof(certBuf->type));
232 fseek(in, 0L, SEEK_SET);
234 if ((x = PEM_read_X509_AUX(in, NULL, NULL, NULL)) != NULL) {
235 strncpy(certBuf->type, "PEM", sizeof(certBuf->type));
239 fseek(in, 0L, SEEK_SET);
241 if ((x = d2i_X509_fp(in, NULL)) != NULL) {
242 strncpy(certBuf->type, "DER", sizeof(certBuf->type));
246 SLOGE("[ERR] Unknown file type: %s", filePath);
247 ret = CERT_SVC_ERR_FILE_IO;
250 if (in && fclose(in)) {
251 SLOGE("[ERR] Fail in fclose.");
252 ret = CERT_SVC_ERR_FILE_IO;
258 int cert_svc_util_load_file_to_buffer(const char* filePath, cert_svc_mem_buff* certBuf)
260 int ret = CERT_SVC_ERR_NO_ERROR;
261 // open file and get content
263 unsigned char* content = NULL;
264 unsigned long int fileSize = 0;
267 if((ret = cert_svc_util_get_file_size(filePath, &fileSize)) != CERT_SVC_ERR_NO_ERROR) {
268 SLOGE("[ERR][%s] Fail to get file size, [%s]", __func__, filePath);
271 certBuf->size = fileSize;
273 /* open file and write to buffer */
274 if(!(fp_in = fopen(filePath, "rb"))) {
275 SLOGE("[ERR][%s] Fail to open file, [%s]", __func__, filePath);
276 ret = CERT_SVC_ERR_FILE_IO;
280 if(!(content = (unsigned char*)malloc(sizeof(unsigned char) * (unsigned int)(fileSize + 1)))) {
281 SLOGE("[ERR][%s] Fail to allocate memory.", __func__);
282 ret = CERT_SVC_ERR_MEMORY_ALLOCATION;
285 memset(content, 0x00, (fileSize + 1)); //ensuring that content[] will be NULL terminated
286 if(fread(content, sizeof(unsigned char), fileSize, fp_in) != fileSize) {
287 SLOGE("[ERR][%s] Fail to read file, [%s]", __func__, filePath);
288 ret = CERT_SVC_ERR_FILE_IO;
291 content[fileSize] = 0; // insert null on the end to make null-terminated string
293 /* find out certificate type */
294 memset(certBuf->type, 0x00, 4);
295 if (cert_svc_util_get_extension(filePath, certBuf) != CERT_SVC_ERR_NO_ERROR) {
296 SLOGE("[ERR] cert_svc_util_get_extension failed to identify %s", filePath);
297 ret = CERT_SVC_ERR_FILE_IO;
301 /* load file into buffer */
302 if(!strncmp(certBuf->type, "PEM", sizeof(certBuf->type))) { // PEM format
303 if((ret = get_content_into_buf_PEM(content, certBuf)) != CERT_SVC_ERR_NO_ERROR) {
304 SLOGE("[ERR][%s] Fail to load file to buffer, [%s]", __func__, filePath);
308 else if(!strncmp(certBuf->type, "DER", sizeof(certBuf->type))) { // DER format
309 if((ret = get_content_into_buf_DER(content, certBuf)) != CERT_SVC_ERR_NO_ERROR) {
310 SLOGE("[ERR][%s] Fail to load file to buffer, [%s]", __func__, filePath);
325 int release_certificate_buf(cert_svc_mem_buff* certBuf)
327 int ret = CERT_SVC_ERR_NO_ERROR;
332 if(certBuf->data != NULL) {
334 certBuf->data = NULL;
342 int release_certificate_data(cert_svc_cert_descriptor* certDesc)
344 int ret = CERT_SVC_ERR_NO_ERROR;
350 /* parse cert descriptor information fields */
351 if(certDesc->info.sigAlgo != NULL) free(certDesc->info.sigAlgo);
352 if(certDesc->info.issuerStr != NULL) free(certDesc->info.issuerStr);
353 if(certDesc->info.issuer.countryName != NULL) free(certDesc->info.issuer.countryName);
354 if(certDesc->info.issuer.localityName != NULL) free(certDesc->info.issuer.localityName);
355 if(certDesc->info.issuer.stateOrProvinceName != NULL) free(certDesc->info.issuer.stateOrProvinceName);
356 if(certDesc->info.issuer.organizationName != NULL) free(certDesc->info.issuer.organizationName);
357 if(certDesc->info.issuer.organizationUnitName != NULL) free(certDesc->info.issuer.organizationUnitName);
358 if(certDesc->info.issuer.commonName != NULL) free(certDesc->info.issuer.commonName);
359 if(certDesc->info.issuer.emailAddress != NULL) free(certDesc->info.issuer.emailAddress);
360 if(certDesc->info.subjectStr != NULL) free(certDesc->info.subjectStr);
361 if(certDesc->info.subject.countryName != NULL) free(certDesc->info.subject.countryName);
362 if(certDesc->info.subject.localityName != NULL) free(certDesc->info.subject.localityName);
363 if(certDesc->info.subject.stateOrProvinceName != NULL) free(certDesc->info.subject.stateOrProvinceName);
364 if(certDesc->info.subject.organizationName != NULL) free(certDesc->info.subject.organizationName);
365 if(certDesc->info.subject.organizationUnitName != NULL) free(certDesc->info.subject.organizationUnitName);
366 if(certDesc->info.subject.commonName != NULL) free(certDesc->info.subject.commonName);
367 if(certDesc->info.subject.emailAddress != NULL) free(certDesc->info.subject.emailAddress);
368 if(certDesc->info.pubKeyAlgo != NULL) free(certDesc->info.pubKeyAlgo);
369 if(certDesc->info.pubKey != NULL) free(certDesc->info.pubKey);
370 if(certDesc->info.issuerUID != NULL) free(certDesc->info.issuerUID);
371 if(certDesc->info.subjectUID != NULL) free(certDesc->info.subjectUID);
373 /* parse cert descriptor extension fields */
374 if(certDesc->ext.numOfFields > 0) {
375 for(i = 0; i < (int)certDesc->ext.numOfFields; i++) {
376 if(certDesc->ext.fields[i].name != NULL) free(certDesc->ext.fields[i].name);
377 if(certDesc->ext.fields[i].data != NULL) free(certDesc->ext.fields[i].data);
379 if(certDesc->ext.fields != NULL) free(certDesc->ext.fields);
382 /* parse signature */
383 if(certDesc->signatureAlgo != NULL) free(certDesc->signatureAlgo);
384 if(certDesc->signatureData != NULL) free(certDesc->signatureData);
386 if(certDesc != NULL) free(certDesc);
391 int release_cert_list(cert_svc_linked_list* certList)
393 int ret = CERT_SVC_ERR_NO_ERROR;
394 cert_svc_linked_list* startCert = NULL;
395 cert_svc_linked_list* curCert = NULL;
400 startCert = certList;
404 startCert = startCert->next;
406 if(curCert->certificate != NULL) {
407 if(curCert->certificate->data != NULL) {
408 free(curCert->certificate->data);
409 curCert->certificate->data = NULL;
411 free(curCert->certificate);
412 curCert->certificate = NULL;
415 curCert->next = NULL;
417 if(curCert != NULL) {
422 if(startCert == NULL)
429 int release_filename_list(cert_svc_filename_list* fileNames)
431 int ret = CERT_SVC_ERR_NO_ERROR;
432 cert_svc_filename_list* startList = NULL;
433 cert_svc_filename_list* curList = NULL;
435 if(fileNames == NULL)
438 startList = fileNames;
442 startList = startList->next;
444 if(curList->filename != NULL) {
445 free(curList->filename);
446 curList->filename = NULL;
448 curList->next = NULL;
449 if(curList != NULL) {
454 if(startList == NULL)