1 // Copyright 2023 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //    https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef ANONYMOUS_TOKENS_CPP_PRIVACY_PASS_RSA_BSSA_PUBLIC_METADATA_CLIENT_H_
16 #define ANONYMOUS_TOKENS_CPP_PRIVACY_PASS_RSA_BSSA_PUBLIC_METADATA_CLIENT_H_
17 
18 #include <memory>
19 #include <string>
20 
21 #include "absl/status/status.h"
22 #include "absl/status/statusor.h"
23 #include "absl/strings/string_view.h"
24 #include "anonymous_tokens/cpp/crypto/rsa_blinder.h"
25 #include "anonymous_tokens/cpp/privacy_pass/token_encodings.h"
26 #include <openssl/base.h>
27 
28 namespace anonymous_tokens {
29 
30 class PrivacyPassRsaBssaPublicMetadataClient {
31  public:
32   #ifndef SWIG
33   // PrivacyPassRsaBssaPublicMetadataClient is neither copyable nor copy
34   // assignable.
35   PrivacyPassRsaBssaPublicMetadataClient(
36       const PrivacyPassRsaBssaPublicMetadataClient&) = delete;
37   PrivacyPassRsaBssaPublicMetadataClient& operator=(
38       const PrivacyPassRsaBssaPublicMetadataClient&) = delete;
39   #endif
40   // This method is to be used to create a client as its constructor is private.
41   // It takes as input RSA public key.
42   static absl::StatusOr<
43       std::unique_ptr<PrivacyPassRsaBssaPublicMetadataClient> >
44   Create(const RSA& rsa_public_key);
45 
46   // Method used to create the ExtendedTokenRequest. It takes in the input
47   // "challenge" as an encoded string, "nonce" must a 32 byte random string,
48   // "token_key_id" is the SHA256 digest of the DER encoding of RSA BSSA public
49   // key containing the correct hash functions and salt size and "extensions" is
50   // the structure carrying the public metadata / info.
51   //
52   // https://www.ietf.org/archive/id/draft-hendrickson-privacypass-public-metadata-01.html#name-client-to-issuer-request-2
53   //
54   // CreateTokenRequest must be called before FinalizeToken.
55   absl::StatusOr<ExtendedTokenRequest> CreateTokenRequest(
56       absl::string_view challenge, absl::string_view nonce,
57       absl::string_view token_key_id, const Extensions& extensions);
58 
59   // Method that uses the client state and outputs the final token by unblinding
60   // the "blinded_signature".
61   //
62   // https://www.ietf.org/archive/id/draft-hendrickson-privacypass-public-metadata-01.html#name-finalization-2
63   //
64   // CreateTokenRequest must be called before FinalizeToken.
65   absl::StatusOr<Token> FinalizeToken(absl::string_view blinded_signature);
66 
67   // Method that takes in a token, extensions encoded as a string and the RSA
68   // public key to run the token verification algorithm. It returns an ok status
69   // on success and errs on verification failure.
70   //
71   // https://datatracker.ietf.org/doc/draft-hendrickson-privacypass-public-metadata/
72   static absl::Status Verify(Token token_to_verify,
73                              absl::string_view encoded_extensions,
74                              RSA& rsa_public_key);
75 
76   static constexpr uint16_t kTokenType = 0xDA7A;
77 
78  private:
79   PrivacyPassRsaBssaPublicMetadataClient(int salt_length,
80                                          std::string rsa_modulus,
81                                          std::string rsa_e,
82                                          const EVP_MD* signature_hash_function,
83                                          const EVP_MD* mgf1_hash_function);
84 
85   const int salt_length_;
86   const std::string rsa_modulus_;
87   const std::string rsa_e_;
88   const EVP_MD* const signature_hash_function_;  // Owned by BoringSSL.
89   const EVP_MD* const mgf1_hash_function_;       // Owned by BoringSSL.
90 
91   // RsaBlinder object to generate the token request and finalize the token.
92   // Once CreateTokenRequest is called, this value is initialized and is no
93   // longer a nullptr.
94   std::unique_ptr<RsaBlinder> rsa_blinder_ = nullptr;
95   // This Token object will be finalized and returned when FinalizeToken is
96   // called.
97   Token token_;
98   // String used as input for (1) creating the token and (2) verifying the final
99   // token against, under some fixed input extensions.
100   std::string authenticator_input_;
101 };
102 
103 }  // namespace anonymous_tokens
104 
105 #endif  // ANONYMOUS_TOKENS_CPP_PRIVACY_PASS_RSA_BSSA_PUBLIC_METADATA_CLIENT_H_
106