1 /*
2 * t_cose_sign1_verify.h
3 *
4 * Copyright 2019, Laurence Lundblade
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 *
8 * See BSD-3-Clause license in README.md
9 */
10
11
12 #ifndef __T_COSE_SIGN1_VERIFY_H__
13 #define __T_COSE_SIGN1_VERIFY_H__
14
15 #include <stdint.h>
16 #include "q_useful_buf.h"
17 #include "t_cose_common.h"
18
19 #ifdef __cplusplus
20 extern "C" {
21 #endif
22
23 /**
24 * \file t_cose_sign1_verify.h
25 *
26 * \brief Verify a COSE_Sign1 Message
27 *
28 * This verifies a \c COSE_Sign1 message in compliance with [COSE (RFC 8152)]
29 * (https://tools.ietf.org/html/rfc8152). A \c COSE_Sign1 message is a CBOR
30 * encoded binary blob that contains header parameters, a payload and a
31 * signature. Usually the signature is made with an EC signing
32 * algorithm like ECDSA.
33 *
34 * This implementation is intended to be small and portable to
35 * different OS's and platforms. Its dependencies are:
36 * - [QCBOR](https://github.com/laurencelundblade/QCBOR)
37 * - <stdint.h>, <string.h>, <stddef.h>
38 * - Hash functions like SHA-256
39 * - Signing functions like ECDSA
40 *
41 * There is a cryptographic adaptation layer defined in
42 * t_cose_crypto.h. An implementation can be made of the functions in
43 * it for different cryptographic libraries. This means that different
44 * integrations with different cryptographic libraries may support
45 * only signing with a particular set of algorithms. Integration with
46 * [OpenSSL](https://www.openssl.org) is supported. Key ID look up
47 * also varies by different cryptographic library integrations.
48 *
49 * See t_cose_common.h for preprocessor defines to reduce object code
50 * and stack use by disabling features.
51 */
52
53
54 /**
55 * Context for signature verification. It is about 24 bytes on a
56 * 64-bit machine and 12 bytes on a 32-bit machine.
57 */
58 struct t_cose_sign1_verify_ctx {
59 /* Private data structure */
60 struct t_cose_key verification_key;
61 int32_t option_flags;
62 };
63
64
65 /**
66 * \brief Initialize for \c COSE_Sign1 message verification.
67 *
68 * \param[in,out] context The context to initialize.
69 * \param[in] option_flags Options controlling the verification.
70 *
71 * This must be called before using the verification context.
72 */
73 static void
74 t_cose_sign1_verify_init(struct t_cose_sign1_verify_ctx *context,
75 int32_t option_flags);
76
77
78 /**
79 * \brief Set key for \c COSE_Sign1 message verification.
80 *
81 * \param[in] verification_key The verification key to use.
82 *
83 * There are four main ways that the verification key is found and
84 * supplied to t_cose so that t_cose_sign1_verify() succeeds.
85 *
86 * -# Look up by kid parameter and set by t_cose_sign1_set_verification_key()
87 * -# Look up by other and set by t_cose_sign1_set_verification_key()
88 * -# Determination by kid that short circuit signing is used (test only)
89 * -# Look up by kid parameter in cryptographic adaptation layer
90 *
91 * Note that there is no means where certificates, like X.509
92 * certificates, are provided in the COSE parameters. Perhaps there
93 * will be in the future but that is not in common use or supported by
94 * this implementation.
95 *
96 * To use 1 it is necessary to call t_cose_sign1_verify_init() and
97 * t_cose_sign1_verify() twice. The first time
98 * t_cose_sign1_verify_init() is called, give the \ref
99 * T_COSE_OPT_DECODE_ONLY option. Then call t_cose_sign1_verify() and
100 * the kid will be returned in \c parameters. The caller finds the kid on
101 * their own. Then call this to set the key. Last call
102 * t_cose_sign1_verify(), again without the \ref T_COSE_OPT_DECODE_ONLY
103 * option.
104 *
105 * To use 2 the key is somehow determined without the kid and
106 * t_cose_sign1_set_verification_key() is called with it. Then
107 * t_cose_sign1_verify() is called. Note that this implementation
108 * cannot return non-standard header parameters, at least not yet.
109 *
110 * To use 3, initialize with \ref T_COSE_OPT_ALLOW_SHORT_CIRCUIT. No
111 * call to t_cose_sign1_set_verification_key() is necessary. If you do
112 * call t_cose_sign1_set_verification_key(), the kid for short circuit
113 * signing will be recognized and the set key will be ignored.
114 *
115 * To use 4, first be sure that the cryptographic adapter supports
116 * look up by kid. There's no API to determine this, so it is
117 * probably determined by other system documentation (aka source
118 * code). In this mode, all that is necessary is to call
119 * t_cose_sign1_verify().
120 *
121 * 3 always works no matter what is done in the cryptographic
122 * adaptation layer because it never calls out to it. The OpenSSL
123 * adaptor supports 1 and 2.
124 */
125 static void
126 t_cose_sign1_set_verification_key(struct t_cose_sign1_verify_ctx *context,
127 struct t_cose_key verification_key);
128
129
130 /**
131 * \brief Verify a COSE_Sign1
132 *
133 * \param[in] sign1 Pointer and length of CBOR encoded \c COSE_Sign1
134 * message that is to be verified.
135 * \param[out] payload Pointer and length of the payload.
136 * \param[out] parameters Place to return parsed parameters. Maybe be \c NULL.
137 *
138 * \return This returns one of the error codes defined by \ref t_cose_err_t.
139 *
140 * See t_cose_sign1_set_verification_key() for discussion on where
141 * the verification key comes from.
142 *
143 * Verification involves the following steps.
144 *
145 * - The CBOR-format COSE_Sign1 structure is parsed. It makes sure \c sign1
146 * is valid CBOR and follows the required structure for \c COSE_Sign1.
147 *
148 * - The protected header parameters are parsed, particular the algorithm id.
149 *
150 * - The unprotected headers parameters are parsed, particularly the kid.
151 *
152 * - The payload is identified. The internals of the payload are not parsed.
153 *
154 * - The expected hash, the "to-be-signed" bytes are computed. The hash
155 * algorithm to use comes from the signing algorithm. If the algorithm is
156 * not known or not supported this will error out.
157 *
158 * - Finally, the signature verification is performed.
159 *
160 * If it is successful, the pointer to the CBOR-encoded payload is
161 * returned. The parameters are returned if requested. All pointers
162 * returned are to memory in the \c sign1 passed in.
163 *
164 * Note that this only handles standard COSE header parameters. There are no
165 * facilities for custom header parameters, even though they are allowed by
166 * the COSE standard.
167 *
168 * This will recognize the special key ID for short-circuit signing
169 * and verify it if the \ref T_COSE_OPT_ALLOW_SHORT_CIRCUIT is set.
170 *
171 * Indefinite length CBOR strings are not supported by this
172 * implementation. \ref T_COSE_ERR_SIGN1_FORMAT will be returned if
173 * they are in the input \c COSE_Sign1 messages. For example, if the
174 * payload is an indefinite length byte string, this error will be
175 * returned.
176 */
177 enum t_cose_err_t t_cose_sign1_verify(struct t_cose_sign1_verify_ctx *context,
178 struct q_useful_buf_c sign1,
179 struct q_useful_buf_c *payload,
180 struct t_cose_parameters *parameters);
181
182
183
184
185 /* ------------------------------------------------------------------------
186 * Inline implementations of public functions defined above.
187 */
188 static inline void
t_cose_sign1_verify_init(struct t_cose_sign1_verify_ctx * me,int32_t option_flags)189 t_cose_sign1_verify_init(struct t_cose_sign1_verify_ctx *me,
190 int32_t option_flags)
191 {
192 me->option_flags = option_flags;
193 me->verification_key = T_COSE_NULL_KEY;
194 }
195
196
197 static inline void
t_cose_sign1_set_verification_key(struct t_cose_sign1_verify_ctx * me,struct t_cose_key verification_key)198 t_cose_sign1_set_verification_key(struct t_cose_sign1_verify_ctx *me,
199 struct t_cose_key verification_key)
200 {
201 me->verification_key = verification_key;
202 }
203 #endif /* __T_COSE_SIGN1_VERIFY_H__ */
204