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"
31 #define TAG "OIC_SRM_PKIX_INTERFACE"
33 static HWPkixContext_t gHwPkixCtx = {
34 .getHwKeyContext = NULL,
35 .freeHwKeyContext = NULL,
37 .setupPkContextCb = NULL,
42 * returns the number of removed zeros
44 static size_t remove_useless_leading_zeros(uint8_t *asn_integer_buf, uint32_t size)
49 uint8_t tag = asn_integer_buf[0];
50 uint8_t len = asn_integer_buf[1];
51 uint8_t *p = asn_integer_buf + 2;
59 if (tag != MBEDTLS_ASN1_INTEGER)
64 if ((uint32_t)len + 2 != size || sizeof(buf) < size)
69 for (idx = 0; idx < (uint32_t)len - 1; idx++)
75 if (p[idx] == 0 && ((p[idx + 1] & 0x80) != 0)) // 00000000 1XXXXXXXX (bit)
87 asn_integer_buf[1] = len;
89 memcpy(buf, p + idx, len);
95 void CheckInvalidDERSignature(uint8_t *crtBuf, size_t *crtBufLen)
97 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
100 OIC_LOG(ERROR, TAG, "Param buf is NULL");
103 if (NULL == crtBufLen)
105 OIC_LOG(ERROR, TAG, "Param bufLen is NULL");
109 mbedtls_x509_crt deviceCert;
112 // check only first(i.e., device) certificate
113 if (crtBuf[0] == 0x30 && crtBuf[1] == 0x82)
115 uint8_t *sign_ptr = NULL;
117 * structure of r_buf & s_buf
118 * +---------------+-------------+----------------------------+
119 * | tag (INTEGER) | length (1B) | value (r or s in integer) |
120 * +---------------+-------------+----------------------------+
122 uint8_t r_buf[32 + 4]; // for ECC 256 sign
123 uint8_t s_buf[32 + 4];
127 uint32_t removed = 0;
128 uint32_t removed_total = 0;
131 mbedtls_x509_crt_init(&deviceCert);
133 unsigned char * tmp = (unsigned char *)crtBuf + 1;
134 if ( 0 != mbedtls_asn1_get_len(&tmp, crtBuf + *crtBufLen, &org_len))
136 OIC_LOG(ERROR, TAG, "Invalid parsed length");
140 if (org_len < *crtBufLen)
142 ret = mbedtls_x509_crt_parse_der(&deviceCert, crtBuf, org_len + 4);
145 OIC_LOG_V(ERROR, TAG, "mbedtls_x509_crt_parse_der returned -0x%04x", -(ret));
149 if (NULL == deviceCert.sig.p)
151 OIC_LOG(ERROR, TAG, "Cert's signature is NULL");
154 sign_ptr = (uint8_t*)deviceCert.sig.p;
155 ret = mbedtls_asn1_get_tag(&sign_ptr, deviceCert.sig.p + deviceCert.sig.len, &sign_len,
156 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
159 OIC_LOG_V(ERROR, TAG, "mbedtls_asn1_get_tag error : %d", ret);
164 r_len = sign_ptr[1] + 2; // including header itself
166 if (r_len > deviceCert.sig.len)
168 OIC_LOG_V(ERROR, TAG, "signature length check error #1 : %d", ret);
171 OIC_LOG_V(DEBUG, TAG, "r_len = %d", r_len);
172 memcpy(r_buf, sign_ptr, r_len);
173 removed = remove_useless_leading_zeros(r_buf, r_len);
175 /* Do not change order */
178 removed_total += removed;
181 s_len = sign_ptr[1] + 2; // including header itself
183 if (s_len + r_len > deviceCert.sig.len)
185 OIC_LOG_V(ERROR, TAG, "signature length check error #2 : %d", ret);
188 OIC_LOG_V(DEBUG, TAG, "s_len = %d", s_len);
189 memcpy(s_buf, sign_ptr, s_len);
190 removed = remove_useless_leading_zeros(s_buf, s_len);
192 removed_total += removed;
194 if (removed_total > 0)
196 // if length of signature is incorrect.
197 OIC_LOG_V(INFO, TAG, "Cert Length (Before) : %lu", *crtBufLen);
198 OIC_LOG(INFO, TAG, "Invalid length of signature is dectected.");
199 OIC_LOG(INFO, TAG, "Update signature...");
201 uint16_t crt_len = 0;
202 /* change bitstring length */
204 uint8_t *sign_len_ptr = deviceCert.sig.p + 1;
205 *sign_len_ptr -= removed_total;
207 /* change signature length */
209 uint8_t *sign_len_ptr = deviceCert.sig.p - 1;
210 if (*sign_len_ptr == 0)
214 *sign_len_ptr -= removed_total;
216 /* change signature */
218 memcpy(deviceCert.sig.p + 2, r_buf, r_len);
219 memcpy(deviceCert.sig.p + 2 + r_len, s_buf, s_len);
221 /* change certificate length */
223 uint8_t *crt_len_ptr = deviceCert.raw.p + 2;
224 crt_len = (crt_len_ptr[0] << 8) & 0x0000FF00;
225 crt_len |= (crt_len_ptr[1] & 0x000000FF);
226 crt_len -= removed_total;
227 crt_len_ptr[0] = (uint8_t)(crt_len >> 8);
228 crt_len_ptr[1] = (uint8_t)(crt_len);
230 crt_len += 4; // include header and length field
231 /* change raw data and crt parse cert again */
233 mbedtls_x509_crt crt_cpy;
234 mbedtls_x509_crt_init( &crt_cpy );
235 if ((ret = mbedtls_x509_crt_parse_der(&crt_cpy, deviceCert.raw.p, (size_t)crt_len)) != 0)
237 OIC_LOG_V(ERROR, TAG, "mbedtls_x509_crt_parse error : %d", ret);
238 mbedtls_x509_crt_free(&crt_cpy);
242 org_len += 4; // include header and length field
243 size_t remained_len = (*crtBufLen - org_len);
244 memcpy(crtBuf, deviceCert.raw.p, crt_len);
245 memcpy(crtBuf + crt_len, crtBuf + org_len, remained_len);
246 *crtBufLen = (size_t)crt_len + remained_len;
248 mbedtls_x509_crt_free(&crt_cpy);
249 OIC_LOG_V(INFO, TAG, "Dev cert : %lu -> %lu", org_len, crt_len);
250 OIC_LOG_V(INFO, TAG, "Remained chain : %lu", remained_len);
251 OIC_LOG_V(INFO, TAG, "Cert Length (After) : %lu", *crtBufLen);
256 // if length of signature is correct.
257 OIC_LOG(INFO, TAG, "Don't need to update signature...");
264 OIC_LOG(ERROR, TAG, "PEM or invalid cert format detected. finish to check");
268 mbedtls_x509_crt_free(&deviceCert);
269 OIC_LOG_V(DEBUG, TAG, "Cert chain length = %d", *crtBufLen);
270 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
274 * Internal API to load the key/cert from HW PKI
276 * @return true on HW PKI is available
278 static bool GetPkixInfoFromHw(PkiInfo_t * inf)
280 OIC_LOG_V(INFO, TAG, "In %s", __func__);
282 if (!gHwPkixCtx.hwKeyCtx && gHwPkixCtx.getHwKeyContext)
284 gHwPkixCtx.hwKeyCtx = gHwPkixCtx.getHwKeyContext(
286 HWKEY_USAGE_PRIMARY, NULL);
287 if (!gHwPkixCtx.hwKeyCtx)
289 OIC_LOG(WARNING, TAG, "gHwPkixCtx.getHwKeyContext return null");
293 if (gHwPkixCtx.hwKeyCtx && gHwPkixCtx.getOwnCertCb)
295 int ret = gHwPkixCtx.getOwnCertCb(gHwPkixCtx.hwKeyCtx, &inf->crt.data, &inf->crt.len);
298 OIC_LOG_V(ERROR, TAG, "gHwPkixCtx.getOwnCertCb error : %d", ret);
299 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
303 // check and fix invalid cert signature
304 CheckInvalidDERSignature(inf->crt.data, &inf->crt.len);
306 OIC_LOG_V(INFO, TAG, "Cert chain length = %d", inf->crt.len);
307 OIC_LOG_V(INFO, TAG, "Out %s", __func__);
310 OIC_LOG_V(INFO, TAG, "Out %s", __func__);
314 void GetPkixInfo(PkiInfo_t * inf)
316 OIC_LOG_V(INFO, TAG, "In %s", __func__);
319 OIC_LOG(ERROR, TAG, "NULL passed");
320 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
324 if (GetPkixInfoFromHw(inf))
326 OIC_LOG(INFO, TAG, "H/W based PKI will be used.");
330 GetDerOwnCert(&inf->crt, PRIMARY_CERT);
331 GetDerKey(&inf->key, PRIMARY_CERT);
333 GetDerCaCert(&inf->ca, TRUST_CA);
334 GetDerCrl(&inf->crl);
336 OIC_LOG_V(INFO, TAG, "Out %s", __func__);
339 void GetManufacturerPkixInfo(PkiInfo_t * inf)
341 OIC_LOG_V(INFO, TAG, "In %s", __func__);
344 OIC_LOG(ERROR, TAG, "NULL passed");
345 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
349 if (GetPkixInfoFromHw(inf))
351 OIC_LOG(INFO, TAG, "H/W based PKI will be used.");
355 GetDerOwnCert(&inf->crt, MF_PRIMARY_CERT);
356 GetDerKey(&inf->key, MF_PRIMARY_CERT);
358 GetDerCaCert(&inf->ca, MF_TRUST_CA);
361 OICFree(inf->crl.data);
363 inf->crl.data = NULL;
365 OIC_LOG_V(INFO, TAG, "Out %s", __func__);
368 void InitCipherSuiteList(bool * list)
370 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
373 OIC_LOG(ERROR, TAG, "NULL passed");
374 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
377 InitCipherSuiteListInternal(list, TRUST_CA);
378 if (gHwPkixCtx.getOwnCertCb)
382 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
385 void InitManufacturerCipherSuiteList(bool * list)
387 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
390 OIC_LOG(ERROR, TAG, "NULL passed");
391 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
394 InitCipherSuiteListInternal(list, MF_TRUST_CA);
395 if (gHwPkixCtx.getOwnCertCb)
399 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
402 int SetupHwPkContext(mbedtls_pk_context* pkCtx)
404 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
407 OIC_LOG(ERROR, TAG, "NULL passed");
408 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
412 if (gHwPkixCtx.setupPkContextCb)
414 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
415 return gHwPkixCtx.setupPkContextCb(pkCtx, gHwPkixCtx.hwKeyCtx);
419 OIC_LOG(ERROR, TAG, "gHwPkixCallbacks.setupPkContextCb is NULL");
422 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
427 int SetHwPkixCallbacks(GetHwKeyContext getHwKeyContext,
428 FreeHwKeyContext freeHwKeyContext,
429 GetOwnCertFromHwCallback getOwnCertCb,
430 SetupPkContextFromHwCallback setupPkContextCb)
432 OIC_LOG_V(INFO, TAG, "In %s", __func__);
434 if (NULL == getHwKeyContext || NULL == freeHwKeyContext
435 || NULL == getOwnCertCb || NULL == setupPkContextCb)
437 OIC_LOG(ERROR, TAG, "NULL Passed");
438 OIC_LOG(ERROR, TAG, "Callback function parameters can not be null");
442 gHwPkixCtx.getHwKeyContext = getHwKeyContext;
443 gHwPkixCtx.freeHwKeyContext = freeHwKeyContext;
444 gHwPkixCtx.getOwnCertCb = getOwnCertCb;
445 gHwPkixCtx.setupPkContextCb = setupPkContextCb;
447 if (gHwPkixCtx.hwKeyCtx)
449 gHwPkixCtx.freeHwKeyContext(gHwPkixCtx.hwKeyCtx);
451 gHwPkixCtx.hwKeyCtx = NULL;
453 // setup pkcontext handler
454 CAregisterSetupPkContextHandler(SetupHwPkContext);
456 OIC_LOG_V(INFO, TAG, "Out %s", __func__);