1 /* Copyright (c) 2019, Google Inc.
2 *
3 * Permission to use, copy, modify, and/or distribute this software for any
4 * purpose with or without fee is hereby granted, provided that the above
5 * copyright notice and this permission notice appear in all copies.
6 *
7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14
15 #include <openssl/bytestring.h>
16 #include <openssl/err.h>
17 #include <openssl/evp.h>
18 #include <openssl/mem.h>
19 #include <openssl/sha.h>
20 #include <openssl/trust_token.h>
21
22 #include "internal.h"
23
24
25 // The Trust Token API is described in
26 // https://github.com/WICG/trust-token-api/blob/master/README.md and provides a
27 // protocol for issuing and redeeming tokens built on top of the PMBTokens
28 // construction.
29
TRUST_TOKEN_experiment_v1(void)30 const TRUST_TOKEN_METHOD *TRUST_TOKEN_experiment_v1(void) {
31 static const TRUST_TOKEN_METHOD kMethod = {
32 pmbtoken_exp1_generate_key,
33 pmbtoken_exp1_client_key_from_bytes,
34 pmbtoken_exp1_issuer_key_from_bytes,
35 pmbtoken_exp1_blind,
36 pmbtoken_exp1_sign,
37 pmbtoken_exp1_unblind,
38 pmbtoken_exp1_read,
39 1, /* has_private_metadata */
40 3, /* max_keys */
41 1, /* has_srr */
42 };
43 return &kMethod;
44 }
45
TRUST_TOKEN_experiment_v2_voprf(void)46 const TRUST_TOKEN_METHOD *TRUST_TOKEN_experiment_v2_voprf(void) {
47 static const TRUST_TOKEN_METHOD kMethod = {
48 voprf_exp2_generate_key,
49 voprf_exp2_client_key_from_bytes,
50 voprf_exp2_issuer_key_from_bytes,
51 voprf_exp2_blind,
52 voprf_exp2_sign,
53 voprf_exp2_unblind,
54 voprf_exp2_read,
55 0, /* has_private_metadata */
56 6, /* max_keys */
57 0, /* has_srr */
58 };
59 return &kMethod;
60 }
61
TRUST_TOKEN_experiment_v2_pmb(void)62 const TRUST_TOKEN_METHOD *TRUST_TOKEN_experiment_v2_pmb(void) {
63 static const TRUST_TOKEN_METHOD kMethod = {
64 pmbtoken_exp2_generate_key,
65 pmbtoken_exp2_client_key_from_bytes,
66 pmbtoken_exp2_issuer_key_from_bytes,
67 pmbtoken_exp2_blind,
68 pmbtoken_exp2_sign,
69 pmbtoken_exp2_unblind,
70 pmbtoken_exp2_read,
71 1, /* has_private_metadata */
72 3, /* max_keys */
73 0, /* has_srr */
74 };
75 return &kMethod;
76 }
77
TRUST_TOKEN_PRETOKEN_free(TRUST_TOKEN_PRETOKEN * pretoken)78 void TRUST_TOKEN_PRETOKEN_free(TRUST_TOKEN_PRETOKEN *pretoken) {
79 OPENSSL_free(pretoken);
80 }
81
TRUST_TOKEN_new(const uint8_t * data,size_t len)82 TRUST_TOKEN *TRUST_TOKEN_new(const uint8_t *data, size_t len) {
83 TRUST_TOKEN *ret = OPENSSL_malloc(sizeof(TRUST_TOKEN));
84 if (ret == NULL) {
85 OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
86 return NULL;
87 }
88 OPENSSL_memset(ret, 0, sizeof(TRUST_TOKEN));
89 ret->data = OPENSSL_memdup(data, len);
90 if (len != 0 && ret->data == NULL) {
91 OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
92 OPENSSL_free(ret);
93 return NULL;
94 }
95 ret->len = len;
96 return ret;
97 }
98
TRUST_TOKEN_free(TRUST_TOKEN * token)99 void TRUST_TOKEN_free(TRUST_TOKEN *token) {
100 if (token == NULL) {
101 return;
102 }
103 OPENSSL_free(token->data);
104 OPENSSL_free(token);
105 }
106
TRUST_TOKEN_generate_key(const TRUST_TOKEN_METHOD * method,uint8_t * out_priv_key,size_t * out_priv_key_len,size_t max_priv_key_len,uint8_t * out_pub_key,size_t * out_pub_key_len,size_t max_pub_key_len,uint32_t id)107 int TRUST_TOKEN_generate_key(const TRUST_TOKEN_METHOD *method,
108 uint8_t *out_priv_key, size_t *out_priv_key_len,
109 size_t max_priv_key_len, uint8_t *out_pub_key,
110 size_t *out_pub_key_len, size_t max_pub_key_len,
111 uint32_t id) {
112 // Prepend the key ID in front of the PMBTokens format.
113 int ret = 0;
114 CBB priv_cbb, pub_cbb;
115 CBB_zero(&priv_cbb);
116 CBB_zero(&pub_cbb);
117 if (!CBB_init_fixed(&priv_cbb, out_priv_key, max_priv_key_len) ||
118 !CBB_init_fixed(&pub_cbb, out_pub_key, max_pub_key_len) ||
119 !CBB_add_u32(&priv_cbb, id) ||
120 !CBB_add_u32(&pub_cbb, id)) {
121 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_BUFFER_TOO_SMALL);
122 goto err;
123 }
124
125 if (!method->generate_key(&priv_cbb, &pub_cbb)) {
126 goto err;
127 }
128
129 if (!CBB_finish(&priv_cbb, NULL, out_priv_key_len) ||
130 !CBB_finish(&pub_cbb, NULL, out_pub_key_len)) {
131 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_BUFFER_TOO_SMALL);
132 goto err;
133 }
134
135 ret = 1;
136
137 err:
138 CBB_cleanup(&priv_cbb);
139 CBB_cleanup(&pub_cbb);
140 return ret;
141 }
142
TRUST_TOKEN_CLIENT_new(const TRUST_TOKEN_METHOD * method,size_t max_batchsize)143 TRUST_TOKEN_CLIENT *TRUST_TOKEN_CLIENT_new(const TRUST_TOKEN_METHOD *method,
144 size_t max_batchsize) {
145 if (max_batchsize > 0xffff) {
146 // The protocol supports only two-byte token counts.
147 OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_OVERFLOW);
148 return NULL;
149 }
150
151 TRUST_TOKEN_CLIENT *ret = OPENSSL_malloc(sizeof(TRUST_TOKEN_CLIENT));
152 if (ret == NULL) {
153 OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
154 return NULL;
155 }
156 OPENSSL_memset(ret, 0, sizeof(TRUST_TOKEN_CLIENT));
157 ret->method = method;
158 ret->max_batchsize = (uint16_t)max_batchsize;
159 return ret;
160 }
161
TRUST_TOKEN_CLIENT_free(TRUST_TOKEN_CLIENT * ctx)162 void TRUST_TOKEN_CLIENT_free(TRUST_TOKEN_CLIENT *ctx) {
163 if (ctx == NULL) {
164 return;
165 }
166 EVP_PKEY_free(ctx->srr_key);
167 sk_TRUST_TOKEN_PRETOKEN_pop_free(ctx->pretokens, TRUST_TOKEN_PRETOKEN_free);
168 OPENSSL_free(ctx);
169 }
170
TRUST_TOKEN_CLIENT_add_key(TRUST_TOKEN_CLIENT * ctx,size_t * out_key_index,const uint8_t * key,size_t key_len)171 int TRUST_TOKEN_CLIENT_add_key(TRUST_TOKEN_CLIENT *ctx, size_t *out_key_index,
172 const uint8_t *key, size_t key_len) {
173 if (ctx->num_keys == OPENSSL_ARRAY_SIZE(ctx->keys) ||
174 ctx->num_keys >= ctx->method->max_keys) {
175 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_TOO_MANY_KEYS);
176 return 0;
177 }
178
179 struct trust_token_client_key_st *key_s = &ctx->keys[ctx->num_keys];
180 CBS cbs;
181 CBS_init(&cbs, key, key_len);
182 uint32_t key_id;
183 if (!CBS_get_u32(&cbs, &key_id) ||
184 !ctx->method->client_key_from_bytes(&key_s->key, CBS_data(&cbs),
185 CBS_len(&cbs))) {
186 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
187 return 0;
188 }
189 key_s->id = key_id;
190 *out_key_index = ctx->num_keys;
191 ctx->num_keys += 1;
192 return 1;
193 }
194
TRUST_TOKEN_CLIENT_set_srr_key(TRUST_TOKEN_CLIENT * ctx,EVP_PKEY * key)195 int TRUST_TOKEN_CLIENT_set_srr_key(TRUST_TOKEN_CLIENT *ctx, EVP_PKEY *key) {
196 if (!ctx->method->has_srr) {
197 return 1;
198 }
199 EVP_PKEY_free(ctx->srr_key);
200 EVP_PKEY_up_ref(key);
201 ctx->srr_key = key;
202 return 1;
203 }
204
TRUST_TOKEN_CLIENT_begin_issuance(TRUST_TOKEN_CLIENT * ctx,uint8_t ** out,size_t * out_len,size_t count)205 int TRUST_TOKEN_CLIENT_begin_issuance(TRUST_TOKEN_CLIENT *ctx, uint8_t **out,
206 size_t *out_len, size_t count) {
207 if (count > ctx->max_batchsize) {
208 count = ctx->max_batchsize;
209 }
210
211 int ret = 0;
212 CBB request;
213 STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens = NULL;
214 if (!CBB_init(&request, 0) ||
215 !CBB_add_u16(&request, count)) {
216 OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
217 goto err;
218 }
219
220 pretokens = ctx->method->blind(&request, count);
221 if (pretokens == NULL) {
222 goto err;
223 }
224
225 if (!CBB_finish(&request, out, out_len)) {
226 OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
227 goto err;
228 }
229
230 sk_TRUST_TOKEN_PRETOKEN_pop_free(ctx->pretokens, TRUST_TOKEN_PRETOKEN_free);
231 ctx->pretokens = pretokens;
232 pretokens = NULL;
233 ret = 1;
234
235 err:
236 CBB_cleanup(&request);
237 sk_TRUST_TOKEN_PRETOKEN_pop_free(pretokens, TRUST_TOKEN_PRETOKEN_free);
238 return ret;
239 }
240
STACK_OF(TRUST_TOKEN)241 STACK_OF(TRUST_TOKEN) *
242 TRUST_TOKEN_CLIENT_finish_issuance(TRUST_TOKEN_CLIENT *ctx,
243 size_t *out_key_index,
244 const uint8_t *response,
245 size_t response_len) {
246 CBS in;
247 CBS_init(&in, response, response_len);
248 uint16_t count;
249 uint32_t key_id;
250 if (!CBS_get_u16(&in, &count) ||
251 !CBS_get_u32(&in, &key_id)) {
252 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
253 return NULL;
254 }
255
256 size_t key_index = 0;
257 const struct trust_token_client_key_st *key = NULL;
258 for (size_t i = 0; i < ctx->num_keys; i++) {
259 if (ctx->keys[i].id == key_id) {
260 key_index = i;
261 key = &ctx->keys[i];
262 break;
263 }
264 }
265
266 if (key == NULL) {
267 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_KEY_ID);
268 return NULL;
269 }
270
271 if (count > sk_TRUST_TOKEN_PRETOKEN_num(ctx->pretokens)) {
272 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
273 return NULL;
274 }
275
276 STACK_OF(TRUST_TOKEN) *tokens =
277 ctx->method->unblind(&key->key, ctx->pretokens, &in, count, key_id);
278 if (tokens == NULL) {
279 return NULL;
280 }
281
282 if (CBS_len(&in) != 0) {
283 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
284 sk_TRUST_TOKEN_pop_free(tokens, TRUST_TOKEN_free);
285 return NULL;
286 }
287
288 sk_TRUST_TOKEN_PRETOKEN_pop_free(ctx->pretokens, TRUST_TOKEN_PRETOKEN_free);
289 ctx->pretokens = NULL;
290
291 *out_key_index = key_index;
292 return tokens;
293 }
294
TRUST_TOKEN_CLIENT_begin_redemption(TRUST_TOKEN_CLIENT * ctx,uint8_t ** out,size_t * out_len,const TRUST_TOKEN * token,const uint8_t * data,size_t data_len,uint64_t time)295 int TRUST_TOKEN_CLIENT_begin_redemption(TRUST_TOKEN_CLIENT *ctx, uint8_t **out,
296 size_t *out_len,
297 const TRUST_TOKEN *token,
298 const uint8_t *data, size_t data_len,
299 uint64_t time) {
300 CBB request, token_inner, inner;
301 if (!CBB_init(&request, 0) ||
302 !CBB_add_u16_length_prefixed(&request, &token_inner) ||
303 !CBB_add_bytes(&token_inner, token->data, token->len) ||
304 !CBB_add_u16_length_prefixed(&request, &inner) ||
305 !CBB_add_bytes(&inner, data, data_len) ||
306 (ctx->method->has_srr && !CBB_add_u64(&request, time)) ||
307 !CBB_finish(&request, out, out_len)) {
308 OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
309 CBB_cleanup(&request);
310 return 0;
311 }
312 return 1;
313 }
314
TRUST_TOKEN_CLIENT_finish_redemption(TRUST_TOKEN_CLIENT * ctx,uint8_t ** out_rr,size_t * out_rr_len,uint8_t ** out_sig,size_t * out_sig_len,const uint8_t * response,size_t response_len)315 int TRUST_TOKEN_CLIENT_finish_redemption(TRUST_TOKEN_CLIENT *ctx,
316 uint8_t **out_rr, size_t *out_rr_len,
317 uint8_t **out_sig, size_t *out_sig_len,
318 const uint8_t *response,
319 size_t response_len) {
320 CBS in, srr, sig;
321 CBS_init(&in, response, response_len);
322 if (!ctx->method->has_srr) {
323 if (!CBS_stow(&in, out_rr, out_rr_len)) {
324 OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
325 return 0;
326 }
327
328 *out_sig = NULL;
329 *out_sig_len = 0;
330 return 1;
331 }
332
333 if (!CBS_get_u16_length_prefixed(&in, &srr) ||
334 !CBS_get_u16_length_prefixed(&in, &sig) ||
335 CBS_len(&in) != 0) {
336 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_ERROR);
337 return 0;
338 }
339
340 if (ctx->srr_key == NULL) {
341 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_NO_SRR_KEY_CONFIGURED);
342 return 0;
343 }
344
345 EVP_MD_CTX md_ctx;
346 EVP_MD_CTX_init(&md_ctx);
347 int sig_ok = EVP_DigestVerifyInit(&md_ctx, NULL, NULL, NULL, ctx->srr_key) &&
348 EVP_DigestVerify(&md_ctx, CBS_data(&sig), CBS_len(&sig),
349 CBS_data(&srr), CBS_len(&srr));
350 EVP_MD_CTX_cleanup(&md_ctx);
351
352 if (!sig_ok) {
353 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_SRR_SIGNATURE_ERROR);
354 return 0;
355 }
356
357 uint8_t *srr_buf = NULL, *sig_buf = NULL;
358 size_t srr_len, sig_len;
359 if (!CBS_stow(&srr, &srr_buf, &srr_len) ||
360 !CBS_stow(&sig, &sig_buf, &sig_len)) {
361 OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
362 OPENSSL_free(srr_buf);
363 OPENSSL_free(sig_buf);
364 return 0;
365 }
366
367 *out_rr = srr_buf;
368 *out_rr_len = srr_len;
369 *out_sig = sig_buf;
370 *out_sig_len = sig_len;
371 return 1;
372 }
373
TRUST_TOKEN_ISSUER_new(const TRUST_TOKEN_METHOD * method,size_t max_batchsize)374 TRUST_TOKEN_ISSUER *TRUST_TOKEN_ISSUER_new(const TRUST_TOKEN_METHOD *method,
375 size_t max_batchsize) {
376 if (max_batchsize > 0xffff) {
377 // The protocol supports only two-byte token counts.
378 OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_OVERFLOW);
379 return NULL;
380 }
381
382 TRUST_TOKEN_ISSUER *ret = OPENSSL_malloc(sizeof(TRUST_TOKEN_ISSUER));
383 if (ret == NULL) {
384 OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
385 return NULL;
386 }
387 OPENSSL_memset(ret, 0, sizeof(TRUST_TOKEN_ISSUER));
388 ret->method = method;
389 ret->max_batchsize = (uint16_t)max_batchsize;
390 return ret;
391 }
392
TRUST_TOKEN_ISSUER_free(TRUST_TOKEN_ISSUER * ctx)393 void TRUST_TOKEN_ISSUER_free(TRUST_TOKEN_ISSUER *ctx) {
394 if (ctx == NULL) {
395 return;
396 }
397 EVP_PKEY_free(ctx->srr_key);
398 OPENSSL_free(ctx->metadata_key);
399 OPENSSL_free(ctx);
400 }
401
TRUST_TOKEN_ISSUER_add_key(TRUST_TOKEN_ISSUER * ctx,const uint8_t * key,size_t key_len)402 int TRUST_TOKEN_ISSUER_add_key(TRUST_TOKEN_ISSUER *ctx, const uint8_t *key,
403 size_t key_len) {
404 if (ctx->num_keys == OPENSSL_ARRAY_SIZE(ctx->keys) ||
405 ctx->num_keys >= ctx->method->max_keys) {
406 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_TOO_MANY_KEYS);
407 return 0;
408 }
409
410 struct trust_token_issuer_key_st *key_s = &ctx->keys[ctx->num_keys];
411 CBS cbs;
412 CBS_init(&cbs, key, key_len);
413 uint32_t key_id;
414 if (!CBS_get_u32(&cbs, &key_id) ||
415 !ctx->method->issuer_key_from_bytes(&key_s->key, CBS_data(&cbs),
416 CBS_len(&cbs))) {
417 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
418 return 0;
419 }
420
421 key_s->id = key_id;
422 ctx->num_keys += 1;
423 return 1;
424 }
425
TRUST_TOKEN_ISSUER_set_srr_key(TRUST_TOKEN_ISSUER * ctx,EVP_PKEY * key)426 int TRUST_TOKEN_ISSUER_set_srr_key(TRUST_TOKEN_ISSUER *ctx, EVP_PKEY *key) {
427 EVP_PKEY_free(ctx->srr_key);
428 EVP_PKEY_up_ref(key);
429 ctx->srr_key = key;
430 return 1;
431 }
432
TRUST_TOKEN_ISSUER_set_metadata_key(TRUST_TOKEN_ISSUER * ctx,const uint8_t * key,size_t len)433 int TRUST_TOKEN_ISSUER_set_metadata_key(TRUST_TOKEN_ISSUER *ctx,
434 const uint8_t *key, size_t len) {
435 if (len < 32) {
436 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_METADATA_KEY);
437 }
438 OPENSSL_free(ctx->metadata_key);
439 ctx->metadata_key_len = 0;
440 ctx->metadata_key = OPENSSL_memdup(key, len);
441 if (ctx->metadata_key == NULL) {
442 OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
443 return 0;
444 }
445 ctx->metadata_key_len = len;
446 return 1;
447 }
448
trust_token_issuer_get_key(const TRUST_TOKEN_ISSUER * ctx,uint32_t key_id)449 static const struct trust_token_issuer_key_st *trust_token_issuer_get_key(
450 const TRUST_TOKEN_ISSUER *ctx, uint32_t key_id) {
451 for (size_t i = 0; i < ctx->num_keys; i++) {
452 if (ctx->keys[i].id == key_id) {
453 return &ctx->keys[i];
454 }
455 }
456 return NULL;
457 }
458
TRUST_TOKEN_ISSUER_issue(const TRUST_TOKEN_ISSUER * ctx,uint8_t ** out,size_t * out_len,size_t * out_tokens_issued,const uint8_t * request,size_t request_len,uint32_t public_metadata,uint8_t private_metadata,size_t max_issuance)459 int TRUST_TOKEN_ISSUER_issue(const TRUST_TOKEN_ISSUER *ctx, uint8_t **out,
460 size_t *out_len, size_t *out_tokens_issued,
461 const uint8_t *request, size_t request_len,
462 uint32_t public_metadata, uint8_t private_metadata,
463 size_t max_issuance) {
464 if (max_issuance > ctx->max_batchsize) {
465 max_issuance = ctx->max_batchsize;
466 }
467
468 const struct trust_token_issuer_key_st *key =
469 trust_token_issuer_get_key(ctx, public_metadata);
470 if (key == NULL || private_metadata > 1 ||
471 (!ctx->method->has_private_metadata && private_metadata != 0)) {
472 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_METADATA);
473 return 0;
474 }
475
476 CBS in;
477 uint16_t num_requested;
478 CBS_init(&in, request, request_len);
479 if (!CBS_get_u16(&in, &num_requested)) {
480 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
481 return 0;
482 }
483
484 size_t num_to_issue = num_requested;
485 if (num_to_issue > max_issuance) {
486 num_to_issue = max_issuance;
487 }
488
489 int ret = 0;
490 CBB response;
491 if (!CBB_init(&response, 0) ||
492 !CBB_add_u16(&response, num_to_issue) ||
493 !CBB_add_u32(&response, public_metadata)) {
494 OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
495 goto err;
496 }
497
498 if (!ctx->method->sign(&key->key, &response, &in, num_requested, num_to_issue,
499 private_metadata)) {
500 goto err;
501 }
502
503 if (CBS_len(&in) != 0) {
504 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
505 goto err;
506 }
507
508 if (!CBB_finish(&response, out, out_len)) {
509 OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
510 goto err;
511 }
512
513 *out_tokens_issued = num_to_issue;
514 ret = 1;
515
516 err:
517 CBB_cleanup(&response);
518 return ret;
519 }
520
521
TRUST_TOKEN_ISSUER_redeem_raw(const TRUST_TOKEN_ISSUER * ctx,uint32_t * out_public,uint8_t * out_private,TRUST_TOKEN ** out_token,uint8_t ** out_client_data,size_t * out_client_data_len,const uint8_t * request,size_t request_len)522 int TRUST_TOKEN_ISSUER_redeem_raw(const TRUST_TOKEN_ISSUER *ctx,
523 uint32_t *out_public, uint8_t *out_private,
524 TRUST_TOKEN **out_token,
525 uint8_t **out_client_data,
526 size_t *out_client_data_len,
527 const uint8_t *request, size_t request_len) {
528 CBS request_cbs, token_cbs;
529 CBS_init(&request_cbs, request, request_len);
530 if (!CBS_get_u16_length_prefixed(&request_cbs, &token_cbs)) {
531 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_ERROR);
532 return 0;
533 }
534
535 uint32_t public_metadata = 0;
536 uint8_t private_metadata = 0;
537
538 // Parse the token. If there is an error, treat it as an invalid token.
539 if (!CBS_get_u32(&token_cbs, &public_metadata)) {
540 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_TOKEN);
541 return 0;
542 }
543
544 const struct trust_token_issuer_key_st *key =
545 trust_token_issuer_get_key(ctx, public_metadata);
546 uint8_t nonce[TRUST_TOKEN_NONCE_SIZE];
547 if (key == NULL ||
548 !ctx->method->read(&key->key, nonce, &private_metadata,
549 CBS_data(&token_cbs), CBS_len(&token_cbs))) {
550 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_TOKEN);
551 return 0;
552 }
553
554 CBS client_data;
555 if (!CBS_get_u16_length_prefixed(&request_cbs, &client_data) ||
556 (ctx->method->has_srr && !CBS_skip(&request_cbs, 8)) ||
557 CBS_len(&request_cbs) != 0) {
558 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_ERROR);
559 return 0;
560 }
561
562 uint8_t *client_data_buf = NULL;
563 size_t client_data_len = 0;
564 if (!CBS_stow(&client_data, &client_data_buf, &client_data_len)) {
565 OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
566 goto err;
567 }
568
569 TRUST_TOKEN *token = TRUST_TOKEN_new(nonce, TRUST_TOKEN_NONCE_SIZE);
570 if (token == NULL) {
571 OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
572 goto err;
573 }
574 *out_public = public_metadata;
575 *out_private = private_metadata;
576 *out_token = token;
577 *out_client_data = client_data_buf;
578 *out_client_data_len = client_data_len;
579
580 return 1;
581
582 err:
583 OPENSSL_free(client_data_buf);
584 return 0;
585 }
586
587 // https://tools.ietf.org/html/rfc7049#section-2.1
add_cbor_int_with_type(CBB * cbb,uint8_t major_type,uint64_t value)588 static int add_cbor_int_with_type(CBB *cbb, uint8_t major_type,
589 uint64_t value) {
590 if (value <= 23) {
591 return CBB_add_u8(cbb, value | major_type);
592 }
593 if (value <= 0xff) {
594 return CBB_add_u8(cbb, 0x18 | major_type) && CBB_add_u8(cbb, value);
595 }
596 if (value <= 0xffff) {
597 return CBB_add_u8(cbb, 0x19 | major_type) && CBB_add_u16(cbb, value);
598 }
599 if (value <= 0xffffffff) {
600 return CBB_add_u8(cbb, 0x1a | major_type) && CBB_add_u32(cbb, value);
601 }
602 if (value <= 0xffffffffffffffff) {
603 return CBB_add_u8(cbb, 0x1b | major_type) && CBB_add_u64(cbb, value);
604 }
605
606 return 0;
607 }
608
609 // https://tools.ietf.org/html/rfc7049#section-2.1
add_cbor_int(CBB * cbb,uint64_t value)610 static int add_cbor_int(CBB *cbb, uint64_t value) {
611 return add_cbor_int_with_type(cbb, 0, value);
612 }
613
614 // https://tools.ietf.org/html/rfc7049#section-2.1
add_cbor_bytes(CBB * cbb,const uint8_t * data,size_t len)615 static int add_cbor_bytes(CBB *cbb, const uint8_t *data, size_t len) {
616 return add_cbor_int_with_type(cbb, 0x40, len) &&
617 CBB_add_bytes(cbb, data, len);
618 }
619
620 // https://tools.ietf.org/html/rfc7049#section-2.1
add_cbor_text(CBB * cbb,const char * data,size_t len)621 static int add_cbor_text(CBB *cbb, const char *data, size_t len) {
622 return add_cbor_int_with_type(cbb, 0x60, len) &&
623 CBB_add_bytes(cbb, (const uint8_t *)data, len);
624 }
625
626 // https://tools.ietf.org/html/rfc7049#section-2.1
add_cbor_map(CBB * cbb,uint8_t size)627 static int add_cbor_map(CBB *cbb, uint8_t size) {
628 return add_cbor_int_with_type(cbb, 0xa0, size);
629 }
630
get_metadata_obfuscator(const uint8_t * key,size_t key_len,const uint8_t * client_data,size_t client_data_len)631 static uint8_t get_metadata_obfuscator(const uint8_t *key, size_t key_len,
632 const uint8_t *client_data,
633 size_t client_data_len) {
634 uint8_t metadata_obfuscator[SHA256_DIGEST_LENGTH];
635 SHA256_CTX sha_ctx;
636 SHA256_Init(&sha_ctx);
637 SHA256_Update(&sha_ctx, key, key_len);
638 SHA256_Update(&sha_ctx, client_data, client_data_len);
639 SHA256_Final(metadata_obfuscator, &sha_ctx);
640 return metadata_obfuscator[0] >> 7;
641 }
642
TRUST_TOKEN_ISSUER_redeem(const TRUST_TOKEN_ISSUER * ctx,uint8_t ** out,size_t * out_len,TRUST_TOKEN ** out_token,uint8_t ** out_client_data,size_t * out_client_data_len,uint64_t * out_redemption_time,const uint8_t * request,size_t request_len,uint64_t lifetime)643 int TRUST_TOKEN_ISSUER_redeem(const TRUST_TOKEN_ISSUER *ctx, uint8_t **out,
644 size_t *out_len, TRUST_TOKEN **out_token,
645 uint8_t **out_client_data,
646 size_t *out_client_data_len,
647 uint64_t *out_redemption_time,
648 const uint8_t *request, size_t request_len,
649 uint64_t lifetime) {
650 CBS request_cbs, token_cbs;
651 CBS_init(&request_cbs, request, request_len);
652 if (!CBS_get_u16_length_prefixed(&request_cbs, &token_cbs)) {
653 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_ERROR);
654 return 0;
655 }
656
657 uint32_t public_metadata = 0;
658 uint8_t private_metadata = 0;
659
660 CBS token_copy = token_cbs;
661
662 // Parse the token. If there is an error, treat it as an invalid token.
663 if (!CBS_get_u32(&token_cbs, &public_metadata)) {
664 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_TOKEN);
665 return 0;
666 }
667
668 const struct trust_token_issuer_key_st *key =
669 trust_token_issuer_get_key(ctx, public_metadata);
670 uint8_t nonce[TRUST_TOKEN_NONCE_SIZE];
671 if (key == NULL ||
672 !ctx->method->read(&key->key, nonce, &private_metadata,
673 CBS_data(&token_cbs), CBS_len(&token_cbs))) {
674 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_TOKEN);
675 return 0;
676 }
677
678 int ok = 0;
679 CBB response, srr;
680 uint8_t *srr_buf = NULL, *sig_buf = NULL, *client_data_buf = NULL;
681 size_t srr_len = 0, sig_len = 0, client_data_len = 0;
682 EVP_MD_CTX md_ctx;
683 EVP_MD_CTX_init(&md_ctx);
684 CBB_zero(&srr);
685 if (!CBB_init(&response, 0)) {
686 OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
687 goto err;
688 }
689
690 CBS client_data;
691 uint64_t redemption_time = 0;
692 if (!CBS_get_u16_length_prefixed(&request_cbs, &client_data) ||
693 (ctx->method->has_srr && !CBS_get_u64(&request_cbs, &redemption_time))) {
694 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_ERROR);
695 goto err;
696 }
697
698 const uint8_t kTokenHashDSTLabel[] = "TrustTokenV0 TokenHash";
699 uint8_t token_hash[SHA256_DIGEST_LENGTH];
700 SHA256_CTX sha_ctx;
701 SHA256_Init(&sha_ctx);
702 SHA256_Update(&sha_ctx, kTokenHashDSTLabel, sizeof(kTokenHashDSTLabel));
703 SHA256_Update(&sha_ctx, CBS_data(&token_copy), CBS_len(&token_copy));
704 SHA256_Final(token_hash, &sha_ctx);
705
706 uint8_t metadata_obfuscator = get_metadata_obfuscator(
707 ctx->metadata_key, ctx->metadata_key_len, token_hash, sizeof(token_hash));
708
709 // The SRR is constructed as per the format described in
710 // https://docs.google.com/document/d/1TNnya6B8pyomDK2F1R9CL3dY10OAmqWlnCxsWyOBDVQ/edit#heading=h.7mkzvhpqb8l5
711
712 // The V2 protocol is intended to be used with
713 // |TRUST_TOKEN_ISSUER_redeem_raw|. However, we temporarily support it with
714 // |TRUST_TOKEN_ISSUER_redeem| to ease the transition for existing issuer
715 // callers. Those callers' consumers currently expect an expiry-timestamp
716 // field, so we fill in a placeholder value.
717 //
718 // TODO(svaldez): After the existing issues have migrated to
719 // |TRUST_TOKEN_ISSUER_redeem_raw| remove this logic.
720 uint64_t expiry_time = 0;
721 if (ctx->method->has_srr) {
722 expiry_time = redemption_time + lifetime;
723 }
724
725 static const char kClientDataLabel[] = "client-data";
726 static const char kExpiryTimestampLabel[] = "expiry-timestamp";
727 static const char kMetadataLabel[] = "metadata";
728 static const char kPrivateLabel[] = "private";
729 static const char kPublicLabel[] = "public";
730 static const char kTokenHashLabel[] = "token-hash";
731
732 // CBOR requires map keys to be sorted by length then sorted lexically.
733 // https://tools.ietf.org/html/rfc7049#section-3.9
734 assert(strlen(kMetadataLabel) < strlen(kTokenHashLabel));
735 assert(strlen(kTokenHashLabel) < strlen(kClientDataLabel));
736 assert(strlen(kClientDataLabel) < strlen(kExpiryTimestampLabel));
737 assert(strlen(kPublicLabel) < strlen(kPrivateLabel));
738
739 size_t map_entries = 4;
740
741 if (!CBB_init(&srr, 0) ||
742 !add_cbor_map(&srr, map_entries) || // SRR map
743 !add_cbor_text(&srr, kMetadataLabel, strlen(kMetadataLabel)) ||
744 !add_cbor_map(&srr, 2) || // Metadata map
745 !add_cbor_text(&srr, kPublicLabel, strlen(kPublicLabel)) ||
746 !add_cbor_int(&srr, public_metadata) ||
747 !add_cbor_text(&srr, kPrivateLabel, strlen(kPrivateLabel)) ||
748 !add_cbor_int(&srr, private_metadata ^ metadata_obfuscator) ||
749 !add_cbor_text(&srr, kTokenHashLabel, strlen(kTokenHashLabel)) ||
750 !add_cbor_bytes(&srr, token_hash, sizeof(token_hash)) ||
751 !add_cbor_text(&srr, kClientDataLabel, strlen(kClientDataLabel)) ||
752 !CBB_add_bytes(&srr, CBS_data(&client_data), CBS_len(&client_data)) ||
753 !add_cbor_text(&srr, kExpiryTimestampLabel,
754 strlen(kExpiryTimestampLabel)) ||
755 !add_cbor_int(&srr, expiry_time) ||
756 !CBB_finish(&srr, &srr_buf, &srr_len)) {
757 OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
758 goto err;
759 }
760
761 if (!EVP_DigestSignInit(&md_ctx, NULL, NULL, NULL, ctx->srr_key) ||
762 !EVP_DigestSign(&md_ctx, NULL, &sig_len, srr_buf, srr_len)) {
763 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_SRR_SIGNATURE_ERROR);
764 goto err;
765 }
766
767 // Merge SRR and Signature into single string.
768 // TODO(svaldez): Expose API to construct this from the caller.
769 if (!ctx->method->has_srr) {
770 static const char kSRRHeader[] = "body=:";
771 static const char kSRRSplit[] = ":, signature=:";
772 static const char kSRREnd[] = ":";
773
774 size_t srr_b64_len, sig_b64_len;
775 if (!EVP_EncodedLength(&srr_b64_len, srr_len) ||
776 !EVP_EncodedLength(&sig_b64_len, sig_len)) {
777 goto err;
778 }
779
780 sig_buf = OPENSSL_malloc(sig_len);
781 uint8_t *srr_b64_buf = OPENSSL_malloc(srr_b64_len);
782 uint8_t *sig_b64_buf = OPENSSL_malloc(sig_b64_len);
783 if (!sig_buf ||
784 !srr_b64_buf ||
785 !sig_b64_buf ||
786 !EVP_DigestSign(&md_ctx, sig_buf, &sig_len, srr_buf, srr_len) ||
787 !CBB_add_bytes(&response, (const uint8_t *)kSRRHeader,
788 strlen(kSRRHeader)) ||
789 !CBB_add_bytes(&response, srr_b64_buf,
790 EVP_EncodeBlock(srr_b64_buf, srr_buf, srr_len)) ||
791 !CBB_add_bytes(&response, (const uint8_t *)kSRRSplit,
792 strlen(kSRRSplit)) ||
793 !CBB_add_bytes(&response, sig_b64_buf,
794 EVP_EncodeBlock(sig_b64_buf, sig_buf, sig_len)) ||
795 !CBB_add_bytes(&response, (const uint8_t *)kSRREnd, strlen(kSRREnd))) {
796 OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
797 OPENSSL_free(srr_b64_buf);
798 OPENSSL_free(sig_b64_buf);
799 goto err;
800 }
801
802 OPENSSL_free(srr_b64_buf);
803 OPENSSL_free(sig_b64_buf);
804 } else {
805 CBB child;
806 uint8_t *ptr;
807 if (!CBB_add_u16_length_prefixed(&response, &child) ||
808 !CBB_add_bytes(&child, srr_buf, srr_len) ||
809 !CBB_add_u16_length_prefixed(&response, &child) ||
810 !CBB_reserve(&child, &ptr, sig_len) ||
811 !EVP_DigestSign(&md_ctx, ptr, &sig_len, srr_buf, srr_len) ||
812 !CBB_did_write(&child, sig_len) ||
813 !CBB_flush(&response)) {
814 OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
815 goto err;
816 }
817 }
818
819 if (!CBS_stow(&client_data, &client_data_buf, &client_data_len) ||
820 !CBB_finish(&response, out, out_len)) {
821 OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
822 goto err;
823 }
824
825 TRUST_TOKEN *token = TRUST_TOKEN_new(nonce, TRUST_TOKEN_NONCE_SIZE);
826 if (token == NULL) {
827 OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
828 goto err;
829 }
830 *out_token = token;
831 *out_client_data = client_data_buf;
832 *out_client_data_len = client_data_len;
833 *out_redemption_time = redemption_time;
834
835 ok = 1;
836
837 err:
838 CBB_cleanup(&response);
839 CBB_cleanup(&srr);
840 OPENSSL_free(srr_buf);
841 OPENSSL_free(sig_buf);
842 EVP_MD_CTX_cleanup(&md_ctx);
843 if (!ok) {
844 OPENSSL_free(client_data_buf);
845 }
846 return ok;
847 }
848
TRUST_TOKEN_decode_private_metadata(const TRUST_TOKEN_METHOD * method,uint8_t * out_value,const uint8_t * key,size_t key_len,const uint8_t * nonce,size_t nonce_len,uint8_t encrypted_bit)849 int TRUST_TOKEN_decode_private_metadata(const TRUST_TOKEN_METHOD *method,
850 uint8_t *out_value, const uint8_t *key,
851 size_t key_len, const uint8_t *nonce,
852 size_t nonce_len,
853 uint8_t encrypted_bit) {
854 uint8_t metadata_obfuscator =
855 get_metadata_obfuscator(key, key_len, nonce, nonce_len);
856 *out_value = encrypted_bit ^ metadata_obfuscator;
857 return 1;
858 }
859