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 
14 #include "edhoc.h"
15 
16 #include "edhoc/retrieve_cred.h"
17 #include "edhoc/plaintext.h"
18 #include "edhoc/signature_or_mac_msg.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_plaintext.h"
25 #include "cbor/edhoc_encode_id_cred_x.h"
26 
27 /**
28  * @brief 	Encodes ID_CRED_x as a CBOR map
29  * @param	label the map label
30  * @param	algo the hash algorithm used in x5t. This parameter kan take any
31  * 			othe value when xchain or kid are used
32  * @param	id the actual credential identifier
33  * @param	id_len length of id
34  * @param
35  */
id_cred_x_encode(enum id_cred_x_label label,int algo,const void * id,uint32_t id_len,uint8_t * id_cred_x,uint32_t * id_cred_x_len)36 static enum err id_cred_x_encode(enum id_cred_x_label label, int algo,
37 				 const void *id, uint32_t id_len,
38 				 uint8_t *id_cred_x, uint32_t *id_cred_x_len)
39 {
40 	struct id_cred_x_map map = { 0 };
41 	size_t payload_len_out;
42 
43 	switch (label) {
44 	case kid:
45 		//todo update that to v15
46 		map._id_cred_x_map_kid_present = true;
47 		map._id_cred_x_map_kid._id_cred_x_map_kid_choice =
48 			_id_cred_x_map_kid_int;
49 		map._id_cred_x_map_kid._id_cred_x_map_kid_int =
50 			*((const int32_t *)id);
51 		break;
52 	case x5chain:
53 		map._id_cred_x_map_x5chain_present = true;
54 		map._id_cred_x_map_x5chain._id_cred_x_map_x5chain.value = id;
55 		map._id_cred_x_map_x5chain._id_cred_x_map_x5chain.len = id_len;
56 		break;
57 	case x5t:
58 		map._id_cred_x_map_x5t_present = true;
59 		map._id_cred_x_map_x5t._id_cred_x_map_x5t_alg_choice =
60 			_id_cred_x_map_x5t_alg_int;
61 		map._id_cred_x_map_x5t._id_cred_x_map_x5t_alg_int = algo;
62 		map._id_cred_x_map_x5t._id_cred_x_map_x5t_hash.value = id;
63 		map._id_cred_x_map_x5t._id_cred_x_map_x5t_hash.len = id_len;
64 		break;
65 	default:
66 		break;
67 	}
68 
69 	TRY_EXPECT(cbor_encode_id_cred_x_map(id_cred_x, *id_cred_x_len, &map,
70 					     &payload_len_out),
71 		   true);
72 
73 	*id_cred_x_len = (uint32_t)payload_len_out;
74 
75 	return ok;
76 }
77 
plaintext_split(uint8_t * ptxt,const uint32_t ptxt_len,uint8_t * id_cred_x,uint32_t * id_cred_x_len,uint8_t * sign_or_mac,uint32_t * sign_or_mac_len,uint8_t * ad,uint32_t * ad_len)78 enum err plaintext_split(uint8_t *ptxt, const uint32_t ptxt_len,
79 			 uint8_t *id_cred_x, uint32_t *id_cred_x_len,
80 			 uint8_t *sign_or_mac, uint32_t *sign_or_mac_len,
81 			 uint8_t *ad, uint32_t *ad_len)
82 {
83 	size_t decode_len = 0;
84 	struct plaintext p;
85 
86 	TRY_EXPECT(cbor_decode_plaintext(ptxt, ptxt_len, &p, &decode_len),
87 		   true);
88 
89 	/*ID_CRED_x*/
90 	if (p._plaintext_ID_CRED_x_choice == _plaintext_ID_CRED_x__map) {
91 		if (p._plaintext_ID_CRED_x__map._map_x5chain_present) {
92 			PRINT_MSG(
93 				"ID_CRED of the other party has label x5chain\n");
94 			TRY(id_cred_x_encode(
95 				x5chain, 0,
96 				p._plaintext_ID_CRED_x__map._map_x5chain
97 					._map_x5chain.value,
98 				(uint32_t)p._plaintext_ID_CRED_x__map
99 					._map_x5chain._map_x5chain.len,
100 				id_cred_x, id_cred_x_len));
101 		}
102 		if (p._plaintext_ID_CRED_x__map._map_x5t_present) {
103 			PRINT_MSG("ID_CRED of the other party has label x5t\n");
104 			TRY(id_cred_x_encode(
105 				x5t,
106 				p._plaintext_ID_CRED_x__map._map_x5t
107 					._map_x5t_alg_int,
108 				p._plaintext_ID_CRED_x__map._map_x5t
109 					._map_x5t_hash.value,
110 				(uint32_t)p._plaintext_ID_CRED_x__map._map_x5t
111 					._map_x5t_hash.len,
112 				id_cred_x, id_cred_x_len));
113 		}
114 	} else {
115 		/*Note that if ID_CRED_x contains a single 'kid' parameter,
116             i.e., ID_CRED_R = { 4 : kid_x }, only the byte string kid_x
117             is conveyed in the plaintext encoded as a bstr or int*/
118 		if (p._plaintext_ID_CRED_x_choice ==
119 		    _plaintext_ID_CRED_x_bstr) {
120 			TRY(id_cred_x_encode(
121 				kid, 0, p._plaintext_ID_CRED_x_bstr.value,
122 				(uint32_t)p._plaintext_ID_CRED_x_bstr.len,
123 				id_cred_x, id_cred_x_len));
124 
125 		} else {
126 			int _kid = p._plaintext_ID_CRED_x_int;
127 			TRY(id_cred_x_encode(kid, 0, &_kid, 1, id_cred_x,
128 					     id_cred_x_len));
129 		}
130 	}
131 	TRY(_memcpy_s(sign_or_mac, *sign_or_mac_len,
132 		      p._plaintext_SGN_or_MAC_x.value,
133 		      (uint32_t)p._plaintext_SGN_or_MAC_x.len));
134 	*sign_or_mac_len = (uint32_t)p._plaintext_SGN_or_MAC_x.len;
135 
136 	if (p._plaintext_AD_x_present == true) {
137 		TRY(_memcpy_s(ad, *ad_len, p._plaintext_AD_x.value,
138 			      (uint32_t)p._plaintext_AD_x.len));
139 		*ad_len = (uint32_t)p._plaintext_AD_x.len;
140 	} else {
141 		if(ad_len)
142 		{
143 			*ad_len = 0;
144 		}
145 	}
146 
147 	return ok;
148 }
149