Fix minor defects
[platform/core/security/cert-svc.git] / vcore / orig / cert-service-util.c
1 /*
2  * certification service
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd All Rights Reserved
5  *
6  * Contact: Kidong Kim <kd0228.kim@samsung.com>
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 #include <string.h>
23 #include <stdlib.h>
24
25 #include <openssl/pkcs12.h>
26 #include <openssl/pem.h>
27 #include <libxml/parser.h>
28 #include <libxml/tree.h>
29
30 #include "orig/cert-service.h"
31 #include "orig/cert-service-util.h"
32 #include "orig/cert-service-debug.h"
33
34
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-----"
39
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
57 };
58
59 static int cert_svc_util_base64_decode(const unsigned char *in, int inLen, unsigned char *out, int* outLen)
60 {
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];
65
66         if((in == NULL) || (inLen < 1)) {
67                 SLOGE("[ERR][%s] Check your parameter.", __func__);
68                 ret = CERT_SVC_ERR_INVALID_PARAMETER;
69                 goto err;
70         }
71
72         cur = in;
73         inputLen = inLen;
74         memset(tmpBuf, 0x00, 4);
75
76         /* decode data */
77         while(inputLen > 1) {
78                 for(j = 0; j < 4; j++) {
79                         if(cur[j] == '=') {
80                                 tail++;
81                                 tmpBuf[j] = 0x00;
82                         }
83                         else
84                                 tmpBuf[j] = (unsigned char)base64DecodeTable[(int)cur[j]];
85                 }
86
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);
90
91                 cur += 4;
92                 inputLen -= 4;
93
94                 memset(tmpBuf, 0x00, 4);
95         }
96
97         i -= tail;
98         out[i] = '\0';
99         (*outLen) = i;
100
101 err:
102         return ret;
103 }
104
105 static int cert_svc_util_get_file_size(const char* filepath, unsigned long int* length)
106 {
107         int ret = CERT_SVC_ERR_NO_ERROR;
108         FILE* fp_in = NULL;
109
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;
113                 goto err;
114         }
115
116         fseek(fp_in, 0L, SEEK_END);
117         (*length) = ftell(fp_in);
118
119 err:
120         if(fp_in != NULL)
121                 fclose(fp_in);
122
123         return ret;
124 }
125
126 int get_content_into_buf_PEM(unsigned char* content, cert_svc_mem_buff* cert)
127 {
128         int ret = CERT_SVC_ERR_NO_ERROR;
129         char *startPEM, *endPEM;
130         unsigned char* original = NULL;
131         long size = 0;
132         unsigned char* decoded = NULL;
133         int decodedSize = 0;
134         int i = 0, j = 0;
135
136         if(!content) {
137                 ret = CERT_SVC_ERR_INVALID_PARAMETER;
138                 goto err;
139         }
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);
147         }
148         if(!startPEM || !endPEM) {
149                 ret = CERT_SVC_ERR_UNKNOWN_ERROR;
150                 goto err;
151         }
152         else {
153                 ++startPEM;
154                 --endPEM;
155                 size = (long)endPEM - (long)startPEM;
156         }
157
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;
161                 goto err;
162         }
163         memset(original, 0x00, (size + 1));
164
165         for(i = 0, j = 0; i < size; i++) {
166                 if(startPEM[i] != '\n')
167                         original[j++] = startPEM[i];
168         }
169
170         size = strlen((char *)original);
171         decodedSize = ((size / 4) * 3) + 1;
172
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;
176                 goto err;
177         }
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__);
181                 free(decoded);
182                 ret = CERT_SVC_ERR_INVALID_OPERATION;
183                 goto err;
184         }
185
186         cert->data = decoded;
187         cert->size = decodedSize;
188
189 err:
190     free(original);
191
192         return ret;
193 }
194
195 int get_content_into_buf_DER(unsigned char* content, cert_svc_mem_buff* cert)
196 {
197         int ret = CERT_SVC_ERR_NO_ERROR;
198         unsigned char* certData = NULL;
199
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;
204                 goto err;
205         }
206
207         memcpy(certData, content, cert->size);
208         cert->data = certData;
209
210 err:
211         return ret;
212 }
213
214
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;
218     FILE *in = NULL;
219     X509 *x = NULL;
220
221     if ((in = fopen(filePath, "r")) == NULL) {
222         SLOGE("[ERR] Error opening file %s", filePath);
223         ret = CERT_SVC_ERR_FILE_IO;
224         goto end;
225     }
226
227     if ((x = PEM_read_X509(in, NULL, NULL, NULL)) != NULL) {
228         strncpy(certBuf->type, "PEM", sizeof(certBuf->type));
229         goto end;
230     }
231
232     fseek(in, 0L, SEEK_SET);
233
234     if ((x = PEM_read_X509_AUX(in, NULL, NULL, NULL)) != NULL) {
235         strncpy(certBuf->type, "PEM", sizeof(certBuf->type));
236         goto end;
237     }
238
239     fseek(in, 0L, SEEK_SET);
240
241     if ((x = d2i_X509_fp(in, NULL)) != NULL) {
242         strncpy(certBuf->type, "DER", sizeof(certBuf->type));
243         goto end;
244     }
245
246     SLOGE("[ERR] Unknown file type: %s", filePath);
247     ret = CERT_SVC_ERR_FILE_IO;
248
249 end:
250     if (in && fclose(in)) {
251         SLOGE("[ERR] Fail in fclose.");
252         ret = CERT_SVC_ERR_FILE_IO;
253     }
254     X509_free(x);
255     return ret;
256 }
257
258 int cert_svc_util_load_file_to_buffer(const char* filePath, cert_svc_mem_buff* certBuf)
259 {
260         int ret = CERT_SVC_ERR_NO_ERROR;
261         // open file and get content
262         FILE* fp_in = NULL;
263         unsigned char* content = NULL;
264         unsigned long int fileSize = 0;
265
266         /* get file size */
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);
269                 goto err;
270         }
271         certBuf->size = fileSize;
272
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;
277                 goto err;
278         }
279
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;
283                 goto err;
284         }
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;
289                 goto err;
290         }
291     content[fileSize] = 0; // insert null on the end to make null-terminated string
292
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;
298         goto err;
299     }
300
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);
305                         goto err;
306                 }
307         }
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);
311                         goto err;
312                 }
313         }
314
315 err:
316         if(fp_in != NULL)
317                 fclose(fp_in);
318
319         if(content != NULL)
320                 free(content);
321
322         return ret;
323 }
324
325 int release_certificate_buf(cert_svc_mem_buff* certBuf)
326 {
327         int ret = CERT_SVC_ERR_NO_ERROR;
328
329         if(certBuf == NULL)
330                 return ret;
331
332         if(certBuf->data != NULL) {
333                 free(certBuf->data);
334                 certBuf->data = NULL;
335         }
336         free(certBuf);
337         certBuf = NULL;
338
339         return ret;
340 }
341
342 int release_certificate_data(cert_svc_cert_descriptor* certDesc)
343 {
344         int ret = CERT_SVC_ERR_NO_ERROR;
345         int i = 0;
346
347         if(certDesc == NULL)
348                 return ret;
349
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);
372
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);
378                 }
379                 if(certDesc->ext.fields != NULL) free(certDesc->ext.fields);
380         }
381
382         /* parse signature */
383         if(certDesc->signatureAlgo != NULL) free(certDesc->signatureAlgo);
384         if(certDesc->signatureData != NULL) free(certDesc->signatureData);
385
386         if(certDesc != NULL) free(certDesc);
387
388         return ret;
389 }
390
391 int release_cert_list(cert_svc_linked_list* certList)
392 {
393         int ret = CERT_SVC_ERR_NO_ERROR;
394         cert_svc_linked_list* startCert = NULL;
395         cert_svc_linked_list* curCert = NULL;
396
397         if(certList == NULL)
398                 return ret;
399
400         startCert = certList;
401
402         while(1) {
403                 curCert = startCert;
404                 startCert = startCert->next;
405
406                 if(curCert->certificate != NULL) {
407                         if(curCert->certificate->data != NULL) {
408                                 free(curCert->certificate->data);
409                                 curCert->certificate->data = NULL;
410                         }
411                         free(curCert->certificate);
412                         curCert->certificate = NULL;
413                 }
414
415                 curCert->next = NULL;
416
417                 if(curCert != NULL) {
418                         free(curCert);
419                         curCert = NULL;
420                 }
421
422                 if(startCert == NULL)
423                         break;
424         }
425
426         return ret;
427 }
428
429 int release_filename_list(cert_svc_filename_list* fileNames)
430 {
431         int ret = CERT_SVC_ERR_NO_ERROR;
432         cert_svc_filename_list* startList = NULL;
433         cert_svc_filename_list* curList = NULL;
434
435         if(fileNames == NULL)
436                 return ret;
437
438         startList = fileNames;
439
440         while(1) {
441                 curList = startList;
442                 startList = startList->next;
443
444                 if(curList->filename != NULL) {
445                         free(curList->filename);
446                         curList->filename = NULL;
447                 }
448                 curList->next = NULL;
449                 if(curList != NULL) {
450                         free(curList);
451                         curList = NULL;
452                 }
453
454                 if(startList == NULL)
455                         break;
456         }
457
458         return ret;
459 }