1 // Copyright 2019 The BoringSSL Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include <openssl/bytestring.h>
16 #include <openssl/err.h>
17 #include <openssl/evp.h>
18 #include <openssl/mem.h>
19 #include <openssl/sha2.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/main/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 =
122       reinterpret_cast<TRUST_TOKEN *>(OPENSSL_zalloc(sizeof(TRUST_TOKEN)));
123   if (ret == NULL) {
124     return NULL;
125   }
126   ret->data = reinterpret_cast<uint8_t *>(OPENSSL_memdup(data, len));
127   if (len != 0 && ret->data == NULL) {
128     OPENSSL_free(ret);
129     return NULL;
130   }
131   ret->len = len;
132   return ret;
133 }
134 
TRUST_TOKEN_free(TRUST_TOKEN * token)135 void TRUST_TOKEN_free(TRUST_TOKEN *token) {
136   if (token == NULL) {
137     return;
138   }
139   OPENSSL_free(token->data);
140   OPENSSL_free(token);
141 }
142 
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)143 int TRUST_TOKEN_generate_key(const TRUST_TOKEN_METHOD *method,
144                              uint8_t *out_priv_key, size_t *out_priv_key_len,
145                              size_t max_priv_key_len, uint8_t *out_pub_key,
146                              size_t *out_pub_key_len, size_t max_pub_key_len,
147                              uint32_t id) {
148   // Prepend the key ID in front of the PMBTokens format.
149   CBB priv_cbb, pub_cbb;
150   CBB_init_fixed(&priv_cbb, out_priv_key, max_priv_key_len);
151   CBB_init_fixed(&pub_cbb, out_pub_key, max_pub_key_len);
152   if (!CBB_add_u32(&priv_cbb, id) ||  //
153       !CBB_add_u32(&pub_cbb, id)) {
154     OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_BUFFER_TOO_SMALL);
155     return 0;
156   }
157 
158   if (!method->generate_key(&priv_cbb, &pub_cbb)) {
159     return 0;
160   }
161 
162   if (!CBB_finish(&priv_cbb, NULL, out_priv_key_len) ||
163       !CBB_finish(&pub_cbb, NULL, out_pub_key_len)) {
164     OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_BUFFER_TOO_SMALL);
165     return 0;
166   }
167 
168   return 1;
169 }
170 
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)171 int TRUST_TOKEN_derive_key_from_secret(
172     const TRUST_TOKEN_METHOD *method, uint8_t *out_priv_key,
173     size_t *out_priv_key_len, size_t max_priv_key_len, uint8_t *out_pub_key,
174     size_t *out_pub_key_len, size_t max_pub_key_len, uint32_t id,
175     const uint8_t *secret, size_t secret_len) {
176   // Prepend the key ID in front of the PMBTokens format.
177   CBB priv_cbb, pub_cbb;
178   CBB_init_fixed(&priv_cbb, out_priv_key, max_priv_key_len);
179   CBB_init_fixed(&pub_cbb, out_pub_key, max_pub_key_len);
180   if (!CBB_add_u32(&priv_cbb, id) ||  //
181       !CBB_add_u32(&pub_cbb, id)) {
182     OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_BUFFER_TOO_SMALL);
183     return 0;
184   }
185 
186   if (!method->derive_key_from_secret(&priv_cbb, &pub_cbb, secret,
187                                       secret_len)) {
188     return 0;
189   }
190 
191   if (!CBB_finish(&priv_cbb, NULL, out_priv_key_len) ||
192       !CBB_finish(&pub_cbb, NULL, out_pub_key_len)) {
193     OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_BUFFER_TOO_SMALL);
194     return 0;
195   }
196 
197   return 1;
198 }
199 
TRUST_TOKEN_CLIENT_new(const TRUST_TOKEN_METHOD * method,size_t max_batchsize)200 TRUST_TOKEN_CLIENT *TRUST_TOKEN_CLIENT_new(const TRUST_TOKEN_METHOD *method,
201                                            size_t max_batchsize) {
202   if (max_batchsize > 0xffff) {
203     // The protocol supports only two-byte token counts.
204     OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_OVERFLOW);
205     return NULL;
206   }
207 
208   TRUST_TOKEN_CLIENT *ret = reinterpret_cast<TRUST_TOKEN_CLIENT *>(
209       OPENSSL_zalloc(sizeof(TRUST_TOKEN_CLIENT)));
210   if (ret == NULL) {
211     return NULL;
212   }
213   ret->method = method;
214   ret->max_batchsize = (uint16_t)max_batchsize;
215   return ret;
216 }
217 
TRUST_TOKEN_CLIENT_free(TRUST_TOKEN_CLIENT * ctx)218 void TRUST_TOKEN_CLIENT_free(TRUST_TOKEN_CLIENT *ctx) {
219   if (ctx == NULL) {
220     return;
221   }
222   EVP_PKEY_free(ctx->srr_key);
223   sk_TRUST_TOKEN_PRETOKEN_pop_free(ctx->pretokens, TRUST_TOKEN_PRETOKEN_free);
224   OPENSSL_free(ctx);
225 }
226 
TRUST_TOKEN_CLIENT_add_key(TRUST_TOKEN_CLIENT * ctx,size_t * out_key_index,const uint8_t * key,size_t key_len)227 int TRUST_TOKEN_CLIENT_add_key(TRUST_TOKEN_CLIENT *ctx, size_t *out_key_index,
228                                const uint8_t *key, size_t key_len) {
229   if (ctx->num_keys == OPENSSL_ARRAY_SIZE(ctx->keys) ||
230       ctx->num_keys >= ctx->method->max_keys) {
231     OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_TOO_MANY_KEYS);
232     return 0;
233   }
234 
235   struct trust_token_client_key_st *key_s = &ctx->keys[ctx->num_keys];
236   CBS cbs;
237   CBS_init(&cbs, key, key_len);
238   uint32_t key_id;
239   if (!CBS_get_u32(&cbs, &key_id) ||
240       !ctx->method->client_key_from_bytes(&key_s->key, CBS_data(&cbs),
241                                           CBS_len(&cbs))) {
242     OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
243     return 0;
244   }
245   key_s->id = key_id;
246   *out_key_index = ctx->num_keys;
247   ctx->num_keys += 1;
248   return 1;
249 }
250 
TRUST_TOKEN_CLIENT_set_srr_key(TRUST_TOKEN_CLIENT * ctx,EVP_PKEY * key)251 int TRUST_TOKEN_CLIENT_set_srr_key(TRUST_TOKEN_CLIENT *ctx, EVP_PKEY *key) {
252   if (!ctx->method->has_srr) {
253     return 1;
254   }
255   EVP_PKEY_free(ctx->srr_key);
256   EVP_PKEY_up_ref(key);
257   ctx->srr_key = key;
258   return 1;
259 }
260 
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)261 static int trust_token_client_begin_issuance_impl(
262     TRUST_TOKEN_CLIENT *ctx, uint8_t **out, size_t *out_len, size_t count,
263     int include_message, const uint8_t *msg, size_t msg_len) {
264   if (count > ctx->max_batchsize) {
265     count = ctx->max_batchsize;
266   }
267 
268   int ret = 0;
269   CBB request;
270   STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens = NULL;
271   if (!CBB_init(&request, 0) || !CBB_add_u16(&request, count)) {
272     goto err;
273   }
274 
275   pretokens =
276       ctx->method->blind(&request, count, include_message, msg, msg_len);
277   if (pretokens == NULL) {
278     goto err;
279   }
280 
281   if (!CBB_finish(&request, out, out_len)) {
282     goto err;
283   }
284 
285   sk_TRUST_TOKEN_PRETOKEN_pop_free(ctx->pretokens, TRUST_TOKEN_PRETOKEN_free);
286   ctx->pretokens = pretokens;
287   pretokens = NULL;
288   ret = 1;
289 
290 err:
291   CBB_cleanup(&request);
292   sk_TRUST_TOKEN_PRETOKEN_pop_free(pretokens, TRUST_TOKEN_PRETOKEN_free);
293   return ret;
294 }
295 
TRUST_TOKEN_CLIENT_begin_issuance(TRUST_TOKEN_CLIENT * ctx,uint8_t ** out,size_t * out_len,size_t count)296 int TRUST_TOKEN_CLIENT_begin_issuance(TRUST_TOKEN_CLIENT *ctx, uint8_t **out,
297                                       size_t *out_len, size_t count) {
298   return trust_token_client_begin_issuance_impl(ctx, out, out_len, count,
299                                                 /*include_message=*/0, NULL, 0);
300 }
301 
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)302 int TRUST_TOKEN_CLIENT_begin_issuance_over_message(
303     TRUST_TOKEN_CLIENT *ctx, uint8_t **out, size_t *out_len, size_t count,
304     const uint8_t *msg, size_t msg_len) {
305   return trust_token_client_begin_issuance_impl(
306       ctx, out, out_len, count, /*include_message=*/1, msg, msg_len);
307 }
308 
309 
STACK_OF(TRUST_TOKEN)310 STACK_OF(TRUST_TOKEN) *TRUST_TOKEN_CLIENT_finish_issuance(
311     TRUST_TOKEN_CLIENT *ctx, size_t *out_key_index, const uint8_t *response,
312     size_t response_len) {
313   CBS in;
314   CBS_init(&in, response, response_len);
315   uint16_t count;
316   uint32_t key_id;
317   if (!CBS_get_u16(&in, &count) || !CBS_get_u32(&in, &key_id)) {
318     OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
319     return NULL;
320   }
321 
322   size_t key_index = 0;
323   const struct trust_token_client_key_st *key = NULL;
324   for (size_t i = 0; i < ctx->num_keys; i++) {
325     if (ctx->keys[i].id == key_id) {
326       key_index = i;
327       key = &ctx->keys[i];
328       break;
329     }
330   }
331 
332   if (key == NULL) {
333     OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_KEY_ID);
334     return NULL;
335   }
336 
337   if (count > sk_TRUST_TOKEN_PRETOKEN_num(ctx->pretokens)) {
338     OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
339     return NULL;
340   }
341 
342   STACK_OF(TRUST_TOKEN) *tokens =
343       ctx->method->unblind(&key->key, ctx->pretokens, &in, count, key_id);
344   if (tokens == NULL) {
345     return NULL;
346   }
347 
348   if (CBS_len(&in) != 0) {
349     OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
350     sk_TRUST_TOKEN_pop_free(tokens, TRUST_TOKEN_free);
351     return NULL;
352   }
353 
354   sk_TRUST_TOKEN_PRETOKEN_pop_free(ctx->pretokens, TRUST_TOKEN_PRETOKEN_free);
355   ctx->pretokens = NULL;
356 
357   *out_key_index = key_index;
358   return tokens;
359 }
360 
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)361 int TRUST_TOKEN_CLIENT_begin_redemption(TRUST_TOKEN_CLIENT *ctx, uint8_t **out,
362                                         size_t *out_len,
363                                         const TRUST_TOKEN *token,
364                                         const uint8_t *data, size_t data_len,
365                                         uint64_t time) {
366   CBB request, token_inner, inner;
367   if (!CBB_init(&request, 0) ||
368       !CBB_add_u16_length_prefixed(&request, &token_inner) ||
369       !CBB_add_bytes(&token_inner, token->data, token->len) ||
370       !CBB_add_u16_length_prefixed(&request, &inner) ||
371       !CBB_add_bytes(&inner, data, data_len) ||
372       (ctx->method->has_srr && !CBB_add_u64(&request, time)) ||
373       !CBB_finish(&request, out, out_len)) {
374     CBB_cleanup(&request);
375     return 0;
376   }
377   return 1;
378 }
379 
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)380 int TRUST_TOKEN_CLIENT_finish_redemption(TRUST_TOKEN_CLIENT *ctx,
381                                          uint8_t **out_rr, size_t *out_rr_len,
382                                          uint8_t **out_sig, size_t *out_sig_len,
383                                          const uint8_t *response,
384                                          size_t response_len) {
385   CBS in, srr, sig;
386   CBS_init(&in, response, response_len);
387   if (!ctx->method->has_srr) {
388     if (!CBS_stow(&in, out_rr, out_rr_len)) {
389       return 0;
390     }
391 
392     *out_sig = NULL;
393     *out_sig_len = 0;
394     return 1;
395   }
396 
397   if (!CBS_get_u16_length_prefixed(&in, &srr) ||
398       !CBS_get_u16_length_prefixed(&in, &sig) || CBS_len(&in) != 0) {
399     OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_ERROR);
400     return 0;
401   }
402 
403   if (ctx->srr_key == NULL) {
404     OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_NO_SRR_KEY_CONFIGURED);
405     return 0;
406   }
407 
408   EVP_MD_CTX md_ctx;
409   EVP_MD_CTX_init(&md_ctx);
410   int sig_ok = EVP_DigestVerifyInit(&md_ctx, NULL, NULL, NULL, ctx->srr_key) &&
411                EVP_DigestVerify(&md_ctx, CBS_data(&sig), CBS_len(&sig),
412                                 CBS_data(&srr), CBS_len(&srr));
413   EVP_MD_CTX_cleanup(&md_ctx);
414 
415   if (!sig_ok) {
416     OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_SRR_SIGNATURE_ERROR);
417     return 0;
418   }
419 
420   uint8_t *srr_buf = NULL, *sig_buf = NULL;
421   size_t srr_len, sig_len;
422   if (!CBS_stow(&srr, &srr_buf, &srr_len) ||
423       !CBS_stow(&sig, &sig_buf, &sig_len)) {
424     OPENSSL_free(srr_buf);
425     OPENSSL_free(sig_buf);
426     return 0;
427   }
428 
429   *out_rr = srr_buf;
430   *out_rr_len = srr_len;
431   *out_sig = sig_buf;
432   *out_sig_len = sig_len;
433   return 1;
434 }
435 
TRUST_TOKEN_ISSUER_new(const TRUST_TOKEN_METHOD * method,size_t max_batchsize)436 TRUST_TOKEN_ISSUER *TRUST_TOKEN_ISSUER_new(const TRUST_TOKEN_METHOD *method,
437                                            size_t max_batchsize) {
438   if (max_batchsize > 0xffff) {
439     // The protocol supports only two-byte token counts.
440     OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_OVERFLOW);
441     return NULL;
442   }
443 
444   TRUST_TOKEN_ISSUER *ret = reinterpret_cast<TRUST_TOKEN_ISSUER *>(
445       OPENSSL_zalloc(sizeof(TRUST_TOKEN_ISSUER)));
446   if (ret == NULL) {
447     return NULL;
448   }
449   ret->method = method;
450   ret->max_batchsize = (uint16_t)max_batchsize;
451   return ret;
452 }
453 
TRUST_TOKEN_ISSUER_free(TRUST_TOKEN_ISSUER * ctx)454 void TRUST_TOKEN_ISSUER_free(TRUST_TOKEN_ISSUER *ctx) {
455   if (ctx == NULL) {
456     return;
457   }
458   EVP_PKEY_free(ctx->srr_key);
459   OPENSSL_free(ctx->metadata_key);
460   OPENSSL_free(ctx);
461 }
462 
TRUST_TOKEN_ISSUER_add_key(TRUST_TOKEN_ISSUER * ctx,const uint8_t * key,size_t key_len)463 int TRUST_TOKEN_ISSUER_add_key(TRUST_TOKEN_ISSUER *ctx, const uint8_t *key,
464                                size_t key_len) {
465   if (ctx->num_keys == OPENSSL_ARRAY_SIZE(ctx->keys) ||
466       ctx->num_keys >= ctx->method->max_keys) {
467     OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_TOO_MANY_KEYS);
468     return 0;
469   }
470 
471   struct trust_token_issuer_key_st *key_s = &ctx->keys[ctx->num_keys];
472   CBS cbs;
473   CBS_init(&cbs, key, key_len);
474   uint32_t key_id;
475   if (!CBS_get_u32(&cbs, &key_id) ||
476       !ctx->method->issuer_key_from_bytes(&key_s->key, CBS_data(&cbs),
477                                           CBS_len(&cbs))) {
478     OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
479     return 0;
480   }
481 
482   key_s->id = key_id;
483   ctx->num_keys += 1;
484   return 1;
485 }
486 
TRUST_TOKEN_ISSUER_set_srr_key(TRUST_TOKEN_ISSUER * ctx,EVP_PKEY * key)487 int TRUST_TOKEN_ISSUER_set_srr_key(TRUST_TOKEN_ISSUER *ctx, EVP_PKEY *key) {
488   EVP_PKEY_free(ctx->srr_key);
489   EVP_PKEY_up_ref(key);
490   ctx->srr_key = key;
491   return 1;
492 }
493 
TRUST_TOKEN_ISSUER_set_metadata_key(TRUST_TOKEN_ISSUER * ctx,const uint8_t * key,size_t len)494 int TRUST_TOKEN_ISSUER_set_metadata_key(TRUST_TOKEN_ISSUER *ctx,
495                                         const uint8_t *key, size_t len) {
496   if (len < 32) {
497     OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_METADATA_KEY);
498   }
499   OPENSSL_free(ctx->metadata_key);
500   ctx->metadata_key_len = 0;
501   ctx->metadata_key = reinterpret_cast<uint8_t *>(OPENSSL_memdup(key, len));
502   if (ctx->metadata_key == NULL) {
503     return 0;
504   }
505   ctx->metadata_key_len = len;
506   return 1;
507 }
508 
trust_token_issuer_get_key(const TRUST_TOKEN_ISSUER * ctx,uint32_t key_id)509 static const struct trust_token_issuer_key_st *trust_token_issuer_get_key(
510     const TRUST_TOKEN_ISSUER *ctx, uint32_t key_id) {
511   for (size_t i = 0; i < ctx->num_keys; i++) {
512     if (ctx->keys[i].id == key_id) {
513       return &ctx->keys[i];
514     }
515   }
516   return NULL;
517 }
518 
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)519 int TRUST_TOKEN_ISSUER_issue(const TRUST_TOKEN_ISSUER *ctx, uint8_t **out,
520                              size_t *out_len, size_t *out_tokens_issued,
521                              const uint8_t *request, size_t request_len,
522                              uint32_t public_metadata, uint8_t private_metadata,
523                              size_t max_issuance) {
524   if (max_issuance > ctx->max_batchsize) {
525     max_issuance = ctx->max_batchsize;
526   }
527 
528   const struct trust_token_issuer_key_st *key =
529       trust_token_issuer_get_key(ctx, public_metadata);
530   if (key == NULL || private_metadata > 1 ||
531       (!ctx->method->has_private_metadata && private_metadata != 0)) {
532     OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_METADATA);
533     return 0;
534   }
535 
536   CBS in;
537   uint16_t num_requested;
538   CBS_init(&in, request, request_len);
539   if (!CBS_get_u16(&in, &num_requested)) {
540     OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
541     return 0;
542   }
543 
544   size_t num_to_issue = num_requested;
545   if (num_to_issue > max_issuance) {
546     num_to_issue = max_issuance;
547   }
548 
549   int ret = 0;
550   CBB response;
551   if (!CBB_init(&response, 0) || !CBB_add_u16(&response, num_to_issue) ||
552       !CBB_add_u32(&response, public_metadata)) {
553     goto err;
554   }
555 
556   if (!ctx->method->sign(&key->key, &response, &in, num_requested, num_to_issue,
557                          private_metadata)) {
558     goto err;
559   }
560 
561   if (CBS_len(&in) != 0) {
562     OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
563     goto err;
564   }
565 
566   if (!CBB_finish(&response, out, out_len)) {
567     goto err;
568   }
569 
570   *out_tokens_issued = num_to_issue;
571   ret = 1;
572 
573 err:
574   CBB_cleanup(&response);
575   return ret;
576 }
577 
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)578 static int trust_token_issuer_redeem_impl(
579     const TRUST_TOKEN_ISSUER *ctx, uint32_t *out_public, uint8_t *out_private,
580     TRUST_TOKEN **out_token, uint8_t **out_client_data,
581     size_t *out_client_data_len, const uint8_t *request, size_t request_len,
582     int include_message, const uint8_t *msg, size_t msg_len) {
583   CBS request_cbs, token_cbs;
584   CBS_init(&request_cbs, request, request_len);
585   if (!CBS_get_u16_length_prefixed(&request_cbs, &token_cbs)) {
586     OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_ERROR);
587     return 0;
588   }
589 
590   uint32_t public_metadata = 0;
591   uint8_t private_metadata = 0;
592 
593   // Parse the token. If there is an error, treat it as an invalid token.
594   if (!CBS_get_u32(&token_cbs, &public_metadata)) {
595     OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_TOKEN);
596     return 0;
597   }
598 
599   const struct trust_token_issuer_key_st *key =
600       trust_token_issuer_get_key(ctx, public_metadata);
601   uint8_t nonce[TRUST_TOKEN_NONCE_SIZE];
602   if (key == NULL ||
603       !ctx->method->read(&key->key, nonce, &private_metadata,
604                          CBS_data(&token_cbs), CBS_len(&token_cbs),
605                          include_message, msg, msg_len)) {
606     OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_TOKEN);
607     return 0;
608   }
609 
610   CBS client_data;
611   if (!CBS_get_u16_length_prefixed(&request_cbs, &client_data) ||
612       (ctx->method->has_srr && !CBS_skip(&request_cbs, 8)) ||
613       CBS_len(&request_cbs) != 0) {
614     OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_ERROR);
615     return 0;
616   }
617 
618   uint8_t *client_data_buf = NULL;
619   size_t client_data_len = 0;
620   TRUST_TOKEN *token;
621   if (!CBS_stow(&client_data, &client_data_buf, &client_data_len)) {
622     goto err;
623   }
624 
625   token = TRUST_TOKEN_new(nonce, TRUST_TOKEN_NONCE_SIZE);
626   if (token == NULL) {
627     goto err;
628   }
629   *out_public = public_metadata;
630   *out_private = private_metadata;
631   *out_token = token;
632   *out_client_data = client_data_buf;
633   *out_client_data_len = client_data_len;
634 
635   return 1;
636 
637 err:
638   OPENSSL_free(client_data_buf);
639   return 0;
640 }
641 
642 
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)643 int TRUST_TOKEN_ISSUER_redeem(const TRUST_TOKEN_ISSUER *ctx,
644                               uint32_t *out_public, uint8_t *out_private,
645                               TRUST_TOKEN **out_token,
646                               uint8_t **out_client_data,
647                               size_t *out_client_data_len,
648                               const uint8_t *request, size_t request_len) {
649   return trust_token_issuer_redeem_impl(ctx, out_public, out_private, out_token,
650                                         out_client_data, out_client_data_len,
651                                         request, request_len, 0, NULL, 0);
652 }
653 
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)654 int TRUST_TOKEN_ISSUER_redeem_over_message(
655     const TRUST_TOKEN_ISSUER *ctx, uint32_t *out_public, uint8_t *out_private,
656     TRUST_TOKEN **out_token, uint8_t **out_client_data,
657     size_t *out_client_data_len, const uint8_t *request, size_t request_len,
658     const uint8_t *msg, size_t msg_len) {
659   return trust_token_issuer_redeem_impl(ctx, out_public, out_private, out_token,
660                                         out_client_data, out_client_data_len,
661                                         request, request_len, 1, msg, msg_len);
662 }
663 
get_metadata_obfuscator(const uint8_t * key,size_t key_len,const uint8_t * client_data,size_t client_data_len)664 static uint8_t get_metadata_obfuscator(const uint8_t *key, size_t key_len,
665                                        const uint8_t *client_data,
666                                        size_t client_data_len) {
667   uint8_t metadata_obfuscator[SHA256_DIGEST_LENGTH];
668   SHA256_CTX sha_ctx;
669   SHA256_Init(&sha_ctx);
670   SHA256_Update(&sha_ctx, key, key_len);
671   SHA256_Update(&sha_ctx, client_data, client_data_len);
672   SHA256_Final(metadata_obfuscator, &sha_ctx);
673   return metadata_obfuscator[0] >> 7;
674 }
675 
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)676 int TRUST_TOKEN_decode_private_metadata(const TRUST_TOKEN_METHOD *method,
677                                         uint8_t *out_value, const uint8_t *key,
678                                         size_t key_len, const uint8_t *nonce,
679                                         size_t nonce_len,
680                                         uint8_t encrypted_bit) {
681   uint8_t metadata_obfuscator =
682       get_metadata_obfuscator(key, key_len, nonce, nonce_len);
683   *out_value = encrypted_bit ^ metadata_obfuscator;
684   return 1;
685 }
686