1 /* *****************************************************************
3 * Copyright 2016 Samsung Electronics All Rights Reserved.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 * *****************************************************************/
21 #include "pkix_interface.h"
22 #include "credresource.h"
23 #include "crlresource.h"
24 #include "srmresourcestrings.h"
25 #include "casecurityinterface.h"
28 #include "oic_malloc.h"
30 #define PEM_BEGIN_CRT "-----BEGIN CERTIFICATE-----"
31 #define PEM_END_CRT "-----END CERTIFICATE-----"
33 #define TAG "OIC_SRM_PKIX_INTERFACE"
35 #define ECC256_SIG_LEN 32+4
37 static HWPkixContext_t gHwPkixCtx = {
38 .getHwKeyContext = NULL,
39 .freeHwKeyContext = NULL,
41 .setupPkContextCb = NULL,
46 * returns the number of removed zeros
48 static size_t remove_useless_leading_zeros(uint8_t *asn_integer_buf, uint32_t size)
53 uint8_t tag = asn_integer_buf[0];
54 uint8_t len = asn_integer_buf[1];
55 uint8_t *p = asn_integer_buf + 2;
63 if (tag != MBEDTLS_ASN1_INTEGER)
68 if ((uint32_t)len + 2 != size || sizeof(buf) < size)
73 for (idx = 0; idx < (uint32_t)len - 1; idx++)
79 if (p[idx] == 0 && ((p[idx + 1] & 0x80) != 0)) // 00000000 1XXXXXXXX (bit)
91 asn_integer_buf[1] = len;
93 memcpy(buf, p + idx, len);
99 void CheckInvalidDERSignature(uint8_t *crtBuf, size_t *crtBufLen)
101 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
104 OIC_LOG(ERROR, TAG, "Param buf is NULL");
107 if (NULL == crtBufLen)
109 OIC_LOG(ERROR, TAG, "Param bufLen is NULL");
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);
117 mbedtls_x509_crt deviceCert;
118 mbedtls_x509_crt_init(&deviceCert);
121 uint8_t *derCrtBuf = NULL;
122 size_t *derCrtBufLen = NULL;
124 uint8_t *derCrtBufTmp = NULL;
125 size_t derCrtBufLenTmp = 0;
127 // check only first(i.e., device) certificate
128 if (crtBuf[0] == 0x30 && crtBuf[1] == 0x82)
131 derCrtBufLen = crtBufLen;
135 uint8_t * begin = (uint8_t *)memmem(crtBuf, *crtBufLen,
136 PEM_BEGIN_CRT, sizeof(PEM_BEGIN_CRT) - 1);
139 uint8_t * end = (uint8_t *)memmem(crtBuf, *crtBufLen,
140 PEM_END_CRT, sizeof(PEM_END_CRT) - 1);
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);
150 uint8_t * certCopy = (uint8_t *)OICCalloc(certLen, 1);
153 OIC_LOG (ERROR, TAG, "Failed to allocate memory.");
156 for (idx = 0; idx < certLen; idx++)
158 if (begin[idx] != '\r' && begin[idx] != '\n')
160 certCopy[count] = begin[idx];
166 derCrtBufTmp = (uint8_t *)OICCalloc(outBufSize, 1);
167 if(NULL == derCrtBufTmp)
169 OIC_LOG (ERROR, TAG, "Failed to allocate memory.");
174 if (B64_OK != b64Decode((char *)certCopy, certLen, derCrtBufTmp, outBufSize, &decodedLen))
181 derCrtBuf = derCrtBufTmp;
182 derCrtBufLenTmp = decodedLen;
183 derCrtBufLen = &derCrtBufLenTmp;
192 if (NULL != derCrtBuf && NULL != derCrtBufLen && 0 != *derCrtBufLen)
194 uint8_t *sign_ptr = NULL;
196 * structure of r_buf & s_buf
197 * +---------------+-------------+----------------------------+
198 * | tag (INTEGER) | length (1B) | value (r or s in integer) |
199 * +---------------+-------------+----------------------------+
201 uint8_t r_buf[ECC256_SIG_LEN]; // for ECC 256 sign
202 uint8_t s_buf[ECC256_SIG_LEN];
206 uint32_t removed = 0;
207 uint32_t removed_total = 0;
210 unsigned char * tmp = (unsigned char *)derCrtBuf + 1;
211 if ( 0 != mbedtls_asn1_get_len(&tmp, derCrtBuf + *derCrtBufLen, &org_len))
213 OIC_LOG(ERROR, TAG, "Invalid parsed length");
217 if (org_len < *derCrtBufLen)
219 ret = mbedtls_x509_crt_parse_der(&deviceCert, derCrtBuf, org_len + 4);
222 OIC_LOG_V(ERROR, TAG, "mbedtls_x509_crt_parse_der returned -0x%04x", -(ret));
226 if (NULL == deviceCert.sig.p)
228 OIC_LOG(ERROR, TAG, "Cert's signature is NULL");
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);
236 OIC_LOG_V(ERROR, TAG, "mbedtls_asn1_get_tag error : %d", ret);
241 r_len = sign_ptr[1] + 2; // including header itself
243 if (r_len > deviceCert.sig.len || r_len > ECC256_SIG_LEN)
245 OIC_LOG_V(ERROR, TAG, "signature length check error #1 : %d", ret);
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);
252 /* Do not change order */
255 removed_total += removed;
258 s_len = sign_ptr[1] + 2; // including header itself
260 if (s_len + r_len > deviceCert.sig.len || s_len > ECC256_SIG_LEN)
262 OIC_LOG_V(ERROR, TAG, "signature length check error #2 : %d", ret);
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);
269 removed_total += removed;
271 if (removed_total > 0)
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...");
278 uint16_t crt_len = 0;
279 /* change bitstring length */
281 uint8_t *sign_len_ptr = deviceCert.sig.p + 1;
282 *sign_len_ptr -= removed_total;
284 /* change signature length */
286 uint8_t *sign_len_ptr = deviceCert.sig.p - 1;
287 if (*sign_len_ptr == 0)
291 *sign_len_ptr -= removed_total;
293 /* change signature */
295 memcpy(deviceCert.sig.p + 2, r_buf, r_len);
296 memcpy(deviceCert.sig.p + 2 + r_len, s_buf, s_len);
298 /* change certificate length */
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);
307 crt_len += 4; // include header and length field
308 /* change raw data and crt parse cert again */
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)
314 OIC_LOG_V(ERROR, TAG, "mbedtls_x509_crt_parse error : %d", ret);
315 mbedtls_x509_crt_free(&crt_cpy);
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;
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);
333 // if length of signature is correct.
334 OIC_LOG(INFO, TAG, "Don't need to update signature...");
341 OIC_LOG(ERROR, TAG, "PEM or invalid cert format detected. finish to check");
345 mbedtls_x509_crt_free(&deviceCert);
346 OICFree(derCrtBufTmp);
347 OIC_LOG_V(DEBUG, TAG, "Cert chain length = %zd", *crtBufLen);
348 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
352 * Internal API to load the key/cert from HW PKI
354 * @return true on HW PKI is available
356 static bool GetPkixInfoFromHw(PkiInfo_t * inf)
358 OIC_LOG_V(INFO, TAG, "In %s", __func__);
360 if (!gHwPkixCtx.hwKeyCtx && gHwPkixCtx.getHwKeyContext)
362 gHwPkixCtx.hwKeyCtx = gHwPkixCtx.getHwKeyContext(
364 HWKEY_USAGE_PRIMARY, NULL);
365 if (!gHwPkixCtx.hwKeyCtx)
367 OIC_LOG(WARNING, TAG, "gHwPkixCtx.getHwKeyContext return null");
371 if (gHwPkixCtx.hwKeyCtx && gHwPkixCtx.getOwnCertCb)
373 int ret = gHwPkixCtx.getOwnCertCb(gHwPkixCtx.hwKeyCtx, &inf->crt.data, &inf->crt.len);
376 OIC_LOG_V(ERROR, TAG, "gHwPkixCtx.getOwnCertCb error : %d", ret);
377 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
381 // check and fix invalid cert signature
382 CheckInvalidDERSignature(inf->crt.data, &inf->crt.len);
384 OIC_LOG_V(INFO, TAG, "Cert chain length = %zd", inf->crt.len);
385 OIC_LOG_V(INFO, TAG, "Out %s", __func__);
388 OIC_LOG_V(INFO, TAG, "Out %s", __func__);
392 void GetPkixInfo(PkiInfo_t * inf)
394 OIC_LOG_V(INFO, TAG, "In %s", __func__);
397 OIC_LOG(ERROR, TAG, "NULL passed");
398 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
402 if (GetPkixInfoFromHw(inf))
404 OIC_LOG(INFO, TAG, "H/W based PKI will be used.");
408 GetDerOwnCert(&inf->crt, PRIMARY_CERT);
409 GetDerKey(&inf->key, PRIMARY_CERT);
411 GetDerCaCert(&inf->ca, TRUST_CA);
412 GetDerCrl(&inf->crl);
414 OIC_LOG_V(INFO, TAG, "Out %s", __func__);
417 void GetManufacturerPkixInfo(PkiInfo_t * inf)
419 OIC_LOG_V(INFO, TAG, "In %s", __func__);
422 OIC_LOG(ERROR, TAG, "NULL passed");
423 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
427 if (GetPkixInfoFromHw(inf))
429 OIC_LOG(INFO, TAG, "H/W based PKI will be used.");
433 GetDerOwnCert(&inf->crt, MF_PRIMARY_CERT);
434 GetDerKey(&inf->key, MF_PRIMARY_CERT);
436 GetDerCaCert(&inf->ca, MF_TRUST_CA);
439 OICFree(inf->crl.data);
441 inf->crl.data = NULL;
443 OIC_LOG_V(INFO, TAG, "Out %s", __func__);
446 void InitCipherSuiteList(bool * list)
448 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
451 OIC_LOG(ERROR, TAG, "NULL passed");
452 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
455 InitCipherSuiteListInternal(list, TRUST_CA);
456 if (gHwPkixCtx.getOwnCertCb)
460 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
463 void InitManufacturerCipherSuiteList(bool * list)
465 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
468 OIC_LOG(ERROR, TAG, "NULL passed");
469 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
472 InitCipherSuiteListInternal(list, MF_TRUST_CA);
473 if (gHwPkixCtx.getOwnCertCb)
477 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
480 int SetupHwPkContext(mbedtls_pk_context* pkCtx)
482 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
485 OIC_LOG(ERROR, TAG, "NULL passed");
486 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
490 if (gHwPkixCtx.setupPkContextCb)
492 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
493 return gHwPkixCtx.setupPkContextCb(pkCtx, gHwPkixCtx.hwKeyCtx);
497 OIC_LOG(ERROR, TAG, "gHwPkixCallbacks.setupPkContextCb is NULL");
500 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
505 int SetHwPkixCallbacks(GetHwKeyContext getHwKeyContext,
506 FreeHwKeyContext freeHwKeyContext,
507 GetOwnCertFromHwCallback getOwnCertCb,
508 SetupPkContextFromHwCallback setupPkContextCb)
510 OIC_LOG_V(INFO, TAG, "In %s", __func__);
512 if (NULL == getHwKeyContext && NULL == freeHwKeyContext
513 && NULL == getOwnCertCb && NULL == setupPkContextCb)
515 OIC_LOG(INFO, TAG, "Unregistering callbacks");
517 else if (NULL == getHwKeyContext || NULL == freeHwKeyContext
518 || NULL == getOwnCertCb || NULL == setupPkContextCb)
520 OIC_LOG(ERROR, TAG, "NULL Passed");
521 OIC_LOG(ERROR, TAG, "Callback function parameters can not be null");
525 gHwPkixCtx.getHwKeyContext = getHwKeyContext;
526 gHwPkixCtx.freeHwKeyContext = freeHwKeyContext;
527 gHwPkixCtx.getOwnCertCb = getOwnCertCb;
528 gHwPkixCtx.setupPkContextCb = setupPkContextCb;
530 if (gHwPkixCtx.hwKeyCtx && NULL != freeHwKeyContext)
532 gHwPkixCtx.freeHwKeyContext(gHwPkixCtx.hwKeyCtx);
534 gHwPkixCtx.hwKeyCtx = NULL;
536 // setup pkcontext handler
537 CAregisterSetupPkContextHandler(SetupHwPkContext);
539 OIC_LOG_V(INFO, TAG, "Out %s", __func__);