From 6cfc53b1e4169640b3287bbc93ed9bee91eca324 Mon Sep 17 00:00:00 2001 From: Laurence Lundblade Date: Sat, 13 Mar 2021 16:10:47 -0800 Subject: [PATCH] first pass at x509 header parameters --- Makefile.ossl | 2 +- inc/t_cose/t_cose_sign1_sign.h | 36 +++++++++++++++++-- inc/t_cose/t_cose_sign1_verify.h | 9 +++++ src/t_cose_parameters.c | 61 ++++++++++++++++++++++++++++++++ src/t_cose_sign1_sign.c | 25 +++++++++++++ 5 files changed, 129 insertions(+), 4 deletions(-) diff --git a/Makefile.ossl b/Makefile.ossl index 50d350bc..94d1fc60 100644 --- a/Makefile.ossl +++ b/Makefile.ossl @@ -131,7 +131,7 @@ src/t_cose_sign1_sign.o: inc/t_cose/t_cose_sign1_sign.h src/t_cose_standard_cons test/t_cose_test.o: test/t_cose_test.h test/t_cose_make_test_messages.h src/t_cose_crypto.h $(PUBLIC_INTERFACE) test/t_cose_sign_verify_test.o: test/t_cose_sign_verify_test.h test/t_cose_make_test_messages.h src/t_cose_crypto.h test/t_cose_make_test_pub_key.h $(PUBLIC_INTERFACE) test/t_cose_make_test_messages.o: test/t_cose_make_test_messages.h inc/t_cose/t_cose_sign1_sign.h inc/t_cose/t_cose_common.h src/t_cose_standard_constants.h src/t_cose_crypto.h src/t_cose_util.h -test/run_test.o: test/run_test.h test/t_cose_test.h test/t_cose_hash_fail_test.h +test/run_test.o: test/run_test.h test/t_cose_test.h test/t_cose_hash_fail_test.h inc/t_cose/t_cose_sign1_sign.h inc/t_cose/t_cose_sign1_verify.h src/t_cose_crypto.h test/t_cose_make_openssl_test_key.o: test/t_cose_make_test_pub_key.h src/t_cose_standard_constants.h inc/t_cose/t_cose_common.h # ---- crypto dependencies ---- diff --git a/inc/t_cose/t_cose_sign1_sign.h b/inc/t_cose/t_cose_sign1_sign.h index cd939f4c..896a0f09 100644 --- a/inc/t_cose/t_cose_sign1_sign.h +++ b/inc/t_cose/t_cose_sign1_sign.h @@ -1,7 +1,7 @@ /* * t_cose_sign1_sign.h * - * Copyright (c) 2018-2019, Laurence Lundblade. All rights reserved. + * Copyright (c) 2018-2021, Laurence Lundblade. All rights reserved. * Copyright (c) 2020, Michael Eckel * * SPDX-License-Identifier: BSD-3-Clause @@ -19,6 +19,9 @@ #ifdef __cplusplus extern "C" { +#if 0 +} /* Keep editor indention formatting happy */ +#endif #endif @@ -68,14 +71,16 @@ extern "C" { struct t_cose_sign1_sign_ctx { /* Private data structure */ struct q_useful_buf_c protected_parameters; /* The encoded protected parameters */ - int32_t cose_algorithm_id; struct t_cose_key signing_key; - uint32_t option_flags; struct q_useful_buf_c kid; + int32_t cose_algorithm_id; + uint32_t option_flags; #ifndef T_COSE_DISABLE_CONTENT_TYPE uint32_t content_type_uint; const char * content_type_tstr; #endif + struct q_useful_buf_c *cert_bag; + struct q_useful_buf_c *cert_chain; }; @@ -174,6 +179,31 @@ t_cose_sign1_set_signing_key(struct t_cose_sign1_sign_ctx *context, + + +/* + Adds the certs to help the verifier. + + These are always put in the protected headers bucket because it is cheap + and easy to do. + + One cert, goes into x5chain. + + An ordered chain. Goes into x5chain. + + Some exta certs that might help but we don't know exactly how. Goes into x5bag. + + + + */ +static void +t_cose_sign1_add_chain_certs(struct t_cose_sign1_sign_ctx *context, + const struct q_useful_buf_c cert[]); + + + + + #ifndef T_COSE_DISABLE_CONTENT_TYPE /** * \brief Set the payload content type using CoAP content types. diff --git a/inc/t_cose/t_cose_sign1_verify.h b/inc/t_cose/t_cose_sign1_verify.h index 156755d8..6440433c 100644 --- a/inc/t_cose/t_cose_sign1_verify.h +++ b/inc/t_cose/t_cose_sign1_verify.h @@ -59,6 +59,10 @@ extern "C" { */ + +#define T_COSE_MAX_X_509_CERTIFICATES 3 + + /** * The result of parsing a set of COSE header parameters. The pointers * are all back into the \c COSE_Sign1 blob passed in to @@ -98,6 +102,11 @@ struct t_cose_parameters { * present. Allowed range is 0 to UINT16_MAX per RFC 7252. */ uint32_t content_type_uint; #endif /* T_COSE_DISABLE_CONTENT_TYPE */ + +#ifndef T_COSE_DISABLE_X_509_CERTS + struct q_useful_buf_c cert_chain[T_COSE_MAX_X_509_CERTIFICATES+1]; + struct q_useful_buf_c cert_bag[T_COSE_MAX_X_509_CERTIFICATES+1]; +#endif /* T_COSE_DISABLE_X_509_CERTS */ }; diff --git a/src/t_cose_parameters.c b/src/t_cose_parameters.c index 1750362f..a895b0ff 100644 --- a/src/t_cose_parameters.c +++ b/src/t_cose_parameters.c @@ -198,6 +198,61 @@ decode_critical_parameter(QCBORDecodeContext *decode_context, } + +static enum t_cose_err_t +decode_cert_param(QCBORDecodeContext *decode_context, int label, struct q_useful_buf_c certs[]) +{ + QCBORError cbor_result; + int i; + + cbor_result = 0; + QCBORDecode_EnterArrayFromMapN(decode_context, label); + + cbor_result = QCBORDecode_GetAndResetError(decode_context); + if(cbor_result == QCBOR_ERR_UNEXPECTED_TYPE) { + QCBORDecode_GetByteStringInMapN(decode_context, label, &certs[0]); + cbor_result = QCBORDecode_GetAndResetError(decode_context); + certs[1] = NULL_Q_USEFUL_BUF_C; + + } else { + + i = 0; + while(1) { + QCBORDecode_GetByteString(decode_context, &certs[i]); + cbor_result = QCBORDecode_GetAndResetError(decode_context); + if(cbor_result == QCBOR_ERR_NO_MORE_ITEMS) { + certs[i] = NULL_Q_USEFUL_BUF_C; + cbor_result = 0; /* Non error exit */ + break; + } + if(i > T_COSE_MAX_X_509_CERTIFICATES) { + cbor_result = 999; + break; + + } + } + QCBORDecode_ExitArray(decode_context); + } + + return cbor_result; +} + +static inline enum t_cose_err_t +decode_certs(QCBORDecodeContext *decode_context, struct t_cose_parameters *parameters) +{ + enum t_cose_err_t return_value; + + return_value = decode_cert_param(decode_context, 44, parameters->cert_bag); + if(return_value != T_COSE_SUCCESS) { + goto Done; + } + + return_value = decode_cert_param(decode_context, 54, parameters->cert_chain); +Done: + return return_value; +} + + /** * Public function. See t_cose_parameters.h */ @@ -497,6 +552,12 @@ parse_cose_header_parameters(QCBORDecodeContext *decode_context, /* COSE_HEADER_PARAM_CRIT */ return_value = decode_critical_parameter(decode_context, critical_labels); + if(return_value != T_COSE_SUCCESS) { + // TODO: should this exit the map? + goto Done; + } + + return_value = decode_certs(decode_context, parameters); QCBORDecode_ExitMap(decode_context); diff --git a/src/t_cose_sign1_sign.c b/src/t_cose_sign1_sign.c index 8fd84251..299ceee0 100644 --- a/src/t_cose_sign1_sign.c +++ b/src/t_cose_sign1_sign.c @@ -128,6 +128,31 @@ short_circuit_sign(int32_t cose_algorithm_id, #endif /* T_COSE_DISABLE_SHORT_CIRCUIT_SIGN */ + +void encode_certs(QCBOREncodeContext *cbor_encode_ctx, const struct q_useful_buf_c *certs) +{ + if(certs == NULL || certs[0].ptr == NULL) { + /* No certs given, nothing to do */ + return; + } + + if(certs[1].ptr == NULL) { + /* Just one cert */ + QCBOREncode_AddBytes(cbor_encode_ctx, certs[0]); + } else { + /* Several certs go into an array */ + QCBOREncode_OpenArray(cbor_encode_ctx); + + while(certs->ptr != NULL) { + QCBOREncode_AddBytes(cbor_encode_ctx, *certs); + certs++; + } + + QCBOREncode_CloseArray(cbor_encode_ctx); + } +} + + /** * \brief Makes the protected header parameters for COSE. *