Line data Source code
1 : /**
2 : * The MIT License (MIT)
3 : *
4 : * Copyright (c) 2021 RSK Labs Ltd
5 : *
6 : * Permission is hereby granted, free of charge, to any person obtaining a copy
7 : * of this software and associated documentation files (the "Software"), to
8 : * deal in the Software without restriction, including without limitation the
9 : * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 : * sell copies of the Software, and to permit persons to whom the Software is
11 : * furnished to do so, subject to the following conditions:
12 : *
13 : * The above copyright notice and this permission notice shall be included in
14 : * all copies or substantial portions of the Software.
15 : *
16 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 : * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 : * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22 : * IN THE SOFTWARE.
23 : */
24 :
25 : #include "evidence.h"
26 :
27 : #include <string.h>
28 : #include "hal/log.h"
29 : #include <openenclave/corelibc/stdlib.h>
30 : #include <openenclave/attestation/attester.h>
31 : #include <openenclave/attestation/verifier.h>
32 :
33 : static struct { bool initialised; } G_evidence_ctx;
34 :
35 : #define EVIDENCE_CHECK(oe_result, error_msg, statement) \
36 : { \
37 : if (OE_OK != oe_result) { \
38 : LOG("%s: result=%u (%s)\n", \
39 : error_msg, \
40 : result, \
41 : oe_result_str(oe_result)); \
42 : { statement; } \
43 : } \
44 : }
45 :
46 : // ****************************************************** //
47 : // ********** Public interface implemenetation ********** //
48 : // ****************************************************** //
49 :
50 15 : bool evidence_init() {
51 : oe_result_t result;
52 :
53 15 : explicit_bzero(&G_evidence_ctx, sizeof(G_evidence_ctx));
54 :
55 : // Initialize modules
56 15 : result = oe_attester_initialize();
57 15 : EVIDENCE_CHECK(result, "Failed to initialize attester", return false);
58 14 : result = oe_verifier_initialize();
59 14 : EVIDENCE_CHECK(result, "Failed to initialize verifier", return false);
60 :
61 14 : G_evidence_ctx.initialised = true;
62 : LOG("Evidence module initialized\n");
63 14 : return true;
64 : }
65 :
66 24 : void evidence_finalise() {
67 24 : oe_verifier_shutdown();
68 24 : oe_attester_shutdown();
69 24 : explicit_bzero(&G_evidence_ctx, sizeof(G_evidence_ctx));
70 24 : }
71 :
72 12 : bool evidence_get_format_settings(evidence_format_t* format) {
73 : oe_result_t result;
74 :
75 12 : if (!G_evidence_ctx.initialised) {
76 : LOG("Evidence module not initialised\n");
77 2 : return false;
78 : }
79 :
80 10 : if (!format || format->settings || format->settings_size) {
81 : LOG("Invalid format getter spec given\n");
82 2 : return false;
83 : }
84 :
85 8 : result = oe_verifier_get_format_settings(
86 8 : &format->id, &format->settings, &format->settings_size);
87 8 : EVIDENCE_CHECK(result, "Failed to gather format settings", return false);
88 :
89 5 : return true;
90 : }
91 :
92 4 : bool evidence_supports_format(oe_uuid_t format_id) {
93 4 : evidence_format_t format = {
94 : .id = format_id,
95 : .settings = NULL,
96 : .settings_size = 0,
97 : };
98 : oe_uuid_t selected_format;
99 : oe_result_t result;
100 :
101 : // Make sure we can get format settings
102 4 : if (!evidence_get_format_settings(&format))
103 2 : return false;
104 2 : oe_free(format.settings);
105 :
106 : // Make sure we can select format for attestation
107 2 : result = oe_attester_select_format(&format.id, 1, &selected_format);
108 2 : EVIDENCE_CHECK(result, "Failed to select attestation format", return false);
109 :
110 1 : return true;
111 : }
112 :
113 : // Generates evidence with the given format id and custom claims.
114 8 : bool evidence_generate(evidence_format_t* format,
115 : uint8_t* ccs,
116 : size_t ccs_size,
117 : uint8_t** evidence_buffer,
118 : size_t* evidence_buffer_size) {
119 : oe_result_t result;
120 : bool gathered_settings;
121 :
122 8 : if (!G_evidence_ctx.initialised) {
123 : LOG("Evidence module not initialised\n");
124 1 : goto generate_evidence_error;
125 : }
126 :
127 7 : if (!format) {
128 : LOG("Invalid evidence format\n");
129 1 : goto generate_evidence_error;
130 : }
131 :
132 6 : if (!evidence_buffer || !evidence_buffer_size) {
133 : LOG("Invalid evidence buffer/size pointers\n");
134 2 : goto generate_evidence_error;
135 : }
136 :
137 : // Gather the corresponding format settings if needed
138 : // Otherwise make sure the format is supported
139 4 : gathered_settings = false;
140 4 : if (!format->settings) {
141 3 : if (!evidence_get_format_settings(format)) {
142 : LOG("Error gathering format settings\n");
143 1 : goto generate_evidence_error;
144 : }
145 2 : gathered_settings = true;
146 : LOG("Gathered settings\n");
147 : }
148 :
149 3 : result = oe_get_evidence(&format->id,
150 : 0,
151 : ccs,
152 : ccs_size,
153 3 : format->settings,
154 : format->settings_size,
155 : evidence_buffer,
156 : evidence_buffer_size,
157 : NULL,
158 : NULL);
159 3 : EVIDENCE_CHECK(
160 : result, "Evidence generation failed", goto generate_evidence_error);
161 :
162 2 : if (gathered_settings) {
163 1 : oe_free(format->settings);
164 1 : format->settings = NULL;
165 1 : format->settings_size = 0;
166 : }
167 :
168 : LOG("Evidence generated successfully\n");
169 :
170 2 : return true;
171 :
172 6 : generate_evidence_error:
173 6 : if (evidence_buffer && *evidence_buffer) {
174 0 : oe_free_evidence(*evidence_buffer);
175 0 : *evidence_buffer = NULL;
176 0 : *evidence_buffer_size = 0;
177 : }
178 6 : if (gathered_settings && format->settings) {
179 1 : oe_free(format->settings);
180 1 : format->settings = NULL;
181 1 : format->settings_size = 0;
182 : }
183 6 : return false;
184 : }
185 :
186 3 : bool evidence_verify_and_extract_claims(oe_uuid_t format_id,
187 : uint8_t* evidence_buffer,
188 : size_t evidence_buffer_size,
189 : oe_claim_t** claims,
190 : size_t* claims_size) {
191 3 : if (!G_evidence_ctx.initialised) {
192 : LOG("Evidence module not initialised\n");
193 1 : return false;
194 : }
195 :
196 2 : if (!claims || !claims_size) {
197 0 : claims = NULL;
198 0 : claims_size = NULL;
199 : }
200 :
201 2 : oe_result_t result = oe_verify_evidence(&format_id,
202 : evidence_buffer,
203 : evidence_buffer_size,
204 : NULL,
205 : 0,
206 : NULL,
207 : 0,
208 : claims,
209 : claims_size);
210 2 : EVIDENCE_CHECK(result, "Evidence verification failed", return false);
211 :
212 : LOG("Evidence verified successfully\n");
213 :
214 1 : return true;
215 : }
216 :
217 10 : oe_claim_t* evidence_get_claim(oe_claim_t* claims,
218 : size_t claims_size,
219 : const char* claim_name) {
220 10 : if (!claims || !claims_size || !claim_name)
221 5 : return NULL;
222 :
223 11 : for (size_t i = 0; i < claims_size; i++) {
224 9 : if (strcmp(claims[i].name, claim_name) == 0)
225 3 : return &claims[i];
226 : }
227 2 : return NULL;
228 : }
229 :
230 4 : oe_claim_t* evidence_get_custom_claim(oe_claim_t* claims, size_t claims_size) {
231 4 : return evidence_get_claim(
232 : claims, claims_size, OE_CLAIM_CUSTOM_CLAIMS_BUFFER);
233 : }
234 :
235 2 : void evidence_free(uint8_t* evidence_buffer) {
236 2 : if (evidence_buffer)
237 1 : oe_free_evidence(evidence_buffer);
238 2 : }
|