Refactor SignatureValidator and reduce interface headers
[platform/core/security/cert-svc.git] / vcore / vcore / utils.c
1 #include <cert-service.h>
2 #include <cert-service-debug.h>
3 #include <cert-svc/cerror.h>
4
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <string.h>
8
9 #include "utils.h"
10
11 void _copy_field(const unsigned char *in, unsigned char **out)
12 {
13         size_t in_len = strlen((const char *)(in));
14
15         *out = (unsigned char *)malloc(sizeof(unsigned char) * (in_len + 1));
16         if (!(*out)) {
17                 LOGE("Failed to allocate memory.");
18                 return;
19         }
20         
21         memcpy(*out, in, in_len + 1);
22 }
23
24 char *get_complete_path(const char *str1, const char *str2)
25 {
26         size_t str1_len = strlen(str1);
27         char *result = NULL;
28         int as_result;
29
30         if (str1[str1_len - 1] != '/')
31                 as_result = asprintf(&result, "%s/%s", str1, str2);
32         else
33                 as_result = asprintf(&result, "%s%s", str1, str2);
34
35         if (as_result < 0)
36                 return NULL;
37
38         return result;
39 }
40
41
42 int get_common_name(const char *path, struct x509_st *x509Struct, char **commonName)
43 {
44         int result = CERTSVC_SUCCESS;
45         const unsigned char* data = NULL;
46         CERT_CONTEXT* context = NULL;
47         unsigned char *_commonName = NULL;
48         unsigned char *tmpSubjectStr = NULL;
49         cert_svc_name_fld_data *certFieldData = NULL;
50
51         if (!path && !x509Struct) {
52                 LOGE("Invalid input parameter.");
53                 return  CERTSVC_WRONG_ARGUMENT;
54         }
55
56         /* If x509Struct is empty, we need to read the certificate and construct the x509 structure */
57         if (!x509Struct) {
58                 context = cert_svc_cert_context_init();
59                 if (!context) {
60                         LOGE("Failed to allocate memory.");
61                         return CERTSVC_BAD_ALLOC;
62                 }
63
64                 result = cert_svc_load_file_to_context(context, path);
65                 if (result != CERT_SVC_ERR_NO_ERROR) {
66                         LOGE("Failed to load file into context.");
67                         result = CERTSVC_FAIL;
68                         goto err;
69                 }
70
71                 if (!context->certBuf || !context->certBuf->data) {
72                         LOGE("Empty certificate buffer.");
73                         result = CERTSVC_FAIL;
74                         goto err;
75                 }
76
77                 data = context->certBuf->data;
78                 d2i_X509(&x509Struct, &data, context->certBuf->size);
79
80                 if (!x509Struct) {
81                         LOGE("[ERR][%s] Fail to construct X509 structure.", __func__);
82                         result = CERT_SVC_ERR_INVALID_CERTIFICATE;
83                         goto err;
84                 }
85         }
86
87         /* At this point we assume that we have the x509Struct filled with information */
88         tmpSubjectStr = (unsigned char *)X509_NAME_oneline((x509Struct->cert_info->subject), NULL, 0);
89         if (!tmpSubjectStr) {
90                 LOGE("[ERR][%s] Fail to parse certificate.", __func__);
91                 result = CERTSVC_FAIL;
92                 goto err;
93         }
94
95         certFieldData = (cert_svc_name_fld_data *)malloc(sizeof(cert_svc_name_fld_data));
96         if (!certFieldData) {
97                 LOGE("Failed to allocate memory.");
98                 result = CERTSVC_BAD_ALLOC;
99                 goto err;
100         }
101
102         certFieldData->commonName = NULL;
103         certFieldData->organizationName = NULL;
104         certFieldData->organizationUnitName = NULL;
105         certFieldData->emailAddress = NULL;
106
107         result = cert_svc_util_parse_name_fld_data(tmpSubjectStr, certFieldData);
108         if (result != CERT_SVC_ERR_NO_ERROR) {
109                 LOGE("[ERR][%s] Fail to parse cert_svc_name_fld_data.", __func__);
110                 result = CERTSVC_FAIL;
111                 goto err;
112         }
113
114         result = CERTSVC_SUCCESS;
115
116         if (certFieldData->commonName)
117                 _copy_field(certFieldData->commonName, &_commonName);
118         else if (certFieldData->organizationName)
119                 _copy_field(certFieldData->organizationName, &_commonName);
120         else if (certFieldData->organizationUnitName)
121                 _copy_field(certFieldData->organizationUnitName, &_commonName);
122         else if (certFieldData->emailAddress)
123                 _copy_field(certFieldData->emailAddress, &_commonName);
124
125         if (!_commonName) {
126                 LOGE("Failed to get common name");
127                 result = CERTSVC_FAIL;
128                 goto err;
129         }
130
131         *commonName = (char *)_commonName;
132         LOGD("Success to get common name for title. commonname[%s]", *commonName);
133
134 err:
135         if (x509Struct)
136                 X509_free(x509Struct);
137
138         if (context)
139                 cert_svc_cert_context_final(context);
140
141         if (tmpSubjectStr)
142                 OPENSSL_free(tmpSubjectStr);
143
144         if (certFieldData) {
145                 free(certFieldData->countryName);
146                 free(certFieldData->localityName);
147                 free(certFieldData->stateOrProvinceName);
148                 free(certFieldData->organizationName);
149                 free(certFieldData->organizationUnitName);
150                 free(certFieldData->commonName);
151                 free(certFieldData->emailAddress);
152                 free(certFieldData);
153         }
154
155         return result;
156 }