blob: f976fb1a8d1e7e372234feaff8c64f7503008a7b [file] [log] [blame]
// 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 <cstddef>
#include <functional>
#include <string>
#include <vector>
#include "absl/status/statusor.h"
#include "absl/strings/string_view.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(absl::string_view oauth_token, int num_tokens,
std::function<void(absl::StatusOr<absl::Span<BlindSignToken>>)>
callback) override;
private:
void HandleGetTokensResponse(
absl::StatusOr<absl::Span<BlindSignToken>> tokens, int num_tokens,
std::function<void(absl::StatusOr<absl::Span<BlindSignToken>>)> callback);
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_