Branch data Line data Source code
1 : : /*
2 : : Copyright (c) 2021 Fraunhofer AISEC. See the COPYRIGHT
3 : : file at the top-level directory of this distribution.
4 : :
5 : : Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 : : http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 : : <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 : : option. This file may not be copied, modified, or distributed
9 : : except according to those terms.
10 : : */
11 : :
12 : : #include <stdint.h>
13 : : #include <stdbool.h>
14 : :
15 : : #include "edhoc/retrieve_cred.h"
16 : : #include "edhoc/plaintext.h"
17 : : #include "edhoc/signature_or_mac_msg.h"
18 : : #include "edhoc/int_encode_decode.h"
19 : :
20 : : #include "common/oscore_edhoc_error.h"
21 : : #include "common/memcpy_s.h"
22 : : #include "common/print_util.h"
23 : :
24 : : #include "cbor/edhoc_decode_plaintext2.h"
25 : : #include "cbor/edhoc_decode_plaintext3.h"
26 : : #include "cbor/edhoc_encode_id_cred_x.h"
27 : :
28 : : /**
29 : : * @brief Encodes ID_CRED_x as a CBOR map.
30 : : * @param label The CBOR map label.
31 : : * @param algo The EDHOC hash algorithm used in x5t. This
32 : : * parameter can take any other value when xchain
33 : : * or kid are used.
34 : : * @param id The actual credential identifier.
35 : : * @param id_len Length of id.
36 : : * @param[out] id_cred_x The encoded value.
37 : : * @retval Ok or error.
38 : : */
39 : 6 : static enum err id_cred_x_encode(enum id_cred_x_label label, int algo,
40 : : const void *id, uint32_t id_len,
41 : : struct byte_array *id_cred_x)
42 : : {
43 : 6 : struct id_cred_x_map map = { 0 };
44 : : size_t payload_len_out;
45 : :
46 [ - + + - ]: 6 : switch (label) {
47 : 0 : case kid:
48 : : //todo update that to v15
49 : 0 : map.id_cred_x_map_kid_present = true;
50 : 0 : map.id_cred_x_map_kid.id_cred_x_map_kid_choice =
51 : : id_cred_x_map_kid_int_c;
52 : 0 : map.id_cred_x_map_kid.id_cred_x_map_kid_int =
53 : 0 : *((const int32_t *)id);
54 : 0 : break;
55 : 2 : case x5chain:
56 : 2 : map.id_cred_x_map_x5chain_present = true;
57 : 2 : map.id_cred_x_map_x5chain.id_cred_x_map_x5chain.value = id;
58 : 2 : map.id_cred_x_map_x5chain.id_cred_x_map_x5chain.len = id_len;
59 : 2 : break;
60 : 4 : case x5t:
61 : 4 : map.id_cred_x_map_x5t_present = true;
62 : 4 : map.id_cred_x_map_x5t.id_cred_x_map_x5t_alg_choice =
63 : : id_cred_x_map_x5t_alg_int_c;
64 : 4 : map.id_cred_x_map_x5t.id_cred_x_map_x5t_alg_int = algo;
65 : 4 : map.id_cred_x_map_x5t.id_cred_x_map_x5t_hash.value = id;
66 : 4 : map.id_cred_x_map_x5t.id_cred_x_map_x5t_hash.len = id_len;
67 : 4 : break;
68 : 0 : default:
69 : 0 : break;
70 : : }
71 : :
72 [ - + ]: 6 : TRY_EXPECT(cbor_encode_id_cred_x_map(id_cred_x->ptr, id_cred_x->len,
73 : : &map, &payload_len_out),
74 : : 0);
75 : :
76 : 6 : id_cred_x->len = (uint32_t)payload_len_out;
77 : :
78 : 6 : return ok;
79 : : }
80 : :
81 : 3 : static enum err plaintext2_split(struct byte_array *ptxt,
82 : : struct byte_array *c_r,
83 : : struct byte_array *id_cred_r,
84 : : struct byte_array *sign_or_mac,
85 : : struct byte_array *ead)
86 : : {
87 : 3 : size_t decode_len = 0;
88 : : struct ptxt2 p;
89 : :
90 [ - + ]: 3 : TRY_EXPECT(cbor_decode_ptxt2(ptxt->ptr, ptxt->len, &p, &decode_len), 0);
91 : :
92 : : /*decode C_R*/
93 [ + + ]: 3 : if (p.ptxt2_C_R_choice == ptxt2_C_R_bstr_c) {
94 [ - + ]: 1 : TRY(_memcpy_s(c_r->ptr, c_r->len, p.ptxt2_C_R_bstr.value,
95 : : (uint32_t)p.ptxt2_C_R_bstr.len));
96 : 1 : c_r->len = (uint32_t)p.ptxt2_C_R_bstr.len;
97 : : } else {
98 : : /*provide C_R in encoded form if it was an int*/
99 : : /*this is how it C_R was chosen by the responder*/
100 [ - + ]: 2 : TRY(encode_int(&p.ptxt2_C_R_int, 1, c_r));
101 : : }
102 : :
103 : : /*ID_CRED_R*/
104 [ + - ]: 3 : if (p.ptxt2_ID_CRED_R_choice == ptxt2_ID_CRED_R_map2_m_c) {
105 [ + + ]: 3 : if (p.ptxt2_ID_CRED_R_map2_m.map2_x5chain_present) {
106 : 1 : PRINT_MSG("ID_CRED_R is x5chain\n");
107 [ - + ]: 1 : TRY(id_cred_x_encode(
108 : : x5chain, 0,
109 : : p.ptxt2_ID_CRED_R_map2_m.map2_x5chain
110 : : .map2_x5chain.value,
111 : : (uint32_t)p.ptxt2_ID_CRED_R_map2_m.map2_x5chain
112 : : .map2_x5chain.len,
113 : : id_cred_r));
114 : : }
115 [ + + ]: 3 : if (p.ptxt2_ID_CRED_R_map2_m.map2_x5t_present) {
116 : 2 : PRINT_MSG("ID_CRED_R is x5t\n");
117 [ - + ]: 2 : TRY(id_cred_x_encode(x5t,
118 : : p.ptxt2_ID_CRED_R_map2_m.map2_x5t
119 : : .map2_x5t_alg_int,
120 : : p.ptxt2_ID_CRED_R_map2_m.map2_x5t
121 : : .map2_x5t_hash.value,
122 : : (uint32_t)p.ptxt2_ID_CRED_R_map2_m
123 : : .map2_x5t.map2_x5t_hash.len,
124 : : id_cred_r));
125 : : }
126 : : } else {
127 : : /*Note that if ID_CRED_x contains a single 'kid' parameter,
128 : : i.e., ID_CRED_R = { 4 : kid_x }, only the byte string kid_x
129 : : is conveyed in the plaintext encoded as a bstr or int*/
130 [ # # ]: 0 : if (p.ptxt2_ID_CRED_R_choice == ptxt2_ID_CRED_R_map2_m_c) {
131 [ # # ]: 0 : TRY(id_cred_x_encode(
132 : : kid, 0, p.ptxt2_ID_CRED_R_bstr.value,
133 : : (uint32_t)p.ptxt2_ID_CRED_R_bstr.len,
134 : : id_cred_r));
135 : :
136 : : } else {
137 : 0 : int _kid = p.ptxt2_ID_CRED_R_int;
138 [ # # ]: 0 : TRY(id_cred_x_encode(kid, 0, &_kid, 1, id_cred_r));
139 : : }
140 : : }
141 [ - + ]: 3 : TRY(_memcpy_s(sign_or_mac->ptr, sign_or_mac->len,
142 : : p.ptxt2_SGN_or_MAC_2.value,
143 : : (uint32_t)p.ptxt2_SGN_or_MAC_2.len));
144 : 3 : sign_or_mac->len = (uint32_t)p.ptxt2_SGN_or_MAC_2.len;
145 : :
146 [ - + ]: 3 : if (p.ptxt2_EAD_2_present == true) {
147 [ # # ]: 0 : TRY(_memcpy_s(ead->ptr, ead->len, p.ptxt2_EAD_2.value,
148 : : (uint32_t)p.ptxt2_EAD_2.len));
149 : 0 : ead->len = (uint32_t)p.ptxt2_EAD_2.len;
150 : : } else {
151 [ - + ]: 3 : if (ead->len) {
152 : 0 : ead->len = 0;
153 : : }
154 : : }
155 : :
156 : 3 : return ok;
157 : : }
158 : :
159 : 3 : static enum err plaintext3_split(struct byte_array *ptxt,
160 : : struct byte_array *id_cred_i,
161 : : struct byte_array *sign_or_mac,
162 : : struct byte_array *ead)
163 : : {
164 : 3 : size_t decode_len = 0;
165 : : struct ptxt3 p;
166 : :
167 [ - + ]: 3 : TRY_EXPECT(cbor_decode_ptxt3(ptxt->ptr, ptxt->len, &p, &decode_len), 0);
168 : :
169 : : /*ID_CRED_I*/
170 [ + - ]: 3 : if (p.ptxt3_ID_CRED_I_choice == ptxt3_ID_CRED_I_map3_m_c) {
171 [ + + ]: 3 : if (p.ptxt3_ID_CRED_I_map3_m.map3_x5chain_present) {
172 : 1 : PRINT_MSG("ID_CRED_I is x5chain\n");
173 [ - + ]: 1 : TRY(id_cred_x_encode(
174 : : x5chain, 0,
175 : : p.ptxt3_ID_CRED_I_map3_m.map3_x5chain
176 : : .map3_x5chain.value,
177 : : (uint32_t)p.ptxt3_ID_CRED_I_map3_m.map3_x5chain
178 : : .map3_x5chain.len,
179 : : id_cred_i));
180 : : }
181 [ + + ]: 3 : if (p.ptxt3_ID_CRED_I_map3_m.map3_x5t_present) {
182 : 2 : PRINT_MSG("ID_CRED_I is x5t\n");
183 [ - + ]: 2 : TRY(id_cred_x_encode(x5t,
184 : : p.ptxt3_ID_CRED_I_map3_m.map3_x5t
185 : : .map3_x5t_alg_int,
186 : : p.ptxt3_ID_CRED_I_map3_m.map3_x5t
187 : : .map3_x5t_hash.value,
188 : : (uint32_t)p.ptxt3_ID_CRED_I_map3_m
189 : : .map3_x5t.map3_x5t_hash.len,
190 : : id_cred_i));
191 : : }
192 : : } else {
193 : : /*Note that if ID_CRED_x contains a single 'kid' parameter,
194 : : i.e., ID_CRED_I = { 4 : kid_x }, only the byte string kid_x
195 : : is conveyed in the plaintext encoded as a bstr or int*/
196 [ # # ]: 0 : if (p.ptxt3_ID_CRED_I_choice == ptxt3_ID_CRED_I_map3_m_c) {
197 [ # # ]: 0 : TRY(id_cred_x_encode(
198 : : kid, 0, p.ptxt3_ID_CRED_I_bstr.value,
199 : : (uint32_t)p.ptxt3_ID_CRED_I_bstr.len,
200 : : id_cred_i));
201 : :
202 : : } else {
203 : 0 : int _kid = p.ptxt3_ID_CRED_I_int;
204 [ # # ]: 0 : TRY(id_cred_x_encode(kid, 0, &_kid, 1, id_cred_i));
205 : : }
206 : : }
207 [ - + ]: 3 : TRY(_memcpy_s(sign_or_mac->ptr, sign_or_mac->len,
208 : : p.ptxt3_SGN_or_MAC_3.value,
209 : : (uint32_t)p.ptxt3_SGN_or_MAC_3.len));
210 : 3 : sign_or_mac->len = (uint32_t)p.ptxt3_SGN_or_MAC_3.len;
211 : :
212 [ - + ]: 3 : if (p.ptxt3_EAD_3_present == true) {
213 [ # # ]: 0 : TRY(_memcpy_s(ead->ptr, ead->len, p.ptxt3_EAD_3.value,
214 : : (uint32_t)p.ptxt3_EAD_3.len));
215 : 0 : ead->len = (uint32_t)p.ptxt3_EAD_3.len;
216 : : } else {
217 [ - + ]: 3 : if (ead->len) {
218 : 0 : ead->len = 0;
219 : : }
220 : : }
221 : 3 : return ok;
222 : : }
223 : :
224 : 6 : enum err plaintext_split(struct byte_array *ptxt, struct byte_array *c_r,
225 : : struct byte_array *id_cred_x,
226 : : struct byte_array *sign_or_mac, struct byte_array *ead)
227 : : {
228 : : /*C_R is present only in plaintext 2*/
229 [ + + ]: 6 : if (c_r != NULL) {
230 : 3 : return plaintext2_split(ptxt, c_r, id_cred_x, sign_or_mac, ead);
231 : : } else {
232 : 3 : return plaintext3_split(ptxt, id_cred_x, sign_or_mac, ead);
233 : : }
234 : : }
|