Merge tizen_5.0 codes into tizen_4.0
[platform/upstream/iotivity.git] / resource / csdk / security / src / pkix_interface.c
1 /* *****************************************************************
2  *
3  * Copyright 2016 Samsung Electronics All Rights Reserved.
4  *
5  *
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 "pkix_interface.h"
22 #include "credresource.h"
23 #include "crlresource.h"
24 #include "srmresourcestrings.h"
25 #include "casecurityinterface.h"
26 #include "logger.h"
27 #include "base64.h"
28 #include "oic_malloc.h"
29
30 #define PEM_BEGIN_CRT "-----BEGIN CERTIFICATE-----"
31 #define PEM_END_CRT "-----END CERTIFICATE-----"
32
33 #define TAG "OIC_SRM_PKIX_INTERFACE"
34
35 #define ECC256_SIG_LEN 32+4
36
37 static HWPkixContext_t gHwPkixCtx = {
38     .getHwKeyContext = NULL,
39     .freeHwKeyContext = NULL,
40     .getOwnCertCb = NULL,
41     .setupPkContextCb = NULL,
42     .hwKeyCtx = NULL
43 };
44
45 /*
46  * returns the number of removed zeros
47  */
48 static size_t remove_useless_leading_zeros(uint8_t *asn_integer_buf, uint32_t size)
49 {
50     /*
51     */
52     uint8_t buf[32 + 4];
53     uint8_t tag = asn_integer_buf[0];
54     uint8_t len = asn_integer_buf[1];
55     uint8_t *p = asn_integer_buf + 2;
56     uint32_t idx = 0;
57
58     if (size < 2)
59     {
60         return 0;
61     }
62
63     if (tag != MBEDTLS_ASN1_INTEGER)
64     {
65         return 0;
66     }
67
68     if ((uint32_t)len + 2 != size || sizeof(buf) < size)
69     {
70         return 0;
71     }
72
73     for (idx = 0; idx < (uint32_t)len - 1; idx++)
74     {
75         if (p[idx] != 0)
76         {
77             break;
78         }
79         if (p[idx] == 0 && ((p[idx + 1] & 0x80) != 0)) // 00000000 1XXXXXXXX (bit)
80         {
81             break;
82         }
83     }
84
85     if (idx == 0)
86     {
87         return 0;
88     }
89
90     len -= idx;
91     asn_integer_buf[1] = len;
92
93     memcpy(buf, p + idx, len);
94     memcpy(p, buf, len);
95
96     return idx;
97 }
98
99 void CheckInvalidDERSignature(uint8_t *crtBuf, size_t *crtBufLen)
100 {
101     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
102     if (NULL == crtBuf)
103     {
104         OIC_LOG(ERROR, TAG, "Param buf is NULL");
105         return;
106     }
107     if (NULL == crtBufLen)
108     {
109         OIC_LOG(ERROR, TAG, "Param bufLen is NULL");
110         return;
111     }
112
113     OIC_LOG_V(INFO, TAG, "Cert Buf Length: %zu", *crtBufLen);
114     OIC_LOG(INFO, TAG, "[Cert Buf] : ");
115     OIC_LOG_BUFFER(INFO, TAG, crtBuf, *crtBufLen);
116
117     mbedtls_x509_crt deviceCert;
118     mbedtls_x509_crt_init(&deviceCert);
119     int ret = 0;
120
121     uint8_t *derCrtBuf = NULL;
122     size_t *derCrtBufLen = NULL;
123
124     uint8_t *derCrtBufTmp = NULL;
125     size_t derCrtBufLenTmp = 0;
126
127     // check only first(i.e., device) certificate
128     if (crtBuf[0] == 0x30 && crtBuf[1] == 0x82)
129     {
130         derCrtBuf = crtBuf;
131         derCrtBufLen = crtBufLen;
132     }
133     else
134     {
135         uint8_t * begin = (uint8_t *)memmem(crtBuf, *crtBufLen,
136                                             PEM_BEGIN_CRT, sizeof(PEM_BEGIN_CRT) - 1);
137         if (NULL != begin)
138         {
139             uint8_t * end = (uint8_t *)memmem(crtBuf, *crtBufLen,
140                                               PEM_END_CRT, sizeof(PEM_END_CRT) - 1);
141             if (NULL != end)
142             {
143                 uint32_t idx = 0;
144                 uint32_t count = 0;
145                 uint32_t decodedLen = 0;
146                 begin += sizeof(PEM_BEGIN_CRT) - 1;
147                 size_t certLen = (size_t)(end - begin);
148                 size_t outBufSize = B64DECODE_OUT_SAFESIZE(certLen + 1);
149
150                 uint8_t * certCopy = (uint8_t *)OICCalloc(certLen, 1);
151                 if(NULL == certCopy)
152                 {
153                     OIC_LOG (ERROR, TAG, "Failed to allocate memory.");
154                     goto exit;
155                 }
156                 for (idx = 0; idx < certLen; idx++)
157                 {
158                     if (begin[idx] != '\r' && begin[idx] != '\n')
159                     {
160                         certCopy[count] = begin[idx];
161                         count++;
162                     }
163                 }
164                 certLen = count;
165
166                 derCrtBufTmp = (uint8_t *)OICCalloc(outBufSize, 1);
167                 if(NULL == derCrtBufTmp)
168                 {
169                     OIC_LOG (ERROR, TAG, "Failed to allocate memory.");
170                     OICFree(certCopy);
171                     goto exit;
172                 }
173
174                 if (B64_OK != b64Decode((char *)certCopy, certLen, derCrtBufTmp, outBufSize, &decodedLen))
175                 {
176                     OICFree(certCopy);
177                     goto exit;
178                 }
179                 OICFree(certCopy);
180
181                 derCrtBuf = derCrtBufTmp;
182                 derCrtBufLenTmp = decodedLen;
183                 derCrtBufLen = &derCrtBufLenTmp;
184             }
185         }
186         else
187         {
188             goto exit;
189         }
190     }
191
192     if (NULL != derCrtBuf && NULL != derCrtBufLen && 0 != *derCrtBufLen)
193     {
194         uint8_t *sign_ptr = NULL;
195         /**
196         * structure of r_buf & s_buf
197         * +---------------+-------------+----------------------------+
198         * | tag (INTEGER) | length (1B) | value (r or s in integer)  |
199         * +---------------+-------------+----------------------------+
200         */
201         uint8_t r_buf[ECC256_SIG_LEN]; // for ECC 256 sign
202         uint8_t s_buf[ECC256_SIG_LEN];
203         uint32_t r_len = 0;
204         uint32_t s_len = 0;
205         size_t sign_len = 0;
206         uint32_t removed = 0;
207         uint32_t removed_total = 0;
208         size_t org_len = 0;
209
210         unsigned char * tmp = (unsigned char *)derCrtBuf + 1;
211         if ( 0 != mbedtls_asn1_get_len(&tmp, derCrtBuf + *derCrtBufLen, &org_len))
212         {
213             OIC_LOG(ERROR, TAG, "Invalid parsed length");
214             goto exit;
215         }
216
217         if (org_len < *derCrtBufLen)
218         {
219             ret = mbedtls_x509_crt_parse_der(&deviceCert, derCrtBuf, org_len + 4);
220             if (0 != ret)
221             {
222                 OIC_LOG_V(ERROR, TAG, "mbedtls_x509_crt_parse_der returned -0x%04x", -(ret));
223                 goto exit;
224             }
225
226             if (NULL == deviceCert.sig.p)
227             {
228                 OIC_LOG(ERROR, TAG, "Cert's signature is NULL");
229                 goto exit;
230             }
231             sign_ptr = (uint8_t*)deviceCert.sig.p;
232             ret = mbedtls_asn1_get_tag(&sign_ptr, deviceCert.sig.p + deviceCert.sig.len, &sign_len,
233                 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
234             if (0 != ret)
235             {
236                 OIC_LOG_V(ERROR, TAG, "mbedtls_asn1_get_tag error : %d", ret);
237                 goto exit;
238             }
239             if (sign_ptr)
240             {
241                 r_len = sign_ptr[1] + 2; // including header itself
242             }
243             if (r_len > deviceCert.sig.len || r_len > ECC256_SIG_LEN)
244             {
245                 OIC_LOG_V(ERROR, TAG, "signature length check error #1 : %d", ret);
246                 goto exit;
247             }
248             OIC_LOG_V(DEBUG, TAG, "r_len = %d", r_len);
249             memcpy(r_buf, sign_ptr, r_len);
250             removed = remove_useless_leading_zeros(r_buf, r_len);
251
252             /* Do not change order */
253             sign_ptr += r_len;
254             r_len -= removed;
255             removed_total += removed;
256             if (sign_ptr)
257             {
258                 s_len = sign_ptr[1] + 2; // including header itself
259             }
260             if (s_len + r_len > deviceCert.sig.len || s_len > ECC256_SIG_LEN)
261             {
262                 OIC_LOG_V(ERROR, TAG, "signature length check error #2 : %d", ret);
263                 goto exit;
264             }
265             OIC_LOG_V(DEBUG, TAG, "s_len = %d", s_len);
266             memcpy(s_buf, sign_ptr, s_len);
267             removed = remove_useless_leading_zeros(s_buf, s_len);
268             s_len -= removed;
269             removed_total += removed;
270
271             if (removed_total > 0)
272             {
273                 // if length of signature is incorrect.
274                 OIC_LOG_V(INFO, TAG, "Cert Length (Before) : %zu", *derCrtBufLen);
275                 OIC_LOG(INFO, TAG, "Invalid length of signature is dectected.");
276                 OIC_LOG(INFO, TAG, "Update signature...");
277
278                 uint16_t crt_len = 0;
279                 /* change bitstring length */
280                 {
281                     uint8_t *sign_len_ptr = deviceCert.sig.p + 1;
282                     *sign_len_ptr -= removed_total;
283                 }
284                 /* change signature length */
285                 {
286                     uint8_t *sign_len_ptr = deviceCert.sig.p - 1;
287                     if (*sign_len_ptr == 0)
288                     {
289                         sign_len_ptr--;
290                     }
291                     *sign_len_ptr -= removed_total;
292                 }
293                 /* change signature */
294                 {
295                     memcpy(deviceCert.sig.p + 2, r_buf, r_len);
296                     memcpy(deviceCert.sig.p + 2 + r_len, s_buf, s_len);
297                 }
298                 /* change certificate length */
299                 {
300                     uint8_t *crt_len_ptr = deviceCert.raw.p + 2;
301                     crt_len = (crt_len_ptr[0] << 8) & 0x0000FF00;
302                     crt_len |= (crt_len_ptr[1] & 0x000000FF);
303                     crt_len -= removed_total;
304                     crt_len_ptr[0] = (uint8_t)(crt_len >> 8);
305                     crt_len_ptr[1] = (uint8_t)(crt_len);
306                 }
307                 crt_len += 4; // include header and length field
308                 /* change raw data and crt parse cert again */
309                 {
310                     mbedtls_x509_crt crt_cpy;
311                     mbedtls_x509_crt_init( &crt_cpy );
312                     if ((ret = mbedtls_x509_crt_parse_der(&crt_cpy, deviceCert.raw.p, (size_t)crt_len)) != 0)
313                     {
314                         OIC_LOG_V(ERROR, TAG, "mbedtls_x509_crt_parse error : %d", ret);
315                         mbedtls_x509_crt_free(&crt_cpy);
316                         goto exit;
317                     }
318
319                     org_len += 4; // include header and length field
320                     size_t remained_len = (*derCrtBufLen - org_len);
321                     memcpy(derCrtBuf, deviceCert.raw.p, crt_len);
322                     memcpy(derCrtBuf + crt_len, derCrtBuf + org_len, remained_len);
323                     *derCrtBufLen = (size_t)crt_len + remained_len;
324
325                     mbedtls_x509_crt_free(&crt_cpy);
326                     OIC_LOG_V(INFO, TAG, "Dev cert : %zu -> %u", org_len, crt_len);
327                     OIC_LOG_V(INFO, TAG, "Remained chain : %zu", remained_len);
328                     OIC_LOG_V(INFO, TAG, "Cert Length (After) : %zu", *crtBufLen);
329                 }
330             }
331             else
332             {
333                 // if length of signature is correct.
334                 OIC_LOG(INFO, TAG, "Don't need to update signature...");
335             }
336
337         }
338     }
339     else
340     {
341         OIC_LOG(ERROR, TAG, "PEM or invalid cert format detected. finish to check");
342     }
343
344 exit:
345     mbedtls_x509_crt_free(&deviceCert);
346     OICFree(derCrtBufTmp);
347     OIC_LOG_V(DEBUG, TAG, "Cert chain length = %u", *crtBufLen);
348     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
349 }
350
351 /**
352  * Internal API to load the key/cert from HW PKI
353  *
354  * @return true on HW PKI is available
355  */
356 static bool GetPkixInfoFromHw(PkiInfo_t * inf)
357 {
358     OIC_LOG_V(INFO, TAG, "In %s", __func__);
359
360     if (!gHwPkixCtx.hwKeyCtx && gHwPkixCtx.getHwKeyContext)
361     {
362         gHwPkixCtx.hwKeyCtx = gHwPkixCtx.getHwKeyContext(
363                                                         HWKEY_SVC_IOTIVITY,
364                                                         HWKEY_USAGE_PRIMARY, NULL);
365         if (!gHwPkixCtx.hwKeyCtx)
366         {
367             OIC_LOG(WARNING, TAG, "gHwPkixCtx.getHwKeyContext return null");
368         }
369     }
370
371     if (gHwPkixCtx.hwKeyCtx && gHwPkixCtx.getOwnCertCb)
372     {
373         int ret = gHwPkixCtx.getOwnCertCb(gHwPkixCtx.hwKeyCtx, &inf->crt.data, &inf->crt.len);
374         if (0 != ret)
375         {
376             OIC_LOG_V(ERROR, TAG, "gHwPkixCtx.getOwnCertCb error : %d", ret);
377             OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
378             return false;
379         }
380
381         // check and fix invalid cert signature
382         CheckInvalidDERSignature(inf->crt.data, &inf->crt.len);
383
384         OIC_LOG_V(INFO, TAG, "Cert chain length = %u", inf->crt.len);
385         OIC_LOG_V(INFO, TAG, "Out %s", __func__);
386         return true;
387     }
388     OIC_LOG_V(INFO, TAG, "Out %s", __func__);
389     return false;
390 }
391
392 void GetPkixInfo(PkiInfo_t * inf)
393 {
394     OIC_LOG_V(INFO, TAG, "In %s", __func__);
395     if (NULL == inf)
396     {
397         OIC_LOG(ERROR, TAG, "NULL passed");
398         OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
399         return;
400     }
401
402     if (GetPkixInfoFromHw(inf))
403     {
404         OIC_LOG(INFO, TAG, "H/W based PKI will be used.");
405     }
406     else
407     {
408         GetDerOwnCert(&inf->crt, PRIMARY_CERT);
409         GetDerKey(&inf->key, PRIMARY_CERT);
410     }
411     GetDerCaCert(&inf->ca, TRUST_CA);
412     GetDerCrl(&inf->crl);
413
414     OIC_LOG_V(INFO, TAG, "Out %s", __func__);
415 }
416
417 void GetManufacturerPkixInfo(PkiInfo_t * inf)
418 {
419     OIC_LOG_V(INFO, TAG, "In %s", __func__);
420     if (NULL == inf)
421     {
422         OIC_LOG(ERROR, TAG, "NULL passed");
423         OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
424         return;
425     }
426
427     if (GetPkixInfoFromHw(inf))
428     {
429         OIC_LOG(INFO, TAG, "H/W based PKI will be used.");
430     }
431     else
432     {
433         GetDerOwnCert(&inf->crt, MF_PRIMARY_CERT);
434         GetDerKey(&inf->key, MF_PRIMARY_CERT);
435     }
436     GetDerCaCert(&inf->ca, MF_TRUST_CA);
437     // CRL not provided
438 #ifdef __TIZENRT__
439     OICFree(inf->crl.data);
440 #endif
441     inf->crl.data = NULL;
442     inf->crl.len = 0;
443     OIC_LOG_V(INFO, TAG, "Out %s", __func__);
444 }
445
446 void InitCipherSuiteList(bool * list)
447 {
448     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
449     if (NULL == list)
450     {
451         OIC_LOG(ERROR, TAG, "NULL passed");
452         OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
453         return;
454     }
455     InitCipherSuiteListInternal(list, TRUST_CA);
456     if (gHwPkixCtx.getOwnCertCb)
457     {
458         list[1] = true;
459     }
460     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
461 }
462
463 void InitManufacturerCipherSuiteList(bool * list)
464 {
465     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
466     if (NULL == list)
467     {
468         OIC_LOG(ERROR, TAG, "NULL passed");
469         OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
470         return;
471     }
472     InitCipherSuiteListInternal(list, MF_TRUST_CA);
473     if (gHwPkixCtx.getOwnCertCb)
474     {
475         list[1] = true;
476     }
477     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
478 }
479
480 int SetupHwPkContext(mbedtls_pk_context* pkCtx)
481 {
482     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
483     if (NULL == pkCtx)
484     {
485         OIC_LOG(ERROR, TAG, "NULL passed");
486         OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
487         return -1;
488     }
489
490     if (gHwPkixCtx.setupPkContextCb)
491     {
492         OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
493         return gHwPkixCtx.setupPkContextCb(pkCtx, gHwPkixCtx.hwKeyCtx);
494     }
495     else
496     {
497         OIC_LOG(ERROR, TAG, "gHwPkixCallbacks.setupPkContextCb is NULL");
498     }
499
500     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
501
502     return -1;
503 }
504
505 int SetHwPkixCallbacks(GetHwKeyContext getHwKeyContext,
506                         FreeHwKeyContext freeHwKeyContext,
507                         GetOwnCertFromHwCallback getOwnCertCb,
508                         SetupPkContextFromHwCallback setupPkContextCb)
509 {
510     OIC_LOG_V(INFO, TAG, "In %s", __func__);
511
512     if (NULL == getHwKeyContext && NULL == freeHwKeyContext
513         && NULL == getOwnCertCb && NULL == setupPkContextCb)
514     {
515         OIC_LOG(INFO, TAG, "Unregistering callbacks");
516     }
517     else if (NULL == getHwKeyContext || NULL == freeHwKeyContext
518              || NULL == getOwnCertCb || NULL == setupPkContextCb)
519     {
520         OIC_LOG(ERROR, TAG, "NULL Passed");
521         OIC_LOG(ERROR, TAG, "Callback function parameters can not be null");
522         return -1;
523     }
524
525     gHwPkixCtx.getHwKeyContext = getHwKeyContext;
526     gHwPkixCtx.freeHwKeyContext = freeHwKeyContext;
527     gHwPkixCtx.getOwnCertCb = getOwnCertCb;
528     gHwPkixCtx.setupPkContextCb = setupPkContextCb;
529
530     if (gHwPkixCtx.hwKeyCtx && NULL != freeHwKeyContext)
531     {
532         gHwPkixCtx.freeHwKeyContext(gHwPkixCtx.hwKeyCtx);
533     }
534     gHwPkixCtx.hwKeyCtx = NULL;
535
536     // setup pkcontext handler
537     CAregisterSetupPkContextHandler(SetupHwPkContext);
538
539     OIC_LOG_V(INFO, TAG, "Out %s", __func__);
540     return 0;
541 }
542