| // Copyright (c) 2023 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef QUICHE_BLIND_SIGN_AUTH_CACHED_BLIND_SIGN_AUTH_H_ |
| #define QUICHE_BLIND_SIGN_AUTH_CACHED_BLIND_SIGN_AUTH_H_ |
| |
| #include <string> |
| #include <vector> |
| |
| #include "absl/status/statusor.h" |
| #include "absl/types/span.h" |
| #include "quiche/blind_sign_auth/blind_sign_auth_interface.h" |
| #include "quiche/common/platform/api/quiche_export.h" |
| #include "quiche/common/platform/api/quiche_mutex.h" |
| #include "quiche/common/quiche_circular_deque.h" |
| |
| namespace quiche { |
| |
| inline constexpr int kBlindSignAuthRequestMaxTokens = 1024; |
| |
| // CachedBlindSignAuth caches signed tokens generated by BlindSignAuth. |
| // This class does not guarantee that tokens returned are fresh. |
| // Tokens may be stale if the backend has rotated its signing key since tokens |
| // were generated. |
| // This class is thread-safe. |
| class QUICHE_EXPORT CachedBlindSignAuth : public BlindSignAuthInterface { |
| public: |
| CachedBlindSignAuth( |
| BlindSignAuthInterface* blind_sign_auth, |
| int max_tokens_per_request = kBlindSignAuthRequestMaxTokens) |
| : blind_sign_auth_(blind_sign_auth), |
| max_tokens_per_request_(max_tokens_per_request) {} |
| |
| // Returns signed unblinded tokens and expiration time in a callback. |
| // Tokens are single-use. They will not be usable after the expiration time. |
| // |
| // The GetTokens callback may be called synchronously on the calling thread, |
| // or asynchronously on BlindSignAuth's BlindSignHttpInterface thread. |
| // The GetTokens callback must not acquire any locks that the calling thread |
| // owns, otherwise the callback will deadlock. |
| void GetTokens(std::string oauth_token, int num_tokens, |
| ProxyLayer proxy_layer, SignedTokenCallback callback) override; |
| |
| // Removes all tokens in the cache. |
| void ClearCache() { |
| QuicheWriterMutexLock lock(&mutex_); |
| cached_tokens_.clear(); |
| } |
| |
| private: |
| void HandleGetTokensResponse( |
| SignedTokenCallback callback, int num_tokens, |
| absl::StatusOr<absl::Span<BlindSignToken>> tokens); |
| std::vector<BlindSignToken> CreateOutputTokens(int num_tokens) |
| QUICHE_EXCLUSIVE_LOCKS_REQUIRED(mutex_); |
| void RemoveExpiredTokens() QUICHE_EXCLUSIVE_LOCKS_REQUIRED(mutex_); |
| |
| BlindSignAuthInterface* blind_sign_auth_; |
| int max_tokens_per_request_; |
| QuicheMutex mutex_; |
| QuicheCircularDeque<BlindSignToken> cached_tokens_ QUICHE_GUARDED_BY(mutex_); |
| }; |
| |
| } // namespace quiche |
| |
| #endif // QUICHE_BLIND_SIGN_AUTH_CACHED_BLIND_SIGN_AUTH_H_ |