• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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