blob: d9247f79f6ad6345b32afb37c9ebe15a78010654 [file] [log] [blame]
Steven Valdez538a1242019-12-16 12:12:31 -05001/* Copyright (c) 2020, Google Inc.
Steven Valdez0b710a32020-02-14 10:34:53 -05002 *
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#ifndef OPENSSL_HEADER_TRUST_TOKEN_H
16#define OPENSSL_HEADER_TRUST_TOKEN_H
17
18#include <openssl/base.h>
19#include <openssl/stack.h>
20
21#if defined(__cplusplus)
22extern "C" {
23#endif
24
25
26// Trust Token implementation.
27//
28// Trust Token is an implementation of an experimental mechanism similar to
29// Privacy Pass which allows issuance and redemption of anonymized tokens with
30// limited private metadata.
31//
32// References:
33// https://eprint.iacr.org/2020/072.pdf
34// https://github.com/alxdavids/privacy-pass-ietf/tree/master/drafts
35// https://github.com/WICG/trust-token-api/blob/master/README.md
36//
37// WARNING: This API is unstable and subject to change.
38
David Benjaminaa764c42020-04-29 12:39:10 -040039// TRUST_TOKEN_experiment_v1 is an experimental Trust Tokens protocol using
Steven Valdezd0637e92020-06-03 15:43:49 -040040// PMBTokens and P-384.
David Benjaminaa764c42020-04-29 12:39:10 -040041OPENSSL_EXPORT const TRUST_TOKEN_METHOD *TRUST_TOKEN_experiment_v1(void);
42
Steven Valdezf2b2ef82020-09-21 11:39:22 -040043// TRUST_TOKEN_experiment_v2_voprf is an experimental Trust Tokens protocol
44// using VOPRFs and P-384 with up to 6 keys, without RR verification.
Steven Valdezf2b2ef82020-09-21 11:39:22 -040045OPENSSL_EXPORT const TRUST_TOKEN_METHOD *TRUST_TOKEN_experiment_v2_voprf(void);
Steven Valdez9adcb0a2020-09-10 10:59:15 -040046
47// TRUST_TOKEN_experiment_v2_pmb is an experimental Trust Tokens protocol using
48// PMBTokens and P-384 with up to 3 keys, without RR verification.
Steven Valdez9adcb0a2020-09-10 10:59:15 -040049OPENSSL_EXPORT const TRUST_TOKEN_METHOD *TRUST_TOKEN_experiment_v2_pmb(void);
50
Steven Valdez538a1242019-12-16 12:12:31 -050051// trust_token_st represents a single-use token for the Trust Token protocol.
52// For the client, this is the token and its corresponding signature. For the
53// issuer, this is the token itself.
54struct trust_token_st {
55 uint8_t *data;
56 size_t len;
57};
58
59DEFINE_STACK_OF(TRUST_TOKEN)
60
61// TRUST_TOKEN_new creates a newly-allocated |TRUST_TOKEN| with value |data| or
62// NULL on allocation failure.
63OPENSSL_EXPORT TRUST_TOKEN *TRUST_TOKEN_new(const uint8_t *data, size_t len);
64
65// TRUST_TOKEN_free releases memory associated with |token|.
66OPENSSL_EXPORT void TRUST_TOKEN_free(TRUST_TOKEN *token);
67
Steven Valdez0b710a32020-02-14 10:34:53 -050068#define TRUST_TOKEN_MAX_PRIVATE_KEY_SIZE 512
69#define TRUST_TOKEN_MAX_PUBLIC_KEY_SIZE 512
70
71// TRUST_TOKEN_generate_key creates a new Trust Token keypair labeled with |id|
72// and serializes the private and public keys, writing the private key to
73// |out_priv_key| and setting |*out_priv_key_len| to the number of bytes
74// written, and writing the public key to |out_pub_key| and setting
75// |*out_pub_key_len| to the number of bytes written.
76//
77// At most |max_priv_key_len| and |max_pub_key_len| bytes are written. In order
78// to ensure success, these should be at least
79// |TRUST_TOKEN_MAX_PRIVATE_KEY_SIZE| and |TRUST_TOKEN_MAX_PUBLIC_KEY_SIZE|.
80//
81// WARNING: This API is unstable and the serializations of these keys are
82// subject to change. Keys generated with this function may not be persisted.
83//
84// This function returns one on success or zero on error.
85OPENSSL_EXPORT int TRUST_TOKEN_generate_key(
David Benjamin239634d2020-04-29 11:17:51 -040086 const TRUST_TOKEN_METHOD *method, uint8_t *out_priv_key,
87 size_t *out_priv_key_len, size_t max_priv_key_len, uint8_t *out_pub_key,
88 size_t *out_pub_key_len, size_t max_pub_key_len, uint32_t id);
Steven Valdez0b710a32020-02-14 10:34:53 -050089
90
Steven Valdez538a1242019-12-16 12:12:31 -050091// Trust Token client implementation.
92//
93// These functions implements the client half of the Trust Token protocol. A
94// single |TRUST_TOKEN_CLIENT| can perform a single protocol operation.
95
96// TRUST_TOKEN_CLIENT_new returns a newly-allocated |TRUST_TOKEN_CLIENT|
97// configured to use a max batchsize of |max_batchsize| or NULL on error.
David Benjamin17078f22020-04-28 17:50:13 -040098// Issuance requests must be made in batches smaller than |max_batchsize|. This
99// function will return an error if |max_batchsize| is too large for Trust
100// Tokens.
David Benjamin239634d2020-04-29 11:17:51 -0400101OPENSSL_EXPORT TRUST_TOKEN_CLIENT *TRUST_TOKEN_CLIENT_new(
102 const TRUST_TOKEN_METHOD *method, size_t max_batchsize);
Steven Valdez538a1242019-12-16 12:12:31 -0500103
104// TRUST_TOKEN_CLIENT_free releases memory associated with |ctx|.
105OPENSSL_EXPORT void TRUST_TOKEN_CLIENT_free(TRUST_TOKEN_CLIENT *ctx);
106
107// TRUST_TOKEN_CLIENT_add_key configures the |ctx| to support the public key
108// |key|. It sets |*out_key_index| to the index this key has been configured to.
109// It returns one on success or zero on error if the |key| can't be parsed or
110// too many keys have been configured.
111OPENSSL_EXPORT int TRUST_TOKEN_CLIENT_add_key(TRUST_TOKEN_CLIENT *ctx,
112 size_t *out_key_index,
113 const uint8_t *key,
114 size_t key_len);
115
116// TRUST_TOKEN_CLIENT_set_srr_key sets the public key used to verify the SRR. It
117// returns one on success and zero on error.
118OPENSSL_EXPORT int TRUST_TOKEN_CLIENT_set_srr_key(TRUST_TOKEN_CLIENT *ctx,
119 EVP_PKEY *key);
120
121// TRUST_TOKEN_CLIENT_begin_issuance produces a request for |count| trust tokens
122// and serializes the request into a newly-allocated buffer, setting |*out| to
123// that buffer and |*out_len| to its length. The caller takes ownership of the
124// buffer and must call |OPENSSL_free| when done. It returns one on success and
125// zero on error.
126OPENSSL_EXPORT int TRUST_TOKEN_CLIENT_begin_issuance(TRUST_TOKEN_CLIENT *ctx,
127 uint8_t **out,
128 size_t *out_len,
129 size_t count);
130
131// TRUST_TOKEN_CLIENT_finish_issuance consumes |response| from the issuer and
132// extracts the tokens, returning a list of tokens and the index of the key used
133// to sign the tokens in |*out_key_index|. The caller can use this to determine
134// what key was used in an issuance and to drop tokens if a new key commitment
135// arrives without the specified key present. The caller takes ownership of the
136// list and must call |sk_TRUST_TOKEN_pop_free| when done. The list is empty if
137// issuance fails.
138OPENSSL_EXPORT STACK_OF(TRUST_TOKEN) *
139 TRUST_TOKEN_CLIENT_finish_issuance(TRUST_TOKEN_CLIENT *ctx,
140 size_t *out_key_index,
141 const uint8_t *response,
142 size_t response_len);
143
144
145// TRUST_TOKEN_CLIENT_begin_redemption produces a request to redeem a token
146// |token| and receive a signature over |data| and serializes the request into
147// a newly-allocated buffer, setting |*out| to that buffer and |*out_len| to
148// its length. |time| is the number of seconds since the UNIX epoch and used to
Steven Valdez07827152020-10-13 11:04:33 -0400149// verify the validity of the issuer's response in TrustTokenV1 and ignored in
150// other versions. The caller takes ownership of the buffer and must call
151// |OPENSSL_free| when done. It returns one on success or zero on error.
Steven Valdez538a1242019-12-16 12:12:31 -0500152OPENSSL_EXPORT int TRUST_TOKEN_CLIENT_begin_redemption(
153 TRUST_TOKEN_CLIENT *ctx, uint8_t **out, size_t *out_len,
154 const TRUST_TOKEN *token, const uint8_t *data, size_t data_len,
155 uint64_t time);
156
Steven Valdez9adcb0a2020-09-10 10:59:15 -0400157// TRUST_TOKEN_CLIENT_finish_redemption consumes |response| from the issuer. In
158// |TRUST_TOKEN_experiment_v1|, it then verifies the SRR and if valid sets
159// |*out_rr| and |*out_rr_len| (respectively, |*out_sig| and |*out_sig_len|)
160// to a newly-allocated buffer containing the SRR (respectively, the SRR
161// signature). In other versions, it sets |*out_rr| and |*out_rr_len|
Steven Valdezf2b2ef82020-09-21 11:39:22 -0400162// to a newly-allocated buffer containing |response| and leaves all validation
163// to the caller. It returns one on success or zero on failure.
Steven Valdez538a1242019-12-16 12:12:31 -0500164OPENSSL_EXPORT int TRUST_TOKEN_CLIENT_finish_redemption(
Steven Valdez9adcb0a2020-09-10 10:59:15 -0400165 TRUST_TOKEN_CLIENT *ctx, uint8_t **out_rr, size_t *out_rr_len,
Steven Valdez538a1242019-12-16 12:12:31 -0500166 uint8_t **out_sig, size_t *out_sig_len, const uint8_t *response,
167 size_t response_len);
168
169
170// Trust Token issuer implementation.
171//
172// These functions implement the issuer half of the Trust Token protocol. A
173// |TRUST_TOKEN_ISSUER| can be reused across multiple protocol operations. It
174// may be used concurrently on multiple threads by non-mutating functions,
175// provided no other thread is concurrently calling a mutating function.
176// Functions which take a |const| pointer are non-mutating and functions which
177// take a non-|const| pointer are mutating.
178
179// TRUST_TOKEN_ISSUER_new returns a newly-allocated |TRUST_TOKEN_ISSUER|
180// configured to use a max batchsize of |max_batchsize| or NULL on error.
David Benjamin17078f22020-04-28 17:50:13 -0400181// Issuance requests must be made in batches smaller than |max_batchsize|. This
182// function will return an error if |max_batchsize| is too large for Trust
183// Tokens.
David Benjamin239634d2020-04-29 11:17:51 -0400184OPENSSL_EXPORT TRUST_TOKEN_ISSUER *TRUST_TOKEN_ISSUER_new(
185 const TRUST_TOKEN_METHOD *method, size_t max_batchsize);
Steven Valdez538a1242019-12-16 12:12:31 -0500186
187// TRUST_TOKEN_ISSUER_free releases memory associated with |ctx|.
188OPENSSL_EXPORT void TRUST_TOKEN_ISSUER_free(TRUST_TOKEN_ISSUER *ctx);
189
190// TRUST_TOKEN_ISSUER_add_key configures the |ctx| to support the private key
191// |key|. It must be a private key returned by |TRUST_TOKEN_generate_key|. It
192// returns one on success or zero on error. This function may fail if the |key|
193// can't be parsed or too many keys have been configured.
194OPENSSL_EXPORT int TRUST_TOKEN_ISSUER_add_key(TRUST_TOKEN_ISSUER *ctx,
195 const uint8_t *key,
196 size_t key_len);
197
198// TRUST_TOKEN_ISSUER_set_srr_key sets the private key used to sign the SRR. It
199// returns one on success and zero on error.
200OPENSSL_EXPORT int TRUST_TOKEN_ISSUER_set_srr_key(TRUST_TOKEN_ISSUER *ctx,
201 EVP_PKEY *key);
202
203// TRUST_TOKEN_ISSUER_set_metadata_key sets the key used to encrypt the private
204// metadata. The key is a randomly generated bytestring of at least 32 bytes
205// used to encode the private metadata bit in the SRR. It returns one on success
206// and zero on error.
207OPENSSL_EXPORT int TRUST_TOKEN_ISSUER_set_metadata_key(TRUST_TOKEN_ISSUER *ctx,
208 const uint8_t *key,
209 size_t len);
210
211// TRUST_TOKEN_ISSUER_issue ingests |request| for token issuance
212// and generates up to |max_issuance| valid tokens, producing a list of blinded
213// tokens and storing the response into a newly-allocated buffer and setting
214// |*out| to that buffer, |*out_len| to its length, and |*out_tokens_issued| to
215// the number of tokens issued. The tokens are issued with public metadata of
216// |public_metadata| and a private metadata value of |private_metadata|.
217// |public_metadata| must be one of the previously configured key IDs.
218// |private_metadata| must be 0 or 1. The caller takes ownership of the buffer
219// and must call |OPENSSL_free| when done. It returns one on success or zero on
220// error.
221OPENSSL_EXPORT int TRUST_TOKEN_ISSUER_issue(
222 const TRUST_TOKEN_ISSUER *ctx, uint8_t **out, size_t *out_len,
David Benjamin17078f22020-04-28 17:50:13 -0400223 size_t *out_tokens_issued, const uint8_t *request, size_t request_len,
Steven Valdez538a1242019-12-16 12:12:31 -0500224 uint32_t public_metadata, uint8_t private_metadata, size_t max_issuance);
225
226// TRUST_TOKEN_ISSUER_redeem ingests a |request| for token redemption and
Steven Valdez07827152020-10-13 11:04:33 -0400227// verifies the token. If the token is valid, a RR is produced with a lifetime
Steven Valdez538a1242019-12-16 12:12:31 -0500228// of |lifetime| (in seconds), signing over the requested data from the request
229// and the value of the token, storing the result into a newly-allocated buffer
230// and setting |*out| to that buffer and |*out_len| to its length. The extracted
231// |TRUST_TOKEN| is stored into a newly-allocated buffer and stored in
232// |*out_token|. The extracted client data is stored into a newly-allocated
Steven Valdez07827152020-10-13 11:04:33 -0400233// buffer and stored in |*out_client_data|. In TrustTokenV1, the extracted
234// redemption time is stored in |*out_redemption_time|. The caller takes
235// ownership of each output buffer and must call |OPENSSL_free| when done. It
236// returns one on success or zero on error.
Steven Valdez538a1242019-12-16 12:12:31 -0500237//
Steven Valdez54304732020-05-04 11:56:12 -0400238// The caller must keep track of all values of |*out_token| seen globally before
239// returning the SRR to the client. If the value has been reused, the caller
240// must discard the SRR and report an error to the caller. Returning an SRR with
241// replayed values allows an attacker to double-spend tokens.
Steven Valdez538a1242019-12-16 12:12:31 -0500242OPENSSL_EXPORT int TRUST_TOKEN_ISSUER_redeem(
243 const TRUST_TOKEN_ISSUER *ctx, uint8_t **out, size_t *out_len,
244 TRUST_TOKEN **out_token, uint8_t **out_client_data,
245 size_t *out_client_data_len, uint64_t *out_redemption_time,
246 const uint8_t *request, size_t request_len, uint64_t lifetime);
247
Steven Valdez07827152020-10-13 11:04:33 -0400248// TRUST_TOKEN_ISSUER_redeem_raw ingests a |request| for token redemption and
249// verifies the token. The public metadata is stored in |*out_public|. The
250// private metadata (if any) is stored in |*out_private|. The extracted
251// |TRUST_TOKEN| is stored into a newly-allocated buffer and stored in
252// |*out_token|. The extracted client data is stored into a newly-allocated
253// buffer and stored in |*out_client_data|. The caller takes ownership of each
254// output buffer and must call |OPENSSL_free| when done. It returns one on
255// success or zero on error.
256//
257// The caller must keep track of all values of |*out_token| seen globally before
258// returning a response to the client. If the value has been reused, the caller
259// must report an error to the client. Returning a response with replayed values
260// allows an attacker to double-spend tokens.
261OPENSSL_EXPORT int TRUST_TOKEN_ISSUER_redeem_raw(
262 const TRUST_TOKEN_ISSUER *ctx, uint32_t *out_public, uint8_t *out_private,
263 TRUST_TOKEN **out_token, uint8_t **out_client_data,
264 size_t *out_client_data_len, const uint8_t *request, size_t request_len);
265
Steven Valdez538a1242019-12-16 12:12:31 -0500266// TRUST_TOKEN_decode_private_metadata decodes |encrypted_bit| using the
267// private metadata key specified by a |key| buffer of length |key_len| and the
Steven Valdez54304732020-05-04 11:56:12 -0400268// nonce by a |nonce| buffer of length |nonce_len|. The nonce in
Steven Valdez54304732020-05-04 11:56:12 -0400269// |TRUST_TOKEN_experiment_v1| is the token-hash field of the SRR. |*out_value|
270// is set to the decrypted value, either zero or one. It returns one on success
271// and zero on error.
Steven Valdez538a1242019-12-16 12:12:31 -0500272OPENSSL_EXPORT int TRUST_TOKEN_decode_private_metadata(
David Benjamin239634d2020-04-29 11:17:51 -0400273 const TRUST_TOKEN_METHOD *method, uint8_t *out_value, const uint8_t *key,
Steven Valdez54304732020-05-04 11:56:12 -0400274 size_t key_len, const uint8_t *nonce, size_t nonce_len,
David Benjamin239634d2020-04-29 11:17:51 -0400275 uint8_t encrypted_bit);
Steven Valdez538a1242019-12-16 12:12:31 -0500276
277
Steven Valdez0b710a32020-02-14 10:34:53 -0500278#if defined(__cplusplus)
279} // extern C
Steven Valdez538a1242019-12-16 12:12:31 -0500280
281extern "C++" {
282
283BSSL_NAMESPACE_BEGIN
284
285BORINGSSL_MAKE_DELETER(TRUST_TOKEN, TRUST_TOKEN_free)
286BORINGSSL_MAKE_DELETER(TRUST_TOKEN_CLIENT, TRUST_TOKEN_CLIENT_free)
287BORINGSSL_MAKE_DELETER(TRUST_TOKEN_ISSUER, TRUST_TOKEN_ISSUER_free)
288
Steven Valdez538a1242019-12-16 12:12:31 -0500289BSSL_NAMESPACE_END
290
291} // extern C++
Steven Valdez0b710a32020-02-14 10:34:53 -0500292#endif
293
294#define TRUST_TOKEN_R_KEYGEN_FAILURE 100
295#define TRUST_TOKEN_R_BUFFER_TOO_SMALL 101
Steven Valdez538a1242019-12-16 12:12:31 -0500296#define TRUST_TOKEN_R_OVER_BATCHSIZE 102
297#define TRUST_TOKEN_R_DECODE_ERROR 103
298#define TRUST_TOKEN_R_SRR_SIGNATURE_ERROR 104
299#define TRUST_TOKEN_R_DECODE_FAILURE 105
300#define TRUST_TOKEN_R_INVALID_METADATA 106
301#define TRUST_TOKEN_R_TOO_MANY_KEYS 107
302#define TRUST_TOKEN_R_NO_KEYS_CONFIGURED 108
303#define TRUST_TOKEN_R_INVALID_KEY_ID 109
304#define TRUST_TOKEN_R_INVALID_TOKEN 110
305#define TRUST_TOKEN_R_BAD_VALIDITY_CHECK 111
306#define TRUST_TOKEN_R_NO_SRR_KEY_CONFIGURED 112
307#define TRUST_TOKEN_R_INVALID_METADATA_KEY 113
Steven Valdez78987bb2020-04-09 14:57:31 -0400308#define TRUST_TOKEN_R_INVALID_PROOF 114
Steven Valdez0b710a32020-02-14 10:34:53 -0500309
310#endif // OPENSSL_HEADER_TRUST_TOKEN_H