xref: /aosp_15_r20/external/boringssl/src/crypto/trust_token/trust_token.c (revision 8fb009dc861624b67b6cdb62ea21f0f22d0c584b)
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_derive_key_from_secret,
34       pmbtoken_exp1_client_key_from_bytes,
35       pmbtoken_exp1_issuer_key_from_bytes,
36       pmbtoken_exp1_blind,
37       pmbtoken_exp1_sign,
38       pmbtoken_exp1_unblind,
39       pmbtoken_exp1_read,
40       1, /* has_private_metadata */
41       3, /* max_keys */
42       1, /* has_srr */
43   };
44   return &kMethod;
45 }
46 
TRUST_TOKEN_experiment_v2_voprf(void)47 const TRUST_TOKEN_METHOD *TRUST_TOKEN_experiment_v2_voprf(void) {
48   static const TRUST_TOKEN_METHOD kMethod = {
49       voprf_exp2_generate_key,
50       voprf_exp2_derive_key_from_secret,
51       voprf_exp2_client_key_from_bytes,
52       voprf_exp2_issuer_key_from_bytes,
53       voprf_exp2_blind,
54       voprf_exp2_sign,
55       voprf_exp2_unblind,
56       voprf_exp2_read,
57       0, /* has_private_metadata */
58       6, /* max_keys */
59       0, /* has_srr */
60   };
61   return &kMethod;
62 }
63 
TRUST_TOKEN_experiment_v2_pmb(void)64 const TRUST_TOKEN_METHOD *TRUST_TOKEN_experiment_v2_pmb(void) {
65   static const TRUST_TOKEN_METHOD kMethod = {
66       pmbtoken_exp2_generate_key,
67       pmbtoken_exp2_derive_key_from_secret,
68       pmbtoken_exp2_client_key_from_bytes,
69       pmbtoken_exp2_issuer_key_from_bytes,
70       pmbtoken_exp2_blind,
71       pmbtoken_exp2_sign,
72       pmbtoken_exp2_unblind,
73       pmbtoken_exp2_read,
74       1, /* has_private_metadata */
75       3, /* max_keys */
76       0, /* has_srr */
77   };
78   return &kMethod;
79 }
80 
TRUST_TOKEN_pst_v1_voprf(void)81 const TRUST_TOKEN_METHOD *TRUST_TOKEN_pst_v1_voprf(void) {
82   static const TRUST_TOKEN_METHOD kMethod = {
83       voprf_pst1_generate_key,
84       voprf_pst1_derive_key_from_secret,
85       voprf_pst1_client_key_from_bytes,
86       voprf_pst1_issuer_key_from_bytes,
87       voprf_pst1_blind,
88       voprf_pst1_sign,
89       voprf_pst1_unblind,
90       voprf_pst1_read,
91       0, /* has_private_metadata */
92       6, /* max_keys */
93       0, /* has_srr */
94   };
95   return &kMethod;
96 }
97 
TRUST_TOKEN_pst_v1_pmb(void)98 const TRUST_TOKEN_METHOD *TRUST_TOKEN_pst_v1_pmb(void) {
99   static const TRUST_TOKEN_METHOD kMethod = {
100       pmbtoken_pst1_generate_key,
101       pmbtoken_pst1_derive_key_from_secret,
102       pmbtoken_pst1_client_key_from_bytes,
103       pmbtoken_pst1_issuer_key_from_bytes,
104       pmbtoken_pst1_blind,
105       pmbtoken_pst1_sign,
106       pmbtoken_pst1_unblind,
107       pmbtoken_pst1_read,
108       1, /* has_private_metadata */
109       3, /* max_keys */
110       0, /* has_srr */
111   };
112   return &kMethod;
113 }
114 
115 
TRUST_TOKEN_PRETOKEN_free(TRUST_TOKEN_PRETOKEN * pretoken)116 void TRUST_TOKEN_PRETOKEN_free(TRUST_TOKEN_PRETOKEN *pretoken) {
117   OPENSSL_free(pretoken);
118 }
119 
TRUST_TOKEN_new(const uint8_t * data,size_t len)120 TRUST_TOKEN *TRUST_TOKEN_new(const uint8_t *data, size_t len) {
121   TRUST_TOKEN *ret = OPENSSL_zalloc(sizeof(TRUST_TOKEN));
122   if (ret == NULL) {
123     return NULL;
124   }
125   ret->data = OPENSSL_memdup(data, len);
126   if (len != 0 && ret->data == NULL) {
127     OPENSSL_free(ret);
128     return NULL;
129   }
130   ret->len = len;
131   return ret;
132 }
133 
TRUST_TOKEN_free(TRUST_TOKEN * token)134 void TRUST_TOKEN_free(TRUST_TOKEN *token) {
135   if (token == NULL) {
136     return;
137   }
138   OPENSSL_free(token->data);
139   OPENSSL_free(token);
140 }
141 
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)142 int TRUST_TOKEN_generate_key(const TRUST_TOKEN_METHOD *method,
143                              uint8_t *out_priv_key, size_t *out_priv_key_len,
144                              size_t max_priv_key_len, uint8_t *out_pub_key,
145                              size_t *out_pub_key_len, size_t max_pub_key_len,
146                              uint32_t id) {
147   // Prepend the key ID in front of the PMBTokens format.
148   CBB priv_cbb, pub_cbb;
149   CBB_init_fixed(&priv_cbb, out_priv_key, max_priv_key_len);
150   CBB_init_fixed(&pub_cbb, out_pub_key, max_pub_key_len);
151   if (!CBB_add_u32(&priv_cbb, id) ||  //
152       !CBB_add_u32(&pub_cbb, id)) {
153     OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_BUFFER_TOO_SMALL);
154     return 0;
155   }
156 
157   if (!method->generate_key(&priv_cbb, &pub_cbb)) {
158     return 0;
159   }
160 
161   if (!CBB_finish(&priv_cbb, NULL, out_priv_key_len) ||
162       !CBB_finish(&pub_cbb, NULL, out_pub_key_len)) {
163     OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_BUFFER_TOO_SMALL);
164     return 0;
165   }
166 
167   return 1;
168 }
169 
TRUST_TOKEN_derive_key_from_secret(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,const uint8_t * secret,size_t secret_len)170 int TRUST_TOKEN_derive_key_from_secret(
171     const TRUST_TOKEN_METHOD *method, uint8_t *out_priv_key,
172     size_t *out_priv_key_len, size_t max_priv_key_len, uint8_t *out_pub_key,
173     size_t *out_pub_key_len, size_t max_pub_key_len, uint32_t id,
174     const uint8_t *secret, size_t secret_len) {
175   // Prepend the key ID in front of the PMBTokens format.
176   CBB priv_cbb, pub_cbb;
177   CBB_init_fixed(&priv_cbb, out_priv_key, max_priv_key_len);
178   CBB_init_fixed(&pub_cbb, out_pub_key, max_pub_key_len);
179   if (!CBB_add_u32(&priv_cbb, id) ||  //
180       !CBB_add_u32(&pub_cbb, id)) {
181     OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_BUFFER_TOO_SMALL);
182     return 0;
183   }
184 
185   if (!method->derive_key_from_secret(&priv_cbb, &pub_cbb, secret,
186                                         secret_len)) {
187     return 0;
188   }
189 
190   if (!CBB_finish(&priv_cbb, NULL, out_priv_key_len) ||
191       !CBB_finish(&pub_cbb, NULL, out_pub_key_len)) {
192     OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_BUFFER_TOO_SMALL);
193     return 0;
194   }
195 
196   return 1;
197 }
198 
TRUST_TOKEN_CLIENT_new(const TRUST_TOKEN_METHOD * method,size_t max_batchsize)199 TRUST_TOKEN_CLIENT *TRUST_TOKEN_CLIENT_new(const TRUST_TOKEN_METHOD *method,
200                                            size_t max_batchsize) {
201   if (max_batchsize > 0xffff) {
202     // The protocol supports only two-byte token counts.
203     OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_OVERFLOW);
204     return NULL;
205   }
206 
207   TRUST_TOKEN_CLIENT *ret = OPENSSL_zalloc(sizeof(TRUST_TOKEN_CLIENT));
208   if (ret == NULL) {
209     return NULL;
210   }
211   ret->method = method;
212   ret->max_batchsize = (uint16_t)max_batchsize;
213   return ret;
214 }
215 
TRUST_TOKEN_CLIENT_free(TRUST_TOKEN_CLIENT * ctx)216 void TRUST_TOKEN_CLIENT_free(TRUST_TOKEN_CLIENT *ctx) {
217   if (ctx == NULL) {
218     return;
219   }
220   EVP_PKEY_free(ctx->srr_key);
221   sk_TRUST_TOKEN_PRETOKEN_pop_free(ctx->pretokens, TRUST_TOKEN_PRETOKEN_free);
222   OPENSSL_free(ctx);
223 }
224 
TRUST_TOKEN_CLIENT_add_key(TRUST_TOKEN_CLIENT * ctx,size_t * out_key_index,const uint8_t * key,size_t key_len)225 int TRUST_TOKEN_CLIENT_add_key(TRUST_TOKEN_CLIENT *ctx, size_t *out_key_index,
226                                const uint8_t *key, size_t key_len) {
227   if (ctx->num_keys == OPENSSL_ARRAY_SIZE(ctx->keys) ||
228       ctx->num_keys >= ctx->method->max_keys) {
229     OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_TOO_MANY_KEYS);
230     return 0;
231   }
232 
233   struct trust_token_client_key_st *key_s = &ctx->keys[ctx->num_keys];
234   CBS cbs;
235   CBS_init(&cbs, key, key_len);
236   uint32_t key_id;
237   if (!CBS_get_u32(&cbs, &key_id) ||
238       !ctx->method->client_key_from_bytes(&key_s->key, CBS_data(&cbs),
239                                           CBS_len(&cbs))) {
240     OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
241     return 0;
242   }
243   key_s->id = key_id;
244   *out_key_index = ctx->num_keys;
245   ctx->num_keys += 1;
246   return 1;
247 }
248 
TRUST_TOKEN_CLIENT_set_srr_key(TRUST_TOKEN_CLIENT * ctx,EVP_PKEY * key)249 int TRUST_TOKEN_CLIENT_set_srr_key(TRUST_TOKEN_CLIENT *ctx, EVP_PKEY *key) {
250   if (!ctx->method->has_srr) {
251     return 1;
252   }
253   EVP_PKEY_free(ctx->srr_key);
254   EVP_PKEY_up_ref(key);
255   ctx->srr_key = key;
256   return 1;
257 }
258 
trust_token_client_begin_issuance_impl(TRUST_TOKEN_CLIENT * ctx,uint8_t ** out,size_t * out_len,size_t count,int include_message,const uint8_t * msg,size_t msg_len)259 static int trust_token_client_begin_issuance_impl(
260     TRUST_TOKEN_CLIENT *ctx, uint8_t **out, size_t *out_len, size_t count,
261     int include_message, const uint8_t *msg, size_t msg_len) {
262   if (count > ctx->max_batchsize) {
263     count = ctx->max_batchsize;
264   }
265 
266   int ret = 0;
267   CBB request;
268   STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens = NULL;
269   if (!CBB_init(&request, 0) ||
270       !CBB_add_u16(&request, count)) {
271     goto err;
272   }
273 
274   pretokens =
275       ctx->method->blind(&request, count, include_message, msg, msg_len);
276   if (pretokens == NULL) {
277     goto err;
278   }
279 
280   if (!CBB_finish(&request, out, out_len)) {
281     goto err;
282   }
283 
284   sk_TRUST_TOKEN_PRETOKEN_pop_free(ctx->pretokens, TRUST_TOKEN_PRETOKEN_free);
285   ctx->pretokens = pretokens;
286   pretokens = NULL;
287   ret = 1;
288 
289 err:
290   CBB_cleanup(&request);
291   sk_TRUST_TOKEN_PRETOKEN_pop_free(pretokens, TRUST_TOKEN_PRETOKEN_free);
292   return ret;
293 }
294 
TRUST_TOKEN_CLIENT_begin_issuance(TRUST_TOKEN_CLIENT * ctx,uint8_t ** out,size_t * out_len,size_t count)295 int TRUST_TOKEN_CLIENT_begin_issuance(TRUST_TOKEN_CLIENT *ctx, uint8_t **out,
296                                       size_t *out_len, size_t count) {
297   return trust_token_client_begin_issuance_impl(ctx, out, out_len, count,
298                                                 /*include_message=*/0, NULL, 0);
299 }
300 
TRUST_TOKEN_CLIENT_begin_issuance_over_message(TRUST_TOKEN_CLIENT * ctx,uint8_t ** out,size_t * out_len,size_t count,const uint8_t * msg,size_t msg_len)301 int TRUST_TOKEN_CLIENT_begin_issuance_over_message(
302     TRUST_TOKEN_CLIENT *ctx, uint8_t **out, size_t *out_len, size_t count,
303     const uint8_t *msg, size_t msg_len) {
304   return trust_token_client_begin_issuance_impl(
305       ctx, out, out_len, count, /*include_message=*/1, msg, msg_len);
306 }
307 
308 
STACK_OF(TRUST_TOKEN)309 STACK_OF(TRUST_TOKEN) *
310     TRUST_TOKEN_CLIENT_finish_issuance(TRUST_TOKEN_CLIENT *ctx,
311                                        size_t *out_key_index,
312                                        const uint8_t *response,
313                                        size_t response_len) {
314   CBS in;
315   CBS_init(&in, response, response_len);
316   uint16_t count;
317   uint32_t key_id;
318   if (!CBS_get_u16(&in, &count) ||
319       !CBS_get_u32(&in, &key_id)) {
320     OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
321     return NULL;
322   }
323 
324   size_t key_index = 0;
325   const struct trust_token_client_key_st *key = NULL;
326   for (size_t i = 0; i < ctx->num_keys; i++) {
327     if (ctx->keys[i].id == key_id) {
328       key_index = i;
329       key = &ctx->keys[i];
330       break;
331     }
332   }
333 
334   if (key == NULL) {
335     OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_KEY_ID);
336     return NULL;
337   }
338 
339   if (count > sk_TRUST_TOKEN_PRETOKEN_num(ctx->pretokens)) {
340     OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
341     return NULL;
342   }
343 
344   STACK_OF(TRUST_TOKEN) *tokens =
345       ctx->method->unblind(&key->key, ctx->pretokens, &in, count, key_id);
346   if (tokens == NULL) {
347     return NULL;
348   }
349 
350   if (CBS_len(&in) != 0) {
351     OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
352     sk_TRUST_TOKEN_pop_free(tokens, TRUST_TOKEN_free);
353     return NULL;
354   }
355 
356   sk_TRUST_TOKEN_PRETOKEN_pop_free(ctx->pretokens, TRUST_TOKEN_PRETOKEN_free);
357   ctx->pretokens = NULL;
358 
359   *out_key_index = key_index;
360   return tokens;
361 }
362 
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)363 int TRUST_TOKEN_CLIENT_begin_redemption(TRUST_TOKEN_CLIENT *ctx, uint8_t **out,
364                                         size_t *out_len,
365                                         const TRUST_TOKEN *token,
366                                         const uint8_t *data, size_t data_len,
367                                         uint64_t time) {
368   CBB request, token_inner, inner;
369   if (!CBB_init(&request, 0) ||
370       !CBB_add_u16_length_prefixed(&request, &token_inner) ||
371       !CBB_add_bytes(&token_inner, token->data, token->len) ||
372       !CBB_add_u16_length_prefixed(&request, &inner) ||
373       !CBB_add_bytes(&inner, data, data_len) ||
374       (ctx->method->has_srr && !CBB_add_u64(&request, time)) ||
375       !CBB_finish(&request, out, out_len)) {
376     CBB_cleanup(&request);
377     return 0;
378   }
379   return 1;
380 }
381 
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)382 int TRUST_TOKEN_CLIENT_finish_redemption(TRUST_TOKEN_CLIENT *ctx,
383                                          uint8_t **out_rr, size_t *out_rr_len,
384                                          uint8_t **out_sig, size_t *out_sig_len,
385                                          const uint8_t *response,
386                                          size_t response_len) {
387   CBS in, srr, sig;
388   CBS_init(&in, response, response_len);
389   if (!ctx->method->has_srr) {
390     if (!CBS_stow(&in, out_rr, out_rr_len)) {
391       return 0;
392     }
393 
394     *out_sig = NULL;
395     *out_sig_len = 0;
396     return 1;
397   }
398 
399   if (!CBS_get_u16_length_prefixed(&in, &srr) ||
400       !CBS_get_u16_length_prefixed(&in, &sig) ||
401       CBS_len(&in) != 0) {
402     OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_ERROR);
403     return 0;
404   }
405 
406   if (ctx->srr_key == NULL) {
407     OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_NO_SRR_KEY_CONFIGURED);
408     return 0;
409   }
410 
411   EVP_MD_CTX md_ctx;
412   EVP_MD_CTX_init(&md_ctx);
413   int sig_ok = EVP_DigestVerifyInit(&md_ctx, NULL, NULL, NULL, ctx->srr_key) &&
414                EVP_DigestVerify(&md_ctx, CBS_data(&sig), CBS_len(&sig),
415                                 CBS_data(&srr), CBS_len(&srr));
416   EVP_MD_CTX_cleanup(&md_ctx);
417 
418   if (!sig_ok) {
419     OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_SRR_SIGNATURE_ERROR);
420     return 0;
421   }
422 
423   uint8_t *srr_buf = NULL, *sig_buf = NULL;
424   size_t srr_len, sig_len;
425   if (!CBS_stow(&srr, &srr_buf, &srr_len) ||
426       !CBS_stow(&sig, &sig_buf, &sig_len)) {
427     OPENSSL_free(srr_buf);
428     OPENSSL_free(sig_buf);
429     return 0;
430   }
431 
432   *out_rr = srr_buf;
433   *out_rr_len = srr_len;
434   *out_sig = sig_buf;
435   *out_sig_len = sig_len;
436   return 1;
437 }
438 
TRUST_TOKEN_ISSUER_new(const TRUST_TOKEN_METHOD * method,size_t max_batchsize)439 TRUST_TOKEN_ISSUER *TRUST_TOKEN_ISSUER_new(const TRUST_TOKEN_METHOD *method,
440                                            size_t max_batchsize) {
441   if (max_batchsize > 0xffff) {
442     // The protocol supports only two-byte token counts.
443     OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_OVERFLOW);
444     return NULL;
445   }
446 
447   TRUST_TOKEN_ISSUER *ret = OPENSSL_zalloc(sizeof(TRUST_TOKEN_ISSUER));
448   if (ret == NULL) {
449     return NULL;
450   }
451   ret->method = method;
452   ret->max_batchsize = (uint16_t)max_batchsize;
453   return ret;
454 }
455 
TRUST_TOKEN_ISSUER_free(TRUST_TOKEN_ISSUER * ctx)456 void TRUST_TOKEN_ISSUER_free(TRUST_TOKEN_ISSUER *ctx) {
457   if (ctx == NULL) {
458     return;
459   }
460   EVP_PKEY_free(ctx->srr_key);
461   OPENSSL_free(ctx->metadata_key);
462   OPENSSL_free(ctx);
463 }
464 
TRUST_TOKEN_ISSUER_add_key(TRUST_TOKEN_ISSUER * ctx,const uint8_t * key,size_t key_len)465 int TRUST_TOKEN_ISSUER_add_key(TRUST_TOKEN_ISSUER *ctx, const uint8_t *key,
466                                size_t key_len) {
467   if (ctx->num_keys == OPENSSL_ARRAY_SIZE(ctx->keys) ||
468       ctx->num_keys >= ctx->method->max_keys) {
469     OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_TOO_MANY_KEYS);
470     return 0;
471   }
472 
473   struct trust_token_issuer_key_st *key_s = &ctx->keys[ctx->num_keys];
474   CBS cbs;
475   CBS_init(&cbs, key, key_len);
476   uint32_t key_id;
477   if (!CBS_get_u32(&cbs, &key_id) ||
478       !ctx->method->issuer_key_from_bytes(&key_s->key, CBS_data(&cbs),
479                                           CBS_len(&cbs))) {
480     OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
481     return 0;
482   }
483 
484   key_s->id = key_id;
485   ctx->num_keys += 1;
486   return 1;
487 }
488 
TRUST_TOKEN_ISSUER_set_srr_key(TRUST_TOKEN_ISSUER * ctx,EVP_PKEY * key)489 int TRUST_TOKEN_ISSUER_set_srr_key(TRUST_TOKEN_ISSUER *ctx, EVP_PKEY *key) {
490   EVP_PKEY_free(ctx->srr_key);
491   EVP_PKEY_up_ref(key);
492   ctx->srr_key = key;
493   return 1;
494 }
495 
TRUST_TOKEN_ISSUER_set_metadata_key(TRUST_TOKEN_ISSUER * ctx,const uint8_t * key,size_t len)496 int TRUST_TOKEN_ISSUER_set_metadata_key(TRUST_TOKEN_ISSUER *ctx,
497                                         const uint8_t *key, size_t len) {
498   if (len < 32) {
499     OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_METADATA_KEY);
500   }
501   OPENSSL_free(ctx->metadata_key);
502   ctx->metadata_key_len = 0;
503   ctx->metadata_key = OPENSSL_memdup(key, len);
504   if (ctx->metadata_key == NULL) {
505     return 0;
506   }
507   ctx->metadata_key_len = len;
508   return 1;
509 }
510 
trust_token_issuer_get_key(const TRUST_TOKEN_ISSUER * ctx,uint32_t key_id)511 static const struct trust_token_issuer_key_st *trust_token_issuer_get_key(
512     const TRUST_TOKEN_ISSUER *ctx, uint32_t key_id) {
513   for (size_t i = 0; i < ctx->num_keys; i++) {
514     if (ctx->keys[i].id == key_id) {
515       return &ctx->keys[i];
516     }
517   }
518   return NULL;
519 }
520 
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)521 int TRUST_TOKEN_ISSUER_issue(const TRUST_TOKEN_ISSUER *ctx, uint8_t **out,
522                              size_t *out_len, size_t *out_tokens_issued,
523                              const uint8_t *request, size_t request_len,
524                              uint32_t public_metadata, uint8_t private_metadata,
525                              size_t max_issuance) {
526   if (max_issuance > ctx->max_batchsize) {
527     max_issuance = ctx->max_batchsize;
528   }
529 
530   const struct trust_token_issuer_key_st *key =
531       trust_token_issuer_get_key(ctx, public_metadata);
532   if (key == NULL || private_metadata > 1 ||
533       (!ctx->method->has_private_metadata && private_metadata != 0)) {
534     OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_METADATA);
535     return 0;
536   }
537 
538   CBS in;
539   uint16_t num_requested;
540   CBS_init(&in, request, request_len);
541   if (!CBS_get_u16(&in, &num_requested)) {
542     OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
543     return 0;
544   }
545 
546   size_t num_to_issue = num_requested;
547   if (num_to_issue > max_issuance) {
548     num_to_issue = max_issuance;
549   }
550 
551   int ret = 0;
552   CBB response;
553   if (!CBB_init(&response, 0) ||
554       !CBB_add_u16(&response, num_to_issue) ||
555       !CBB_add_u32(&response, public_metadata)) {
556     goto err;
557   }
558 
559   if (!ctx->method->sign(&key->key, &response, &in, num_requested, num_to_issue,
560                          private_metadata)) {
561     goto err;
562   }
563 
564   if (CBS_len(&in) != 0) {
565     OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
566     goto err;
567   }
568 
569   if (!CBB_finish(&response, out, out_len)) {
570     goto err;
571   }
572 
573   *out_tokens_issued = num_to_issue;
574   ret = 1;
575 
576 err:
577   CBB_cleanup(&response);
578   return ret;
579 }
580 
trust_token_issuer_redeem_impl(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,int include_message,const uint8_t * msg,size_t msg_len)581 static int trust_token_issuer_redeem_impl(
582     const TRUST_TOKEN_ISSUER *ctx, uint32_t *out_public, uint8_t *out_private,
583     TRUST_TOKEN **out_token, uint8_t **out_client_data,
584     size_t *out_client_data_len, const uint8_t *request, size_t request_len,
585     int include_message, const uint8_t *msg, size_t msg_len) {
586   CBS request_cbs, token_cbs;
587   CBS_init(&request_cbs, request, request_len);
588   if (!CBS_get_u16_length_prefixed(&request_cbs, &token_cbs)) {
589     OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_ERROR);
590     return 0;
591   }
592 
593   uint32_t public_metadata = 0;
594   uint8_t private_metadata = 0;
595 
596   // Parse the token. If there is an error, treat it as an invalid token.
597   if (!CBS_get_u32(&token_cbs, &public_metadata)) {
598     OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_TOKEN);
599     return 0;
600   }
601 
602   const struct trust_token_issuer_key_st *key =
603       trust_token_issuer_get_key(ctx, public_metadata);
604   uint8_t nonce[TRUST_TOKEN_NONCE_SIZE];
605   if (key == NULL ||
606       !ctx->method->read(&key->key, nonce, &private_metadata,
607                          CBS_data(&token_cbs), CBS_len(&token_cbs),
608                          include_message, msg, msg_len)) {
609     OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_TOKEN);
610     return 0;
611   }
612 
613   CBS client_data;
614   if (!CBS_get_u16_length_prefixed(&request_cbs, &client_data) ||
615       (ctx->method->has_srr && !CBS_skip(&request_cbs, 8)) ||
616       CBS_len(&request_cbs) != 0) {
617     OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_ERROR);
618     return 0;
619   }
620 
621   uint8_t *client_data_buf = NULL;
622   size_t client_data_len = 0;
623   if (!CBS_stow(&client_data, &client_data_buf, &client_data_len)) {
624     goto err;
625   }
626 
627   TRUST_TOKEN *token = TRUST_TOKEN_new(nonce, TRUST_TOKEN_NONCE_SIZE);
628   if (token == NULL) {
629     goto err;
630   }
631   *out_public = public_metadata;
632   *out_private = private_metadata;
633   *out_token = token;
634   *out_client_data = client_data_buf;
635   *out_client_data_len = client_data_len;
636 
637   return 1;
638 
639 err:
640   OPENSSL_free(client_data_buf);
641   return 0;
642 }
643 
644 
TRUST_TOKEN_ISSUER_redeem(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)645 int TRUST_TOKEN_ISSUER_redeem(const TRUST_TOKEN_ISSUER *ctx,
646                               uint32_t *out_public, uint8_t *out_private,
647                               TRUST_TOKEN **out_token,
648                               uint8_t **out_client_data,
649                               size_t *out_client_data_len,
650                               const uint8_t *request, size_t request_len) {
651   return trust_token_issuer_redeem_impl(ctx, out_public, out_private, out_token,
652                                         out_client_data, out_client_data_len,
653                                         request, request_len, 0, NULL, 0);
654 }
655 
TRUST_TOKEN_ISSUER_redeem_over_message(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,const uint8_t * msg,size_t msg_len)656 int TRUST_TOKEN_ISSUER_redeem_over_message(
657     const TRUST_TOKEN_ISSUER *ctx, uint32_t *out_public, uint8_t *out_private,
658     TRUST_TOKEN **out_token, uint8_t **out_client_data,
659     size_t *out_client_data_len, const uint8_t *request, size_t request_len,
660     const uint8_t *msg, size_t msg_len) {
661   return trust_token_issuer_redeem_impl(ctx, out_public, out_private, out_token,
662                                         out_client_data, out_client_data_len,
663                                         request, request_len, 1, msg, msg_len);
664 }
665 
get_metadata_obfuscator(const uint8_t * key,size_t key_len,const uint8_t * client_data,size_t client_data_len)666 static uint8_t get_metadata_obfuscator(const uint8_t *key, size_t key_len,
667                                        const uint8_t *client_data,
668                                        size_t client_data_len) {
669   uint8_t metadata_obfuscator[SHA256_DIGEST_LENGTH];
670   SHA256_CTX sha_ctx;
671   SHA256_Init(&sha_ctx);
672   SHA256_Update(&sha_ctx, key, key_len);
673   SHA256_Update(&sha_ctx, client_data, client_data_len);
674   SHA256_Final(metadata_obfuscator, &sha_ctx);
675   return metadata_obfuscator[0] >> 7;
676 }
677 
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)678 int TRUST_TOKEN_decode_private_metadata(const TRUST_TOKEN_METHOD *method,
679                                         uint8_t *out_value, const uint8_t *key,
680                                         size_t key_len, const uint8_t *nonce,
681                                         size_t nonce_len,
682                                         uint8_t encrypted_bit) {
683   uint8_t metadata_obfuscator =
684       get_metadata_obfuscator(key, key_len, nonce, nonce_len);
685   *out_value = encrypted_bit ^ metadata_obfuscator;
686   return 1;
687 }
688