Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support x509 certificate header parameters #31

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile.ossl
Original file line number Diff line number Diff line change
Expand Up @@ -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 ----
Expand Down
36 changes: 33 additions & 3 deletions inc/t_cose/t_cose_sign1_sign.h
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -19,6 +19,9 @@

#ifdef __cplusplus
extern "C" {
#if 0
} /* Keep editor indention formatting happy */
#endif
#endif


Expand Down Expand Up @@ -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;
};


Expand Down Expand Up @@ -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.
Expand Down
9 changes: 9 additions & 0 deletions inc/t_cose/t_cose_sign1_verify.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 */
};


Expand Down
61 changes: 61 additions & 0 deletions src/t_cose_parameters.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down Expand Up @@ -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);

Expand Down
25 changes: 25 additions & 0 deletions src/t_cose_sign1_sign.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down