1 // Copyright (c) 2023 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef QUICHE_BLIND_SIGN_AUTH_CACHED_BLIND_SIGN_AUTH_H_ 6 #define QUICHE_BLIND_SIGN_AUTH_CACHED_BLIND_SIGN_AUTH_H_ 7 8 #include <string> 9 #include <vector> 10 11 #include "absl/status/statusor.h" 12 #include "absl/types/span.h" 13 #include "quiche/blind_sign_auth/blind_sign_auth_interface.h" 14 #include "quiche/common/platform/api/quiche_export.h" 15 #include "quiche/common/platform/api/quiche_mutex.h" 16 #include "quiche/common/quiche_circular_deque.h" 17 18 namespace quiche { 19 20 inline constexpr int kBlindSignAuthRequestMaxTokens = 1024; 21 22 // CachedBlindSignAuth caches signed tokens generated by BlindSignAuth. 23 // This class does not guarantee that tokens returned are fresh. 24 // Tokens may be stale if the backend has rotated its signing key since tokens 25 // were generated. 26 // This class is thread-safe. 27 class QUICHE_EXPORT CachedBlindSignAuth : public BlindSignAuthInterface { 28 public: 29 CachedBlindSignAuth( 30 BlindSignAuthInterface* blind_sign_auth, 31 int max_tokens_per_request = kBlindSignAuthRequestMaxTokens) blind_sign_auth_(blind_sign_auth)32 : blind_sign_auth_(blind_sign_auth), 33 max_tokens_per_request_(max_tokens_per_request) {} 34 35 // Returns signed unblinded tokens and expiration time in a callback. 36 // Tokens are single-use. They will not be usable after the expiration time. 37 // 38 // The GetTokens callback may be called synchronously on the calling thread, 39 // or asynchronously on BlindSignAuth's BlindSignMessageInterface thread. 40 // The GetTokens callback must not acquire any locks that the calling thread 41 // owns, otherwise the callback will deadlock. 42 void GetTokens(std::optional<std::string> oauth_token, int num_tokens, 43 ProxyLayer proxy_layer, SignedTokenCallback callback) override; 44 45 // Removes all tokens in the cache. ClearCache()46 void ClearCache() { 47 QuicheWriterMutexLock lock(&mutex_); 48 cached_tokens_.clear(); 49 } 50 51 private: 52 void HandleGetTokensResponse( 53 SignedTokenCallback callback, int num_tokens, 54 absl::StatusOr<absl::Span<BlindSignToken>> tokens); 55 std::vector<BlindSignToken> CreateOutputTokens(int num_tokens) 56 QUICHE_EXCLUSIVE_LOCKS_REQUIRED(mutex_); 57 void RemoveExpiredTokens() QUICHE_EXCLUSIVE_LOCKS_REQUIRED(mutex_); 58 59 BlindSignAuthInterface* blind_sign_auth_; 60 int max_tokens_per_request_; 61 QuicheMutex mutex_; 62 QuicheCircularDeque<BlindSignToken> cached_tokens_ QUICHE_GUARDED_BY(mutex_); 63 }; 64 65 } // namespace quiche 66 67 #endif // QUICHE_BLIND_SIGN_AUTH_CACHED_BLIND_SIGN_AUTH_H_ 68