1 /* Copyright (c) 2020, 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 #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) 22 extern "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 39 // TRUST_TOKEN_experiment_v1 is an experimental Trust Tokens protocol using 40 // PMBTokens and P-384. 41 OPENSSL_EXPORT const TRUST_TOKEN_METHOD *TRUST_TOKEN_experiment_v1(void); 42 43 // 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. 45 OPENSSL_EXPORT const TRUST_TOKEN_METHOD *TRUST_TOKEN_experiment_v2_voprf(void); 46 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. 49 OPENSSL_EXPORT const TRUST_TOKEN_METHOD *TRUST_TOKEN_experiment_v2_pmb(void); 50 51 // 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. 54 struct trust_token_st { 55 uint8_t *data; 56 size_t len; 57 }; 58 59 DEFINE_STACK_OF(TRUST_TOKEN) 60 61 // TRUST_TOKEN_new creates a newly-allocated |TRUST_TOKEN| with value |data| or 62 // NULL on allocation failure. 63 OPENSSL_EXPORT TRUST_TOKEN *TRUST_TOKEN_new(const uint8_t *data, size_t len); 64 65 // TRUST_TOKEN_free releases memory associated with |token|. 66 OPENSSL_EXPORT void TRUST_TOKEN_free(TRUST_TOKEN *token); 67 68 #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. 85 OPENSSL_EXPORT int TRUST_TOKEN_generate_key( 86 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); 89 90 91 // 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. 98 // 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. 101 OPENSSL_EXPORT TRUST_TOKEN_CLIENT *TRUST_TOKEN_CLIENT_new( 102 const TRUST_TOKEN_METHOD *method, size_t max_batchsize); 103 104 // TRUST_TOKEN_CLIENT_free releases memory associated with |ctx|. 105 OPENSSL_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. 111 OPENSSL_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. 118 OPENSSL_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. 126 OPENSSL_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. 138 OPENSSL_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 149 // 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. 152 OPENSSL_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 157 // 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| 162 // to a newly-allocated buffer containing |response| and leaves all validation 163 // to the caller. It returns one on success or zero on failure. 164 OPENSSL_EXPORT int TRUST_TOKEN_CLIENT_finish_redemption( 165 TRUST_TOKEN_CLIENT *ctx, uint8_t **out_rr, size_t *out_rr_len, 166 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. 181 // 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. 184 OPENSSL_EXPORT TRUST_TOKEN_ISSUER *TRUST_TOKEN_ISSUER_new( 185 const TRUST_TOKEN_METHOD *method, size_t max_batchsize); 186 187 // TRUST_TOKEN_ISSUER_free releases memory associated with |ctx|. 188 OPENSSL_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. 194 OPENSSL_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. 200 OPENSSL_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. 207 OPENSSL_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. 221 OPENSSL_EXPORT int TRUST_TOKEN_ISSUER_issue( 222 const TRUST_TOKEN_ISSUER *ctx, uint8_t **out, size_t *out_len, 223 size_t *out_tokens_issued, const uint8_t *request, size_t request_len, 224 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 227 // verifies the token. If the token is valid, a RR is produced with a lifetime 228 // 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 233 // 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. 237 // 238 // 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. 242 OPENSSL_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 248 // 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. 261 OPENSSL_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 266 // 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 268 // nonce by a |nonce| buffer of length |nonce_len|. The nonce in 269 // |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. 272 OPENSSL_EXPORT int TRUST_TOKEN_decode_private_metadata( 273 const TRUST_TOKEN_METHOD *method, uint8_t *out_value, const uint8_t *key, 274 size_t key_len, const uint8_t *nonce, size_t nonce_len, 275 uint8_t encrypted_bit); 276 277 278 #if defined(__cplusplus) 279 } // extern C 280 281 extern "C++" { 282 283 BSSL_NAMESPACE_BEGIN 284 285 BORINGSSL_MAKE_DELETER(TRUST_TOKEN, TRUST_TOKEN_free) 286 BORINGSSL_MAKE_DELETER(TRUST_TOKEN_CLIENT, TRUST_TOKEN_CLIENT_free) 287 BORINGSSL_MAKE_DELETER(TRUST_TOKEN_ISSUER, TRUST_TOKEN_ISSUER_free) 288 289 BSSL_NAMESPACE_END 290 291 } // extern C++ 292 #endif 293 294 #define TRUST_TOKEN_R_KEYGEN_FAILURE 100 295 #define TRUST_TOKEN_R_BUFFER_TOO_SMALL 101 296 #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 308 #define TRUST_TOKEN_R_INVALID_PROOF 114 309 310 #endif // OPENSSL_HEADER_TRUST_TOKEN_H 311