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 static HWPkixContext_t gHwPkixCtx = {
36 .getHwKeyContext = NULL,
37 .freeHwKeyContext = NULL,
39 .setupPkContextCb = NULL,
44 * returns the number of removed zeros
46 static size_t remove_useless_leading_zeros(uint8_t *asn_integer_buf, uint32_t size)
51 uint8_t tag = asn_integer_buf[0];
52 uint8_t len = asn_integer_buf[1];
53 uint8_t *p = asn_integer_buf + 2;
61 if (tag != MBEDTLS_ASN1_INTEGER)
66 if ((uint32_t)len + 2 != size || sizeof(buf) < size)
71 for (idx = 0; idx < (uint32_t)len - 1; idx++)
77 if (p[idx] == 0 && ((p[idx + 1] & 0x80) != 0)) // 00000000 1XXXXXXXX (bit)
89 asn_integer_buf[1] = len;
91 memcpy(buf, p + idx, len);
97 void CheckInvalidDERSignature(uint8_t *crtBuf, size_t *crtBufLen)
99 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
102 OIC_LOG(ERROR, TAG, "Param buf is NULL");
105 if (NULL == crtBufLen)
107 OIC_LOG(ERROR, TAG, "Param bufLen is NULL");
111 OIC_LOG_V(INFO, TAG, "Cert Buf Length: %lu", *crtBufLen);
112 OIC_LOG(INFO, TAG, "[Cert Buf] : ");
113 OIC_LOG_BUFFER(INFO, TAG, crtBuf, *crtBufLen);
115 mbedtls_x509_crt deviceCert;
116 mbedtls_x509_crt_init(&deviceCert);
119 uint8_t *derCrtBuf = NULL;
120 size_t *derCrtBufLen = NULL;
122 uint8_t *derCrtBufTmp = NULL;
123 size_t derCrtBufLenTmp = 0;
125 // check only first(i.e., device) certificate
126 if (crtBuf[0] == 0x30 && crtBuf[1] == 0x82)
129 derCrtBufLen = crtBufLen;
133 uint8_t * begin = (uint8_t *)memmem(crtBuf, *crtBufLen,
134 PEM_BEGIN_CRT, sizeof(PEM_BEGIN_CRT) - 1);
137 uint8_t * end = (uint8_t *)memmem(crtBuf, *crtBufLen,
138 PEM_END_CRT, sizeof(PEM_END_CRT) - 1);
143 uint32_t decodedLen = 0;
144 begin += sizeof(PEM_BEGIN_CRT) - 1;
145 size_t certLen = (size_t)(end - begin);
146 size_t outBufSize = B64DECODE_OUT_SAFESIZE(certLen + 1);
148 uint8_t * certCopy = (uint8_t *)OICCalloc(certLen, 1);
151 OIC_LOG (ERROR, TAG, "Failed to allocate memory.");
154 for (idx = 0; idx < certLen; idx++)
156 if (begin[idx] != '\r' && begin[idx] != '\n')
158 certCopy[count] = begin[idx];
164 derCrtBufTmp = (uint8_t *)OICCalloc(outBufSize, 1);
165 if(NULL == derCrtBufTmp)
167 OIC_LOG (ERROR, TAG, "Failed to allocate memory.");
171 if (B64_OK != b64Decode((char *)certCopy, certLen, derCrtBufTmp, outBufSize, &decodedLen))
178 derCrtBuf = derCrtBufTmp;
179 derCrtBufLenTmp = decodedLen;
180 derCrtBufLen = &derCrtBufLenTmp;
189 if (NULL != derCrtBuf && NULL != derCrtBufLen && 0 != *derCrtBufLen)
191 uint8_t *sign_ptr = NULL;
193 * structure of r_buf & s_buf
194 * +---------------+-------------+----------------------------+
195 * | tag (INTEGER) | length (1B) | value (r or s in integer) |
196 * +---------------+-------------+----------------------------+
198 uint8_t r_buf[32 + 4]; // for ECC 256 sign
199 uint8_t s_buf[32 + 4];
203 uint32_t removed = 0;
204 uint32_t removed_total = 0;
207 unsigned char * tmp = (unsigned char *)derCrtBuf + 1;
208 if ( 0 != mbedtls_asn1_get_len(&tmp, derCrtBuf + *derCrtBufLen, &org_len))
210 OIC_LOG(ERROR, TAG, "Invalid parsed length");
214 if (org_len < *derCrtBufLen)
216 ret = mbedtls_x509_crt_parse_der(&deviceCert, derCrtBuf, org_len + 4);
219 OIC_LOG_V(ERROR, TAG, "mbedtls_x509_crt_parse_der returned -0x%04x", -(ret));
223 if (NULL == deviceCert.sig.p)
225 OIC_LOG(ERROR, TAG, "Cert's signature is NULL");
228 sign_ptr = (uint8_t*)deviceCert.sig.p;
229 ret = mbedtls_asn1_get_tag(&sign_ptr, deviceCert.sig.p + deviceCert.sig.len, &sign_len,
230 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
233 OIC_LOG_V(ERROR, TAG, "mbedtls_asn1_get_tag error : %d", ret);
238 r_len = sign_ptr[1] + 2; // including header itself
240 if (r_len > deviceCert.sig.len)
242 OIC_LOG_V(ERROR, TAG, "signature length check error #1 : %d", ret);
245 OIC_LOG_V(DEBUG, TAG, "r_len = %d", r_len);
246 memcpy(r_buf, sign_ptr, r_len);
247 removed = remove_useless_leading_zeros(r_buf, r_len);
249 /* Do not change order */
252 removed_total += removed;
255 s_len = sign_ptr[1] + 2; // including header itself
257 if (s_len + r_len > deviceCert.sig.len)
259 OIC_LOG_V(ERROR, TAG, "signature length check error #2 : %d", ret);
262 OIC_LOG_V(DEBUG, TAG, "s_len = %d", s_len);
263 memcpy(s_buf, sign_ptr, s_len);
264 removed = remove_useless_leading_zeros(s_buf, s_len);
266 removed_total += removed;
268 if (removed_total > 0)
270 // if length of signature is incorrect.
271 OIC_LOG_V(INFO, TAG, "Cert Length (Before) : %lu", *derCrtBufLen);
272 OIC_LOG(INFO, TAG, "Invalid length of signature is dectected.");
273 OIC_LOG(INFO, TAG, "Update signature...");
275 uint16_t crt_len = 0;
276 /* change bitstring length */
278 uint8_t *sign_len_ptr = deviceCert.sig.p + 1;
279 *sign_len_ptr -= removed_total;
281 /* change signature length */
283 uint8_t *sign_len_ptr = deviceCert.sig.p - 1;
284 if (*sign_len_ptr == 0)
288 *sign_len_ptr -= removed_total;
290 /* change signature */
292 memcpy(deviceCert.sig.p + 2, r_buf, r_len);
293 memcpy(deviceCert.sig.p + 2 + r_len, s_buf, s_len);
295 /* change certificate length */
297 uint8_t *crt_len_ptr = deviceCert.raw.p + 2;
298 crt_len = (crt_len_ptr[0] << 8) & 0x0000FF00;
299 crt_len |= (crt_len_ptr[1] & 0x000000FF);
300 crt_len -= removed_total;
301 crt_len_ptr[0] = (uint8_t)(crt_len >> 8);
302 crt_len_ptr[1] = (uint8_t)(crt_len);
304 crt_len += 4; // include header and length field
305 /* change raw data and crt parse cert again */
307 mbedtls_x509_crt crt_cpy;
308 mbedtls_x509_crt_init( &crt_cpy );
309 if ((ret = mbedtls_x509_crt_parse_der(&crt_cpy, deviceCert.raw.p, (size_t)crt_len)) != 0)
311 OIC_LOG_V(ERROR, TAG, "mbedtls_x509_crt_parse error : %d", ret);
312 mbedtls_x509_crt_free(&crt_cpy);
316 org_len += 4; // include header and length field
317 size_t remained_len = (*derCrtBufLen - org_len);
318 memcpy(derCrtBuf, deviceCert.raw.p, crt_len);
319 memcpy(derCrtBuf + crt_len, derCrtBuf + org_len, remained_len);
320 *derCrtBufLen = (size_t)crt_len + remained_len;
322 mbedtls_x509_crt_free(&crt_cpy);
323 OIC_LOG_V(INFO, TAG, "Dev cert : %lu -> %lu", org_len, crt_len);
324 OIC_LOG_V(INFO, TAG, "Remained chain : %lu", remained_len);
325 OIC_LOG_V(INFO, TAG, "Cert Length (After) : %lu", *crtBufLen);
330 // if length of signature is correct.
331 OIC_LOG(INFO, TAG, "Don't need to update signature...");
338 OIC_LOG(ERROR, TAG, "PEM or invalid cert format detected. finish to check");
342 mbedtls_x509_crt_free(&deviceCert);
343 OICFree(derCrtBufTmp);
344 OIC_LOG_V(DEBUG, TAG, "Cert chain length = %d", *crtBufLen);
345 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
349 * Internal API to load the key/cert from HW PKI
351 * @return true on HW PKI is available
353 static bool GetPkixInfoFromHw(PkiInfo_t * inf)
355 OIC_LOG_V(INFO, TAG, "In %s", __func__);
357 if (!gHwPkixCtx.hwKeyCtx && gHwPkixCtx.getHwKeyContext)
359 gHwPkixCtx.hwKeyCtx = gHwPkixCtx.getHwKeyContext(
361 HWKEY_USAGE_PRIMARY, NULL);
362 if (!gHwPkixCtx.hwKeyCtx)
364 OIC_LOG(WARNING, TAG, "gHwPkixCtx.getHwKeyContext return null");
368 if (gHwPkixCtx.hwKeyCtx && gHwPkixCtx.getOwnCertCb)
370 int ret = gHwPkixCtx.getOwnCertCb(gHwPkixCtx.hwKeyCtx, &inf->crt.data, &inf->crt.len);
373 OIC_LOG_V(ERROR, TAG, "gHwPkixCtx.getOwnCertCb error : %d", ret);
374 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
378 // check and fix invalid cert signature
379 CheckInvalidDERSignature(inf->crt.data, &inf->crt.len);
381 OIC_LOG_V(INFO, TAG, "Cert chain length = %d", inf->crt.len);
382 OIC_LOG_V(INFO, TAG, "Out %s", __func__);
385 OIC_LOG_V(INFO, TAG, "Out %s", __func__);
389 void GetPkixInfo(PkiInfo_t * inf)
391 OIC_LOG_V(INFO, TAG, "In %s", __func__);
394 OIC_LOG(ERROR, TAG, "NULL passed");
395 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
399 if (GetPkixInfoFromHw(inf))
401 OIC_LOG(INFO, TAG, "H/W based PKI will be used.");
405 GetDerOwnCert(&inf->crt, PRIMARY_CERT);
406 GetDerKey(&inf->key, PRIMARY_CERT);
408 GetDerCaCert(&inf->ca, TRUST_CA);
409 GetDerCrl(&inf->crl);
411 OIC_LOG_V(INFO, TAG, "Out %s", __func__);
414 void GetManufacturerPkixInfo(PkiInfo_t * inf)
416 OIC_LOG_V(INFO, TAG, "In %s", __func__);
419 OIC_LOG(ERROR, TAG, "NULL passed");
420 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
424 if (GetPkixInfoFromHw(inf))
426 OIC_LOG(INFO, TAG, "H/W based PKI will be used.");
430 GetDerOwnCert(&inf->crt, MF_PRIMARY_CERT);
431 GetDerKey(&inf->key, MF_PRIMARY_CERT);
433 GetDerCaCert(&inf->ca, MF_TRUST_CA);
436 OICFree(inf->crl.data);
438 inf->crl.data = NULL;
440 OIC_LOG_V(INFO, TAG, "Out %s", __func__);
443 void InitCipherSuiteList(bool * list)
445 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
448 OIC_LOG(ERROR, TAG, "NULL passed");
449 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
452 InitCipherSuiteListInternal(list, TRUST_CA);
453 if (gHwPkixCtx.getOwnCertCb)
457 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
460 void InitManufacturerCipherSuiteList(bool * list)
462 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
465 OIC_LOG(ERROR, TAG, "NULL passed");
466 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
469 InitCipherSuiteListInternal(list, MF_TRUST_CA);
470 if (gHwPkixCtx.getOwnCertCb)
474 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
477 int SetupHwPkContext(mbedtls_pk_context* pkCtx)
479 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
482 OIC_LOG(ERROR, TAG, "NULL passed");
483 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
487 if (gHwPkixCtx.setupPkContextCb)
489 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
490 return gHwPkixCtx.setupPkContextCb(pkCtx, gHwPkixCtx.hwKeyCtx);
494 OIC_LOG(ERROR, TAG, "gHwPkixCallbacks.setupPkContextCb is NULL");
497 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
502 int SetHwPkixCallbacks(GetHwKeyContext getHwKeyContext,
503 FreeHwKeyContext freeHwKeyContext,
504 GetOwnCertFromHwCallback getOwnCertCb,
505 SetupPkContextFromHwCallback setupPkContextCb)
507 OIC_LOG_V(INFO, TAG, "In %s", __func__);
509 if (NULL == getHwKeyContext && NULL == freeHwKeyContext
510 && NULL == getOwnCertCb && NULL == setupPkContextCb)
512 OIC_LOG(INFO, TAG, "Unregistering callbacks");
514 else if (NULL == getHwKeyContext || NULL == freeHwKeyContext
515 || NULL == getOwnCertCb || NULL == setupPkContextCb)
517 OIC_LOG(ERROR, TAG, "NULL Passed");
518 OIC_LOG(ERROR, TAG, "Callback function parameters can not be null");
522 gHwPkixCtx.getHwKeyContext = getHwKeyContext;
523 gHwPkixCtx.freeHwKeyContext = freeHwKeyContext;
524 gHwPkixCtx.getOwnCertCb = getOwnCertCb;
525 gHwPkixCtx.setupPkContextCb = setupPkContextCb;
527 if (gHwPkixCtx.hwKeyCtx && NULL != freeHwKeyContext)
529 gHwPkixCtx.freeHwKeyContext(gHwPkixCtx.hwKeyCtx);
531 gHwPkixCtx.hwKeyCtx = NULL;
533 // setup pkcontext handler
534 CAregisterSetupPkContextHandler(SetupHwPkContext);
536 OIC_LOG_V(INFO, TAG, "Out %s", __func__);