Remove Anonymous Tokens export from BlindSignAuth and update QUICHE copybara to allow BlindSignAuth-in-Chrome to use the standalone Anonymous Tokens Git repo. PiperOrigin-RevId: 569492201
diff --git a/build/source_list.bzl b/build/source_list.bzl index c9c0224..964887a 100644 --- a/build/source_list.bzl +++ b/build/source_list.bzl
@@ -1586,21 +1586,6 @@ "quic/qbone/qbone_stream_test.cc", ] blind_sign_auth_hdrs = [ - "blind_sign_auth/anonymous_tokens/cpp/client/anonymous_tokens_rsa_bssa_client.h", - "blind_sign_auth/anonymous_tokens/cpp/crypto/anonymous_tokens_pb_openssl_converters.h", - "blind_sign_auth/anonymous_tokens/cpp/crypto/blind_signer.h", - "blind_sign_auth/anonymous_tokens/cpp/crypto/blinder.h", - "blind_sign_auth/anonymous_tokens/cpp/crypto/constants.h", - "blind_sign_auth/anonymous_tokens/cpp/crypto/crypto_utils.h", - "blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blind_signer.h", - "blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blinder.h", - "blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_ssa_pss_verifier.h", - "blind_sign_auth/anonymous_tokens/cpp/crypto/verifier.h", - "blind_sign_auth/anonymous_tokens/cpp/shared/proto_utils.h", - "blind_sign_auth/anonymous_tokens/cpp/shared/status_utils.h", - "blind_sign_auth/anonymous_tokens/cpp/testing/proto_utils.h", - "blind_sign_auth/anonymous_tokens/cpp/testing/testdata_utils.h", - "blind_sign_auth/anonymous_tokens/cpp/testing/utils.h", "blind_sign_auth/blind_sign_auth.h", "blind_sign_auth/blind_sign_auth_interface.h", "blind_sign_auth/blind_sign_auth_protos.h", @@ -1611,33 +1596,16 @@ "blind_sign_auth/test_tools/mock_blind_sign_http_interface.h", ] blind_sign_auth_srcs = [ - "blind_sign_auth/anonymous_tokens/cpp/client/anonymous_tokens_rsa_bssa_client.cc", - "blind_sign_auth/anonymous_tokens/cpp/crypto/anonymous_tokens_pb_openssl_converters.cc", - "blind_sign_auth/anonymous_tokens/cpp/crypto/crypto_utils.cc", - "blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blind_signer.cc", - "blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blinder.cc", - "blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_ssa_pss_verifier.cc", - "blind_sign_auth/anonymous_tokens/cpp/shared/proto_utils.cc", - "blind_sign_auth/anonymous_tokens/cpp/testing/proto_utils.cc", - "blind_sign_auth/anonymous_tokens/cpp/testing/utils.cc", "blind_sign_auth/blind_sign_auth.cc", "blind_sign_auth/cached_blind_sign_auth.cc", ] blind_sign_auth_tests_hdrs = [ ] blind_sign_auth_tests_srcs = [ - "blind_sign_auth/anonymous_tokens/cpp/client/anonymous_tokens_rsa_bssa_client_test.cc", - "blind_sign_auth/anonymous_tokens/cpp/crypto/anonymous_tokens_pb_openssl_converters_test.cc", - "blind_sign_auth/anonymous_tokens/cpp/crypto/at_crypto_utils_test.cc", - "blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blind_signer_test.cc", - "blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blinder_test.cc", - "blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_ssa_pss_verifier_test.cc", - "blind_sign_auth/anonymous_tokens/cpp/shared/proto_utils_test.cc", "blind_sign_auth/blind_sign_auth_test.cc", "blind_sign_auth/cached_blind_sign_auth_test.cc", ] protobuf_blind_sign_auth = [ - "blind_sign_auth/anonymous_tokens/proto/anonymous_tokens.proto", "blind_sign_auth/proto/any.proto", "blind_sign_auth/proto/attestation.proto", "blind_sign_auth/proto/auth_and_sign.proto",
diff --git a/build/source_list.gni b/build/source_list.gni index e70f003..e02373f 100644 --- a/build/source_list.gni +++ b/build/source_list.gni
@@ -1590,21 +1590,6 @@ "src/quiche/quic/qbone/qbone_stream_test.cc", ] blind_sign_auth_hdrs = [ - "src/quiche/blind_sign_auth/anonymous_tokens/cpp/client/anonymous_tokens_rsa_bssa_client.h", - "src/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/anonymous_tokens_pb_openssl_converters.h", - "src/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/blind_signer.h", - "src/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/blinder.h", - "src/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/constants.h", - "src/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/crypto_utils.h", - "src/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blind_signer.h", - "src/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blinder.h", - "src/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_ssa_pss_verifier.h", - "src/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/verifier.h", - "src/quiche/blind_sign_auth/anonymous_tokens/cpp/shared/proto_utils.h", - "src/quiche/blind_sign_auth/anonymous_tokens/cpp/shared/status_utils.h", - "src/quiche/blind_sign_auth/anonymous_tokens/cpp/testing/proto_utils.h", - "src/quiche/blind_sign_auth/anonymous_tokens/cpp/testing/testdata_utils.h", - "src/quiche/blind_sign_auth/anonymous_tokens/cpp/testing/utils.h", "src/quiche/blind_sign_auth/blind_sign_auth.h", "src/quiche/blind_sign_auth/blind_sign_auth_interface.h", "src/quiche/blind_sign_auth/blind_sign_auth_protos.h", @@ -1615,15 +1600,6 @@ "src/quiche/blind_sign_auth/test_tools/mock_blind_sign_http_interface.h", ] blind_sign_auth_srcs = [ - "src/quiche/blind_sign_auth/anonymous_tokens/cpp/client/anonymous_tokens_rsa_bssa_client.cc", - "src/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/anonymous_tokens_pb_openssl_converters.cc", - "src/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/crypto_utils.cc", - "src/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blind_signer.cc", - "src/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blinder.cc", - "src/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_ssa_pss_verifier.cc", - "src/quiche/blind_sign_auth/anonymous_tokens/cpp/shared/proto_utils.cc", - "src/quiche/blind_sign_auth/anonymous_tokens/cpp/testing/proto_utils.cc", - "src/quiche/blind_sign_auth/anonymous_tokens/cpp/testing/utils.cc", "src/quiche/blind_sign_auth/blind_sign_auth.cc", "src/quiche/blind_sign_auth/cached_blind_sign_auth.cc", ] @@ -1631,18 +1607,10 @@ ] blind_sign_auth_tests_srcs = [ - "src/quiche/blind_sign_auth/anonymous_tokens/cpp/client/anonymous_tokens_rsa_bssa_client_test.cc", - "src/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/anonymous_tokens_pb_openssl_converters_test.cc", - "src/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/at_crypto_utils_test.cc", - "src/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blind_signer_test.cc", - "src/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blinder_test.cc", - "src/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_ssa_pss_verifier_test.cc", - "src/quiche/blind_sign_auth/anonymous_tokens/cpp/shared/proto_utils_test.cc", "src/quiche/blind_sign_auth/blind_sign_auth_test.cc", "src/quiche/blind_sign_auth/cached_blind_sign_auth_test.cc", ] protobuf_blind_sign_auth = [ - "src/quiche/blind_sign_auth/anonymous_tokens/proto/anonymous_tokens.proto", "src/quiche/blind_sign_auth/proto/any.proto", "src/quiche/blind_sign_auth/proto/attestation.proto", "src/quiche/blind_sign_auth/proto/auth_and_sign.proto",
diff --git a/build/source_list.json b/build/source_list.json index 07bf1a6..4db9bc0 100644 --- a/build/source_list.json +++ b/build/source_list.json
@@ -1589,21 +1589,6 @@ "quiche/quic/qbone/qbone_stream_test.cc" ], "blind_sign_auth_hdrs": [ - "quiche/blind_sign_auth/anonymous_tokens/cpp/client/anonymous_tokens_rsa_bssa_client.h", - "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/anonymous_tokens_pb_openssl_converters.h", - "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/blind_signer.h", - "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/blinder.h", - "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/constants.h", - "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/crypto_utils.h", - "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blind_signer.h", - "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blinder.h", - "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_ssa_pss_verifier.h", - "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/verifier.h", - "quiche/blind_sign_auth/anonymous_tokens/cpp/shared/proto_utils.h", - "quiche/blind_sign_auth/anonymous_tokens/cpp/shared/status_utils.h", - "quiche/blind_sign_auth/anonymous_tokens/cpp/testing/proto_utils.h", - "quiche/blind_sign_auth/anonymous_tokens/cpp/testing/testdata_utils.h", - "quiche/blind_sign_auth/anonymous_tokens/cpp/testing/utils.h", "quiche/blind_sign_auth/blind_sign_auth.h", "quiche/blind_sign_auth/blind_sign_auth_interface.h", "quiche/blind_sign_auth/blind_sign_auth_protos.h", @@ -1614,15 +1599,6 @@ "quiche/blind_sign_auth/test_tools/mock_blind_sign_http_interface.h" ], "blind_sign_auth_srcs": [ - "quiche/blind_sign_auth/anonymous_tokens/cpp/client/anonymous_tokens_rsa_bssa_client.cc", - "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/anonymous_tokens_pb_openssl_converters.cc", - "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/crypto_utils.cc", - "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blind_signer.cc", - "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blinder.cc", - "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_ssa_pss_verifier.cc", - "quiche/blind_sign_auth/anonymous_tokens/cpp/shared/proto_utils.cc", - "quiche/blind_sign_auth/anonymous_tokens/cpp/testing/proto_utils.cc", - "quiche/blind_sign_auth/anonymous_tokens/cpp/testing/utils.cc", "quiche/blind_sign_auth/blind_sign_auth.cc", "quiche/blind_sign_auth/cached_blind_sign_auth.cc" ], @@ -1630,18 +1606,10 @@ ], "blind_sign_auth_tests_srcs": [ - "quiche/blind_sign_auth/anonymous_tokens/cpp/client/anonymous_tokens_rsa_bssa_client_test.cc", - "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/anonymous_tokens_pb_openssl_converters_test.cc", - "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/at_crypto_utils_test.cc", - "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blind_signer_test.cc", - "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blinder_test.cc", - "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_ssa_pss_verifier_test.cc", - "quiche/blind_sign_auth/anonymous_tokens/cpp/shared/proto_utils_test.cc", "quiche/blind_sign_auth/blind_sign_auth_test.cc", "quiche/blind_sign_auth/cached_blind_sign_auth_test.cc" ], "protobuf_blind_sign_auth": [ - "quiche/blind_sign_auth/anonymous_tokens/proto/anonymous_tokens.proto", "quiche/blind_sign_auth/proto/any.proto", "quiche/blind_sign_auth/proto/attestation.proto", "quiche/blind_sign_auth/proto/auth_and_sign.proto",
diff --git a/quiche/blind_sign_auth/anonymous_tokens/cpp/client/anonymous_tokens_rsa_bssa_client.cc b/quiche/blind_sign_auth/anonymous_tokens/cpp/client/anonymous_tokens_rsa_bssa_client.cc deleted file mode 100644 index d1f7de1..0000000 --- a/quiche/blind_sign_auth/anonymous_tokens/cpp/client/anonymous_tokens_rsa_bssa_client.cc +++ /dev/null
@@ -1,295 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/client/anonymous_tokens_rsa_bssa_client.h" - -#include <cstddef> -#include <memory> -#include <optional> -#include <string> -#include <utility> -#include <vector> - -#include "absl/container/flat_hash_set.h" -#include "absl/status/status.h" -#include "absl/time/time.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/anonymous_tokens_pb_openssl_converters.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/crypto_utils.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/shared/proto_utils.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/shared/status_utils.h" -#include "quiche/blind_sign_auth/anonymous_tokens/proto/anonymous_tokens.pb.h" - -namespace private_membership { -namespace anonymous_tokens { - -namespace { - -absl::Status ValidityChecksForClientCreation( - const RSABlindSignaturePublicKey& public_key) { - // Basic validity checks. - if (!ParseUseCase(public_key.use_case()).ok()) { - return absl::InvalidArgumentError("Invalid use case for public key."); - } else if (public_key.key_version() <= 0) { - return absl::InvalidArgumentError( - "Key version cannot be zero or negative."); - } else if (public_key.key_size() < 256) { - return absl::InvalidArgumentError( - "Key modulus size cannot be less than 256 bytes."); - } else if (public_key.mask_gen_function() == AT_TEST_MGF || - public_key.mask_gen_function() == AT_MGF_UNDEFINED) { - return absl::InvalidArgumentError("Unknown or unacceptable mgf1 hash."); - } else if (public_key.sig_hash_type() == AT_TEST_HASH_TYPE || - public_key.sig_hash_type() == AT_HASH_TYPE_UNDEFINED) { - return absl::InvalidArgumentError( - "Unknown or unacceptable signature hash."); - } else if (public_key.salt_length() <= 0) { - return absl::InvalidArgumentError( - "Non-positive salt length is not allowed."); - } - - switch (public_key.message_mask_type()) { - case AT_MESSAGE_MASK_CONCAT: - if (public_key.message_mask_size() < 32) { - return absl::InvalidArgumentError( - "Message mask concat type must have a size of at least 32 bytes."); - } - break; - case AT_MESSAGE_MASK_NO_MASK: - if (public_key.message_mask_size() != 0) { - return absl::InvalidArgumentError( - "Message mask no mask type must be set to size 0 bytes."); - } - break; - default: - return absl::InvalidArgumentError( - "Message mask type must be defined and supported."); - } - - RSAPublicKey rsa_public_key; - if (!rsa_public_key.ParseFromString(public_key.serialized_public_key())) { - return absl::InvalidArgumentError("Public key is malformed."); - } - if (rsa_public_key.n().size() != static_cast<size_t>(public_key.key_size())) { - return absl::InvalidArgumentError( - "Public key size does not match key size."); - } - return absl::OkStatus(); -} - -absl::Status CheckPublicKeyValidity( - const RSABlindSignaturePublicKey& public_key) { - absl::Time time_now = absl::Now(); - ANON_TOKENS_ASSIGN_OR_RETURN( - absl::Time start_time, - TimeFromProto(public_key.key_validity_start_time())); - if (start_time > time_now) { - return absl::FailedPreconditionError("Key is not valid yet."); - } - if (public_key.has_expiration_time()) { - ANON_TOKENS_ASSIGN_OR_RETURN(absl::Time expiration_time, - TimeFromProto(public_key.expiration_time())); - if (expiration_time <= time_now) { - return absl::FailedPreconditionError("Key is already expired."); - } - } - return absl::OkStatus(); -} - -} // namespace - -AnonymousTokensRsaBssaClient::AnonymousTokensRsaBssaClient( - const RSABlindSignaturePublicKey& public_key) - : public_key_(public_key) {} - -absl::StatusOr<std::unique_ptr<AnonymousTokensRsaBssaClient>> -AnonymousTokensRsaBssaClient::Create( - const RSABlindSignaturePublicKey& public_key) { - ANON_TOKENS_RETURN_IF_ERROR(ValidityChecksForClientCreation(public_key)); - return absl::WrapUnique(new AnonymousTokensRsaBssaClient(public_key)); -} - -// TODO(b/261866075): Offer an API to simply return bytes of blinded requests. -absl::StatusOr<AnonymousTokensSignRequest> -AnonymousTokensRsaBssaClient::CreateRequest( - const std::vector<PlaintextMessageWithPublicMetadata>& inputs) { - if (inputs.empty()) { - return absl::InvalidArgumentError("Cannot create an empty request."); - } else if (!blinding_info_map_.empty()) { - return absl::FailedPreconditionError( - "Blind signature request already created."); - } - - ANON_TOKENS_RETURN_IF_ERROR(CheckPublicKeyValidity(public_key_)); - RSAPublicKey rsa_public_key_proto; - if (!rsa_public_key_proto.ParseFromString( - public_key_.serialized_public_key())) { - return absl::InvalidArgumentError("Public key is malformed."); - } - - AnonymousTokensSignRequest request; - for (const PlaintextMessageWithPublicMetadata& input : inputs) { - // Generate nonce and masked message. For more details, see - // https://datatracker.ietf.org/doc/draft-irtf-cfrg-rsa-blind-signatures/ - ANON_TOKENS_ASSIGN_OR_RETURN(std::string mask, GenerateMask(public_key_)); - std::string masked_message = - MaskMessageConcat(mask, input.plaintext_message()); - - std::optional<std::string> public_metadata = std::nullopt; - if (public_key_.public_metadata_support()) { - // Empty public metadata is a valid value. - public_metadata = input.public_metadata(); - } - const bool use_rsa_public_exponent = false; - // Owned by BoringSSL. - ANON_TOKENS_ASSIGN_OR_RETURN( - const EVP_MD* sig_hash, - ProtoHashTypeToEVPDigest(public_key_.sig_hash_type())); - // Owned by BoringSSL. - ANON_TOKENS_ASSIGN_OR_RETURN( - const EVP_MD* mgf1_hash, - ProtoMaskGenFunctionToEVPDigest(public_key_.mask_gen_function())); - // Generate RSA blinder. - ANON_TOKENS_ASSIGN_OR_RETURN( - auto rsa_bssa_blinder, - RsaBlinder::New(rsa_public_key_proto.n(), rsa_public_key_proto.e(), - sig_hash, mgf1_hash, public_key_.salt_length(), - use_rsa_public_exponent, public_metadata)); - ANON_TOKENS_ASSIGN_OR_RETURN(const std::string blinded_message, - rsa_bssa_blinder->Blind(masked_message)); - - // Store randomness needed to unblind. - BlindingInfo blinding_info = { - input, - mask, - std::move(rsa_bssa_blinder), - }; - - // Create the blinded token. - AnonymousTokensSignRequest_BlindedToken* blinded_token = - request.add_blinded_tokens(); - blinded_token->set_use_case(public_key_.use_case()); - blinded_token->set_key_version(public_key_.key_version()); - blinded_token->set_serialized_token(blinded_message); - blinded_token->set_public_metadata(input.public_metadata()); - blinded_token->set_do_not_use_rsa_public_exponent(!use_rsa_public_exponent); - blinding_info_map_[blinded_message] = std::move(blinding_info); - } - - return request; -} - -absl::StatusOr<std::vector<RSABlindSignatureTokenWithInput>> -AnonymousTokensRsaBssaClient::ProcessResponse( - const AnonymousTokensSignResponse& response) { - if (blinding_info_map_.empty()) { - return absl::FailedPreconditionError( - "A valid Blind signature request was not created before calling " - "RetrieveAnonymousTokensFromSignResponse."); - } else if (response.anonymous_tokens().empty()) { - return absl::InvalidArgumentError("Cannot process an empty response."); - } else if (static_cast<size_t>(response.anonymous_tokens().size()) != - blinding_info_map_.size()) { - return absl::InvalidArgumentError( - "Response is missing some requested tokens."); - } - - // Vector to accumulate output tokens. - std::vector<RSABlindSignatureTokenWithInput> tokens; - - // Temporary set structure to check for duplicate responses. - absl::flat_hash_set<absl::string_view> blinded_messages; - - // Loop over all the anonymous tokens in the response. - for (const AnonymousTokensSignResponse_AnonymousToken& anonymous_token : - response.anonymous_tokens()) { - // Basic validity checks on the response. - if (anonymous_token.use_case() != public_key_.use_case()) { - return absl::InvalidArgumentError("Use case does not match public key."); - } else if (anonymous_token.key_version() != public_key_.key_version()) { - return absl::InvalidArgumentError( - "Key version does not match public key."); - } else if (anonymous_token.serialized_blinded_message().empty()) { - return absl::InvalidArgumentError( - "Blinded message that was sent in request cannot be empty in " - "response."); - } else if (anonymous_token.serialized_token().empty()) { - return absl::InvalidArgumentError( - "Blinded anonymous token (serialized_token) in response cannot be " - "empty."); - } - - // Check for duplicate in responses. - if (!blinded_messages.insert(anonymous_token.serialized_blinded_message()) - .second) { - return absl::InvalidArgumentError( - "Blinded message was repeated in the response."); - } - - // Retrieve blinding info associated with blind response. - auto it = - blinding_info_map_.find(anonymous_token.serialized_blinded_message()); - if (it == blinding_info_map_.end()) { - return absl::InvalidArgumentError( - "Response has some tokens for some blinded messages that were not " - "requested."); - } - const BlindingInfo& blinding_info = it->second; - - if (blinding_info.input.public_metadata() != - anonymous_token.public_metadata()) { - return absl::InvalidArgumentError( - "Response public metadata does not match input."); - } else if (public_key_.public_metadata_support() && - !anonymous_token.do_not_use_rsa_public_exponent()) { - // Bool do_not_use_rsa_public_exponent does not matter for the non-public - // metadata version. - return absl::InvalidArgumentError( - "Setting do_not_use_rsa_public_exponent to false is no longer " - "supported."); - } - - // Unblind the blinded anonymous token to obtain the final anonymous token - // (signature). - ANON_TOKENS_ASSIGN_OR_RETURN( - const std::string final_anonymous_token, - blinding_info.rsa_blinder->Unblind(anonymous_token.serialized_token())); - - // Verify the signature for correctness. - ANON_TOKENS_RETURN_IF_ERROR(blinding_info.rsa_blinder->Verify( - final_anonymous_token, - MaskMessageConcat(blinding_info.mask, - blinding_info.input.plaintext_message()))); - - // Construct the final signature proto. - RSABlindSignatureTokenWithInput final_token_proto; - *final_token_proto.mutable_token()->mutable_token() = final_anonymous_token; - *final_token_proto.mutable_token()->mutable_message_mask() = - blinding_info.mask; - *final_token_proto.mutable_input() = blinding_info.input; - - tokens.push_back(final_token_proto); - } - - return tokens; -} - -absl::Status AnonymousTokensRsaBssaClient::Verify( - const RSABlindSignaturePublicKey& /*public_key*/, - const RSABlindSignatureToken& /*token*/, - const PlaintextMessageWithPublicMetadata& /*input*/) { - return absl::UnimplementedError("Verify not implemented yet."); -} - -} // namespace anonymous_tokens -} // namespace private_membership
diff --git a/quiche/blind_sign_auth/anonymous_tokens/cpp/client/anonymous_tokens_rsa_bssa_client.h b/quiche/blind_sign_auth/anonymous_tokens/cpp/client/anonymous_tokens_rsa_bssa_client.h deleted file mode 100644 index e760182..0000000 --- a/quiche/blind_sign_auth/anonymous_tokens/cpp/client/anonymous_tokens_rsa_bssa_client.h +++ /dev/null
@@ -1,104 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef THIRD_PARTY_ANONYMOUS_TOKENS_CPP_CLIENT_ANONYMOUS_TOKENS_RSA_BSSA_CLIENT_H_ -#define THIRD_PARTY_ANONYMOUS_TOKENS_CPP_CLIENT_ANONYMOUS_TOKENS_RSA_BSSA_CLIENT_H_ - -#include <memory> -#include <string> -#include <vector> - -#include "absl/container/flat_hash_map.h" -#include "absl/status/statusor.h" -#include "absl/strings/string_view.h" -#include "absl/types/optional.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blinder.h" -#include "quiche/blind_sign_auth/anonymous_tokens/proto/anonymous_tokens.pb.h" -#include "quiche/common/platform/api/quiche_export.h" -// copybara:strip_begin(internal comment) -// The QUICHE_EXPORT annotation is necessary for some classes and functions -// to link correctly on Windows. Please do not remove them! -// copybara:strip_end - -namespace private_membership { -namespace anonymous_tokens { - -// This class generates AnonymousTokens RSA blind signatures, -// (https://datatracker.ietf.org/doc/draft-irtf-cfrg-rsa-blind-signatures/) -// blind message signing request and processes the response. -// -// Each execution of the Anonymous Tokens RSA blind signatures protocol requires -// a new instance of the AnonymousTokensRsaBssaClient. -// -// This class is not thread-safe. -class QUICHE_EXPORT AnonymousTokensRsaBssaClient { - public: - // AnonymousTokensRsaBssaClient is neither copyable nor copy assignable. - AnonymousTokensRsaBssaClient(const AnonymousTokensRsaBssaClient&) = delete; - AnonymousTokensRsaBssaClient& operator=(const AnonymousTokensRsaBssaClient&) = - delete; - - // Create client with the specified public key which can be used to send a - // sign request and process a response. - // - // This method is to be used to create a client as its constructor is private. - // It takes as input RSABlindSignaturePublicKey which contains the public key - // and relevant parameters. - static absl::StatusOr<std::unique_ptr<AnonymousTokensRsaBssaClient>> Create( - const RSABlindSignaturePublicKey& public_key); - - // Class method that creates the signature requests by taking a vector where - // each element in the vector is the plaintext message along with its - // respective public metadata (if the metadata exists). - // - // The library will also fail if the key has expired. - // - // It only puts the blinded version of the messages in the request. - absl::StatusOr<AnonymousTokensSignRequest> CreateRequest( - const std::vector<PlaintextMessageWithPublicMetadata>& inputs); - - // Class method that processes the signature response from the server. - // - // It outputs a vector of a protos where each element contains an input - // plaintext message and associated public metadata (if it exists) along with - // its final (unblinded) anonymous token resulting from the RSA blind - // signatures protocol. - absl::StatusOr<std::vector<RSABlindSignatureTokenWithInput>> ProcessResponse( - const AnonymousTokensSignResponse& response); - - // Method to verify whether an anonymous token is valid or not. - // - // Returns OK on a valid token and non-OK otherwise. - absl::Status Verify(const RSABlindSignaturePublicKey& public_key, - const RSABlindSignatureToken& token, - const PlaintextMessageWithPublicMetadata& input); - - private: - struct BlindingInfo { - PlaintextMessageWithPublicMetadata input; - std::string mask; - std::unique_ptr<RsaBlinder> rsa_blinder; - }; - - explicit AnonymousTokensRsaBssaClient( - const RSABlindSignaturePublicKey& public_key); - - const RSABlindSignaturePublicKey public_key_; - absl::flat_hash_map<std::string, BlindingInfo> blinding_info_map_; -}; - -} // namespace anonymous_tokens -} // namespace private_membership - -#endif // THIRD_PARTY_ANONYMOUS_TOKENS_CPP_CLIENT_ANONYMOUS_TOKENS_RSA_BSSA_CLIENT_H_
diff --git a/quiche/blind_sign_auth/anonymous_tokens/cpp/client/anonymous_tokens_rsa_bssa_client_test.cc b/quiche/blind_sign_auth/anonymous_tokens/cpp/client/anonymous_tokens_rsa_bssa_client_test.cc deleted file mode 100644 index 95caa30..0000000 --- a/quiche/blind_sign_auth/anonymous_tokens/cpp/client/anonymous_tokens_rsa_bssa_client_test.cc +++ /dev/null
@@ -1,609 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/client/anonymous_tokens_rsa_bssa_client.h" - -#include <memory> -#include <string> -#include <tuple> -#include <utility> -#include <vector> - -#include "quiche/common/platform/api/quiche_test.h" -#include "quiche/common/test_tools/quiche_test_utils.h" -#include "absl/status/status.h" -#include "absl/status/statusor.h" -#include "absl/time/time.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/constants.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blind_signer.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/shared/proto_utils.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/shared/status_utils.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/testing/proto_utils.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/testing/utils.h" -#include "quiche/blind_sign_auth/anonymous_tokens/proto/anonymous_tokens.pb.h" -#include "openssl/base.h" -#include "openssl/rsa.h" - -namespace private_membership { -namespace anonymous_tokens { -namespace { - -using ::testing::SizeIs; - -// Returns a fixed public private key pair by calling GetStrongRsaKeys4096(). -absl::StatusOr<std::pair<RSABlindSignaturePublicKey, RSAPrivateKey>> -CreateClientTestKey(absl::string_view use_case = "TEST_USE_CASE", - int key_version = 1, - MessageMaskType mask_type = AT_MESSAGE_MASK_CONCAT, - int message_mask_size = 32, - bool enable_public_metadata = false) { - ANON_TOKENS_ASSIGN_OR_RETURN(auto key_pair, GetStrongRsaKeys4096()); - RSABlindSignaturePublicKey public_key; - public_key.set_use_case(std::string(use_case)); - public_key.set_key_version(key_version); - public_key.set_serialized_public_key(key_pair.first.SerializeAsString()); - absl::Time start_time = absl::Now() - absl::Minutes(100); - ANON_TOKENS_ASSIGN_OR_RETURN(*public_key.mutable_key_validity_start_time(), - TimeToProto(start_time)); - public_key.set_sig_hash_type(AT_HASH_TYPE_SHA384); - public_key.set_mask_gen_function(AT_MGF_SHA384); - public_key.set_salt_length(kSaltLengthInBytes48); - public_key.set_key_size(kRsaModulusSizeInBytes512); - public_key.set_message_mask_type(mask_type); - public_key.set_message_mask_size(message_mask_size); - public_key.set_public_metadata_support(enable_public_metadata); - - return std::make_pair(std::move(public_key), std::move(key_pair.second)); -} - -// Creates the input consisting on plaintext messages and public metadata that -// can be passed to the AnonymousTokensRsaBssaClient. -absl::StatusOr<std::vector<PlaintextMessageWithPublicMetadata>> CreateInput( - absl::Span<const std::string> messages, - absl::Span<const std::string> public_metadata = {}) { - // Check input parameter sizes. - if (!public_metadata.empty() && messages.size() != public_metadata.size()) { - return absl::InvalidArgumentError( - "Input vectors should be of the same size."); - } - - std::vector<PlaintextMessageWithPublicMetadata> anonymmous_tokens_input_proto; - anonymmous_tokens_input_proto.reserve(messages.size()); - for (int i = 0; i < messages.size(); ++i) { - PlaintextMessageWithPublicMetadata input_message_and_metadata; - input_message_and_metadata.set_plaintext_message(messages[i]); - if (!public_metadata.empty()) { - input_message_and_metadata.set_public_metadata(public_metadata[i]); - } - anonymmous_tokens_input_proto.push_back(input_message_and_metadata); - } - return anonymmous_tokens_input_proto; -} - -// Creates the server response for anonymous tokens request by using -// RsaBlindSigner. -absl::StatusOr<AnonymousTokensSignResponse> CreateResponse( - const AnonymousTokensSignRequest& request, const RSAPrivateKey& private_key, - bool enable_public_metadata = false) { - AnonymousTokensSignResponse response; - const bool use_rsa_public_exponent = false; - for (const auto& request_token : request.blinded_tokens()) { - auto* response_token = response.add_anonymous_tokens(); - response_token->set_use_case(request_token.use_case()); - response_token->set_key_version(request_token.key_version()); - response_token->set_public_metadata(request_token.public_metadata()); - response_token->set_serialized_blinded_message( - request_token.serialized_token()); - response_token->set_do_not_use_rsa_public_exponent( - !use_rsa_public_exponent); - std::optional<std::string> public_metadata = std::nullopt; - if (enable_public_metadata) { - public_metadata = request_token.public_metadata(); - } - ANON_TOKENS_ASSIGN_OR_RETURN( - std::unique_ptr<RsaBlindSigner> blind_signer, - RsaBlindSigner::New(private_key, use_rsa_public_exponent, - public_metadata)); - ANON_TOKENS_ASSIGN_OR_RETURN( - *response_token->mutable_serialized_token(), - blind_signer->Sign(request_token.serialized_token())); - } - return response; -} - -TEST(CreateAnonymousTokensRsaBssaClientTest, Success) { - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(auto rsa_key, CreateClientTestKey()); - EXPECT_TRUE(AnonymousTokensRsaBssaClient::Create(rsa_key.first).ok()); -} - -TEST(CreateAnonymousTokensRsaBssaClientTest, InvalidUseCase) { - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(auto rsa_key, - CreateClientTestKey("INVALID_USE_CASE")); - absl::StatusOr<std::unique_ptr<AnonymousTokensRsaBssaClient>> client = - AnonymousTokensRsaBssaClient::Create(rsa_key.first); - EXPECT_EQ(client.status().code(), absl::StatusCode::kInvalidArgument); - EXPECT_THAT(client.status().message(), - testing::HasSubstr("Invalid use case for public key")); -} - -TEST(CreateAnonymousTokensRsaBssaClientTest, NotAUseCase) { - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(auto rsa_key, - CreateClientTestKey("NOT_A_USE_CASE")); - absl::StatusOr<std::unique_ptr<AnonymousTokensRsaBssaClient>> client = - AnonymousTokensRsaBssaClient::Create(rsa_key.first); - EXPECT_EQ(client.status().code(), absl::StatusCode::kInvalidArgument); - EXPECT_THAT(client.status().message(), - testing::HasSubstr("Invalid use case for public key")); -} - -TEST(CreateAnonymousTokensRsaBssaClientTest, InvalidKeyVersion) { - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(auto rsa_key, - CreateClientTestKey("TEST_USE_CASE", 0)); - absl::StatusOr<std::unique_ptr<AnonymousTokensRsaBssaClient>> client = - AnonymousTokensRsaBssaClient::Create(rsa_key.first); - EXPECT_EQ(client.status().code(), absl::StatusCode::kInvalidArgument); - EXPECT_THAT(client.status().message(), - testing::HasSubstr("Key version cannot be zero or negative")); -} - -TEST(CreateAnonymousTokensRsaBssaClientTest, InvalidMessageMaskType) { - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - auto rsa_key, - CreateClientTestKey("TEST_USE_CASE", 1, AT_MESSAGE_MASK_TYPE_UNDEFINED)); - absl::StatusOr<std::unique_ptr<AnonymousTokensRsaBssaClient>> client = - AnonymousTokensRsaBssaClient::Create(rsa_key.first); - EXPECT_EQ(client.status().code(), absl::StatusCode::kInvalidArgument); - EXPECT_THAT(client.status().message(), - testing::HasSubstr("Message mask type must be defined")); -} - -TEST(CreateAnonymousTokensRsaBssaClientTest, - MessageMaskConcatInvalidMessageMaskSize) { - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - auto rsa_key, - CreateClientTestKey("TEST_USE_CASE", 1, AT_MESSAGE_MASK_CONCAT, 0)); - absl::StatusOr<std::unique_ptr<AnonymousTokensRsaBssaClient>> client = - AnonymousTokensRsaBssaClient::Create(rsa_key.first); - EXPECT_EQ(client.status().code(), absl::StatusCode::kInvalidArgument); - EXPECT_THAT( - client.status().message(), - testing::HasSubstr( - "Message mask concat type must have a size of at least 32 bytes")); -} - -TEST(CreateAnonymousTokensRsaBssaClientTest, - MessageMaskNoMaskInvalidMessageMaskSize) { - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - auto rsa_key, - CreateClientTestKey("TEST_USE_CASE", 1, AT_MESSAGE_MASK_NO_MASK, 32)); - absl::StatusOr<std::unique_ptr<AnonymousTokensRsaBssaClient>> client = - AnonymousTokensRsaBssaClient::Create(rsa_key.first); - EXPECT_EQ(client.status().code(), absl::StatusCode::kInvalidArgument); - EXPECT_THAT(client.status().message(), - testing::HasSubstr( - "Message mask no mask type must be set to size 0 bytes.")); -} - -class AnonymousTokensRsaBssaClientTest : public testing::Test { - protected: - void SetUp() override { - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::tie(public_key_, private_key_), - CreateClientTestKey()); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - client_, AnonymousTokensRsaBssaClient::Create(public_key_)); - } - - RSAPrivateKey private_key_; - RSABlindSignaturePublicKey public_key_; - std::unique_ptr<AnonymousTokensRsaBssaClient> client_; -}; - -TEST_F(AnonymousTokensRsaBssaClientTest, SuccessOneMessage) { - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::vector<PlaintextMessageWithPublicMetadata> input_messages, - CreateInput({"message"})); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(AnonymousTokensSignRequest request, - client_->CreateRequest(input_messages)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(AnonymousTokensSignResponse response, - CreateResponse(request, private_key_)); - EXPECT_THAT(response.anonymous_tokens(), SizeIs(1)); - EXPECT_TRUE(client_->ProcessResponse(response).ok()); -} - -TEST_F(AnonymousTokensRsaBssaClientTest, SuccessMultipleMessages) { - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::vector<PlaintextMessageWithPublicMetadata> input_messages, - CreateInput({"message1", "msg2", "anotherMessage", "one_more_message"})); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(AnonymousTokensSignRequest request, - client_->CreateRequest(input_messages)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(AnonymousTokensSignResponse response, - CreateResponse(request, private_key_)); - EXPECT_THAT(response.anonymous_tokens(), SizeIs(4)); - EXPECT_TRUE(client_->ProcessResponse(response).ok()); -} - -TEST_F(AnonymousTokensRsaBssaClientTest, SuccessMultipleMessagesNoMessageMask) { - RSABlindSignaturePublicKey public_key; - RSAPrivateKey private_key; - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::tie(public_key, private_key), - CreateClientTestKey("TEST_USE_CASE", /*key_version=*/1, - AT_MESSAGE_MASK_NO_MASK, /*message_mask_size=*/0)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::unique_ptr<AnonymousTokensRsaBssaClient> client, - AnonymousTokensRsaBssaClient::Create(public_key)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::vector<PlaintextMessageWithPublicMetadata> input_messages, - CreateInput({"message1", "msg2", "anotherMessage", "one_more_message"})); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(AnonymousTokensSignRequest request, - client->CreateRequest(input_messages)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(AnonymousTokensSignResponse response, - CreateResponse(request, private_key)); - ASSERT_EQ(response.anonymous_tokens().size(), 4); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::vector<RSABlindSignatureTokenWithInput> finalized_tokens_with_inputs, - client->ProcessResponse(response)); - - for (const RSABlindSignatureTokenWithInput& token_with_input : - finalized_tokens_with_inputs) { - EXPECT_TRUE(token_with_input.token().message_mask().empty()); - } -} - -TEST_F(AnonymousTokensRsaBssaClientTest, EnsureRandomTokens) { - std::string message = "test_same_message"; - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::vector<PlaintextMessageWithPublicMetadata> input_messages, - CreateInput({message, message})); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(AnonymousTokensSignRequest request, - client_->CreateRequest(input_messages)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(AnonymousTokensSignResponse response, - CreateResponse(request, private_key_)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::vector<RSABlindSignatureTokenWithInput> tokens, - client_->ProcessResponse(response)); - ASSERT_EQ(tokens.size(), 2); - for (const RSABlindSignatureTokenWithInput& token : tokens) { - EXPECT_EQ(token.input().plaintext_message(), message); - } - EXPECT_NE(tokens[0].token().message_mask(), tokens[1].token().message_mask()); - EXPECT_NE(tokens[0].token().token(), tokens[1].token().token()); -} - -TEST_F(AnonymousTokensRsaBssaClientTest, EmptyInput) { - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::vector<PlaintextMessageWithPublicMetadata> input_messages, - CreateInput({})); - absl::StatusOr<AnonymousTokensSignRequest> request = - client_->CreateRequest(input_messages); - EXPECT_EQ(request.status().code(), absl::StatusCode::kInvalidArgument); - EXPECT_THAT(request.status().message(), - testing::HasSubstr("Cannot create an empty request")); -} - -TEST_F(AnonymousTokensRsaBssaClientTest, NotYetValidKey) { - RSABlindSignaturePublicKey not_valid_key = public_key_; - absl::Time start_time = absl::Now() + absl::Minutes(100); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - *not_valid_key.mutable_key_validity_start_time(), - TimeToProto(start_time)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::unique_ptr<AnonymousTokensRsaBssaClient> client, - AnonymousTokensRsaBssaClient::Create(not_valid_key)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::vector<PlaintextMessageWithPublicMetadata> input_messages, - CreateInput({"message"})); - absl::StatusOr<AnonymousTokensSignRequest> request = - client->CreateRequest(input_messages); - EXPECT_EQ(request.status().code(), absl::StatusCode::kFailedPrecondition); - EXPECT_THAT(request.status().message(), - testing::HasSubstr("Key is not valid yet")); -} - -TEST_F(AnonymousTokensRsaBssaClientTest, ExpiredKey) { - RSABlindSignaturePublicKey expired_key = public_key_; - absl::Time end_time = absl::Now() - absl::Seconds(1); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(*expired_key.mutable_expiration_time(), - TimeToProto(end_time)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::unique_ptr<AnonymousTokensRsaBssaClient> client, - AnonymousTokensRsaBssaClient::Create(expired_key)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::vector<PlaintextMessageWithPublicMetadata> input_messages, - CreateInput({"message"})); - absl::StatusOr<AnonymousTokensSignRequest> request = - client->CreateRequest(input_messages); - EXPECT_EQ(request.status().code(), absl::StatusCode::kFailedPrecondition); - EXPECT_THAT(request.status().message(), - testing::HasSubstr("Key is already expired")); -} - -TEST_F(AnonymousTokensRsaBssaClientTest, CreateRequestTwice) { - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::vector<PlaintextMessageWithPublicMetadata> input_messages, - CreateInput({"message"})); - EXPECT_TRUE(client_->CreateRequest(input_messages).ok()); - absl::StatusOr<AnonymousTokensSignRequest> request = - client_->CreateRequest(input_messages); - EXPECT_EQ(request.status().code(), absl::StatusCode::kFailedPrecondition); - EXPECT_THAT(request.status().message(), - testing::HasSubstr("Blind signature request already created")); -} - -TEST_F(AnonymousTokensRsaBssaClientTest, ProcessResponseWithoutCreateRequest) { - AnonymousTokensSignResponse response; - absl::StatusOr<std::vector<RSABlindSignatureTokenWithInput>> - processed_response = client_->ProcessResponse(response); - EXPECT_EQ(processed_response.status().code(), - absl::StatusCode::kFailedPrecondition); - EXPECT_THAT( - processed_response.status().message(), - testing::HasSubstr("A valid Blind signature request was not created")); -} - -TEST_F(AnonymousTokensRsaBssaClientTest, ProcessEmptyResponse) { - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::vector<PlaintextMessageWithPublicMetadata> input_messages, - CreateInput({"message"})); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(AnonymousTokensSignRequest request, - client_->CreateRequest(input_messages)); - AnonymousTokensSignResponse response; - absl::StatusOr<std::vector<RSABlindSignatureTokenWithInput>> - processed_response = client_->ProcessResponse(response); - EXPECT_EQ(processed_response.status().code(), - absl::StatusCode::kInvalidArgument); - EXPECT_THAT(processed_response.status().message(), - testing::HasSubstr("Cannot process an empty response")); -} - -TEST_F(AnonymousTokensRsaBssaClientTest, ProcessResponseWithBadUseCase) { - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::vector<PlaintextMessageWithPublicMetadata> input_messages, - CreateInput({"message"})); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(AnonymousTokensSignRequest request, - client_->CreateRequest(input_messages)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(AnonymousTokensSignResponse response, - CreateResponse(request, private_key_)); - response.mutable_anonymous_tokens(0)->set_use_case("TEST_USE_CASE_2"); - absl::StatusOr<std::vector<RSABlindSignatureTokenWithInput>> - processed_response = client_->ProcessResponse(response); - EXPECT_EQ(processed_response.status().code(), - absl::StatusCode::kInvalidArgument); - EXPECT_THAT(processed_response.status().message(), - testing::HasSubstr("Use case does not match public key")); -} - -TEST_F(AnonymousTokensRsaBssaClientTest, ProcessResponseWithBadKeyVersion) { - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::vector<PlaintextMessageWithPublicMetadata> input_messages, - CreateInput({"message"})); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(AnonymousTokensSignRequest request, - client_->CreateRequest(input_messages)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(AnonymousTokensSignResponse response, - CreateResponse(request, private_key_)); - response.mutable_anonymous_tokens(0)->set_key_version(2); - absl::StatusOr<std::vector<RSABlindSignatureTokenWithInput>> - processed_response = client_->ProcessResponse(response); - EXPECT_EQ(processed_response.status().code(), - absl::StatusCode::kInvalidArgument); - EXPECT_THAT(processed_response.status().message(), - testing::HasSubstr("Key version does not match public key")); -} - -TEST_F(AnonymousTokensRsaBssaClientTest, ProcessResponseFromDifferentClient) { - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::vector<PlaintextMessageWithPublicMetadata> input_messages, - CreateInput({"message"})); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::unique_ptr<AnonymousTokensRsaBssaClient> client2, - AnonymousTokensRsaBssaClient::Create(public_key_)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(AnonymousTokensSignRequest request1, - client_->CreateRequest(input_messages)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(AnonymousTokensSignRequest request2, - client2->CreateRequest(input_messages)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(AnonymousTokensSignResponse response1, - CreateResponse(request1, private_key_)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(AnonymousTokensSignResponse response2, - CreateResponse(request2, private_key_)); - absl::StatusOr<std::vector<RSABlindSignatureTokenWithInput>> - processed_response2 = client_->ProcessResponse(response2); - EXPECT_EQ(processed_response2.status().code(), - absl::StatusCode::kInvalidArgument); - absl::StatusOr<std::vector<RSABlindSignatureTokenWithInput>> - processed_response1 = client2->ProcessResponse(response1); - EXPECT_EQ(processed_response1.status().code(), - absl::StatusCode::kInvalidArgument); -} - -class AnonymousTokensRsaBssaClientWithPublicMetadataTest - : public testing::Test { - protected: - void SetUp() override { - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::tie(public_key_, private_key_), - CreateClientTestKey("TEST_USE_CASE", /*key_version=*/1, - AT_MESSAGE_MASK_CONCAT, - kRsaMessageMaskSizeInBytes32, - /*enable_public_metadata=*/true)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - public_metadata_client_, - AnonymousTokensRsaBssaClient::Create(public_key_)); - } - - RSAPrivateKey private_key_; - RSABlindSignaturePublicKey public_key_; - std::unique_ptr<AnonymousTokensRsaBssaClient> public_metadata_client_; -}; - -TEST_F(AnonymousTokensRsaBssaClientWithPublicMetadataTest, - SuccessOneMessageWithPublicMetadata) { - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::vector<PlaintextMessageWithPublicMetadata> input_messages, - CreateInput({"message"}, {"md1"})); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - AnonymousTokensSignRequest request, - public_metadata_client_->CreateRequest(input_messages)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - AnonymousTokensSignResponse response, - CreateResponse(request, private_key_, /*enable_public_metadata=*/true)); - EXPECT_THAT(response.anonymous_tokens(), SizeIs(1)); - EXPECT_TRUE(public_metadata_client_->ProcessResponse(response).ok()); -} - -TEST_F(AnonymousTokensRsaBssaClientWithPublicMetadataTest, - FailureWithEmptyPublicMetadata) { - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::vector<PlaintextMessageWithPublicMetadata> input_messages, - CreateInput({"message"}, {"md1"})); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - AnonymousTokensSignRequest request, - public_metadata_client_->CreateRequest(input_messages)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - AnonymousTokensSignResponse response, - CreateResponse(request, private_key_, /*enable_public_metadata=*/false)); - absl::StatusOr<std::vector<RSABlindSignatureTokenWithInput>> - processed_response = public_metadata_client_->ProcessResponse(response); - EXPECT_EQ(processed_response.status().code(), - absl::StatusCode::kInvalidArgument); -} - -TEST_F(AnonymousTokensRsaBssaClientWithPublicMetadataTest, - FailureWithWrongPublicMetadata) { - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::vector<PlaintextMessageWithPublicMetadata> input_messages, - CreateInput({"message"}, {"md1"})); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - AnonymousTokensSignRequest request, - public_metadata_client_->CreateRequest(input_messages)); - request.mutable_blinded_tokens(0)->set_public_metadata( - "wrong_public_metadata"); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - AnonymousTokensSignResponse response, - CreateResponse(request, private_key_, /*enable_public_metadata=*/true)); - absl::StatusOr<std::vector<RSABlindSignatureTokenWithInput>> - processed_response = public_metadata_client_->ProcessResponse(response); - EXPECT_EQ(processed_response.status().code(), - absl::StatusCode::kInvalidArgument); -} - -TEST_F(AnonymousTokensRsaBssaClientWithPublicMetadataTest, - FailureWithPublicMetadataSupportOff) { - // Create a client with public metadata support disabled. - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(auto key_pair, CreateClientTestKey()); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::unique_ptr<AnonymousTokensRsaBssaClient> non_public_metadata_client, - AnonymousTokensRsaBssaClient::Create(key_pair.first)); - - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::vector<PlaintextMessageWithPublicMetadata> input_messages, - CreateInput({"message"}, {"md1"})); - // Use client_ that does not support public metadata. - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - AnonymousTokensSignRequest request, - non_public_metadata_client->CreateRequest(input_messages)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - AnonymousTokensSignResponse response, - CreateResponse(request, private_key_, /*enable_public_metadata=*/true)); - absl::StatusOr<std::vector<RSABlindSignatureTokenWithInput>> - processed_response = - non_public_metadata_client->ProcessResponse(response); - EXPECT_EQ(processed_response.status().code(), - absl::StatusCode::kInvalidArgument); -} - -TEST_F(AnonymousTokensRsaBssaClientWithPublicMetadataTest, - SuccessMultipleMessagesWithDistinctPublicMetadata) { - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::vector<PlaintextMessageWithPublicMetadata> input_messages, - CreateInput({"message1", "msg2", "anotherMessage", "one_more_message"}, - {"md1", "md2", "md3", "md4"})); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - AnonymousTokensSignRequest request, - public_metadata_client_->CreateRequest(input_messages)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - AnonymousTokensSignResponse response, - CreateResponse(request, private_key_, /*enable_public_metadata=*/true)); - EXPECT_THAT(response.anonymous_tokens(), SizeIs(4)); - EXPECT_TRUE(public_metadata_client_->ProcessResponse(response).ok()); -} - -TEST_F(AnonymousTokensRsaBssaClientWithPublicMetadataTest, - SuccessMultipleMessagesWithRepeatedPublicMetadata) { - // Create input with repeated public metadata - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::vector<PlaintextMessageWithPublicMetadata> input_messages, - CreateInput({"message1", "msg2", "anotherMessage", "one_more_message"}, - {"md1", "md2", "md2", "md1"})); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - AnonymousTokensSignRequest request, - public_metadata_client_->CreateRequest(input_messages)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - AnonymousTokensSignResponse response, - CreateResponse(request, private_key_, /*enable_public_metadata=*/true)); - EXPECT_THAT(response.anonymous_tokens(), SizeIs(4)); - EXPECT_TRUE(public_metadata_client_->ProcessResponse(response).ok()); -} - -TEST_F(AnonymousTokensRsaBssaClientWithPublicMetadataTest, - SuccessMultipleMessagesWithEmptyStringPublicMetadata) { - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::vector<PlaintextMessageWithPublicMetadata> input_messages, - CreateInput({"message1", "msg2", "anotherMessage", "one_more_message"}, - {"md1", "", "", "md4"})); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - AnonymousTokensSignRequest request, - public_metadata_client_->CreateRequest(input_messages)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - AnonymousTokensSignResponse response, - CreateResponse(request, private_key_, /*enable_public_metadata=*/true)); - EXPECT_THAT(response.anonymous_tokens(), SizeIs(4)); - EXPECT_TRUE(public_metadata_client_->ProcessResponse(response).ok()); -} - -TEST_F(AnonymousTokensRsaBssaClientWithPublicMetadataTest, - SuccessMultipleMessagesNoMessageMask) { - RSABlindSignaturePublicKey public_key; - RSAPrivateKey private_key; - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::tie(public_key, private_key), - CreateClientTestKey("TEST_USE_CASE", /*key_version=*/1, - AT_MESSAGE_MASK_NO_MASK, /*message_mask_size=*/0, - /*enable_public_metadata=*/true)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::unique_ptr<AnonymousTokensRsaBssaClient> public_metadata_client, - AnonymousTokensRsaBssaClient::Create(public_key)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::vector<PlaintextMessageWithPublicMetadata> input_messages, - CreateInput({"message1", "msg2", "anotherMessage", "one_more_message"}, - {"md1", "md2", "md3", "md4"})); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - AnonymousTokensSignRequest request, - public_metadata_client->CreateRequest(input_messages)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - AnonymousTokensSignResponse response, - CreateResponse(request, private_key, /*enable_public_metadata=*/true)); - ASSERT_EQ(response.anonymous_tokens().size(), 4); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::vector<RSABlindSignatureTokenWithInput> finalized_tokens_with_inputs, - public_metadata_client->ProcessResponse(response)); - - for (const RSABlindSignatureTokenWithInput& token_with_input : - finalized_tokens_with_inputs) { - EXPECT_TRUE(token_with_input.token().message_mask().empty()); - } -} - -} // namespace -} // namespace anonymous_tokens -} // namespace private_membership
diff --git a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/anonymous_tokens_pb_openssl_converters.cc b/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/anonymous_tokens_pb_openssl_converters.cc deleted file mode 100644 index eef32d3..0000000 --- a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/anonymous_tokens_pb_openssl_converters.cc +++ /dev/null
@@ -1,90 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/anonymous_tokens_pb_openssl_converters.h" - -#include <cstdint> -#include <string> - -#include "absl/status/status.h" -#include "absl/status/statusor.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/constants.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/crypto_utils.h" -#include "quiche/blind_sign_auth/anonymous_tokens/proto/anonymous_tokens.pb.h" -#include "openssl/base.h" -#include "openssl/digest.h" -#include "openssl/rand.h" - -namespace private_membership { -namespace anonymous_tokens { - -absl::StatusOr<std::string> GenerateMask( - const RSABlindSignaturePublicKey& public_key) { - std::string mask; - if (public_key.message_mask_type() == AT_MESSAGE_MASK_CONCAT && - public_key.message_mask_size() >= kRsaMessageMaskSizeInBytes32) { - mask = std::string(public_key.message_mask_size(), '\0'); - RAND_bytes(reinterpret_cast<uint8_t*>(mask.data()), mask.size()); - } else if (public_key.message_mask_type() == AT_MESSAGE_MASK_NO_MASK && - public_key.message_mask_size() == 0) { - return ""; - } else { - return absl::InvalidArgumentError( - "Unsupported message mask type Or invalid message mask size " - "requested."); - } - return mask; -} - -absl::StatusOr<const EVP_MD*> ProtoHashTypeToEVPDigest( - const HashType hash_type) { - switch (hash_type) { - case AT_HASH_TYPE_SHA256: - return EVP_sha256(); - case AT_HASH_TYPE_SHA384: - return EVP_sha384(); - case AT_HASH_TYPE_UNDEFINED: - default: - return absl::InvalidArgumentError("Unknown hash type."); - } -} - -absl::StatusOr<const EVP_MD*> ProtoMaskGenFunctionToEVPDigest( - const MaskGenFunction mgf) { - switch (mgf) { - case AT_MGF_SHA256: - return EVP_sha256(); - case AT_MGF_SHA384: - return EVP_sha384(); - case AT_MGF_UNDEFINED: - default: - return absl::InvalidArgumentError( - "Unknown hash type for mask generation hash function."); - } -} - -absl::StatusOr<bssl::UniquePtr<RSA>> AnonymousTokensRSAPrivateKeyToRSA( - const RSAPrivateKey& private_key) { - return CreatePrivateKeyRSA(private_key.n(), private_key.e(), private_key.d(), - private_key.p(), private_key.q(), private_key.dp(), - private_key.dq(), private_key.crt()); -} - -absl::StatusOr<bssl::UniquePtr<RSA>> AnonymousTokensRSAPublicKeyToRSA( - const RSAPublicKey& public_key) { - return CreatePublicKeyRSA(public_key.n(), public_key.e()); -} - -} // namespace anonymous_tokens -} // namespace private_membership
diff --git a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/anonymous_tokens_pb_openssl_converters.h b/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/anonymous_tokens_pb_openssl_converters.h deleted file mode 100644 index 2ef4c06..0000000 --- a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/anonymous_tokens_pb_openssl_converters.h +++ /dev/null
@@ -1,59 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef THIRD_PARTY_ANONYMOUS_TOKENS_CPP_CRYPTO_ANONYMOUS_TOKENS_PB_OPENSSL_CONVERTERS_H_ -#define THIRD_PARTY_ANONYMOUS_TOKENS_CPP_CRYPTO_ANONYMOUS_TOKENS_PB_OPENSSL_CONVERTERS_H_ - -#include <string> - -#include "absl/status/statusor.h" -#include "quiche/blind_sign_auth/anonymous_tokens/proto/anonymous_tokens.pb.h" -#include "openssl/base.h" -#include "quiche/common/platform/api/quiche_export.h" -// copybara:strip_begin(internal comment) -// The QUICHE_EXPORT annotation is necessary for some classes and functions -// to link correctly on Windows. Please do not remove them! -// copybara:strip_end - -namespace private_membership { -namespace anonymous_tokens { - -// Generate a message mask. For more details, see -// https://datatracker.ietf.org/doc/draft-irtf-cfrg-rsa-blind-signatures/ -absl::StatusOr<std::string> QUICHE_EXPORT GenerateMask( - const RSABlindSignaturePublicKey& public_key); - -// Converts the AnonymousTokens proto hash type to the equivalent EVP digest. -absl::StatusOr<const EVP_MD*> QUICHE_EXPORT -ProtoHashTypeToEVPDigest(HashType hash_type); - -// Converts the AnonymousTokens proto hash type for mask generation function to -// the equivalent EVP digest. -absl::StatusOr<const EVP_MD*> QUICHE_EXPORT -ProtoMaskGenFunctionToEVPDigest(MaskGenFunction mgf); - -// Converts AnonymousTokens::RSAPrivateKey to bssl::UniquePtr<RSA> without -// public metadata augmentation. -absl::StatusOr<bssl::UniquePtr<RSA>> QUICHE_EXPORT -AnonymousTokensRSAPrivateKeyToRSA(const RSAPrivateKey& private_key); - -// Converts AnonymousTokens::RSAPublicKey to bssl::UniquePtr<RSA> without -// public metadata augmentation. -absl::StatusOr<bssl::UniquePtr<RSA>> QUICHE_EXPORT -AnonymousTokensRSAPublicKeyToRSA(const RSAPublicKey& public_key); - -} // namespace anonymous_tokens -} // namespace private_membership - -#endif // THIRD_PARTY_ANONYMOUS_TOKENS_CPP_CRYPTO_ANONYMOUS_TOKENS_PB_OPENSSL_CONVERTERS_H_
diff --git a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/anonymous_tokens_pb_openssl_converters_test.cc b/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/anonymous_tokens_pb_openssl_converters_test.cc deleted file mode 100644 index 5010373..0000000 --- a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/anonymous_tokens_pb_openssl_converters_test.cc +++ /dev/null
@@ -1,201 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/anonymous_tokens_pb_openssl_converters.h" - -#include <string> -#include <utility> - -#include "quiche/common/platform/api/quiche_test.h" -#include "quiche/common/test_tools/quiche_test_utils.h" -#include "absl/status/status.h" -#include "absl/status/statusor.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/constants.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/crypto_utils.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/testing/proto_utils.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/testing/utils.h" -#include "quiche/blind_sign_auth/anonymous_tokens/proto/anonymous_tokens.pb.h" -#include "openssl/base.h" -#include "openssl/bn.h" -#include "openssl/digest.h" -#include "openssl/rsa.h" - -namespace private_membership { -namespace anonymous_tokens { -namespace { - -TEST(AnonymousTokensPbOpensslConvertersTests, GenerateMaskTestInvalidType) { - RSABlindSignaturePublicKey public_key; - public_key.set_message_mask_type(AT_MESSAGE_MASK_TYPE_UNDEFINED); - public_key.set_message_mask_size(kRsaMessageMaskSizeInBytes32); - absl::StatusOr<std::string> mask_32_bytes = GenerateMask(public_key); - EXPECT_EQ(mask_32_bytes.status().code(), absl::StatusCode::kInvalidArgument); - EXPECT_THAT(mask_32_bytes.status().message(), - ::testing::HasSubstr("Unsupported message mask type")); -} - -TEST(AnonymousTokensPbOpensslConvertersTests, GenerateMaskTestInvalidLength) { - RSABlindSignaturePublicKey public_key; - // Mask meant to be concatenated is less than 32 bytes. - public_key.set_message_mask_type(AT_MESSAGE_MASK_CONCAT); - public_key.set_message_mask_size(kRsaMessageMaskSizeInBytes32 - 1); - absl::StatusOr<std::string> mask_32_bytes = GenerateMask(public_key); - // Mask type set to no mask but mask length requested is greater than 0. - public_key.set_message_mask_type(AT_MESSAGE_MASK_NO_MASK); - public_key.set_message_mask_size(kRsaMessageMaskSizeInBytes32); - absl::StatusOr<std::string> mask_0_bytes = GenerateMask(public_key); - - EXPECT_EQ(mask_32_bytes.status().code(), absl::StatusCode::kInvalidArgument); - EXPECT_EQ(mask_0_bytes.status().code(), absl::StatusCode::kInvalidArgument); - EXPECT_THAT(mask_32_bytes.status().message(), - ::testing::HasSubstr("invalid message mask size")); - EXPECT_THAT(mask_0_bytes.status().message(), - ::testing::HasSubstr("invalid message mask size")); -} - -TEST(AnonymousTokensPbOpensslConvertersTests, GenerateMaskTestSuccess) { - RSABlindSignaturePublicKey public_key; - public_key.set_message_mask_type(AT_MESSAGE_MASK_CONCAT); - public_key.set_message_mask_size(kRsaMessageMaskSizeInBytes32); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string mask_32_bytes, - GenerateMask(public_key)); - // Longer mask. - public_key.set_message_mask_size(kRsaMessageMaskSizeInBytes32 * 2); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string mask_64_bytes, - GenerateMask(public_key)); - - // No mask. - public_key.set_message_mask_type(AT_MESSAGE_MASK_NO_MASK); - public_key.set_message_mask_size(0); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string mask_0_bytes, - GenerateMask(public_key)); - - EXPECT_FALSE(mask_32_bytes.empty()); - EXPECT_FALSE(mask_64_bytes.empty()); - EXPECT_TRUE(mask_0_bytes.empty()); - EXPECT_EQ(mask_32_bytes.size(), kRsaMessageMaskSizeInBytes32); - EXPECT_EQ(mask_64_bytes.size(), kRsaMessageMaskSizeInBytes32 * 2); - EXPECT_EQ(mask_0_bytes.size(), 0); -} - -TEST(AnonymousTokensPbOpensslConvertersTests, - HashTypeConverterTestInvalidType) { - absl::StatusOr<const EVP_MD *> evp = - ProtoHashTypeToEVPDigest(AT_HASH_TYPE_UNDEFINED); - EXPECT_EQ(evp.status().code(), absl::StatusCode::kInvalidArgument); - EXPECT_THAT(evp.status().message(), - ::testing::HasSubstr("Unknown hash type")); -} - -TEST(AnonymousTokensPbOpensslConvertersTests, HashTypeConverterTestSuccess) { - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - const EVP_MD *evp_256, ProtoHashTypeToEVPDigest(AT_HASH_TYPE_SHA256)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - const EVP_MD *evp_384, ProtoHashTypeToEVPDigest(AT_HASH_TYPE_SHA384)); - EXPECT_EQ(evp_256, EVP_sha256()); - EXPECT_EQ(evp_384, EVP_sha384()); -} - -TEST(AnonymousTokensPbOpensslConvertersStrongTests, - MaskGenFunctionConverterStrongTestInvalidType) { - absl::StatusOr<const EVP_MD *> evp = - ProtoMaskGenFunctionToEVPDigest(AT_MGF_UNDEFINED); - EXPECT_EQ(evp.status().code(), absl::StatusCode::kInvalidArgument); - EXPECT_THAT(evp.status().message(), - ::testing::HasSubstr( - "Unknown hash type for mask generation hash function")); -} - -TEST(AnonymousTokensPbOpensslConvertersTests, - MaskGenFunctionConverterTestSuccess) { - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - const EVP_MD *evp_256, ProtoMaskGenFunctionToEVPDigest(AT_MGF_SHA256)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - const EVP_MD *evp_384, ProtoMaskGenFunctionToEVPDigest(AT_MGF_SHA384)); - EXPECT_EQ(evp_256, EVP_sha256()); - EXPECT_EQ(evp_384, EVP_sha384()); -} - -using CreateTestKeyPairFunction = - absl::StatusOr<std::pair<RSAPublicKey, RSAPrivateKey>>(); - -class AnonymousTokensRsaKeyPairConverterTest - : public testing::TestWithParam<CreateTestKeyPairFunction *> { - protected: - void SetUp() override { - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(auto keys_pair, (*GetParam())()); - public_key_ = std::move(keys_pair.first); - private_key_ = std::move(keys_pair.second); - - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(rsa_modulus_, - StringToBignum(private_key_.n())); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(rsa_e_, StringToBignum(private_key_.e())); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(rsa_d_, StringToBignum(private_key_.d())); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(rsa_p_, StringToBignum(private_key_.p())); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(rsa_q_, StringToBignum(private_key_.q())); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(rsa_dp_, - StringToBignum(private_key_.dp())); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(rsa_dq_, - StringToBignum(private_key_.dq())); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(rsa_crt_, - StringToBignum(private_key_.crt())); - } - - bssl::UniquePtr<BIGNUM> rsa_modulus_; - bssl::UniquePtr<BIGNUM> rsa_e_; - bssl::UniquePtr<BIGNUM> rsa_d_; - bssl::UniquePtr<BIGNUM> rsa_p_; - bssl::UniquePtr<BIGNUM> rsa_q_; - bssl::UniquePtr<BIGNUM> rsa_dp_; - bssl::UniquePtr<BIGNUM> rsa_dq_; - bssl::UniquePtr<BIGNUM> rsa_crt_; - - RSAPublicKey public_key_; - RSAPrivateKey private_key_; -}; - -TEST_P(AnonymousTokensRsaKeyPairConverterTest, PublicKeyTest) { - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - bssl::UniquePtr<RSA> rsa_public_key, - AnonymousTokensRSAPublicKeyToRSA(public_key_)); - - EXPECT_EQ(BN_cmp(RSA_get0_n(rsa_public_key.get()), rsa_modulus_.get()), 0); - EXPECT_EQ(BN_cmp(RSA_get0_e(rsa_public_key.get()), rsa_e_.get()), 0); -} - -TEST_P(AnonymousTokensRsaKeyPairConverterTest, PrivateKeyTest) { - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - bssl::UniquePtr<RSA> rsa_private_key, - AnonymousTokensRSAPrivateKeyToRSA(private_key_)); - - EXPECT_EQ(BN_cmp(RSA_get0_n(rsa_private_key.get()), rsa_modulus_.get()), 0); - EXPECT_EQ(BN_cmp(RSA_get0_e(rsa_private_key.get()), rsa_e_.get()), 0); - EXPECT_EQ(BN_cmp(RSA_get0_d(rsa_private_key.get()), rsa_d_.get()), 0); - EXPECT_EQ(BN_cmp(RSA_get0_p(rsa_private_key.get()), rsa_p_.get()), 0); - EXPECT_EQ(BN_cmp(RSA_get0_q(rsa_private_key.get()), rsa_q_.get()), 0); - EXPECT_EQ(BN_cmp(RSA_get0_dmp1(rsa_private_key.get()), rsa_dp_.get()), 0); - EXPECT_EQ(BN_cmp(RSA_get0_dmq1(rsa_private_key.get()), rsa_dq_.get()), 0); - EXPECT_EQ(BN_cmp(RSA_get0_iqmp(rsa_private_key.get()), rsa_crt_.get()), 0); -} - -INSTANTIATE_TEST_SUITE_P(AnonymousTokensRsaKeyPairConverterTest, - AnonymousTokensRsaKeyPairConverterTest, - testing::Values(&GetStrongRsaKeys2048, - &GetAnotherStrongRsaKeys2048, - &GetStrongRsaKeys3072, - &GetStrongRsaKeys4096)); - -} // namespace -} // namespace anonymous_tokens -} // namespace private_membership
diff --git a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/at_crypto_utils_test.cc b/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/at_crypto_utils_test.cc deleted file mode 100644 index ba507b1..0000000 --- a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/at_crypto_utils_test.cc +++ /dev/null
@@ -1,548 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/crypto_utils.h" - -#include <memory> -#include <string> -#include <utility> -#include <vector> - -#include "quiche/common/platform/api/quiche_test.h" -#include "quiche/common/test_tools/quiche_test_utils.h" -#include "absl/strings/escaping.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/testing/utils.h" -#include "openssl/base.h" -#include "openssl/rsa.h" - -namespace private_membership { -namespace anonymous_tokens { -namespace { - -struct IetfNewPublicExponentWithPublicMetadataTestVector { - std::string rsa_modulus; - std::string e; - std::string public_metadata; - std::string new_e; -}; - -TEST(AnonymousTokensCryptoUtilsTest, BignumToStringAndBack) { - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(BnCtxPtr ctx, GetAndStartBigNumCtx()); - - // Create a new BIGNUM using the context and set it - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> bn_1, NewBigNum()); - ASSERT_EQ(BN_set_u64(bn_1.get(), 0x124435435), 1); - EXPECT_NE(bn_1, nullptr); - EXPECT_EQ(BN_is_zero(bn_1.get()), 0); - EXPECT_EQ(BN_is_one(bn_1.get()), 0); - - // Convert bn_1 to string from BIGNUM - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - const std::string converted_str, - BignumToString(*bn_1, BN_num_bytes(bn_1.get()))); - // Convert the string version of bn_1 back to BIGNUM - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> bn_2, - StringToBignum(converted_str)); - // Check whether the conversion back worked - EXPECT_EQ(BN_cmp(bn_1.get(), bn_2.get()), 0); -} - -TEST(AnonymousTokensCryptoUtilsTest, PowerOfTwoAndRsaSqrtTwo) { - // Compute 2^(10-1/2). - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> sqrt2, - GetRsaSqrtTwo(10)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> small_pow2, - ComputePowerOfTwo(9)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> large_pow2, - ComputePowerOfTwo(10)); - EXPECT_GT(BN_cmp(sqrt2.get(), small_pow2.get()), 0); - EXPECT_LT(BN_cmp(sqrt2.get(), large_pow2.get()), 0); -} - -TEST(AnonymousTokensCryptoUtilsTest, ComputeHashAcceptsNullStringView) { - absl::StatusOr<std::string> null_hash = - ComputeHash(absl::string_view(nullptr, 0), *EVP_sha512()); - absl::StatusOr<std::string> empty_hash = ComputeHash("", *EVP_sha512()); - std::string str; - absl::StatusOr<std::string> empty_str_hash = ComputeHash(str, *EVP_sha512()); - - ASSERT_TRUE(null_hash.ok()); - ASSERT_TRUE(empty_hash.ok()); - ASSERT_TRUE(empty_str_hash.ok()); - - EXPECT_EQ(*null_hash, *empty_hash); - EXPECT_EQ(*null_hash, *empty_str_hash); -} - -TEST(AnonymousTokensCryptoUtilsTest, ComputeCarmichaelLcm) { - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(BnCtxPtr ctx, GetAndStartBigNumCtx()); - - // Suppose that N = 1019 * 1187. - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> phi_p, NewBigNum()); - ASSERT_TRUE(BN_set_word(phi_p.get(), 1019 - 1)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> phi_q, NewBigNum()); - ASSERT_TRUE(BN_set_word(phi_q.get(), 1187 - 1)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> expected_lcm, - NewBigNum()); - ASSERT_TRUE(BN_set_word(expected_lcm.get(), (1019 - 1) * (1187 - 1) / 2)); - - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> lcm, - ComputeCarmichaelLcm(*phi_p, *phi_q, *ctx)); - EXPECT_EQ(BN_cmp(lcm.get(), expected_lcm.get()), 0); -} - -struct ComputeHashTestParam { - const EVP_MD* hasher; - absl::string_view input_hex; - absl::string_view expected_digest_hex; -}; - -using ComputeHashTest = testing::TestWithParam<ComputeHashTestParam>; - -// Returns the test parameters for ComputeHashTestParam from NIST's -// samples. -std::vector<ComputeHashTestParam> GetComputeHashTestParams() { - std::vector<ComputeHashTestParam> params; - params.push_back({ - EVP_sha256(), - "af397a8b8dd73ab702ce8e53aa9f", - "d189498a3463b18e846b8ab1b41583b0b7efc789dad8a7fb885bbf8fb5b45c5c", - }); - params.push_back({ - EVP_sha256(), - "59eb45bbbeb054b0b97334d53580ce03f699", - "32c38c54189f2357e96bd77eb00c2b9c341ebebacc2945f97804f59a93238288", - }); - params.push_back({ - EVP_sha512(), - "16b17074d3e3d97557f9ed77d920b4b1bff4e845b345a922", - "6884134582a760046433abcbd53db8ff1a89995862f305b887020f6da6c7b903a314721e" - "972bf438483f452a8b09596298a576c903c91df4a414c7bd20fd1d07", - }); - params.push_back({ - EVP_sha512(), - "7651ab491b8fa86f969d42977d09df5f8bee3e5899180b52c968b0db057a6f02a886ad61" - "7a84915a", - "f35e50e2e02b8781345f8ceb2198f068ba103476f715cfb487a452882c9f0de0c720b2a0" - "88a39d06a8a6b64ce4d6470dfeadc4f65ae06672c057e29f14c4daf9", - }); - return params; -} - -TEST_P(ComputeHashTest, ComputesHash) { - const ComputeHashTestParam& params = GetParam(); - ASSERT_NE(params.hasher, nullptr); - std::string data = absl::HexStringToBytes(params.input_hex); - std::string expected_digest = - absl::HexStringToBytes(params.expected_digest_hex); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(auto computed_hash, - ComputeHash(data, *params.hasher)); - EXPECT_EQ(computed_hash, expected_digest); -} - -INSTANTIATE_TEST_SUITE_P(ComputeHashTests, ComputeHashTest, - testing::ValuesIn(GetComputeHashTestParams())); - -TEST(PublicMetadataCryptoUtilsInternalTest, PublicMetadataHashWithHKDF) { - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(BnCtxPtr ctx, GetAndStartBigNumCtx()); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> max_value, - NewBigNum()); - ASSERT_TRUE(BN_set_word(max_value.get(), 4294967295)); - const auto [public_key, _] = GetStrongTestRsaKeyPair2048(); - std::string input1 = "ro1"; - std::string input2 = "ro2"; - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - bssl::UniquePtr<BIGNUM> output1, - internal::PublicMetadataHashWithHKDF(input1, public_key.n, - 1 + input1.size())); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - bssl::UniquePtr<BIGNUM> another_output1, - internal::PublicMetadataHashWithHKDF(input1, public_key.n, - 1 + input1.size())); - EXPECT_EQ(BN_cmp(output1.get(), another_output1.get()), 0); - - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - bssl::UniquePtr<BIGNUM> output2, - internal::PublicMetadataHashWithHKDF(input2, public_key.n, - 1 + input2.size())); - EXPECT_NE(BN_cmp(output1.get(), output2.get()), 0); - - EXPECT_LE(BN_cmp(output1.get(), max_value.get()), 0); - EXPECT_LE(BN_cmp(output2.get(), max_value.get()), 0); -} - -TEST(PublicMetadataCryptoUtilsTest, PublicExponentHashDifferentModulus) { - const auto public_key_1 = std::get<0>(GetStrongTestRsaKeyPair2048()); - const auto public_key_2 = std::get<0>(GetAnotherStrongTestRsaKeyPair2048()); - std::string metadata = "md"; - // Check that same metadata and different modulus result in different - // hashes. - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> rsa_modulus_1, - StringToBignum(public_key_1.n)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - bssl::UniquePtr<BIGNUM> exp1, - ComputeExponentWithPublicMetadata(*rsa_modulus_1.get(), metadata)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(auto rsa_modulus_2, - StringToBignum(public_key_2.n)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - bssl::UniquePtr<BIGNUM> exp2, - ComputeExponentWithPublicMetadata(*rsa_modulus_2.get(), metadata)); - EXPECT_NE(BN_cmp(exp1.get(), exp2.get()), 0); -} - -std::vector<IetfNewPublicExponentWithPublicMetadataTestVector> -GetIetfNewPublicExponentWithPublicMetadataTestVectors( - bool use_rsa_public_exponent) { - std::vector<IetfNewPublicExponentWithPublicMetadataTestVector> test_vectors; - - std::string modulus = absl::HexStringToBytes( - "d6930820f71fe517bf3259d14d40209b02a5c0d3d61991c731dd7da39f8d69821552e231" - "8d6c9ad897e603887a476ea3162c1205da9ac96f02edf31df049bd55f142134c17d4382a" - "0e78e275345f165fbe8e49cdca6cf5c726c599dd39e09e75e0f330a33121e73976e4facb" - "a9cfa001c28b7c96f8134f9981db6750b43a41710f51da4240fe03106c12acb1e7bb53d7" - "5ec7256da3fddd0718b89c365410fce61bc7c99b115fb4c3c318081fa7e1b65a37774e8e" - "50c96e8ce2b2cc6b3b367982366a2bf9924c4bafdb3ff5e722258ab705c76d43e5f1f121" - "b984814e98ea2b2b8725cd9bc905c0bc3d75c2a8db70a7153213c39ae371b2b5dc1dafcb" - "19d6fae9"); - std::string e = absl::HexStringToBytes("010001"); - - if (use_rsa_public_exponent) { - // Test vector 1 - test_vectors.push_back( - {.rsa_modulus = modulus, - .e = e, - .public_metadata = absl::HexStringToBytes("6d65746164617461"), - .new_e = absl::HexStringToBytes( - "30584b72f5cb557085106232f051d039e23358feee9204cf30ea567620e90d79e" - "4a7a81388b1f390e18ea5240a1d8cc296ce1325128b445c48aa5a3b34fa07c324" - "bf17bc7f1b3efebaff81d7e032948f1477493bc183d2f8d94c947c984c6f07575" - "27615bf2a2f0ef0db5ad80ce99905beed0440b47fa5cb9a2334fea40ad88e6ef" - "1")}); - - // Test vector 2 - test_vectors.push_back( - {.rsa_modulus = modulus, - .e = e, - .public_metadata = "", - .new_e = absl::HexStringToBytes( - "2ed5a8d2592a11bbeef728bb39018ef5c3cf343507dd77dd156d5eec7f06f0473" - "2e4be944c5d2443d244c59e52c9fa5e8de40f55ffd0e70fbe9093d3f7be2aafd7" - "7c14b263b71c1c6b3ca2b9629842a902128fee4878392a950906fae35d6194e0d" - "2548e58bbc20f841188ca2fceb20b2b1b45448da5c7d1c73fb6e83fa58867397" - "b")}); - } else { - // Test vector 1 - test_vectors.push_back( - {.rsa_modulus = modulus, - .e = e, - .public_metadata = absl::HexStringToBytes("6d65746164617461"), - .new_e = absl::HexStringToBytes( - "30581b1adab07ac00a5057e2986f37caaa68ae963ffbc4d36c16ea5f3689d6f00" - "db79a5bee56053adc53c8d0414d4b754b58c7cc4abef99d4f0d0b2e29cbddf746" - "c7d0f4ae2690d82a2757b088820c0d086a40d180b2524687060d768ad5e431732" - "102f4bc3572d97e01dcd6301368f255faae4606399f91fa913a6d699d6ef1")}); - - // Test vector 2 - test_vectors.push_back( - {.rsa_modulus = modulus, - .e = e, - .public_metadata = "", - .new_e = absl::HexStringToBytes( - "2ed579fcdf2d328ebc686c52ccaec247018832acd530a2ac72c0ec2b92db5d6bd" - "578e91b6341c1021142b45b9e6e5bf031f3dd62226ec4a0f9ef99e45dd9ccd60a" - "a60a0c59aac271a8caf9ee68a9d9ff281367dae09d588d3c7bca7f18de48b6981" - "bbc729c4925c65e4b2a7f054facbb7e5fc6e4c6c10110c62ef0b94eec397b")}); - } - return test_vectors; -} - -TEST(PublicMetadataCryptoUtilsTest, - IetfNewPublicExponentWithPublicMetadataTests) { - const auto test_vectors = - GetIetfNewPublicExponentWithPublicMetadataTestVectors( - /*use_rsa_public_exponent=*/true); - for (const IetfNewPublicExponentWithPublicMetadataTestVector& test_vector : - test_vectors) { - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> rsa_modulus, - StringToBignum(test_vector.rsa_modulus)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> rsa_e, - StringToBignum(test_vector.e)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> expected_new_e, - StringToBignum(test_vector.new_e)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - bssl::UniquePtr<BIGNUM> modified_e, - ComputeExponentWithPublicMetadataAndPublicExponent( - *rsa_modulus.get(), *rsa_e.get(), test_vector.public_metadata)); - - EXPECT_EQ(BN_cmp(modified_e.get(), expected_new_e.get()), 0); - } -} - -TEST(PublicMetadataCryptoUtilsTest, - IetfNewPublicExponentWithPublicMetadataNoPublicExponentTests) { - const auto test_vectors = - GetIetfNewPublicExponentWithPublicMetadataTestVectors( - /*use_rsa_public_exponent=*/false); - for (const IetfNewPublicExponentWithPublicMetadataTestVector& test_vector : - test_vectors) { - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> rsa_modulus, - StringToBignum(test_vector.rsa_modulus)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> expected_new_e, - StringToBignum(test_vector.new_e)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - bssl::UniquePtr<BIGNUM> modified_e, - ComputeExponentWithPublicMetadata(*rsa_modulus.get(), - test_vector.public_metadata)); - - EXPECT_EQ(BN_cmp(modified_e.get(), expected_new_e.get()), 0); - } -} - -// copybara:strip_begin(internal comment) -// The input public key and the expected DER encoding are taken from the -// following Goa test: -// http://google3/privacy/net/boq/common/tokens/token_types_test.go;l=21;rcl=528885322 -// copybara:strip_end -TEST(AnonymousTokensCryptoUtilsTest, RsaPssDerEncoding) { - std::string rsa_modulus = absl::HexStringToBytes( - "b259758bb02bc75b68b17612c9bf68c5fa05958a334c61e167bc20bcc75757c126e892" - "10b9df3989072cf6260e6883c7cd4af4d31dde9915b69b301fbef962de8c71bd2db5ec62" - "5da259712f86a8dc3d241e9688c82391b7bf1ebc358311f55c26be910b76f61fea408ed6" - "92f1a9578a622c82c0fcf6f69ef3670e38bfc90f63da4f3bbbd088c8ae7a3c5a55e66f64" - "74d562d32cce7b7edd7cf0149ca0e96cb6525e81fbba815a8f12748e34e5135f572b2e17" - "b7ba430081597e6fb9033c005884d5935118c60d75b010f6fece7ecdcc1cb7d58d138969" - "3d43377f4f3de949cb1e4105e792b96d7f04b0cd262ac33cffc5a890d267425e61c19e93" - "63550f2285"); - // A hex string of 3 bytes in length is passed. - std::string e_not_padded = absl::HexStringToBytes("010001"); - // A hex string of 4 bytes in length is passed. - std::string e_padded = absl::HexStringToBytes("00010001"); - - // Convert both padded and not padded rsa public keys to rsa structs. - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - bssl::UniquePtr<RSA> rsa_e_not_padded, - CreatePublicKeyRSA(rsa_modulus, e_not_padded)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<RSA> rsa_e_padded, - CreatePublicKeyRSA(rsa_modulus, e_padded)); - // Encode both padded and not padded rsa structs to DER. - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::string result_e_not_padded, - RsaSsaPssPublicKeyToDerEncoding(rsa_e_not_padded.get())); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::string result_e_padded, - RsaSsaPssPublicKeyToDerEncoding(rsa_e_padded.get())); - - std::string expected_der_encoding = absl::HexStringToBytes( - "30820152303d06092a864886f70d01010a3030a00d300b0609608648016503040202a11a" - "301806092a864886f70d010108300b0609608648016503040202a2030201300382010f00" - "3082010a0282010100b259758bb02bc75b68b17612c9bf68c5fa05958a334c61e167bc20" - "bcc75757c126e89210b9df3989072cf6260e6883c7cd4af4d31dde9915b69b301fbef962" - "de8c71bd2db5ec625da259712f86a8dc3d241e9688c82391b7bf1ebc358311f55c26be91" - "0b76f61fea408ed692f1a9578a622c82c0fcf6f69ef3670e38bfc90f63da4f3bbbd088c8" - "ae7a3c5a55e66f6474d562d32cce7b7edd7cf0149ca0e96cb6525e81fbba815a8f12748e" - "34e5135f572b2e17b7ba430081597e6fb9033c005884d5935118c60d75b010f6fece7ecd" - "cc1cb7d58d1389693d43377f4f3de949cb1e4105e792b96d7f04b0cd262ac33cffc5a890" - "d267425e61c19e9363550f22850203010001"); - - EXPECT_EQ(result_e_not_padded, expected_der_encoding); - EXPECT_EQ(result_e_padded, expected_der_encoding); -} - -// The public key used in this test is taken from the test vectors found here: -// https://www.ietf.org/archive/id/draft-ietf-privacypass-protocol-10.html#name-issuance-protocol-2-blind-rs -TEST(AnonymousTokensCryptoUtilsTest, IetfPrivacyPassBlindRsaPublicKeyToDer) { - std::string rsa_modulus = absl::HexStringToBytes( - "cb1aed6b6a95f5b1ce013a4cfcab25b94b2e64a23034e4250a7eab43c0df3a8c12993af1" - "2b111908d4b471bec31d4b6c9ad9cdda90612a2ee903523e6de5a224d6b02f09e5c374d0" - "cfe01d8f529c500a78a2f67908fa682b5a2b430c81eaf1af72d7b5e794fc98a313927687" - "9757ce453b526ef9bf6ceb99979b8423b90f4461a22af37aab0cf5733f7597abe44d31c7" - "32db68a181c6cbbe607d8c0e52e0655fd9996dc584eca0be87afbcd78a337d17b1dba9e8" - "28bbd81e291317144e7ff89f55619709b096cbb9ea474cead264c2073fe49740c01f00e1" - "09106066983d21e5f83f086e2e823c879cd43cef700d2a352a9babd612d03cad02db134b" - "7e225a5f"); - std::string e = absl::HexStringToBytes("010001"); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<RSA> rsa, - CreatePublicKeyRSA(rsa_modulus, e)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string result, - RsaSsaPssPublicKeyToDerEncoding(rsa.get())); - - std::string expected_der_encoding = absl::HexStringToBytes( - "30820152303d06092a864886f70d01010a3030a00d300b0609608648016503040202a11a" - "301806092a864886f70d010108300b0609608648016503040202a2030201300382010f00" - "3082010a0282010100cb1aed6b6a95f5b1ce013a4cfcab25b94b2e64a23034e4250a7eab" - "43c0df3a8c12993af12b111908d4b471bec31d4b6c9ad9cdda90612a2ee903523e6de5a2" - "24d6b02f09e5c374d0cfe01d8f529c500a78a2f67908fa682b5a2b430c81eaf1af72d7b5" - "e794fc98a3139276879757ce453b526ef9bf6ceb99979b8423b90f4461a22af37aab0cf5" - "733f7597abe44d31c732db68a181c6cbbe607d8c0e52e0655fd9996dc584eca0be87afbc" - "d78a337d17b1dba9e828bbd81e291317144e7ff89f55619709b096cbb9ea474cead264c2" - "073fe49740c01f00e109106066983d21e5f83f086e2e823c879cd43cef700d2a352a9bab" - "d612d03cad02db134b7e225a5f0203010001"); - - EXPECT_EQ(result, expected_der_encoding); -} - -using CreateTestKeyPairFunction = std::pair< - anonymous_tokens::TestRsaPublicKey, anonymous_tokens::TestRsaPrivateKey>(); - -class CryptoUtilsTest - : public testing::TestWithParam<CreateTestKeyPairFunction*> { - protected: - void SetUp() override { - const auto [_, private_key] = (*GetParam())(); - private_key_ = private_key; - - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(rsa_modulus_, - StringToBignum(private_key_.n)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(rsa_e_, StringToBignum(private_key_.e)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(rsa_p_, StringToBignum(private_key_.p)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(rsa_q_, StringToBignum(private_key_.q)); - } - - TestRsaPrivateKey private_key_; - - bssl::UniquePtr<BIGNUM> rsa_modulus_; - bssl::UniquePtr<BIGNUM> rsa_e_; - bssl::UniquePtr<BIGNUM> rsa_p_; - bssl::UniquePtr<BIGNUM> rsa_q_; -}; - -TEST_P(CryptoUtilsTest, PublicExponentCoprime) { - std::string metadata = "md"; - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - bssl::UniquePtr<BIGNUM> exp, - ComputeExponentWithPublicMetadata(*rsa_modulus_.get(), metadata)); - int rsa_mod_size_bits = BN_num_bits(rsa_modulus_.get()); - // Check that exponent is odd. - EXPECT_EQ(BN_is_odd(exp.get()), 1); - // Check that exponent is small enough. - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> sqrt2, - GetRsaSqrtTwo(rsa_mod_size_bits / 2)); - EXPECT_LT(BN_cmp(exp.get(), sqrt2.get()), 0); - EXPECT_LT(BN_cmp(exp.get(), rsa_p_.get()), 0); - EXPECT_LT(BN_cmp(exp.get(), rsa_q_.get()), 0); -} - -TEST_P(CryptoUtilsTest, PublicExponentHash) { - std::string metadata1 = "md1"; - std::string metadata2 = "md2"; - // Check that hash is deterministic. - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - bssl::UniquePtr<BIGNUM> exp1, - ComputeExponentWithPublicMetadata(*rsa_modulus_.get(), metadata1)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - bssl::UniquePtr<BIGNUM> another_exp1, - ComputeExponentWithPublicMetadata(*rsa_modulus_.get(), metadata1)); - EXPECT_EQ(BN_cmp(exp1.get(), another_exp1.get()), 0); - // Check that hashes are distinct for different metadata. - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - bssl::UniquePtr<BIGNUM> exp2, - ComputeExponentWithPublicMetadata(*rsa_modulus_.get(), metadata2)); - EXPECT_NE(BN_cmp(exp1.get(), exp2.get()), 0); -} - -TEST_P(CryptoUtilsTest, FinalExponentCoprime) { - std::string metadata = "md"; - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - bssl::UniquePtr<BIGNUM> final_exponent, - ComputeExponentWithPublicMetadataAndPublicExponent( - *rsa_modulus_.get(), *rsa_e_.get(), metadata)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(BnCtxPtr ctx, GetAndStartBigNumCtx()); - - // Check that exponent is odd. - EXPECT_EQ(BN_is_odd(final_exponent.get()), 1); - // Check that exponent is co-prime to factors of the rsa modulus. - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> gcd_p_fe, - NewBigNum()); - ASSERT_EQ( - BN_gcd(gcd_p_fe.get(), rsa_p_.get(), final_exponent.get(), ctx.get()), 1); - EXPECT_EQ(BN_cmp(gcd_p_fe.get(), BN_value_one()), 0); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> gcd_q_fe, - NewBigNum()); - ASSERT_EQ( - BN_gcd(gcd_q_fe.get(), rsa_q_.get(), final_exponent.get(), ctx.get()), 1); - EXPECT_EQ(BN_cmp(gcd_q_fe.get(), BN_value_one()), 0); -} - -TEST_P(CryptoUtilsTest, DeterministicModificationOfPublicExponentWithMetadata) { - std::string metadata = "md"; - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - bssl::UniquePtr<BIGNUM> public_exp_1, - ComputeExponentWithPublicMetadataAndPublicExponent( - *rsa_modulus_.get(), *rsa_e_.get(), metadata)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - bssl::UniquePtr<BIGNUM> public_exp_2, - ComputeExponentWithPublicMetadataAndPublicExponent( - *rsa_modulus_.get(), *rsa_e_.get(), metadata)); - - EXPECT_EQ(BN_cmp(public_exp_1.get(), public_exp_2.get()), 0); -} - -TEST_P(CryptoUtilsTest, DifferentPublicExponentWithDifferentPublicMetadata) { - std::string metadata_1 = "md1"; - std::string metadata_2 = "md2"; - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - bssl::UniquePtr<BIGNUM> public_exp_1, - ComputeExponentWithPublicMetadataAndPublicExponent( - *rsa_modulus_.get(), *rsa_e_.get(), metadata_1)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - bssl::UniquePtr<BIGNUM> public_exp_2, - ComputeExponentWithPublicMetadataAndPublicExponent( - *rsa_modulus_.get(), *rsa_e_.get(), metadata_2)); - // Check that exponent is different in all keys - EXPECT_NE(BN_cmp(public_exp_1.get(), public_exp_2.get()), 0); - EXPECT_NE(BN_cmp(public_exp_1.get(), rsa_e_.get()), 0); - EXPECT_NE(BN_cmp(public_exp_2.get(), rsa_e_.get()), 0); -} - -TEST_P(CryptoUtilsTest, ModifiedPublicExponentWithEmptyPublicMetadata) { - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - bssl::UniquePtr<BIGNUM> new_public_exp, - ComputeExponentWithPublicMetadataAndPublicExponent(*rsa_modulus_.get(), - *rsa_e_.get(), "")); - - EXPECT_NE(BN_cmp(new_public_exp.get(), rsa_e_.get()), 0); -} - -TEST_P(CryptoUtilsTest, CreateRsaPublicKeyWithPublicMetadataSuccessfully) { - std::string metadata = "md"; - // Key derived using the public exponent, modulus and public metadata. - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<RSA> rsa_public_key, - CreatePublicKeyRSAWithPublicMetadata( - private_key_.n, private_key_.e, metadata, - /*use_rsa_public_exponent=*/true)); - // Key derived using only the modulus and public metadata. - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<RSA> rsa_public_key_2, - CreatePublicKeyRSAWithPublicMetadata( - private_key_.n, private_key_.e, metadata, - /*use_rsa_public_exponent=*/false)); - - EXPECT_EQ(BN_cmp(RSA_get0_n(rsa_public_key.get()), rsa_modulus_.get()), 0); - EXPECT_EQ(BN_cmp(RSA_get0_n(rsa_public_key_2.get()), rsa_modulus_.get()), 0); - - EXPECT_NE(BN_cmp(RSA_get0_e(rsa_public_key.get()), rsa_e_.get()), 0); - EXPECT_NE(BN_cmp(RSA_get0_e(rsa_public_key_2.get()), rsa_e_.get()), 0); - EXPECT_NE(BN_cmp(RSA_get0_e(rsa_public_key.get()), - RSA_get0_e(rsa_public_key_2.get())), - 0); -} - -INSTANTIATE_TEST_SUITE_P(CryptoUtilsTest, CryptoUtilsTest, - testing::Values(&GetStrongTestRsaKeyPair2048, - &GetAnotherStrongTestRsaKeyPair2048, - &GetStrongTestRsaKeyPair3072, - &GetStrongTestRsaKeyPair4096)); - -} // namespace -} // namespace anonymous_tokens -} // namespace private_membership
diff --git a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/blind_signer.h b/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/blind_signer.h deleted file mode 100644 index 3c3e5db..0000000 --- a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/blind_signer.h +++ /dev/null
@@ -1,37 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef THIRD_PARTY_ANONYMOUS_TOKENS_CPP_CRYPTO_BLIND_SIGNER_H_ -#define THIRD_PARTY_ANONYMOUS_TOKENS_CPP_CRYPTO_BLIND_SIGNER_H_ - -#include <string> - -#include "absl/status/statusor.h" -#include "absl/strings/string_view.h" - -namespace private_membership { -namespace anonymous_tokens { - -class BlindSigner { - public: - virtual absl::StatusOr<std::string> Sign( - absl::string_view blinded_data) const = 0; - - virtual ~BlindSigner() = default; -}; - -} // namespace anonymous_tokens -} // namespace private_membership - -#endif // THIRD_PARTY_ANONYMOUS_TOKENS_CPP_CRYPTO_BLIND_SIGNER_H_
diff --git a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/blinder.h b/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/blinder.h deleted file mode 100644 index fd29ad7..0000000 --- a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/blinder.h +++ /dev/null
@@ -1,38 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef THIRD_PARTY_ANONYMOUS_TOKENS_CPP_CRYPTO_BLINDER_H_ -#define THIRD_PARTY_ANONYMOUS_TOKENS_CPP_CRYPTO_BLINDER_H_ - -#include <string> - -#include "absl/status/statusor.h" - -namespace private_membership { -namespace anonymous_tokens { - -class Blinder { - public: - enum class BlinderState { kCreated = 0, kBlinded, kUnblinded }; - virtual absl::StatusOr<std::string> Blind(absl::string_view message) = 0; - - virtual absl::StatusOr<std::string> Unblind( - absl::string_view blind_signature) = 0; - - virtual ~Blinder() = default; -}; - -} // namespace anonymous_tokens -} // namespace private_membership -#endif // THIRD_PARTY_ANONYMOUS_TOKENS_CPP_CRYPTO_BLINDER_H_
diff --git a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/constants.h b/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/constants.h deleted file mode 100644 index d020d5b..0000000 --- a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/constants.h +++ /dev/null
@@ -1,82 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef THIRD_PARTY_ANONYMOUS_TOKENS_CPP_CRYPTO_CONSTANTS_H_ -#define THIRD_PARTY_ANONYMOUS_TOKENS_CPP_CRYPTO_CONSTANTS_H_ - -#include <cstdint> - -#include "absl/strings/string_view.h" - -namespace private_membership { -namespace anonymous_tokens { - -// Returned integer on successful execution of BoringSSL methods -constexpr int kBsslSuccess = 1; - -// RSA modulus size, 4096 bits -// -// Our recommended size. -constexpr int kRsaModulusSizeInBits4096 = 4096; - -// RSA modulus size, 512 bytes -constexpr int kRsaModulusSizeInBytes512 = 512; - -// RSA modulus size, 2048 bits -// -// Recommended size for RSA Blind Signatures without Public Metadata. -// -// https://www.ietf.org/archive/id/draft-ietf-privacypass-protocol-08.html#name-token-type-blind-rsa-2048-b. -constexpr int kRsaModulusSizeInBits2048 = 2048; - -// RSA modulus size, 256 bytes -constexpr int kRsaModulusSizeInBytes256 = 256; - -// Salt length, 48 bytes -// -// Recommended size. The convention is to use hLen, the length of the output of -// the hash function in bytes. A salt length of zero will result in a -// deterministic signature value. -// -// https://datatracker.ietf.org/doc/draft-irtf-cfrg-rsa-blind-signatures/ -constexpr int kSaltLengthInBytes48 = 48; - -// Length of message mask, 32 bytes. -// -// https://datatracker.ietf.org/doc/draft-irtf-cfrg-rsa-blind-signatures/ -constexpr int kRsaMessageMaskSizeInBytes32 = 32; - -// Info used in HKDF for Public Metadata Hash. -constexpr absl::string_view kHkdfPublicMetadataInfo = "PBRSA"; - -constexpr int kHkdfPublicMetadataInfoSizeInBytes = 5; - -// Object identifier for Rivest, Shamir, Adleman (RSA) Signature Scheme with -// Appendix - Probabilistic Signature Scheme (RSASSA-PSS) defined here: -// https://oidref.com/1.2.840.113549.1.1.10 -constexpr char kRsaSsaPssOid[] = "1.2.840.113549.1.1.10"; - -// Object identifier for SHA384 defined here: -// https://oidref.com/2.16.840.1.101.3.4.2.2 -constexpr char kSha384Oid[] = "2.16.840.1.101.3.4.2.2"; - -// Object identifier for RSA algorithm that uses the Mask Generator Function 1 -// (MGF1) defined here: -// https://oidref.com/1.2.840.113549.1.1.8 -constexpr char kRsaSsaPssMgf1Oid[] = "1.2.840.113549.1.1.8"; - -} // namespace anonymous_tokens -} // namespace private_membership - -#endif // THIRD_PARTY_ANONYMOUS_TOKENS_CPP_CRYPTO_CONSTANTS_H_
diff --git a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/crypto_utils.cc b/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/crypto_utils.cc deleted file mode 100644 index 3ed32a2..0000000 --- a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/crypto_utils.cc +++ /dev/null
@@ -1,618 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/crypto_utils.h" - -#include <stddef.h> -#include <stdint.h> - -#include <cstdint> -#include <iterator> -#include <memory> -#include <string> -#include <utility> -#include <vector> - -#include "absl/status/status.h" -#include "absl/status/statusor.h" -#include "absl/strings/str_cat.h" -#include "absl/strings/string_view.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/constants.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/shared/status_utils.h" -#include "openssl/bytestring.h" -#include "openssl/err.h" -#include "openssl/hkdf.h" -#include "openssl/mem.h" -#include "openssl/rand.h" -#include "openssl/rsa.h" - -namespace private_membership { -namespace anonymous_tokens { - -namespace internal { - -// Approximation of sqrt(2) taken from -// //depot/google3/third_party/openssl/boringssl/src/crypto/fipsmodule/rsa/rsa_impl.c;l=997 -constexpr uint32_t kBoringSSLRSASqrtTwo[] = { - 0x4d7c60a5, 0xe633e3e1, 0x5fcf8f7b, 0xca3ea33b, 0xc246785e, 0x92957023, - 0xf9acce41, 0x797f2805, 0xfdfe170f, 0xd3b1f780, 0xd24f4a76, 0x3facb882, - 0x18838a2e, 0xaff5f3b2, 0xc1fcbdde, 0xa2f7dc33, 0xdea06241, 0xf7aa81c2, - 0xf6a1be3f, 0xca221307, 0x332a5e9f, 0x7bda1ebf, 0x0104dc01, 0xfe32352f, - 0xb8cf341b, 0x6f8236c7, 0x4264dabc, 0xd528b651, 0xf4d3a02c, 0xebc93e0c, - 0x81394ab6, 0xd8fd0efd, 0xeaa4a089, 0x9040ca4a, 0xf52f120f, 0x836e582e, - 0xcb2a6343, 0x31f3c84d, 0xc6d5a8a3, 0x8bb7e9dc, 0x460abc72, 0x2f7c4e33, - 0xcab1bc91, 0x1688458a, 0x53059c60, 0x11bc337b, 0xd2202e87, 0x42af1f4e, - 0x78048736, 0x3dfa2768, 0x0f74a85e, 0x439c7b4a, 0xa8b1fe6f, 0xdc83db39, - 0x4afc8304, 0x3ab8a2c3, 0xed17ac85, 0x83339915, 0x1d6f60ba, 0x893ba84c, - 0x597d89b3, 0x754abe9f, 0xb504f333, 0xf9de6484, -}; - -absl::StatusOr<bssl::UniquePtr<BIGNUM>> PublicMetadataHashWithHKDF( - absl::string_view public_metadata, absl::string_view rsa_modulus_str, - size_t out_len_bytes) { - const EVP_MD* evp_md_sha_384 = EVP_sha384(); - // Prepend "key" to input. - std::string modified_input = absl::StrCat("key", public_metadata); - std::vector<uint8_t> input_buffer(modified_input.begin(), - modified_input.end()); - // Append 0x00 to input. - input_buffer.push_back(0x00); - std::string out_e; - // We set the out_e size beyond out_len_bytes so that out_e bytes are - // indifferentiable from truly random bytes even after truncations. - // - // Expanding to 16 more bytes is sufficient. - // https://cfrg.github.io/draft-irtf-cfrg-hash-to-curve/draft-irtf-cfrg-hash-to-curve.html#name-hashing-to-a-finite-field - const size_t hkdf_output_size = out_len_bytes + 16; - out_e.resize(hkdf_output_size); - // The modulus is used as salt to ensure different outputs for same metadata - // and different modulus. - if (HKDF(reinterpret_cast<uint8_t*>(out_e.data()), hkdf_output_size, - evp_md_sha_384, input_buffer.data(), input_buffer.size(), - reinterpret_cast<const uint8_t*>(rsa_modulus_str.data()), - rsa_modulus_str.size(), - reinterpret_cast<const uint8_t*>(kHkdfPublicMetadataInfo.data()), - kHkdfPublicMetadataInfoSizeInBytes) != kBsslSuccess) { - return absl::InternalError("HKDF failed in public_metadata_crypto_utils"); - } - // Truncate out_e to out_len_bytes - out_e.resize(out_len_bytes); - ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> out, - StringToBignum(out_e)); - return out; -} - -} // namespace internal - -namespace { - -// Marshals an RSA public key in the DER format. -absl::StatusOr<std::string> MarshalRsaPublicKey(const RSA* rsa) { - uint8_t* rsa_public_key_bytes; - size_t rsa_public_key_bytes_len = 0; - if (!RSA_public_key_to_bytes(&rsa_public_key_bytes, &rsa_public_key_bytes_len, - rsa)) { - return absl::InvalidArgumentError(absl::StrCat( - "Failed to marshall rsa public key to a DER encoded RSAPublicKey " - "structure (RFC 8017): ", - GetSslErrors())); - } - std::string rsa_public_key_str(reinterpret_cast<char*>(rsa_public_key_bytes), - rsa_public_key_bytes_len); - OPENSSL_free(rsa_public_key_bytes); - return rsa_public_key_str; -} - -} // namespace - -absl::StatusOr<BnCtxPtr> GetAndStartBigNumCtx() { - // Create context to be used in intermediate computation. - BnCtxPtr bn_ctx = BnCtxPtr(BN_CTX_new()); - if (!bn_ctx.get()) { - return absl::InternalError("Error generating bignum context."); - } - BN_CTX_start(bn_ctx.get()); - - return bn_ctx; -} - -absl::StatusOr<bssl::UniquePtr<BIGNUM>> NewBigNum() { - bssl::UniquePtr<BIGNUM> bn(BN_new()); - if (!bn.get()) { - return absl::InternalError("Error generating bignum."); - } - return bn; -} - -absl::StatusOr<std::string> BignumToString(const BIGNUM& big_num, - const size_t output_len) { - std::vector<uint8_t> serialization(output_len); - if (BN_bn2bin_padded(serialization.data(), serialization.size(), &big_num) != - kBsslSuccess) { - return absl::InternalError( - absl::StrCat("Function BN_bn2bin_padded failed: ", GetSslErrors())); - } - return std::string(std::make_move_iterator(serialization.begin()), - std::make_move_iterator(serialization.end())); -} - -absl::StatusOr<bssl::UniquePtr<BIGNUM>> StringToBignum( - const absl::string_view input_str) { - ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> output, NewBigNum()); - if (!BN_bin2bn(reinterpret_cast<const uint8_t*>(input_str.data()), - input_str.size(), output.get())) { - return absl::InternalError( - absl::StrCat("Function BN_bin2bn failed: ", GetSslErrors())); - } - if (!output.get()) { - return absl::InternalError("Function BN_bin2bn failed."); - } - return output; -} - -std::string GetSslErrors() { - std::string ret; - ERR_print_errors_cb( - [](const char* str, size_t len, void* ctx) -> int { - static_cast<std::string*>(ctx)->append(str, len); - return 1; - }, - &ret); - return ret; -} - -std::string MaskMessageConcat(absl::string_view mask, - absl::string_view message) { - return absl::StrCat(mask, message); -} - -std::string EncodeMessagePublicMetadata(absl::string_view message, - absl::string_view public_metadata) { - // Prepend encoding of "msg" followed by 4 bytes representing public metadata - // length. - std::string tag = "msg"; - std::vector<uint8_t> buffer(tag.begin(), tag.end()); - buffer.push_back((public_metadata.size() >> 24) & 0xFF); - buffer.push_back((public_metadata.size() >> 16) & 0xFF); - buffer.push_back((public_metadata.size() >> 8) & 0xFF); - buffer.push_back((public_metadata.size() >> 0) & 0xFF); - - // Finally append public metadata and then the message to the output. - std::string encoding(buffer.begin(), buffer.end()); - return absl::StrCat(encoding, public_metadata, message); -} - -absl::StatusOr<bssl::UniquePtr<BIGNUM>> GetRsaSqrtTwo(int x) { - // Compute hard-coded sqrt(2). - ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> sqrt2, NewBigNum()); - // TODO(b/277606961): simplify RsaSqrtTwo initialization logic - const int sqrt2_size = sizeof(internal::kBoringSSLRSASqrtTwo) / - sizeof(*internal::kBoringSSLRSASqrtTwo); - for (int i = sqrt2_size - 2; i >= 0; i = i - 2) { - // Add the uint32_t values as words directly and shift. - // 'i' is the "hi" value of a uint64_t, and 'i+1' is the "lo" value. - if (BN_add_word(sqrt2.get(), internal::kBoringSSLRSASqrtTwo[i]) != 1) { - return absl::InternalError(absl::StrCat( - "Cannot add word to compute RSA sqrt(2): ", GetSslErrors())); - } - if (BN_lshift(sqrt2.get(), sqrt2.get(), 32) != 1) { - return absl::InternalError(absl::StrCat( - "Cannot shift to compute RSA sqrt(2): ", GetSslErrors())); - } - if (BN_add_word(sqrt2.get(), internal::kBoringSSLRSASqrtTwo[i + 1]) != 1) { - return absl::InternalError(absl::StrCat( - "Cannot add word to compute RSA sqrt(2): ", GetSslErrors())); - } - if (i > 0) { - if (BN_lshift(sqrt2.get(), sqrt2.get(), 32) != 1) { - return absl::InternalError(absl::StrCat( - "Cannot shift to compute RSA sqrt(2): ", GetSslErrors())); - } - } - } - - // Check that hard-coded result is correct length. - int sqrt2_bits = 32 * sqrt2_size; - if (BN_num_bits(sqrt2.get()) != sqrt2_bits) { - return absl::InternalError("RSA sqrt(2) is not correct length."); - } - - // Either shift left or right depending on value x. - if (sqrt2_bits > x) { - if (BN_rshift(sqrt2.get(), sqrt2.get(), sqrt2_bits - x) != 1) { - return absl::InternalError( - absl::StrCat("Cannot rshift to compute 2^(x-1/2): ", GetSslErrors())); - } - } else { - // Round up and be pessimistic about minimium factors. - if (BN_add_word(sqrt2.get(), 1) != 1 || - BN_lshift(sqrt2.get(), sqrt2.get(), x - sqrt2_bits) != 1) { - return absl::InternalError(absl::StrCat( - "Cannot add/lshift to compute 2^(x-1/2): ", GetSslErrors())); - } - } - - // Check that 2^(x - 1/2) is correct length. - if (BN_num_bits(sqrt2.get()) != x) { - return absl::InternalError( - "2^(x-1/2) is not correct length after shifting."); - } - - return std::move(sqrt2); -} - -absl::StatusOr<bssl::UniquePtr<BIGNUM>> ComputePowerOfTwo(int x) { - ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> ret, NewBigNum()); - if (BN_set_bit(ret.get(), x) != 1) { - return absl::InternalError( - absl::StrCat("Unable to set bit to compute 2^x: ", GetSslErrors())); - } - if (!BN_is_pow2(ret.get()) || !BN_is_bit_set(ret.get(), x)) { - return absl::InternalError(absl::StrCat("Unable to compute 2^", x, ".")); - } - return ret; -} - -absl::StatusOr<std::string> ComputeHash(absl::string_view input, - const EVP_MD& hasher) { - std::string digest; - digest.resize(EVP_MAX_MD_SIZE); - - uint32_t digest_length = 0; - if (EVP_Digest(input.data(), input.length(), - reinterpret_cast<uint8_t*>(&digest[0]), &digest_length, - &hasher, /*impl=*/nullptr) != 1) { - return absl::InternalError(absl::StrCat( - "Openssl internal error computing hash: ", GetSslErrors())); - } - digest.resize(digest_length); - return digest; -} - -absl::StatusOr<bssl::UniquePtr<RSA>> CreatePrivateKeyRSA( - const absl::string_view rsa_modulus, - const absl::string_view public_exponent, - const absl::string_view private_exponent, const absl::string_view p, - const absl::string_view q, const absl::string_view dp, - const absl::string_view dq, const absl::string_view crt) { - ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> n_bn, - StringToBignum(rsa_modulus)); - ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> e_bn, - StringToBignum(public_exponent)); - ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> d_bn, - StringToBignum(private_exponent)); - ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> p_bn, StringToBignum(p)); - ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> q_bn, StringToBignum(q)); - ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> dp_bn, - StringToBignum(dp)); - ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> dq_bn, - StringToBignum(dq)); - ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> crt_bn, - StringToBignum(crt)); - - bssl::UniquePtr<RSA> rsa_private_key( - RSA_new_private_key(n_bn.get(), e_bn.get(), d_bn.get(), p_bn.get(), - q_bn.get(), dp_bn.get(), dq_bn.get(), crt_bn.get())); - if (!rsa_private_key.get()) { - return absl::InternalError( - absl::StrCat("RSA_new_private_key failed: ", GetSslErrors())); - } - return rsa_private_key; -} - -absl::StatusOr<bssl::UniquePtr<RSA>> CreatePublicKeyRSA( - const absl::string_view rsa_modulus, - const absl::string_view public_exponent) { - ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> n_bn, - StringToBignum(rsa_modulus)); - ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> e_bn, - StringToBignum(public_exponent)); - // Convert to OpenSSL RSA. - bssl::UniquePtr<RSA> rsa_public_key( - RSA_new_public_key(n_bn.get(), e_bn.get())); - if (!rsa_public_key.get()) { - return absl::InternalError( - absl::StrCat("RSA_new_public_key failed: ", GetSslErrors())); - } - return rsa_public_key; -} - -absl::StatusOr<bssl::UniquePtr<RSA>> CreatePublicKeyRSAWithPublicMetadata( - const BIGNUM& rsa_modulus, const BIGNUM& public_exponent, - absl::string_view public_metadata, const bool use_rsa_public_exponent) { - bssl::UniquePtr<BIGNUM> derived_rsa_e; - if (use_rsa_public_exponent) { - ANON_TOKENS_ASSIGN_OR_RETURN( - derived_rsa_e, ComputeExponentWithPublicMetadataAndPublicExponent( - rsa_modulus, public_exponent, public_metadata)); - } else { - ANON_TOKENS_ASSIGN_OR_RETURN( - derived_rsa_e, - ComputeExponentWithPublicMetadata(rsa_modulus, public_metadata)); - } - bssl::UniquePtr<RSA> rsa_public_key = bssl::UniquePtr<RSA>( - RSA_new_public_key_large_e(&rsa_modulus, derived_rsa_e.get())); - if (!rsa_public_key.get()) { - return absl::InternalError( - absl::StrCat("RSA_new_public_key_large_e failed: ", GetSslErrors())); - } - return rsa_public_key; -} - -absl::StatusOr<bssl::UniquePtr<RSA>> CreatePublicKeyRSAWithPublicMetadata( - const absl::string_view rsa_modulus, - const absl::string_view public_exponent, - const absl::string_view public_metadata, - const bool use_rsa_public_exponent) { - ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> rsa_n, - StringToBignum(rsa_modulus)); - ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> rsa_e, - StringToBignum(public_exponent)); - return CreatePublicKeyRSAWithPublicMetadata( - *rsa_n.get(), *rsa_e.get(), public_metadata, use_rsa_public_exponent); -} - -absl::StatusOr<bssl::UniquePtr<BIGNUM>> ComputeCarmichaelLcm( - const BIGNUM& phi_p, const BIGNUM& phi_q, BN_CTX& bn_ctx) { - // To compute lcm(phi(p), phi(q)), we first compute phi(n) = - // (p-1)(q-1). As n is assumed to be a safe RSA modulus (signing_key is - // assumed to be part of a strong rsa key pair), phi(n) = (p-1)(q-1) = - // (2 phi(p))(2 phi(q)) = 4 * phi(p) * phi(q) where phi(p) and phi(q) are also - // primes. So we get the lcm by outputting phi(n) >> 1 = 2 * phi(p) * phi(q). - ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> phi_n, NewBigNum()); - if (BN_mul(phi_n.get(), &phi_p, &phi_q, &bn_ctx) != 1) { - return absl::InternalError( - absl::StrCat("Unable to compute phi(n): ", GetSslErrors())); - } - ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> lcm, NewBigNum()); - if (BN_rshift1(lcm.get(), phi_n.get()) != 1) { - return absl::InternalError(absl::StrCat( - "Could not compute LCM(phi(p), phi(q)): ", GetSslErrors())); - } - return lcm; -} - -absl::StatusOr<bssl::UniquePtr<BIGNUM>> ComputeExponentWithPublicMetadata( - const BIGNUM& n, absl::string_view public_metadata) { - // Check modulus length. - if (BN_num_bits(&n) % 2 == 1) { - return absl::InvalidArgumentError( - "Strong RSA modulus should be even length."); - } - int modulus_bytes = BN_num_bytes(&n); - // The integer modulus_bytes is expected to be a power of 2. - int prime_bytes = modulus_bytes / 2; - - ANON_TOKENS_ASSIGN_OR_RETURN(std::string rsa_modulus_str, - BignumToString(n, modulus_bytes)); - - // Get HKDF output of length prime_bytes. - ANON_TOKENS_ASSIGN_OR_RETURN( - bssl::UniquePtr<BIGNUM> exponent, - internal::PublicMetadataHashWithHKDF(public_metadata, rsa_modulus_str, - prime_bytes)); - - // We need to generate random odd exponents < 2^(primes_bits - 2) where - // prime_bits = prime_bytes * 8. This will guarantee that the resulting - // exponent is coprime to phi(N) = 4p'q' as 2^(prime_bits - 2) < p', q' < - // 2^(prime_bits - 1). - // - // To do this, we can truncate the HKDF output (exponent) which is prime_bits - // long, to prime_bits - 2, by clearing its top two bits. We then set the - // least significant bit to 1. This way the final exponent will be less than - // 2^(primes_bits - 2) and will always be odd. - if (BN_clear_bit(exponent.get(), (prime_bytes * 8) - 1) != kBsslSuccess || - BN_clear_bit(exponent.get(), (prime_bytes * 8) - 2) != kBsslSuccess || - BN_set_bit(exponent.get(), 0) != kBsslSuccess) { - return absl::InvalidArgumentError(absl::StrCat( - "Could not clear the two most significant bits and set the least " - "significant bit to zero: ", - GetSslErrors())); - } - // Check that exponent is small enough to ensure it is coprime to phi(n). - if (BN_num_bits(exponent.get()) >= (8 * prime_bytes - 1)) { - return absl::InternalError("Generated exponent is too large."); - } - - return exponent; -} - -absl::StatusOr<bssl::UniquePtr<BIGNUM>> -ComputeExponentWithPublicMetadataAndPublicExponent( - const BIGNUM& n, const BIGNUM& e, absl::string_view public_metadata) { - ANON_TOKENS_ASSIGN_OR_RETURN( - bssl::UniquePtr<BIGNUM> md_exp, - ComputeExponentWithPublicMetadata(n, public_metadata)); - ANON_TOKENS_ASSIGN_OR_RETURN(BnCtxPtr bn_ctx, GetAndStartBigNumCtx()); - // new_e=e*md_exp - ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> new_e, NewBigNum()); - if (BN_mul(new_e.get(), md_exp.get(), &e, bn_ctx.get()) != kBsslSuccess) { - return absl::InternalError( - absl::StrCat("Unable to multiply e with md_exp: ", GetSslErrors())); - } - return new_e; -} - -absl::Status RsaBlindSignatureVerify(const int salt_length, - const EVP_MD* sig_hash, - const EVP_MD* mgf1_hash, - const absl::string_view signature, - const absl::string_view message, - RSA* rsa_public_key) { - ANON_TOKENS_ASSIGN_OR_RETURN(std::string message_digest, - ComputeHash(message, *sig_hash)); - const int hash_size = EVP_MD_size(sig_hash); - // Make sure the size of the digest is correct. - if (message_digest.size() != hash_size) { - return absl::InvalidArgumentError( - absl::StrCat("Size of the digest doesn't match the one " - "of the hashing algorithm; expected ", - hash_size, " got ", message_digest.size())); - } - // Make sure the size of the signature is correct. - const int rsa_modulus_size = BN_num_bytes(RSA_get0_n(rsa_public_key)); - if (signature.size() != rsa_modulus_size) { - return absl::InvalidArgumentError( - "Signature size not equal to modulus size."); - } - - std::string recovered_message_digest(rsa_modulus_size, 0); - int recovered_message_digest_size = RSA_public_decrypt( - /*flen=*/signature.size(), - /*from=*/reinterpret_cast<const uint8_t*>(signature.data()), - /*to=*/ - reinterpret_cast<uint8_t*>(recovered_message_digest.data()), - /*rsa=*/rsa_public_key, - /*padding=*/RSA_NO_PADDING); - if (recovered_message_digest_size != rsa_modulus_size) { - return absl::InvalidArgumentError( - absl::StrCat("Invalid signature size (likely an incorrect key is " - "used); expected ", - rsa_modulus_size, " got ", recovered_message_digest_size, - ": ", GetSslErrors())); - } - if (RSA_verify_PKCS1_PSS_mgf1( - rsa_public_key, reinterpret_cast<const uint8_t*>(&message_digest[0]), - sig_hash, mgf1_hash, - reinterpret_cast<const uint8_t*>(recovered_message_digest.data()), - salt_length) != kBsslSuccess) { - return absl::InvalidArgumentError( - absl::StrCat("PSS padding verification failed: ", GetSslErrors())); - } - return absl::OkStatus(); -} - -absl::StatusOr<std::string> RsaSsaPssPublicKeyToDerEncoding(const RSA* rsa) { - if (rsa == NULL) { - return absl::InvalidArgumentError("Public Key rsa is null."); - } - // Create DER encoded RSA public key string. - ANON_TOKENS_ASSIGN_OR_RETURN(std::string rsa_public_key_str, - MarshalRsaPublicKey(rsa)); - // Main CRYPTO ByteBuilder object cbb which will be passed to CBB_finish to - // finalize and output the DER encoding of the RsaSsaPssPublicKey. - bssl::ScopedCBB cbb; - // initial_capacity only serves as a hint. - if (!CBB_init(cbb.get(), /*initial_capacity=*/2 * RSA_size(rsa))) { - return absl::InternalError("CBB_init() failed."); - } - - // Temporary CBB objects to write ASN1 sequences and object identifiers into. - CBB outer_seq, inner_seq, param_seq, sha384_seq, mgf1_seq, mgf1_sha384_seq; - CBB param0_tag, param1_tag, param2_tag; - CBB rsassa_pss_oid, sha384_oid, mgf1_oid, mgf1_sha384_oid; - CBB public_key_bit_str_cbb; - // RsaSsaPssPublicKey ASN.1 structure example: - // - // SEQUENCE { # outer_seq - // SEQUENCE { # inner_seq - // OBJECT_IDENTIFIER{1.2.840.113549.1.1.10} # rsassa_pss_oid - // SEQUENCE { # param_seq - // [0] { # param0_tag - // { # sha384_seq - // OBJECT_IDENTIFIER{2.16.840.1.101.3.4.2.2} # sha384_oid - // } - // } - // [1] { # param1_tag - // { # mgf1_seq - // OBJECT_IDENTIFIER{1.2.840.113549.1.1.8} # mgf1_oid - // { # mgf1_sha384_seq - // OBJECT_IDENTIFIER{2.16.840.1.101.3.4.2.2}# mgf1_sha384_oid - // } - // } - // } - // [2] { # param2_tag - // INTEGER { 48 } # salt length - // } - // } - // } - // BIT STRING { # public_key_bit_str_cbb - // 0 # unused bits - // der_encoded_rsa_public_key_structure - // } - // } - // - // Start with the outer sequence. - if (!CBB_add_asn1(cbb.get(), &outer_seq, CBS_ASN1_SEQUENCE) || - // The outer sequence consists of two parts; the inner sequence and the - // encoded rsa public key. - // - // Add the inner sequence to the outer sequence. - !CBB_add_asn1(&outer_seq, &inner_seq, CBS_ASN1_SEQUENCE) || - // Add object identifier for RSASSA-PSS algorithm to the inner sequence. - !CBB_add_asn1(&inner_seq, &rsassa_pss_oid, CBS_ASN1_OBJECT) || - !CBB_add_asn1_oid_from_text(&rsassa_pss_oid, kRsaSsaPssOid, - strlen(kRsaSsaPssOid)) || - // Add a parameter sequence to the inner sequence. - !CBB_add_asn1(&inner_seq, ¶m_seq, CBS_ASN1_SEQUENCE) || - // SHA384 hash function algorithm identifier will be parameter 0 in the - // parameter sequence. - !CBB_add_asn1(¶m_seq, ¶m0_tag, - CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0) || - !CBB_add_asn1(¶m0_tag, &sha384_seq, CBS_ASN1_SEQUENCE) || - // Add SHA384 object identifier to finish the SHA384 algorithm identifier - // and parameter 0. - !CBB_add_asn1(&sha384_seq, &sha384_oid, CBS_ASN1_OBJECT) || - !CBB_add_asn1_oid_from_text(&sha384_oid, kSha384Oid, - strlen(kSha384Oid)) || - // mgf1-SHA384 algorithm identifier as parameter 1 to the parameter - // sequence. - !CBB_add_asn1(¶m_seq, ¶m1_tag, - CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 1) || - !CBB_add_asn1(¶m1_tag, &mgf1_seq, CBS_ASN1_SEQUENCE) || - // Add mgf1 object identifier to the mgf1-SHA384 algorithm identifier. - !CBB_add_asn1(&mgf1_seq, &mgf1_oid, CBS_ASN1_OBJECT) || - !CBB_add_asn1_oid_from_text(&mgf1_oid, kRsaSsaPssMgf1Oid, - strlen(kRsaSsaPssMgf1Oid)) || - // Add SHA384 algorithm identifier to the mgf1-SHA384 algorithm - // identifier. - !CBB_add_asn1(&mgf1_seq, &mgf1_sha384_seq, CBS_ASN1_SEQUENCE) || - // Add SHA384 object identifier to finish SHA384 algorithm identifier, - // mgf1-SHA384 algorithm identifier and parameter 1. - !CBB_add_asn1(&mgf1_sha384_seq, &mgf1_sha384_oid, CBS_ASN1_OBJECT) || - !CBB_add_asn1_oid_from_text(&mgf1_sha384_oid, kSha384Oid, - strlen(kSha384Oid)) || - // Add salt length as parameter 2 to the parameter sequence to finish the - // parameter sequence and the inner sequence. - !CBB_add_asn1(¶m_seq, ¶m2_tag, - CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 2) || - !CBB_add_asn1_int64(¶m2_tag, kSaltLengthInBytes48) || - // Add public key to the outer sequence as an ASN1 bitstring. - !CBB_add_asn1(&outer_seq, &public_key_bit_str_cbb, CBS_ASN1_BITSTRING) || - !CBB_add_u8(&public_key_bit_str_cbb, 0 /* no unused bits */) || - !CBB_add_bytes( - &public_key_bit_str_cbb, - reinterpret_cast<const uint8_t*>(rsa_public_key_str.data()), - rsa_public_key_str.size())) { - return absl::InvalidArgumentError( - "Failed to set the crypto byte builder object."); - } - // Finish creating the DER-encoding of RsaSsaPssPublicKey. - uint8_t* rsa_ssa_pss_public_key_der; - size_t rsa_ssa_pss_public_key_der_len; - if (!CBB_finish(cbb.get(), &rsa_ssa_pss_public_key_der, - &rsa_ssa_pss_public_key_der_len)) { - return absl::InternalError("CBB_finish() failed."); - } - std::string rsa_ssa_pss_public_key_der_str( - reinterpret_cast<const char*>(rsa_ssa_pss_public_key_der), - rsa_ssa_pss_public_key_der_len); - // Free memory. - OPENSSL_free(rsa_ssa_pss_public_key_der); - // Return the DER encoding as string. - return rsa_ssa_pss_public_key_der_str; -} - -} // namespace anonymous_tokens -} // namespace private_membership
diff --git a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/crypto_utils.h b/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/crypto_utils.h deleted file mode 100644 index 80bbdcc..0000000 --- a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/crypto_utils.h +++ /dev/null
@@ -1,233 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef THIRD_PARTY_ANONYMOUS_TOKENS_CPP_CRYPTO_CRYPTO_UTILS_H_ -#define THIRD_PARTY_ANONYMOUS_TOKENS_CPP_CRYPTO_CRYPTO_UTILS_H_ - -#include <stddef.h> - -#include <memory> -#include <optional> -#include <string> - -#include "absl/status/statusor.h" -#include "absl/strings/string_view.h" -#include "openssl/base.h" -#include "openssl/bn.h" -#include "openssl/evp.h" -#include "openssl/rsa.h" -#include "quiche/common/platform/api/quiche_export.h" -// copybara:strip_begin(internal comment) -// The QUICHE_EXPORT annotation is necessary for some classes and functions -// to link correctly on Windows. Please do not remove them! -// copybara:strip_end - -namespace private_membership { -namespace anonymous_tokens { - -// Internal functions only exposed for testing. -namespace internal { - -// Outputs a public metadata `hash` using HKDF with the public metadata as -// input and the rsa modulus as salt. The expected output hash size is passed as -// out_len_bytes. -// -// Implementation follows the steps listed in -// https://datatracker.ietf.org/doc/draft-amjad-cfrg-partially-blind-rsa/ -// -// This method internally calls HKDF with output size of more than -// out_len_bytes and later truncates the output to out_len_bytes. This is done -// so that the output is indifferentiable from truly random bytes. -// https://cfrg.github.io/draft-irtf-cfrg-hash-to-curve/draft-irtf-cfrg-hash-to-curve.html#name-hashing-to-a-finite-field -absl::StatusOr<bssl::UniquePtr<BIGNUM>> QUICHE_EXPORT -PublicMetadataHashWithHKDF(absl::string_view public_metadata, - absl::string_view rsa_modulus_str, - size_t out_len_bytes); - -} // namespace internal - -// Deletes a BN_CTX. -class BnCtxDeleter { - public: - void operator()(BN_CTX* ctx) { BN_CTX_free(ctx); } -}; -typedef std::unique_ptr<BN_CTX, BnCtxDeleter> BnCtxPtr; - -// Deletes a BN_MONT_CTX. -class BnMontCtxDeleter { - public: - void operator()(BN_MONT_CTX* mont_ctx) { BN_MONT_CTX_free(mont_ctx); } -}; -typedef std::unique_ptr<BN_MONT_CTX, BnMontCtxDeleter> BnMontCtxPtr; - -// Deletes an EVP_MD_CTX. -class EvpMdCtxDeleter { - public: - void operator()(EVP_MD_CTX* ctx) { EVP_MD_CTX_destroy(ctx); } -}; -typedef std::unique_ptr<EVP_MD_CTX, EvpMdCtxDeleter> EvpMdCtxPtr; - -// Creates and starts a BIGNUM context. -absl::StatusOr<BnCtxPtr> QUICHE_EXPORT GetAndStartBigNumCtx(); - -// Creates a new BIGNUM. -absl::StatusOr<bssl::UniquePtr<BIGNUM>> QUICHE_EXPORT NewBigNum(); - -// Converts a BIGNUM to string. -absl::StatusOr<std::string> QUICHE_EXPORT BignumToString( - const BIGNUM& big_num, size_t output_len); - -// Converts a string to BIGNUM. -absl::StatusOr<bssl::UniquePtr<BIGNUM>> QUICHE_EXPORT StringToBignum( - absl::string_view input_str); - -// Retrieve error messages from OpenSSL. -std::string QUICHE_EXPORT GetSslErrors(); - -// Mask message using protocol at -// https://datatracker.ietf.org/doc/draft-irtf-cfrg-rsa-blind-signatures/ -std::string QUICHE_EXPORT MaskMessageConcat(absl::string_view mask, - absl::string_view message); - -// Encode Message and Public Metadata using steps in -// https://datatracker.ietf.org/doc/draft-amjad-cfrg-partially-blind-rsa/ -// -// The length of public metadata must fit in 4 bytes. -std::string QUICHE_EXPORT EncodeMessagePublicMetadata( - absl::string_view message, absl::string_view public_metadata); - -// Compute 2^(x - 1/2). -absl::StatusOr<bssl::UniquePtr<BIGNUM>> QUICHE_EXPORT GetRsaSqrtTwo( - int x); - -// Compute compute 2^x. -absl::StatusOr<bssl::UniquePtr<BIGNUM>> QUICHE_EXPORT ComputePowerOfTwo( - int x); - -// ComputeHash sub-routine used during blindness and verification of RSA blind -// signatures protocol with or without public metadata. -absl::StatusOr<std::string> QUICHE_EXPORT ComputeHash( - absl::string_view input, const EVP_MD& hasher); - -// Computes the Carmichael LCM given phi(p) and phi(q) where N = p*q is a safe -// RSA modulus. -absl::StatusOr<bssl::UniquePtr<BIGNUM>> QUICHE_EXPORT -ComputeCarmichaelLcm(const BIGNUM& phi_p, const BIGNUM& phi_q, BN_CTX& bn_ctx); - -// Create bssl::UniquePtr<RSA> representing a RSA private key. -// -// Note that this method should not be used to create a key with public exponent -// greater than 2^32. -absl::StatusOr<bssl::UniquePtr<RSA>> QUICHE_EXPORT -CreatePrivateKeyRSA(absl::string_view rsa_modulus, - absl::string_view public_exponent, - absl::string_view private_exponent, absl::string_view p, - absl::string_view q, absl::string_view dp, - absl::string_view dq, absl::string_view crt); - -// Create bssl::UniquePtr<RSA> representing a RSA public key. -// -// Note that this method should not be used to create a key with public exponent -// greater than 2^32. -absl::StatusOr<bssl::UniquePtr<RSA>> QUICHE_EXPORT -CreatePublicKeyRSA(absl::string_view rsa_modulus, - absl::string_view public_exponent); - -// Create bssl::UniquePtr<RSA> representing a RSA public key derived using -// public metadata. -// -// If the boolean "use_rsa_public_exponent" is set to false, the public exponent -// is not used in any computations. -// -// Setting "use_rsa_public_exponent" to true is deprecated. -absl::StatusOr<bssl::UniquePtr<RSA>> QUICHE_EXPORT -CreatePublicKeyRSAWithPublicMetadata(const BIGNUM& rsa_modulus, - const BIGNUM& public_exponent, - absl::string_view public_metadata, - bool use_rsa_public_exponent); - -// Create bssl::UniquePtr<RSA> representing a RSA public key derived using -// public metadata. -// -// If the boolean "use_rsa_public_exponent" is set to false, the public exponent -// is not used in any computations. -// -// Setting "use_rsa_public_exponent" to true is deprecated. -absl::StatusOr<bssl::UniquePtr<RSA>> QUICHE_EXPORT -CreatePublicKeyRSAWithPublicMetadata(absl::string_view rsa_modulus, - absl::string_view public_exponent, - absl::string_view public_metadata, - bool use_rsa_public_exponent); - -// Compute exponent using only the public metadata and RSA modulus n. Assumes -// that n is a safe modulus i.e. it produces a strong RSA key pair. If not, the -// exponent may be invalid. -// -// Empty public metadata is considered to be a valid value for public_metadata -// and will output a valid exponent. -absl::StatusOr<bssl::UniquePtr<BIGNUM>> QUICHE_EXPORT -ComputeExponentWithPublicMetadata(const BIGNUM& n, - absl::string_view public_metadata); - -// Computes exponent by multiplying the public exponent e with the -// exponent derived from public metadata and RSA modulus n. Assumes that n is a -// safe modulus i.e. it produces a strong RSA key pair. If not, the exponent may -// be invalid. -// -// Empty public metadata is considered to be a valid value for public_metadata -// and will output an exponent different than `e` as well. -// -// This function is now deprecated. -absl::StatusOr<bssl::UniquePtr<BIGNUM>> QUICHE_EXPORT -ComputeExponentWithPublicMetadataAndPublicExponent( - const BIGNUM& n, const BIGNUM& e, absl::string_view public_metadata); - -// Helper method that implements RSA PSS Blind Signatures verification protocol -// for both the standard scheme as well as the public metadata version. -// -// For the public metadata version, -// -// 1) `rsa_public_key' must contain a public exponent derived using the public -// metadata. -// -// 2) The `message' must be an encoding of an original input message -// and the public metadata e.g. by using EncodeMessagePublicMetadata method in -// this file. The caller should make sure that its original input message is a -// random message. In case it is not, it should be concatenated with a random -// string. -absl::Status QUICHE_EXPORT RsaBlindSignatureVerify( - int salt_length, const EVP_MD* sig_hash, const EVP_MD* mgf1_hash, - absl::string_view signature, absl::string_view message, - RSA* rsa_public_key); - -// This method outputs a DER encoding of RSASSA-PSS (RSA Signature Scheme with -// Appendix - Probabilistic Signature Scheme) Public Key as described here -// https://datatracker.ietf.org/doc/html/rfc3447.html using the object -// identifier(s) here: https://oidref.com/1.2.840.113549.1.1.10 and using a -// fixed salt length of 48 bytes, SHA384 as the signature's hash function as -// well as the hash function that the signature's mask generating function is -// based on. A publicly availble equivalent function is available in Goa here: -// https://github.com/cloudflare/pat-go/blob/11579ba5b0b9b77d3e8e3d5247a98811227ac82e/x509util.go#L56 -// -// copybara:strip_begin(internal comment) -// This method serves as a C++ version for the following Goa method: -// http://google3/privacy/net/boq/common/tokens/token_types.go;l=85;rcl=515461856 -// copybara:strip_end -absl::StatusOr<std::string> QUICHE_EXPORT RsaSsaPssPublicKeyToDerEncoding( - const RSA* rsa); - -} // namespace anonymous_tokens -} // namespace private_membership - -#endif // THIRD_PARTY_ANONYMOUS_TOKENS_CPP_CRYPTO_CRYPTO_UTILS_H_
diff --git a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blind_signer.cc b/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blind_signer.cc deleted file mode 100644 index 71294fd..0000000 --- a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blind_signer.cc +++ /dev/null
@@ -1,189 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blind_signer.h" - -#include <cstddef> -#include <cstdint> -#include <memory> -#include <string> -#include <utility> - -#include "absl/memory/memory.h" -#include "absl/status/status.h" -#include "absl/status/statusor.h" -#include "absl/strings/str_cat.h" -#include "absl/strings/string_view.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/anonymous_tokens_pb_openssl_converters.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/constants.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/crypto_utils.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/shared/status_utils.h" -#include "quiche/blind_sign_auth/anonymous_tokens/proto/anonymous_tokens.pb.h" -#include "openssl/rsa.h" - -namespace private_membership { -namespace anonymous_tokens { -namespace { - -absl::StatusOr<bssl::UniquePtr<RSA>> CreatePrivateKeyWithPublicMetadata( - const absl::string_view rsa_modulus_str, - const absl::string_view rsa_public_exponent_str, - const absl::string_view rsa_p_str, const absl::string_view rsa_q_str, - const absl::string_view rsa_crt_str, - const absl::string_view public_metadata, - const bool use_rsa_public_exponent) { - // Convert RSA modulus n (=p*q) to BIGNUM. - ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> rsa_modulus, - StringToBignum(rsa_modulus_str)); - // Convert public exponent e to BIGNUM. - ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> old_e, - StringToBignum(rsa_public_exponent_str)); - - // Compute new public exponent based on public metadata. - bssl::UniquePtr<BIGNUM> derived_rsa_e; - if (use_rsa_public_exponent) { - ANON_TOKENS_ASSIGN_OR_RETURN( - derived_rsa_e, ComputeExponentWithPublicMetadataAndPublicExponent( - *rsa_modulus, *old_e, public_metadata)); - } else { - ANON_TOKENS_ASSIGN_OR_RETURN( - derived_rsa_e, - ComputeExponentWithPublicMetadata(*rsa_modulus, public_metadata)); - } - - // Convert p & q to BIGNUM. - ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> rsa_p, - StringToBignum(rsa_p_str)); - ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> rsa_q, - StringToBignum(rsa_q_str)); - - // Compute phi(p) = p-1 and phi(q) = q-1. - ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> phi_p, NewBigNum()); - if (BN_sub(phi_p.get(), rsa_p.get(), BN_value_one()) != 1) { - return absl::InternalError( - absl::StrCat("Unable to compute phi(p): ", GetSslErrors())); - } - ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> phi_q, NewBigNum()); - if (BN_sub(phi_q.get(), rsa_q.get(), BN_value_one()) != 1) { - return absl::InternalError( - absl::StrCat("Unable to compute phi(q): ", GetSslErrors())); - } - - bssl::UniquePtr<BN_CTX> bn_ctx(BN_CTX_new()); - if (!bn_ctx) { - return absl::InternalError("BN_CTX_new failed."); - } - // Compute lcm(phi(p), phi(q)). - ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> lcm, - ComputeCarmichaelLcm(*phi_p, *phi_q, *bn_ctx)); - - // Compute the new private exponent derived_rsa_d. - ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> derived_rsa_d, - NewBigNum()); - if (!BN_mod_inverse(derived_rsa_d.get(), derived_rsa_e.get(), lcm.get(), - bn_ctx.get())) { - return absl::InternalError( - absl::StrCat("Could not compute private exponent d: ", GetSslErrors())); - } - - // Compute new_dpm1 = derived_rsa_d mod p-1. - ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> new_dpm1, NewBigNum()); - BN_mod(new_dpm1.get(), derived_rsa_d.get(), phi_p.get(), bn_ctx.get()); - // Compute new_dqm1 = derived_rsa_d mod q-1. - ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> new_dqm1, NewBigNum()); - BN_mod(new_dqm1.get(), derived_rsa_d.get(), phi_q.get(), bn_ctx.get()); - // Convert crt to BIGNUM. - ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> rsa_crt, - StringToBignum(rsa_crt_str)); - - // Create private key derived from given key and public metadata. - bssl::UniquePtr<RSA> derived_private_key(RSA_new_private_key_large_e( - rsa_modulus.get(), derived_rsa_e.get(), derived_rsa_d.get(), rsa_p.get(), - rsa_q.get(), new_dpm1.get(), new_dqm1.get(), rsa_crt.get())); - if (!derived_private_key.get()) { - return absl::InternalError( - absl::StrCat("RSA_new_private_key_large_e failed: ", GetSslErrors())); - } - - return derived_private_key; -} - -} // namespace - -RsaBlindSigner::RsaBlindSigner(std::optional<absl::string_view> public_metadata, - bssl::UniquePtr<RSA> rsa_private_key) - : public_metadata_(public_metadata), - rsa_private_key_(std::move(rsa_private_key)) {} - -absl::StatusOr<std::unique_ptr<RsaBlindSigner>> RsaBlindSigner::New( - const RSAPrivateKey& signing_key, const bool use_rsa_public_exponent, - std::optional<absl::string_view> public_metadata) { - bssl::UniquePtr<RSA> rsa_private_key; - if (!public_metadata.has_value()) { - // The RSA modulus and exponent are checked as part of the conversion to - // bssl::UniquePtr<RSA>. - ANON_TOKENS_ASSIGN_OR_RETURN( - rsa_private_key, AnonymousTokensRSAPrivateKeyToRSA(signing_key)); - } else { - // If public metadata is passed, RsaBlindSigner will compute a new private - // exponent using the public metadata. - // - // Empty string is a valid public metadata value. - ANON_TOKENS_ASSIGN_OR_RETURN( - rsa_private_key, - CreatePrivateKeyWithPublicMetadata( - signing_key.n(), signing_key.e(), signing_key.p(), signing_key.q(), - signing_key.crt(), *public_metadata, use_rsa_public_exponent)); - } - return absl::WrapUnique( - new RsaBlindSigner(public_metadata, std::move(rsa_private_key))); -} - -absl::StatusOr<std::string> RsaBlindSigner::Sign( - const absl::string_view blinded_data) const { - if (blinded_data.empty() || blinded_data.data() == nullptr) { - return absl::InvalidArgumentError("blinded_data string is empty."); - } - - int mod_size = RSA_size(rsa_private_key_.get()); - if (blinded_data.size() != mod_size) { - return absl::InternalError(absl::StrCat( - "Expected blind data size = ", mod_size, - " actual blind data size = ", blinded_data.size(), " bytes.")); - } - - std::string signature(mod_size, 0); - // Compute a raw RSA signature. - size_t out_len; - if (RSA_sign_raw( - /*rsa=*/rsa_private_key_.get(), /*out_len=*/&out_len, - /*out=*/reinterpret_cast<uint8_t*>(&signature[0]), - /*max_out=*/mod_size, - /*in=*/reinterpret_cast<const uint8_t*>(&blinded_data[0]), - /*in_len=*/mod_size, - /*padding=*/RSA_NO_PADDING) != kBsslSuccess) { - return absl::InternalError( - "RSA_sign_raw failed when called from RsaBlindSigner::Sign"); - } - if (out_len != mod_size || out_len != signature.size()) { - return absl::InternalError(absl::StrCat( - "Expected value of out_len and signature.size() = ", mod_size, - " bytes, actual value of out_len and signature.size() = ", out_len, - " and ", signature.size(), " bytes.")); - } - return signature; -} - -} // namespace anonymous_tokens -} // namespace private_membership
diff --git a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blind_signer.h b/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blind_signer.h deleted file mode 100644 index cc31ac5..0000000 --- a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blind_signer.h +++ /dev/null
@@ -1,78 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef THIRD_PARTY_ANONYMOUS_TOKENS_CPP_CRYPTO_RSA_BLIND_SIGNER_H_ -#define THIRD_PARTY_ANONYMOUS_TOKENS_CPP_CRYPTO_RSA_BLIND_SIGNER_H_ - -#include <memory> -#include <string> - -#include "absl/status/statusor.h" -#include "absl/strings/string_view.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/blind_signer.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/crypto_utils.h" -#include "quiche/blind_sign_auth/anonymous_tokens/proto/anonymous_tokens.pb.h" -#include "quiche/common/platform/api/quiche_export.h" -// copybara:strip_begin(internal comment) -// The QUICHE_EXPORT annotation is necessary for some classes and functions -// to link correctly on Windows. Please do not remove them! -// copybara:strip_end - -namespace private_membership { -namespace anonymous_tokens { - -// The RSA SSA (Signature Schemes with Appendix) using PSS (Probabilistic -// Signature Scheme) encoding is defined at -// https://tools.ietf.org/html/rfc8017#section-8.1). This implementation uses -// Boring SSL for the underlying cryptographic operations. -class QUICHE_EXPORT RsaBlindSigner : public BlindSigner { - public: - ~RsaBlindSigner() override = default; - RsaBlindSigner(const RsaBlindSigner&) = delete; - RsaBlindSigner& operator=(const RsaBlindSigner&) = delete; - - // Passing of public_metadata is optional. If it is set to any value including - // an empty string, RsaBlindSigner will assume that partially blind RSA - // signature protocol is being executed. - // - // If public metadata is passed and the boolean "use_rsa_public_exponent" is - // set to false, the public exponent in the signing_key is not used in any - // computations in the protocol. - // - // Setting "use_rsa_public_exponent" to true is deprecated. All new users - // should set it to false. - static absl::StatusOr<std::unique_ptr<RsaBlindSigner>> New( - const RSAPrivateKey& signing_key, bool use_rsa_public_exponent, - std::optional<absl::string_view> public_metadata = std::nullopt); - - // Computes the signature for 'blinded_data'. - absl::StatusOr<std::string> Sign( - absl::string_view blinded_data) const override; - - private: - // Use New to construct. - RsaBlindSigner(std::optional<absl::string_view> public_metadata, - bssl::UniquePtr<RSA> rsa_private_key); - - const std::optional<std::string> public_metadata_; - - // In case public metadata is passed to RsaBlindSigner::New, rsa_private_key_ - // will be initialized using RSA_new_private_key_large_e method. - const bssl::UniquePtr<RSA> rsa_private_key_; -}; - -} // namespace anonymous_tokens -} // namespace private_membership - -#endif // THIRD_PARTY_ANONYMOUS_TOKENS_CPP_CRYPTO_RSA_BLIND_SIGNER_H_
diff --git a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blind_signer_test.cc b/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blind_signer_test.cc deleted file mode 100644 index 4294467..0000000 --- a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blind_signer_test.cc +++ /dev/null
@@ -1,304 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blind_signer.h" - -#include <memory> -#include <random> -#include <string> -#include <utility> - -#include "quiche/common/platform/api/quiche_test.h" -#include "quiche/common/test_tools/quiche_test_utils.h" -#include "absl/status/status.h" -#include "absl/status/statusor.h" -#include "absl/strings/string_view.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/constants.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/crypto_utils.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_ssa_pss_verifier.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/testing/proto_utils.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/testing/utils.h" -#include "quiche/blind_sign_auth/anonymous_tokens/proto/anonymous_tokens.pb.h" -#include "openssl/digest.h" -#include "openssl/rsa.h" - -namespace private_membership { -namespace anonymous_tokens { -namespace { - -using CreateTestKeyPairFunction = - absl::StatusOr<std::pair<RSAPublicKey, RSAPrivateKey>>(); - -class RsaBlindSignerTest - : public ::testing::TestWithParam<CreateTestKeyPairFunction *> { - protected: - void SetUp() override { - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(auto keys_pair, (*GetParam())()); - public_key_ = std::move(keys_pair.first); - private_key_ = std::move(keys_pair.second); - generator_.seed(0); - // NOTE: using recommended RsaSsaPssParams - sig_hash_ = EVP_sha384(); - mgf1_hash_ = EVP_sha384(); - salt_length_ = kSaltLengthInBytes48; - } - - RSAPrivateKey private_key_; - RSAPublicKey public_key_; - std::mt19937_64 generator_; - const EVP_MD *sig_hash_; // Owned by BoringSSL. - const EVP_MD *mgf1_hash_; // Owned by BoringSSL. - int salt_length_; - std::uniform_int_distribution<int> distr_u8_ = - std::uniform_int_distribution<int>{0, 255}; -}; - -// This test only tests whether the implemented signer 'signs' properly. The -// outline of method calls in this test should not be assumed a secure signature -// scheme (and used in other places) as the security has not been -// proven/analyzed. -// -// Test for the standard signer does not take public metadata as a parameter -// which means public metadata is set to std::nullopt. -TEST_P(RsaBlindSignerTest, StandardSignerWorks) { - absl::string_view message = "Hello World!"; - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::string encoded_message, - EncodeMessageForTests(message, public_key_, sig_hash_, mgf1_hash_, - salt_length_)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::unique_ptr<RsaBlindSigner> signer, - RsaBlindSigner::New(private_key_, /*use_rsa_public_exponent=*/true)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string potentially_insecure_signature, - signer->Sign(encoded_message)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - const auto verifier, - RsaSsaPssVerifier::New(salt_length_, sig_hash_, mgf1_hash_, public_key_, - /*use_rsa_public_exponent=*/true)); - EXPECT_TRUE(verifier->Verify(potentially_insecure_signature, message).ok()); -} - -TEST_P(RsaBlindSignerTest, SignerFails) { - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::unique_ptr<RsaBlindSigner> signer, - RsaBlindSigner::New(private_key_, /*use_rsa_public_exponent=*/true)); - absl::string_view message = "Hello World!"; - - absl::StatusOr<std::string> signature = signer->Sign(message); - EXPECT_EQ(signature.status().code(), absl::StatusCode::kInternal); - EXPECT_THAT(signature.status().message(), - ::testing::HasSubstr("Expected blind data size")); - - int sig_size = public_key_.n().size(); - std::string message2 = RandomString(sig_size, &distr_u8_, &generator_); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string insecure_sig, - signer->Sign(message2)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - const auto verifier, - RsaSsaPssVerifier::New(salt_length_, sig_hash_, mgf1_hash_, public_key_, - /*use_rsa_public_exponent=*/true)); - absl::Status verification_result = verifier->Verify(insecure_sig, message2); - EXPECT_EQ(verification_result.code(), absl::StatusCode::kInvalidArgument); - EXPECT_THAT(verification_result.message(), - ::testing::HasSubstr("verification failed")); -} - -INSTANTIATE_TEST_SUITE_P(RsaBlindSignerTest, RsaBlindSignerTest, - ::testing::Values(&GetStrongRsaKeys2048, - &GetAnotherStrongRsaKeys2048, - &GetStrongRsaKeys3072, - &GetStrongRsaKeys4096)); - -using RsaBlindSignerPublicMetadataTestParams = - std::tuple<absl::StatusOr<std::pair<RSAPublicKey, RSAPrivateKey>>, - /*use_rsa_public_exponent*/ bool>; - -class RsaBlindSignerTestWithPublicMetadata - : public ::testing::TestWithParam<RsaBlindSignerPublicMetadataTestParams> { - protected: - void SetUp() override { - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(auto keys_pair, std::get<0>(GetParam())); - use_rsa_public_exponent_ = std::get<1>(GetParam()); - public_key_ = std::move(keys_pair.first); - private_key_ = std::move(keys_pair.second); - // NOTE: using recommended RsaSsaPssParams - sig_hash_ = EVP_sha384(); - mgf1_hash_ = EVP_sha384(); - salt_length_ = kSaltLengthInBytes48; - } - - RSAPrivateKey private_key_; - RSAPublicKey public_key_; - const EVP_MD *sig_hash_; // Owned by BoringSSL. - const EVP_MD *mgf1_hash_; // Owned by BoringSSL. - int salt_length_; - bool use_rsa_public_exponent_; -}; - -// This test only tests whether the implemented signer 'signs' properly under -// some public metadata. The outline of method calls in this test should not -// be assumed a secure signature scheme (and used in other places) as the -// security has not been proven/analyzed. -TEST_P(RsaBlindSignerTestWithPublicMetadata, SignerWorksWithPublicMetadata) { - absl::string_view message = "Hello World!"; - absl::string_view public_metadata = "pubmd!"; - std::string augmented_message = - EncodeMessagePublicMetadata(message, public_metadata); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::string encoded_message, - EncodeMessageForTests(augmented_message, public_key_, sig_hash_, - mgf1_hash_, salt_length_)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::unique_ptr<RsaBlindSigner> signer, - RsaBlindSigner::New(private_key_, use_rsa_public_exponent_, - public_metadata)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string potentially_insecure_signature, - signer->Sign(encoded_message)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - auto verifier, - RsaSsaPssVerifier::New(salt_length_, sig_hash_, mgf1_hash_, public_key_, - use_rsa_public_exponent_, public_metadata)); - EXPECT_TRUE(verifier->Verify(potentially_insecure_signature, message).ok()); -} - -TEST_P(RsaBlindSignerTestWithPublicMetadata, - SignerWorksWithEmptyPublicMetadata) { - absl::string_view message = "Hello World!"; - absl::string_view empty_public_metadata = ""; - std::string augmented_message = - EncodeMessagePublicMetadata(message, empty_public_metadata); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::string encoded_message, - EncodeMessageForTests(augmented_message, public_key_, sig_hash_, - mgf1_hash_, salt_length_)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::unique_ptr<RsaBlindSigner> signer, - RsaBlindSigner::New(private_key_, use_rsa_public_exponent_, - empty_public_metadata)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string potentially_insecure_signature, - signer->Sign(encoded_message)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - auto verifier, - RsaSsaPssVerifier::New(salt_length_, sig_hash_, mgf1_hash_, public_key_, - use_rsa_public_exponent_, empty_public_metadata)); - EXPECT_TRUE(verifier->Verify(potentially_insecure_signature, message).ok()); -} - -TEST_P(RsaBlindSignerTestWithPublicMetadata, - SignatureFailstoVerifyWithWrongPublicMetadata) { - absl::string_view message = "Hello World!"; - absl::string_view public_metadata = "pubmd!"; - absl::string_view public_metadata_2 = "pubmd2"; - std::string augmented_message = - EncodeMessagePublicMetadata(message, public_metadata); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::string encoded_message, - EncodeMessageForTests(augmented_message, public_key_, sig_hash_, - mgf1_hash_, salt_length_)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::unique_ptr<RsaBlindSigner> signer, - RsaBlindSigner::New(private_key_, use_rsa_public_exponent_, - public_metadata)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string potentially_insecure_signature, - signer->Sign(encoded_message)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - auto verifier, - RsaSsaPssVerifier::New(salt_length_, sig_hash_, mgf1_hash_, public_key_, - use_rsa_public_exponent_, public_metadata_2)); - absl::Status verification_result = - verifier->Verify(potentially_insecure_signature, message); - EXPECT_EQ(verification_result.code(), absl::StatusCode::kInvalidArgument); - EXPECT_THAT(verification_result.message(), - ::testing::HasSubstr("verification failed")); -} - -TEST_P(RsaBlindSignerTestWithPublicMetadata, - SignatureFailsToVerifyWithNoPublicMetadata) { - absl::string_view message = "Hello World!"; - absl::string_view public_metadata = "pubmd!"; - absl::string_view public_metadata_2 = ""; - std::string augmented_message = - EncodeMessagePublicMetadata(message, public_metadata); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::string encoded_message, - EncodeMessageForTests(augmented_message, public_key_, sig_hash_, - mgf1_hash_, salt_length_)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::unique_ptr<RsaBlindSigner> signer, - RsaBlindSigner::New(private_key_, use_rsa_public_exponent_, - public_metadata)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string potentially_insecure_signature, - signer->Sign(encoded_message)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - auto verifier, - RsaSsaPssVerifier::New(salt_length_, sig_hash_, mgf1_hash_, public_key_, - use_rsa_public_exponent_, public_metadata_2)); - absl::Status verification_result = - verifier->Verify(potentially_insecure_signature, message); - EXPECT_EQ(verification_result.code(), absl::StatusCode::kInvalidArgument); - EXPECT_THAT(verification_result.message(), - ::testing::HasSubstr("verification failed")); -} - -INSTANTIATE_TEST_SUITE_P( - RsaBlindSignerTestWithPublicMetadata, RsaBlindSignerTestWithPublicMetadata, - ::testing::Combine( - ::testing::Values(GetStrongRsaKeys2048(), GetAnotherStrongRsaKeys2048(), - GetStrongRsaKeys3072(), GetStrongRsaKeys4096()), - /*use_rsa_public_exponent*/ ::testing::Values(true, false))); - -// TODO(b/275956922): Consolidate all tests that use IETF test vectors into one -// E2E test. -// -// The following tests use IETF test vectors for RSA blind signatures with -// public metadata. The vectors includes tests for public metadata set to an -// empty string as well as a non-empty value. -TEST(IetfRsaBlindSignerTest, - IetfRsaBlindSignaturesWithPublicMetadataTestVectorsSuccess) { - auto test_vectors = GetIetfRsaBlindSignatureWithPublicMetadataTestVectors(); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - const auto test_key, - GetIetfRsaBlindSignatureWithPublicMetadataTestKeys()); - for (const auto &test_vector : test_vectors) { - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::unique_ptr<RsaBlindSigner> signer, - RsaBlindSigner::New(test_key.second, /*use_rsa_public_exponent=*/true, - test_vector.public_metadata)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string blind_signature, - signer->Sign(test_vector.blinded_message)); - EXPECT_EQ(blind_signature, test_vector.blinded_signature); - } -} - -TEST(IetfRsaBlindSignerTest, - IetfPartiallyBlindRsaSignaturesNoPublicExponentTestVectorsSuccess) { - auto test_vectors = - GetIetfPartiallyBlindRSASignatureNoPublicExponentTestVectors(); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - const auto test_key, - GetIetfRsaBlindSignatureWithPublicMetadataTestKeys()); - for (const auto &test_vector : test_vectors) { - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::unique_ptr<RsaBlindSigner> signer, - RsaBlindSigner::New(test_key.second, /*use_rsa_public_exponent=*/false, - test_vector.public_metadata)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string blind_signature, - signer->Sign(test_vector.blinded_message)); - EXPECT_EQ(blind_signature, test_vector.blinded_signature); - } -} - -} // namespace -} // namespace anonymous_tokens -} // namespace private_membership
diff --git a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blinder.cc b/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blinder.cc deleted file mode 100644 index 752bcb9..0000000 --- a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blinder.cc +++ /dev/null
@@ -1,260 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blinder.h" - -#include <memory> -#include <string> -#include <utility> -#include <vector> - -#include "absl/status/status.h" -#include "absl/status/statusor.h" -#include "absl/strings/str_cat.h" -#include "absl/strings/string_view.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/constants.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/crypto_utils.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/shared/status_utils.h" -#include "openssl/digest.h" -#include "openssl/rsa.h" - -namespace private_membership { -namespace anonymous_tokens { - -absl::StatusOr<std::unique_ptr<RsaBlinder>> RsaBlinder::New( - absl::string_view rsa_modulus, absl::string_view rsa_public_exponent, - const EVP_MD* signature_hash_function, const EVP_MD* mgf1_hash_function, - int salt_length, const bool use_rsa_public_exponent, - std::optional<absl::string_view> public_metadata) { - bssl::UniquePtr<RSA> rsa_public_key; - - if (!public_metadata.has_value()) { - ANON_TOKENS_ASSIGN_OR_RETURN( - rsa_public_key, CreatePublicKeyRSA(rsa_modulus, rsa_public_exponent)); - } else { - // If public metadata is passed, RsaBlinder will compute a new public - // exponent using the public metadata. - // - // Empty string is a valid public metadata value. - ANON_TOKENS_ASSIGN_OR_RETURN( - rsa_public_key, CreatePublicKeyRSAWithPublicMetadata( - rsa_modulus, rsa_public_exponent, *public_metadata, - use_rsa_public_exponent)); - } - - ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> r, NewBigNum()); - ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> r_inv_mont, NewBigNum()); - - // Limit r between [2, n) so that an r of 1 never happens. An r of 1 doesn't - // blind. - if (BN_rand_range_ex(r.get(), 2, RSA_get0_n(rsa_public_key.get())) != - kBsslSuccess) { - return absl::InternalError( - "BN_rand_range_ex failed when called from RsaBlinder::New."); - } - - bssl::UniquePtr<BN_CTX> bn_ctx(BN_CTX_new()); - if (!bn_ctx) { - return absl::InternalError("BN_CTX_new failed."); - } - - bssl::UniquePtr<BN_MONT_CTX> bn_mont_ctx(BN_MONT_CTX_new_for_modulus( - RSA_get0_n(rsa_public_key.get()), bn_ctx.get())); - if (!bn_mont_ctx) { - return absl::InternalError("BN_MONT_CTX_new_for_modulus failed."); - } - - // We wish to compute r^-1 in the Montgomery domain, or r^-1 R mod n. This is - // can be done with BN_mod_inverse_blinded followed by BN_to_montgomery, but - // it is equivalent and slightly more efficient to first compute r R^-1 mod n - // with BN_from_montgomery, and then inverting that to give r^-1 R mod n. - int is_r_not_invertible = 0; - if (BN_from_montgomery(r_inv_mont.get(), r.get(), bn_mont_ctx.get(), - bn_ctx.get()) != kBsslSuccess || - BN_mod_inverse_blinded(r_inv_mont.get(), &is_r_not_invertible, - r_inv_mont.get(), bn_mont_ctx.get(), - bn_ctx.get()) != kBsslSuccess) { - return absl::InternalError( - absl::StrCat("BN_mod_inverse failed when called from RsaBlinder::New, " - "is_r_not_invertible = ", - is_r_not_invertible)); - } - - return absl::WrapUnique(new RsaBlinder( - salt_length, public_metadata, signature_hash_function, mgf1_hash_function, - std::move(rsa_public_key), std::move(r), std::move(r_inv_mont), - std::move(bn_mont_ctx))); -} - -RsaBlinder::RsaBlinder(int salt_length, - std::optional<absl::string_view> public_metadata, - const EVP_MD* sig_hash, const EVP_MD* mgf1_hash, - bssl::UniquePtr<RSA> rsa_public_key, - bssl::UniquePtr<BIGNUM> r, - bssl::UniquePtr<BIGNUM> r_inv_mont, - bssl::UniquePtr<BN_MONT_CTX> mont_n) - : salt_length_(salt_length), - public_metadata_(public_metadata), - sig_hash_(sig_hash), - mgf1_hash_(mgf1_hash), - rsa_public_key_(std::move(rsa_public_key)), - r_(std::move(r)), - r_inv_mont_(std::move(r_inv_mont)), - mont_n_(std::move(mont_n)), - blinder_state_(RsaBlinder::BlinderState::kCreated) {} - -absl::StatusOr<std::string> RsaBlinder::Blind(const absl::string_view message) { - // Check that the blinder state was kCreated - if (blinder_state_ != RsaBlinder::BlinderState::kCreated) { - return absl::FailedPreconditionError( - "RsaBlinder is in wrong state to blind message."); - } - std::string augmented_message(message); - if (public_metadata_.has_value()) { - augmented_message = EncodeMessagePublicMetadata(message, *public_metadata_); - } - ANON_TOKENS_ASSIGN_OR_RETURN(std::string digest_str, - ComputeHash(augmented_message, *sig_hash_)); - std::vector<uint8_t> digest(digest_str.begin(), digest_str.end()); - - // Construct the PSS padded message, using the same workflow as BoringSSL's - // RSA_sign_pss_mgf1 for processing the message (but not signing the message): - // google3/third_party/openssl/boringssl/src/crypto/fipsmodule/rsa/rsa.c?l=557 - if (digest.size() != EVP_MD_size(sig_hash_)) { - return absl::InternalError("Invalid input message length."); - } - - // Allocate for padded length - const int padded_len = BN_num_bytes(RSA_get0_n(rsa_public_key_.get())); - std::vector<uint8_t> padded(padded_len); - - // The |md| and |mgf1_md| arguments identify the hash used to calculate - // |digest| and the MGF1 hash, respectively. If |mgf1_md| is NULL, |md| is - // used. |salt_len| specifies the expected salt length in bytes. If |salt_len| - // is -1, then the salt length is the same as the hash length. If -2, then the - // salt length is maximal given the size of |rsa|. If unsure, use -1. - if (RSA_padding_add_PKCS1_PSS_mgf1( - /*rsa=*/rsa_public_key_.get(), /*EM=*/padded.data(), - /*mHash=*/digest.data(), /*Hash=*/sig_hash_, /*mgf1Hash=*/mgf1_hash_, - /*sLen=*/salt_length_) != kBsslSuccess) { - return absl::InternalError( - "RSA_padding_add_PKCS1_PSS_mgf1 failed when called from " - "RsaBlinder::Blind"); - } - - bssl::UniquePtr<BN_CTX> bn_ctx(BN_CTX_new()); - if (!bn_ctx) { - return absl::InternalError("BN_CTX_new failed."); - } - - std::string encoded_message(padded.begin(), padded.end()); - ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> encoded_message_bn, - StringToBignum(encoded_message)); - - // Take `r^e mod n`. This is an equivalent operation to RSA_encrypt, without - // extra encode/decode trips. - ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> rE, NewBigNum()); - if (BN_mod_exp_mont(rE.get(), r_.get(), RSA_get0_e(rsa_public_key_.get()), - RSA_get0_n(rsa_public_key_.get()), bn_ctx.get(), - mont_n_.get()) != kBsslSuccess) { - return absl::InternalError( - "BN_mod_exp_mont failed when called from RsaBlinder::Blind."); - } - - // Do `encoded_message*r^e mod n`. - // - // To avoid leaking side channels, we use Montgomery reduction. This would be - // FromMontgomery(ModMulMontgomery(ToMontgomery(m), ToMontgomery(r^e))). - // However, this is equivalent to ModMulMontgomery(m, ToMontgomery(r^e)). - // Each BN_mod_mul_montgomery removes a factor of R, so by having only one - // input in the Montgomery domain, we save a To/FromMontgomery pair. - // - // Internally, BN_mod_exp_mont actually computes r^e in the Montgomery domain - // and converts it out, but there is no public API for this, so we perform an - // extra conversion. - ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> multiplication_res, - NewBigNum()); - if (BN_to_montgomery(multiplication_res.get(), rE.get(), mont_n_.get(), - bn_ctx.get()) != kBsslSuccess || - BN_mod_mul_montgomery(multiplication_res.get(), encoded_message_bn.get(), - multiplication_res.get(), mont_n_.get(), - bn_ctx.get()) != kBsslSuccess) { - return absl::InternalError( - "BN_mod_mul failed when called from RsaBlinder::Blind."); - } - - absl::StatusOr<std::string> blinded_msg = - BignumToString(*multiplication_res, padded_len); - - // Update RsaBlinder state to kBlinded - blinder_state_ = RsaBlinder::BlinderState::kBlinded; - - return blinded_msg; -} - -// Unblinds `blind_signature`. -absl::StatusOr<std::string> RsaBlinder::Unblind( - const absl::string_view blind_signature) { - if (blinder_state_ != RsaBlinder::BlinderState::kBlinded) { - return absl::FailedPreconditionError( - "RsaBlinder is in wrong state to unblind signature."); - } - const int mod_size = BN_num_bytes(RSA_get0_n(rsa_public_key_.get())); - // Parse the signed_blinded_data as BIGNUM. - if (blind_signature.size() != mod_size) { - return absl::InternalError(absl::StrCat( - "Expected blind signature size = ", mod_size, - " actual blind signature size = ", blind_signature.size(), " bytes.")); - } - - bssl::UniquePtr<BN_CTX> bn_ctx(BN_CTX_new()); - if (!bn_ctx) { - return absl::InternalError("BN_CTX_new failed."); - } - - ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> signed_big_num, - StringToBignum(blind_signature)); - ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> unblinded_sig_big, - NewBigNum()); - // Do `signed_message*r^-1 mod n`. - // - // To avoid leaking side channels, we use Montgomery reduction. This would be - // FromMontgomery(ModMulMontgomery(ToMontgomery(m), ToMontgomery(r^-1))). - // However, this is equivalent to ModMulMontgomery(m, ToMontgomery(r^-1)). - // Each BN_mod_mul_montgomery removes a factor of R, so by having only one - // input in the Montgomery domain, we save a To/FromMontgomery pair. - if (BN_mod_mul_montgomery(unblinded_sig_big.get(), signed_big_num.get(), - r_inv_mont_.get(), mont_n_.get(), - bn_ctx.get()) != kBsslSuccess) { - return absl::InternalError( - "BN_mod_mul failed when called from RsaBlinder::Unblind."); - } - absl::StatusOr<std::string> unblinded_signed_message = - BignumToString(*unblinded_sig_big, /*output_len=*/mod_size); - blinder_state_ = RsaBlinder::BlinderState::kUnblinded; - return unblinded_signed_message; -} - -absl::Status RsaBlinder::Verify(absl::string_view signature, - absl::string_view message) { - std::string augmented_message(message); - if (public_metadata_.has_value()) { - augmented_message = EncodeMessagePublicMetadata(message, *public_metadata_); - } - return RsaBlindSignatureVerify(salt_length_, sig_hash_, mgf1_hash_, signature, - augmented_message, rsa_public_key_.get()); -} - -} // namespace anonymous_tokens -} // namespace private_membership
diff --git a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blinder.h b/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blinder.h deleted file mode 100644 index a71f0b2..0000000 --- a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blinder.h +++ /dev/null
@@ -1,104 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef THIRD_PARTY_ANONYMOUS_TOKENS_CPP_CRYPTO_RSA_BLINDER_H_ -#define THIRD_PARTY_ANONYMOUS_TOKENS_CPP_CRYPTO_RSA_BLINDER_H_ - -#include <stdint.h> - -#include <memory> -#include <optional> -#include <string> - -#include "absl/status/status.h" -#include "absl/status/statusor.h" -#include "absl/strings/string_view.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/blinder.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/crypto_utils.h" -#include "quiche/common/platform/api/quiche_export.h" -// copybara:strip_begin(internal comment) -// The QUICHE_EXPORT annotation is necessary for some classes and functions -// to link correctly on Windows. Please do not remove them! -// copybara:strip_end - -namespace private_membership { -namespace anonymous_tokens { - -// RsaBlinder `blinds` input messages, and then unblinds them after they are -// signed. -class QUICHE_EXPORT RsaBlinder : public Blinder { - public: - // Passing of public_metadata is optional. If it is set to any value including - // an empty string, RsaBlinder will assume that partially blind RSA signature - // protocol is being executed. - // - // If public metadata is passed and the boolean "use_rsa_public_exponent" is - // set to false, the rsa_public_exponent is not used in any computations in - // the protocol. - // - // Setting "use_rsa_public_exponent" to true is deprecated. All new users - // should set it to false. - static absl::StatusOr<std::unique_ptr<RsaBlinder>> New( - absl::string_view rsa_modulus, absl::string_view rsa_public_exponent, - const EVP_MD* signature_hash_function, const EVP_MD* mgf1_hash_function, - int salt_length, bool use_rsa_public_exponent, - std::optional<absl::string_view> public_metadata = std::nullopt); - - // Blind `message` using n and e derived from an RSA public key and the public - // metadata if applicable. - // - // Before blinding, the `message` will first be hashed and then encoded with - // the EMSA-PSS operation. - absl::StatusOr<std::string> Blind(absl::string_view message) override; - - // Unblinds `blind_signature`. - // - // Callers should run Verify on the returned signature before using it / - // passing it on. - absl::StatusOr<std::string> Unblind( - absl::string_view blind_signature) override; - - // Verifies an `unblinded` signature against the same `message' that was - // passed to Blind. - absl::Status Verify(absl::string_view signature, absl::string_view message); - - private: - // Use `New` to construct - RsaBlinder(int salt_length, std::optional<absl::string_view> public_metadata, - const EVP_MD* sig_hash, const EVP_MD* mgf1_hash, - bssl::UniquePtr<RSA> rsa_public_key, bssl::UniquePtr<BIGNUM> r, - bssl::UniquePtr<BIGNUM> r_inv_mont, - bssl::UniquePtr<BN_MONT_CTX> mont_n); - - const int salt_length_; - std::optional<std::string> public_metadata_; - const EVP_MD* sig_hash_; // Owned by BoringSSL. - const EVP_MD* mgf1_hash_; // Owned by BoringSSL. - - // If public metadata was passed to RsaBlinder::New, rsa_public_key_ will - // will be initialized using RSA_new_public_key_large_e method. - const bssl::UniquePtr<RSA> rsa_public_key_; - - const bssl::UniquePtr<BIGNUM> r_; - // r^-1 mod n in the Montgomery domain - const bssl::UniquePtr<BIGNUM> r_inv_mont_; - const bssl::UniquePtr<BN_MONT_CTX> mont_n_; - - BlinderState blinder_state_; -}; - -} // namespace anonymous_tokens -} // namespace private_membership - -#endif // THIRD_PARTY_ANONYMOUS_TOKENS_CPP_CRYPTO_RSA_BLINDER_H_
diff --git a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blinder_test.cc b/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blinder_test.cc deleted file mode 100644 index 5723caf..0000000 --- a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blinder_test.cc +++ /dev/null
@@ -1,446 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blinder.h" - -#include <memory> -#include <string> -#include <tuple> -#include <utility> - -#include "quiche/common/platform/api/quiche_test.h" -#include "quiche/common/test_tools/quiche_test_utils.h" -#include "absl/status/status.h" -#include "absl/status/statusor.h" -#include "absl/strings/string_view.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/constants.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/testing/utils.h" -#include "openssl/base.h" -#include "openssl/digest.h" -#include "openssl/rsa.h" - -namespace private_membership { -namespace anonymous_tokens { -namespace { - -// TODO(b/275965524): Figure out a way to test RsaBlinder class with IETF test -// vectors in rsa_blinder_test.cc. - -struct RsaBlinderTestParameters { - TestRsaPublicKey public_key; - TestRsaPrivateKey private_key; - const EVP_MD* sig_hash; - const EVP_MD* mgf1_hash; - int salt_length; -}; - -RsaBlinderTestParameters CreateDefaultTestKeyParameters() { - const auto [public_key, private_key] = GetStrongTestRsaKeyPair4096(); - return {public_key, private_key, EVP_sha384(), EVP_sha384(), - kSaltLengthInBytes48}; -} - -RsaBlinderTestParameters CreateShorterTestKeyParameters() { - const auto [public_key, private_key] = GetStrongTestRsaKeyPair3072(); - return {public_key, private_key, EVP_sha384(), EVP_sha384(), - kSaltLengthInBytes48}; -} - -RsaBlinderTestParameters CreateShortestTestKeyParameters() { - const auto [public_key, private_key] = GetStrongTestRsaKeyPair2048(); - return {public_key, private_key, EVP_sha384(), EVP_sha384(), - kSaltLengthInBytes48}; -} - -RsaBlinderTestParameters CreateSHA256TestKeyParameters() { - const auto [public_key, private_key] = GetStrongTestRsaKeyPair4096(); - return {public_key, private_key, EVP_sha256(), EVP_sha256(), 32}; -} - -RsaBlinderTestParameters CreateLongerSaltTestKeyParameters() { - const auto [public_key, private_key] = GetStrongTestRsaKeyPair4096(); - return {public_key, private_key, EVP_sha384(), EVP_sha384(), 64}; -} - -class RsaBlinderTest : public testing::TestWithParam<RsaBlinderTestParameters> { - protected: - void SetUp() override { - rsa_blinder_test_params_ = GetParam(); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - rsa_key_, - CreatePrivateKeyRSA(rsa_blinder_test_params_.private_key.n, - rsa_blinder_test_params_.private_key.e, - rsa_blinder_test_params_.private_key.d, - rsa_blinder_test_params_.private_key.p, - rsa_blinder_test_params_.private_key.q, - rsa_blinder_test_params_.private_key.dp, - rsa_blinder_test_params_.private_key.dq, - rsa_blinder_test_params_.private_key.crt)); - } - - RsaBlinderTestParameters rsa_blinder_test_params_; - bssl::UniquePtr<RSA> rsa_key_; -}; - -TEST_P(RsaBlinderTest, BlindSignUnblindEnd2EndTest) { - const absl::string_view message = "Hello World!"; - - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::unique_ptr<RsaBlinder> blinder, - RsaBlinder::New(rsa_blinder_test_params_.public_key.n, - rsa_blinder_test_params_.public_key.e, - rsa_blinder_test_params_.sig_hash, - rsa_blinder_test_params_.mgf1_hash, - rsa_blinder_test_params_.salt_length, - /*use_rsa_public_exponent=*/true)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string blinded_message, - blinder->Blind(message)); - EXPECT_NE(blinded_message, message); - - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string blinded_signature, - TestSign(blinded_message, rsa_key_.get())); - EXPECT_NE(blinded_signature, blinded_message); - EXPECT_NE(blinded_signature, message); - - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string signature, - blinder->Unblind(blinded_signature)); - EXPECT_NE(signature, blinded_signature); - EXPECT_NE(signature, blinded_message); - EXPECT_NE(signature, message); - - EXPECT_TRUE(blinder->Verify(signature, message).ok()); -} - -TEST_P(RsaBlinderTest, DoubleBlindingFailure) { - const absl::string_view message = "Hello World2!"; - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::unique_ptr<RsaBlinder> blinder, - RsaBlinder::New(rsa_blinder_test_params_.public_key.n, - rsa_blinder_test_params_.public_key.e, - rsa_blinder_test_params_.sig_hash, - rsa_blinder_test_params_.mgf1_hash, - rsa_blinder_test_params_.salt_length, - /*use_rsa_public_exponent=*/true)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(const std::string blinded_message, - blinder->Blind(message)); - // Blind the blinded_message - absl::StatusOr<std::string> result = blinder->Blind(blinded_message); - EXPECT_EQ(result.status().code(), absl::StatusCode::kFailedPrecondition); - EXPECT_THAT(result.status().message(), testing::HasSubstr("wrong state")); - // Blind a new message - const absl::string_view new_message = "Hello World3!"; - result = blinder->Blind(new_message); - EXPECT_EQ(result.status().code(), absl::StatusCode::kFailedPrecondition); - EXPECT_THAT(result.status().message(), testing::HasSubstr("wrong state")); -} - -TEST_P(RsaBlinderTest, DoubleUnblindingFailure) { - const absl::string_view message = "Hello World2!"; - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::unique_ptr<RsaBlinder> blinder, - RsaBlinder::New(rsa_blinder_test_params_.public_key.n, - rsa_blinder_test_params_.public_key.e, - rsa_blinder_test_params_.sig_hash, - rsa_blinder_test_params_.mgf1_hash, - rsa_blinder_test_params_.salt_length, - /*use_rsa_public_exponent=*/true)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(const std::string blinded_message, - blinder->Blind(message)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(const std::string blinded_signature, - TestSign(blinded_message, rsa_key_.get())); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string signature, - blinder->Unblind(blinded_signature)); - // Unblind the unblinded signature - absl::StatusOr<std::string> result = blinder->Unblind(signature); - EXPECT_EQ(result.status().code(), absl::StatusCode::kFailedPrecondition); - EXPECT_THAT(result.status().message(), testing::HasSubstr("wrong state")); - // Unblind the blinded_signature again - result = blinder->Unblind(signature); - EXPECT_EQ(result.status().code(), absl::StatusCode::kFailedPrecondition); - EXPECT_THAT(result.status().message(), testing::HasSubstr("wrong state")); -} - -TEST_P(RsaBlinderTest, InvalidSignature) { - const absl::string_view message = "Hello World2!"; - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::unique_ptr<RsaBlinder> blinder, - RsaBlinder::New(rsa_blinder_test_params_.public_key.n, - rsa_blinder_test_params_.public_key.e, - rsa_blinder_test_params_.sig_hash, - rsa_blinder_test_params_.mgf1_hash, - rsa_blinder_test_params_.salt_length, - /*use_rsa_public_exponent=*/true)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(const std::string blinded_message, - blinder->Blind(message)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(const std::string blinded_signature, - TestSign(blinded_message, rsa_key_.get())); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string signature, - blinder->Unblind(blinded_signature)); - EXPECT_TRUE(blinder->Verify(signature, message).ok()); - - // Invalidate the signature by replacing the last 10 characters by 10 '0's - for (int i = 0; i < 10; i++) { - signature.pop_back(); - } - for (int i = 0; i < 10; i++) { - signature.push_back('0'); - } - - absl::Status result = blinder->Verify(signature, message); - EXPECT_EQ(result.code(), absl::StatusCode::kInvalidArgument); - EXPECT_THAT(result.message(), testing::HasSubstr("verification failed")); -} - -TEST_P(RsaBlinderTest, InvalidVerificationKey) { - const absl::string_view message = "Hello World4!"; - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::unique_ptr<RsaBlinder> blinder, - RsaBlinder::New(rsa_blinder_test_params_.public_key.n, - rsa_blinder_test_params_.public_key.e, - rsa_blinder_test_params_.sig_hash, - rsa_blinder_test_params_.mgf1_hash, - rsa_blinder_test_params_.salt_length, - /*use_rsa_public_exponent=*/true)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(const std::string blinded_message, - blinder->Blind(message)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(const std::string blinded_signature, - TestSign(blinded_message, rsa_key_.get())); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string signature, - blinder->Unblind(blinded_signature)); - - const auto [bad_key, _] = GetAnotherStrongTestRsaKeyPair2048(); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::unique_ptr<RsaBlinder> bad_blinder, - RsaBlinder::New(bad_key.n, bad_key.e, rsa_blinder_test_params_.sig_hash, - rsa_blinder_test_params_.mgf1_hash, - rsa_blinder_test_params_.salt_length, - /*use_rsa_public_exponent=*/true)); - EXPECT_THAT(bad_blinder->Verify(signature, message).code(), - absl::StatusCode::kInvalidArgument); -} - -INSTANTIATE_TEST_SUITE_P(RsaBlinderTest, RsaBlinderTest, - testing::Values(CreateDefaultTestKeyParameters(), - CreateShorterTestKeyParameters(), - CreateShortestTestKeyParameters(), - CreateSHA256TestKeyParameters(), - CreateLongerSaltTestKeyParameters())); - -using RsaBlinderPublicMetadataTestParams = - std::tuple<std::pair<TestRsaPublicKey, TestRsaPrivateKey>, - /*use_rsa_public_exponent*/ bool>; - -class RsaBlinderWithPublicMetadataTest - : public testing::TestWithParam<RsaBlinderPublicMetadataTestParams> { - protected: - void SetUp() override { - std::pair<TestRsaPublicKey, TestRsaPrivateKey> key_pair; - std::tie(key_pair, use_rsa_public_exponent_) = GetParam(); - const auto [public_key, private_key] = key_pair; - rsa_blinder_test_params_ = {public_key, private_key, EVP_sha384(), - EVP_sha384(), kSaltLengthInBytes48}; - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - rsa_key_, - CreatePrivateKeyRSA(rsa_blinder_test_params_.private_key.n, - rsa_blinder_test_params_.private_key.e, - rsa_blinder_test_params_.private_key.d, - rsa_blinder_test_params_.private_key.p, - rsa_blinder_test_params_.private_key.q, - rsa_blinder_test_params_.private_key.dp, - rsa_blinder_test_params_.private_key.dq, - rsa_blinder_test_params_.private_key.crt)); - } - - RsaBlinderTestParameters rsa_blinder_test_params_; - bssl::UniquePtr<RSA> rsa_key_; - bool use_rsa_public_exponent_; -}; - -TEST_P(RsaBlinderWithPublicMetadataTest, - BlindSignUnblindWithPublicMetadataEnd2EndTest) { - const absl::string_view message = "Hello World!"; - const absl::string_view public_metadata = "pubmd!"; - - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::unique_ptr<RsaBlinder> blinder, - RsaBlinder::New(rsa_blinder_test_params_.public_key.n, - rsa_blinder_test_params_.public_key.e, - rsa_blinder_test_params_.sig_hash, - rsa_blinder_test_params_.mgf1_hash, - rsa_blinder_test_params_.salt_length, - use_rsa_public_exponent_, public_metadata)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string blinded_message, - blinder->Blind(message)); - EXPECT_NE(blinded_message, message); - - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::string blinded_signature, - TestSignWithPublicMetadata(blinded_message, public_metadata, *rsa_key_, - use_rsa_public_exponent_)); - EXPECT_NE(blinded_signature, blinded_message); - EXPECT_NE(blinded_signature, message); - - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string signature, - blinder->Unblind(blinded_signature)); - EXPECT_NE(signature, blinded_signature); - EXPECT_NE(signature, blinded_message); - EXPECT_NE(signature, message); - - EXPECT_TRUE(blinder->Verify(signature, message).ok()); -} - -TEST_P(RsaBlinderWithPublicMetadataTest, - BlindSignUnblindWithEmptyPublicMetadataEnd2EndTest) { - const absl::string_view message = "Hello World!"; - const absl::string_view empty_public_metadata = ""; - - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::unique_ptr<RsaBlinder> blinder, - RsaBlinder::New(rsa_blinder_test_params_.public_key.n, - rsa_blinder_test_params_.public_key.e, - rsa_blinder_test_params_.sig_hash, - rsa_blinder_test_params_.mgf1_hash, - rsa_blinder_test_params_.salt_length, - use_rsa_public_exponent_, empty_public_metadata)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string blinded_message, - blinder->Blind(message)); - EXPECT_NE(blinded_message, message); - - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::string blinded_signature, - TestSignWithPublicMetadata(blinded_message, empty_public_metadata, - *rsa_key_, use_rsa_public_exponent_)); - EXPECT_NE(blinded_signature, blinded_message); - EXPECT_NE(blinded_signature, message); - - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string signature, - blinder->Unblind(blinded_signature)); - EXPECT_NE(signature, blinded_signature); - EXPECT_NE(signature, blinded_message); - EXPECT_NE(signature, message); - - EXPECT_TRUE(blinder->Verify(signature, message).ok()); -} - -TEST_P(RsaBlinderWithPublicMetadataTest, WrongPublicMetadata) { - const absl::string_view message = "Hello World!"; - const absl::string_view public_metadata = "pubmd!"; - const absl::string_view public_metadata_2 = "pubmd2"; - - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::unique_ptr<RsaBlinder> blinder, - RsaBlinder::New(rsa_blinder_test_params_.public_key.n, - rsa_blinder_test_params_.public_key.e, - rsa_blinder_test_params_.sig_hash, - rsa_blinder_test_params_.mgf1_hash, - rsa_blinder_test_params_.salt_length, - use_rsa_public_exponent_, public_metadata)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string blinded_message, - blinder->Blind(message)); - EXPECT_NE(blinded_message, message); - - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::string blinded_signature, - TestSignWithPublicMetadata(blinded_message, public_metadata_2, *rsa_key_, - use_rsa_public_exponent_)); - EXPECT_NE(blinded_signature, blinded_message); - EXPECT_NE(blinded_signature, message); - - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string signature, - blinder->Unblind(blinded_signature)); - EXPECT_NE(signature, blinded_signature); - EXPECT_NE(signature, blinded_message); - EXPECT_NE(signature, message); - absl::Status verification_result = blinder->Verify(signature, message); - EXPECT_EQ(verification_result.code(), absl::StatusCode::kInvalidArgument); - EXPECT_THAT(verification_result.message(), - ::testing::HasSubstr("verification failed")); -} - -TEST_P(RsaBlinderWithPublicMetadataTest, NoPublicMetadataForSigning) { - const absl::string_view message = "Hello World!"; - const absl::string_view public_metadata = "pubmd!"; - - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::unique_ptr<RsaBlinder> blinder, - RsaBlinder::New(rsa_blinder_test_params_.public_key.n, - rsa_blinder_test_params_.public_key.e, - rsa_blinder_test_params_.sig_hash, - rsa_blinder_test_params_.mgf1_hash, - rsa_blinder_test_params_.salt_length, - use_rsa_public_exponent_, public_metadata)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string blinded_message, - blinder->Blind(message)); - EXPECT_NE(blinded_message, message); - - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string blinded_signature, - TestSign(blinded_message, rsa_key_.get())); - EXPECT_NE(blinded_signature, blinded_message); - EXPECT_NE(blinded_signature, message); - - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string signature, - blinder->Unblind(blinded_signature)); - EXPECT_NE(signature, blinded_signature); - EXPECT_NE(signature, blinded_message); - EXPECT_NE(signature, message); - absl::Status verification_result = blinder->Verify(signature, message); - EXPECT_EQ(verification_result.code(), absl::StatusCode::kInvalidArgument); - EXPECT_THAT(verification_result.message(), - ::testing::HasSubstr("verification failed")); -} - -TEST_P(RsaBlinderWithPublicMetadataTest, NoPublicMetadataInBlinding) { - const absl::string_view message = "Hello World!"; - const absl::string_view public_metadata = "pubmd!"; - - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::unique_ptr<RsaBlinder> blinder, - RsaBlinder::New( - rsa_blinder_test_params_.public_key.n, - rsa_blinder_test_params_.public_key.e, - rsa_blinder_test_params_.sig_hash, rsa_blinder_test_params_.mgf1_hash, - rsa_blinder_test_params_.salt_length, use_rsa_public_exponent_)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string blinded_message, - blinder->Blind(message)); - EXPECT_NE(blinded_message, message); - - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::string blinded_signature, - TestSignWithPublicMetadata(blinded_message, public_metadata, *rsa_key_, - use_rsa_public_exponent_)); - EXPECT_NE(blinded_signature, blinded_message); - EXPECT_NE(blinded_signature, message); - - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string signature, - blinder->Unblind(blinded_signature)); - EXPECT_NE(signature, blinded_signature); - EXPECT_NE(signature, blinded_message); - EXPECT_NE(signature, message); - absl::Status verification_result = blinder->Verify(signature, message); - EXPECT_EQ(verification_result.code(), absl::StatusCode::kInvalidArgument); - EXPECT_THAT(verification_result.message(), - ::testing::HasSubstr("verification failed")); -} - -INSTANTIATE_TEST_SUITE_P( - RsaBlinderWithPublicMetadataTest, RsaBlinderWithPublicMetadataTest, - testing::Combine(testing::Values(GetStrongTestRsaKeyPair2048(), - GetAnotherStrongTestRsaKeyPair2048(), - GetStrongTestRsaKeyPair3072(), - GetStrongTestRsaKeyPair4096()), - /*use_rsa_public_exponent*/ testing::Values(true, false))); - -} // namespace -} // namespace anonymous_tokens -} // namespace private_membership
diff --git a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_ssa_pss_verifier.cc b/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_ssa_pss_verifier.cc deleted file mode 100644 index 5a890cc..0000000 --- a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_ssa_pss_verifier.cc +++ /dev/null
@@ -1,86 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_ssa_pss_verifier.h" - -#include <stdint.h> - -#include <memory> -#include <string> -#include <utility> - -#include "absl/memory/memory.h" -#include "absl/status/status.h" -#include "absl/status/statusor.h" -#include "absl/strings/str_cat.h" -#include "absl/strings/string_view.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/anonymous_tokens_pb_openssl_converters.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/constants.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/crypto_utils.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/shared/status_utils.h" -#include "quiche/blind_sign_auth/anonymous_tokens/proto/anonymous_tokens.pb.h" -#include "openssl/bn.h" -#include "openssl/rsa.h" - -namespace private_membership { -namespace anonymous_tokens { - -absl::StatusOr<std::unique_ptr<RsaSsaPssVerifier>> RsaSsaPssVerifier::New( - const int salt_length, const EVP_MD* sig_hash, const EVP_MD* mgf1_hash, - const RSAPublicKey& public_key, const bool use_rsa_public_exponent, - std::optional<absl::string_view> public_metadata) { - bssl::UniquePtr<RSA> rsa_public_key; - - if (!public_metadata.has_value()) { - ANON_TOKENS_ASSIGN_OR_RETURN(rsa_public_key, - AnonymousTokensRSAPublicKeyToRSA(public_key)); - } else { - // If public metadata is passed, RsaSsaPssVerifier will compute a new public - // exponent using the public metadata. - // - // Empty string is a valid public metadata value. - ANON_TOKENS_ASSIGN_OR_RETURN( - rsa_public_key, CreatePublicKeyRSAWithPublicMetadata( - public_key.n(), public_key.e(), *public_metadata, - use_rsa_public_exponent)); - } - - return absl::WrapUnique(new RsaSsaPssVerifier(salt_length, public_metadata, - sig_hash, mgf1_hash, - std::move(rsa_public_key))); -} - -RsaSsaPssVerifier::RsaSsaPssVerifier( - int salt_length, std::optional<absl::string_view> public_metadata, - const EVP_MD* sig_hash, const EVP_MD* mgf1_hash, - bssl::UniquePtr<RSA> rsa_public_key) - : salt_length_(salt_length), - public_metadata_(public_metadata), - sig_hash_(sig_hash), - mgf1_hash_(mgf1_hash), - rsa_public_key_(std::move(rsa_public_key)) {} - -absl::Status RsaSsaPssVerifier::Verify(absl::string_view unblind_token, - absl::string_view message) { - std::string augmented_message(message); - if (public_metadata_.has_value()) { - augmented_message = EncodeMessagePublicMetadata(message, *public_metadata_); - } - return RsaBlindSignatureVerify(salt_length_, sig_hash_, mgf1_hash_, - unblind_token, augmented_message, - rsa_public_key_.get()); -} - -} // namespace anonymous_tokens -} // namespace private_membership
diff --git a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_ssa_pss_verifier.h b/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_ssa_pss_verifier.h deleted file mode 100644 index 9026ba0..0000000 --- a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_ssa_pss_verifier.h +++ /dev/null
@@ -1,83 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef THIRD_PARTY_ANONYMOUS_TOKENS_CPP_CRYPTO_RSA_SSA_PSS_VERIFIER_H_ -#define THIRD_PARTY_ANONYMOUS_TOKENS_CPP_CRYPTO_RSA_SSA_PSS_VERIFIER_H_ - -#include <stdint.h> - -#include <memory> -#include <optional> - -#include "absl/status/status.h" -#include "absl/status/statusor.h" -#include "absl/strings/string_view.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/crypto_utils.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/verifier.h" -#include "quiche/blind_sign_auth/anonymous_tokens/proto/anonymous_tokens.pb.h" -#include "quiche/common/platform/api/quiche_export.h" -// copybara:strip_begin(internal comment) -// The QUICHE_EXPORT annotation is necessary for some classes and functions -// to link correctly on Windows. Please do not remove them! -// copybara:strip_end - -namespace private_membership { -namespace anonymous_tokens { - -// RsaSsaPssVerifier is able to verify an unblinded token (signature) against an -// inputted message using a public key and other input parameters. -class QUICHE_EXPORT RsaSsaPssVerifier : public Verifier { - public: - // Passing of public_metadata is optional. If it is set to any value including - // an empty string, RsaSsaPssVerifier will assume that partially blind RSA - // signature protocol is being executed. - // - // If public metadata is passed and the boolean "use_rsa_public_exponent" is - // set to false, the public exponent in the public_key is not used in any - // computations in the protocol. - // - // Setting "use_rsa_public_exponent" to true is deprecated. All new users - // should set it to false. - static absl::StatusOr<std::unique_ptr<RsaSsaPssVerifier>> New( - int salt_length, const EVP_MD* sig_hash, const EVP_MD* mgf1_hash, - const RSAPublicKey& public_key, bool use_rsa_public_exponent, - std::optional<absl::string_view> public_metadata = std::nullopt); - - // Verifies the signature. - // - // Returns OkStatus() on successful verification. Otherwise returns an error. - absl::Status Verify(absl::string_view unblind_token, - absl::string_view message) override; - - private: - // Use `New` to construct - RsaSsaPssVerifier(int salt_length, - std::optional<absl::string_view> public_metadata, - const EVP_MD* sig_hash, const EVP_MD* mgf1_hash, - bssl::UniquePtr<RSA> rsa_public_key); - - const int salt_length_; - std::optional<std::string> public_metadata_; - const EVP_MD* const sig_hash_; // Owned by BoringSSL. - const EVP_MD* const mgf1_hash_; // Owned by BoringSSL. - - // If public metadata is passed to RsaSsaPssVerifier::New, rsa_public_key_ - // will be initialized using RSA_new_public_key_large_e method. - const bssl::UniquePtr<RSA> rsa_public_key_; -}; - -} // namespace anonymous_tokens -} // namespace private_membership - -#endif // THIRD_PARTY_ANONYMOUS_TOKENS_CPP_CRYPTO_RSA_SSA_PSS_VERIFIER_H_
diff --git a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_ssa_pss_verifier_test.cc b/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_ssa_pss_verifier_test.cc deleted file mode 100644 index 3542627..0000000 --- a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_ssa_pss_verifier_test.cc +++ /dev/null
@@ -1,332 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_ssa_pss_verifier.h" - -#include <memory> -#include <string> -#include <utility> - -#include "quiche/common/platform/api/quiche_test.h" -#include "quiche/common/test_tools/quiche_test_utils.h" -#include "absl/status/status.h" -#include "absl/status/statusor.h" -#include "absl/strings/string_view.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/anonymous_tokens_pb_openssl_converters.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/constants.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/crypto_utils.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/testing/proto_utils.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/testing/utils.h" -#include "quiche/blind_sign_auth/anonymous_tokens/proto/anonymous_tokens.pb.h" -#include "openssl/rsa.h" - -namespace private_membership { -namespace anonymous_tokens { -namespace { - -// TODO(b/259581423): Add tests incorporating blinder and signer. -// TODO(b/275956922): Consolidate all tests that use IETF test vectors into one -// E2E test. -TEST(RsaSsaPssVerifier, SuccessfulVerification) { - const IetfStandardRsaBlindSignatureTestVector test_vec = - GetIetfStandardRsaBlindSignatureTestVector(); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(const auto test_keys, - GetIetfStandardRsaBlindSignatureTestKeys()); - const EVP_MD *sig_hash = EVP_sha384(); // Owned by BoringSSL - const EVP_MD *mgf1_hash = EVP_sha384(); // Owned by BoringSSL - const int salt_length = kSaltLengthInBytes48; - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - const auto verifier, - RsaSsaPssVerifier::New(salt_length, sig_hash, mgf1_hash, test_keys.first, - /*use_rsa_public_exponent=*/true)); - EXPECT_TRUE(verifier->Verify(test_vec.signature, test_vec.message).ok()); -} - -TEST(RsaSsaPssVerifier, InvalidSignature) { - const IetfStandardRsaBlindSignatureTestVector test_vec = - GetIetfStandardRsaBlindSignatureTestVector(); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(const auto test_keys, - GetIetfStandardRsaBlindSignatureTestKeys()); - const EVP_MD *sig_hash = EVP_sha384(); // Owned by BoringSSL - const EVP_MD *mgf1_hash = EVP_sha384(); // Owned by BoringSSL - const int salt_length = kSaltLengthInBytes48; - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - const auto verifier, - RsaSsaPssVerifier::New(salt_length, sig_hash, mgf1_hash, test_keys.first, - /*use_rsa_public_exponent=*/true)); - // corrupt signature - std::string wrong_sig = test_vec.signature; - wrong_sig.replace(10, 1, "x"); - - absl::Status verification_result = - verifier->Verify(wrong_sig, test_vec.message); - EXPECT_EQ(verification_result.code(), absl::StatusCode::kInvalidArgument); - EXPECT_THAT(verification_result.message(), - testing::HasSubstr("verification failed")); -} - -TEST(RsaSsaPssVerifier, InvalidVerificationKey) { - const IetfStandardRsaBlindSignatureTestVector test_vec = - GetIetfStandardRsaBlindSignatureTestVector(); - const EVP_MD *sig_hash = EVP_sha384(); // Owned by BoringSSL - const EVP_MD *mgf1_hash = EVP_sha384(); // Owned by BoringSSL - const int salt_length = kSaltLengthInBytes48; - // wrong key - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(auto new_keys_pair, GetStandardRsaKeyPair()); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - const auto verifier, - RsaSsaPssVerifier::New(salt_length, sig_hash, mgf1_hash, - new_keys_pair.first, - /*use_rsa_public_exponent=*/true)); - - absl::Status verification_result = - verifier->Verify(test_vec.signature, test_vec.message); - EXPECT_EQ(verification_result.code(), absl::StatusCode::kInvalidArgument); - EXPECT_THAT(verification_result.message(), - testing::HasSubstr("verification failed")); -} - -TEST(RsaSsaPssVerifierTestWithPublicMetadata, - EmptyMessageStandardVerificationSuccess) { - absl::string_view message = ""; - const EVP_MD *sig_hash = EVP_sha384(); // Owned by BoringSSL - const EVP_MD *mgf1_hash = EVP_sha384(); // Owned by BoringSSL - const int salt_length = kSaltLengthInBytes48; - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(const auto test_key, - GetStandardRsaKeyPair()); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - auto private_key, AnonymousTokensRSAPrivateKeyToRSA(test_key.second)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::string encoded_message, - EncodeMessageForTests(message, test_key.first, sig_hash, mgf1_hash, - salt_length)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::string potentially_insecure_signature, - TestSign(encoded_message, private_key.get())); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - auto verifier, - RsaSsaPssVerifier::New(salt_length, sig_hash, mgf1_hash, test_key.first, - /*use_rsa_public_exponent=*/true)); - EXPECT_TRUE(verifier->Verify(potentially_insecure_signature, message).ok()); -} - -// TODO(b/275956922): Consolidate all tests that use IETF test vectors into one -// E2E test. -TEST(RsaSsaPssVerifierTestWithPublicMetadata, - IetfRsaBlindSignaturesWithPublicMetadataTestVectorsSuccess) { - auto test_vectors = GetIetfRsaBlindSignatureWithPublicMetadataTestVectors(); - const EVP_MD *sig_hash = EVP_sha384(); // Owned by BoringSSL - const EVP_MD *mgf1_hash = EVP_sha384(); // Owned by BoringSSL - const int salt_length = kSaltLengthInBytes48; - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - const auto test_key, - GetIetfRsaBlindSignatureWithPublicMetadataTestKeys()); - for (const auto &test_vector : test_vectors) { - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - auto verifier, - RsaSsaPssVerifier::New(salt_length, sig_hash, mgf1_hash, test_key.first, - /*use_rsa_public_exponent=*/true, - test_vector.public_metadata)); - EXPECT_TRUE(verifier - ->Verify(test_vector.signature, - MaskMessageConcat(test_vector.message_mask, - test_vector.message)) - .ok()); - } -} - -TEST(RsaSsaPssVerifierTestWithPublicMetadata, - IetfRsaBlindSignaturesWithPublicMetadataNoPublicExponentSuccess) { - auto test_vectors = - GetIetfPartiallyBlindRSASignatureNoPublicExponentTestVectors(); - const EVP_MD *sig_hash = EVP_sha384(); // Owned by BoringSSL - const EVP_MD *mgf1_hash = EVP_sha384(); // Owned by BoringSSL - const int salt_length = kSaltLengthInBytes48; - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - const auto test_key, - GetIetfRsaBlindSignatureWithPublicMetadataTestKeys()); - for (const auto &test_vector : test_vectors) { - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - auto verifier, - RsaSsaPssVerifier::New(salt_length, sig_hash, mgf1_hash, test_key.first, - /*use_rsa_public_exponent=*/false, - test_vector.public_metadata)); - EXPECT_TRUE( - verifier->Verify(test_vector.signature, test_vector.message).ok()); - } -} - -using RsaSsaPssVerifierPublicMetadataTestParams = - std::tuple<absl::StatusOr<std::pair<RSAPublicKey, RSAPrivateKey>>, - /*use_rsa_public_exponent*/ bool>; - -class RsaSsaPssVerifierTestWithPublicMetadata - : public ::testing::TestWithParam< - RsaSsaPssVerifierPublicMetadataTestParams> { - protected: - void SetUp() override { - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(auto keys_pair, std::get<0>(GetParam())); - use_rsa_public_exponent_ = std::get<1>(GetParam()); - public_key_ = std::move(keys_pair.first); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - private_key_, AnonymousTokensRSAPrivateKeyToRSA(keys_pair.second)); - // NOTE: using recommended RsaSsaPssParams - sig_hash_ = EVP_sha384(); - mgf1_hash_ = EVP_sha384(); - salt_length_ = kSaltLengthInBytes48; - } - - RSAPublicKey public_key_; - bssl::UniquePtr<RSA> private_key_; - const EVP_MD *sig_hash_; // Owned by BoringSSL. - const EVP_MD *mgf1_hash_; // Owned by BoringSSL. - int salt_length_; - bool use_rsa_public_exponent_; -}; - -// This test only tests whether the implemented verfier 'verifies' properly -// under some public metadata. The outline of method calls in this test should -// not be assumed a secure signature scheme (and used in other places) as the -// security has not been proven/analyzed. -TEST_P(RsaSsaPssVerifierTestWithPublicMetadata, - VerifierWorksWithPublicMetadata) { - absl::string_view message = "Hello World!"; - absl::string_view public_metadata = "pubmd!"; - std::string augmented_message = - EncodeMessagePublicMetadata(message, public_metadata); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::string encoded_message, - EncodeMessageForTests(augmented_message, public_key_, sig_hash_, - mgf1_hash_, salt_length_)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::string potentially_insecure_signature, - TestSignWithPublicMetadata(encoded_message, public_metadata, - *private_key_, use_rsa_public_exponent_)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - auto verifier, - RsaSsaPssVerifier::New(salt_length_, sig_hash_, mgf1_hash_, public_key_, - use_rsa_public_exponent_, public_metadata)); - EXPECT_TRUE(verifier->Verify(potentially_insecure_signature, message).ok()); -} - -TEST_P(RsaSsaPssVerifierTestWithPublicMetadata, - VerifierFailsToVerifyWithWrongPublicMetadata) { - absl::string_view message = "Hello World!"; - absl::string_view public_metadata = "pubmd!"; - absl::string_view public_metadata_2 = "pubmd2"; - std::string augmented_message = - EncodeMessagePublicMetadata(message, public_metadata); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::string encoded_message, - EncodeMessageForTests(augmented_message, public_key_, sig_hash_, - mgf1_hash_, salt_length_)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::string potentially_insecure_signature, - TestSignWithPublicMetadata(encoded_message, public_metadata, - *private_key_, use_rsa_public_exponent_)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - auto verifier, - RsaSsaPssVerifier::New(salt_length_, sig_hash_, mgf1_hash_, public_key_, - use_rsa_public_exponent_, public_metadata_2)); - absl::Status verification_result = - verifier->Verify(potentially_insecure_signature, message); - EXPECT_EQ(verification_result.code(), absl::StatusCode::kInvalidArgument); - EXPECT_THAT(verification_result.message(), - testing::HasSubstr("verification failed")); -} - -TEST_P(RsaSsaPssVerifierTestWithPublicMetadata, - VerifierFailsToVerifyWithEmptyPublicMetadata) { - absl::string_view message = "Hello World!"; - absl::string_view public_metadata = "pubmd!"; - absl::string_view empty_public_metadata = ""; - std::string augmented_message = - EncodeMessagePublicMetadata(message, public_metadata); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::string encoded_message, - EncodeMessageForTests(augmented_message, public_key_, sig_hash_, - mgf1_hash_, salt_length_)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::string potentially_insecure_signature, - TestSignWithPublicMetadata(encoded_message, public_metadata, - *private_key_, use_rsa_public_exponent_)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - auto verifier, - RsaSsaPssVerifier::New(salt_length_, sig_hash_, mgf1_hash_, public_key_, - use_rsa_public_exponent_, empty_public_metadata)); - absl::Status verification_result = - verifier->Verify(potentially_insecure_signature, message); - EXPECT_EQ(verification_result.code(), absl::StatusCode::kInvalidArgument); - EXPECT_THAT(verification_result.message(), - testing::HasSubstr("verification failed")); -} - -TEST_P(RsaSsaPssVerifierTestWithPublicMetadata, - VerifierFailsToVerifyWithoutPublicMetadataSupport) { - absl::string_view message = "Hello World!"; - absl::string_view public_metadata = "pubmd!"; - std::string augmented_message = - EncodeMessagePublicMetadata(message, public_metadata); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::string encoded_message, - EncodeMessageForTests(augmented_message, public_key_, sig_hash_, - mgf1_hash_, salt_length_)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::string potentially_insecure_signature, - TestSignWithPublicMetadata(encoded_message, public_metadata, - *private_key_, use_rsa_public_exponent_)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - auto verifier, - RsaSsaPssVerifier::New(salt_length_, sig_hash_, mgf1_hash_, public_key_, - use_rsa_public_exponent_)); - absl::Status verification_result = - verifier->Verify(potentially_insecure_signature, message); - EXPECT_EQ(verification_result.code(), absl::StatusCode::kInvalidArgument); - EXPECT_THAT(verification_result.message(), - testing::HasSubstr("verification failed")); -} - -TEST_P(RsaSsaPssVerifierTestWithPublicMetadata, - EmptyMessageEmptyPublicMetadataVerificationSuccess) { - absl::string_view message = ""; - absl::string_view public_metadata = ""; - std::string augmented_message = - EncodeMessagePublicMetadata(message, public_metadata); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::string encoded_message, - EncodeMessageForTests(augmented_message, public_key_, sig_hash_, - mgf1_hash_, salt_length_)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - std::string potentially_insecure_signature, - TestSignWithPublicMetadata(encoded_message, public_metadata, - *private_key_.get(), - use_rsa_public_exponent_)); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - auto verifier, - RsaSsaPssVerifier::New(salt_length_, sig_hash_, mgf1_hash_, public_key_, - use_rsa_public_exponent_, public_metadata)); - EXPECT_TRUE(verifier->Verify(potentially_insecure_signature, message).ok()); -} - -INSTANTIATE_TEST_SUITE_P( - RsaSsaPssVerifierTestWithPublicMetadata, - RsaSsaPssVerifierTestWithPublicMetadata, - ::testing::Combine( - ::testing::Values(GetStrongRsaKeys2048(), GetAnotherStrongRsaKeys2048(), - GetStrongRsaKeys3072(), GetStrongRsaKeys4096()), - /*use_rsa_public_exponent*/ ::testing::Values(true, false))); - -} // namespace -} // namespace anonymous_tokens -} // namespace private_membership
diff --git a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/verifier.h b/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/verifier.h deleted file mode 100644 index 14e3d2f..0000000 --- a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/verifier.h +++ /dev/null
@@ -1,29 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef THIRD_PARTY_ANONYMOUS_TOKENS_CPP_CRYPTO_VERIFIER_H_ -#define THIRD_PARTY_ANONYMOUS_TOKENS_CPP_CRYPTO_VERIFIER_H_ - -#include "absl/status/status.h" -#include "absl/strings/string_view.h" - -class Verifier { - public: - virtual absl::Status Verify(absl::string_view signature, - absl::string_view message) = 0; - - virtual ~Verifier() = default; -}; - -#endif // THIRD_PARTY_ANONYMOUS_TOKENS_CPP_CRYPTO_VERIFIER_H_
diff --git a/quiche/blind_sign_auth/anonymous_tokens/cpp/shared/proto_utils.cc b/quiche/blind_sign_auth/anonymous_tokens/cpp/shared/proto_utils.cc deleted file mode 100644 index f311d3c..0000000 --- a/quiche/blind_sign_auth/anonymous_tokens/cpp/shared/proto_utils.cc +++ /dev/null
@@ -1,70 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/shared/proto_utils.h" - -#include "absl/status/status.h" -#include "absl/status/statusor.h" -#include "absl/strings/str_cat.h" -#include "absl/strings/string_view.h" -#include "absl/time/time.h" - -namespace private_membership { -namespace anonymous_tokens { - -absl::StatusOr<AnonymousTokensUseCase> ParseUseCase( - absl::string_view use_case) { - AnonymousTokensUseCase parsed_use_case; - if (!AnonymousTokensUseCase_Parse(std::string(use_case), &parsed_use_case) || - parsed_use_case == ANONYMOUS_TOKENS_USE_CASE_UNDEFINED) { - return absl::InvalidArgumentError( - "Invalid / undefined use case cannot be parsed."); - } - return parsed_use_case; -} - -absl::StatusOr<absl::Time> TimeFromProto( - const private_membership::anonymous_tokens::Timestamp& proto) { - const auto sec = proto.seconds(); - const auto ns = proto.nanos(); - // sec must be [0001-01-01T00:00:00Z, 9999-12-31T23:59:59.999999999Z] - if (sec < -62135596800 || sec > 253402300799) { - return absl::InvalidArgumentError(absl::StrCat("seconds=", sec)); - } - if (ns < 0 || ns > 999999999) { - return absl::InvalidArgumentError(absl::StrCat("nanos=", ns)); - } - return absl::FromUnixSeconds(proto.seconds()) + - absl::Nanoseconds(proto.nanos()); -} - -absl::StatusOr<private_membership::anonymous_tokens::Timestamp> TimeToProto(absl::Time time) { - private_membership::anonymous_tokens::Timestamp proto; - const int64_t seconds = absl::ToUnixSeconds(time); - proto.set_seconds(seconds); - proto.set_nanos((time - absl::FromUnixSeconds(seconds)) / - absl::Nanoseconds(1)); - // seconds must be [0001-01-01T00:00:00Z, 9999-12-31T23:59:59.999999999Z] - if (seconds < -62135596800 || seconds > 253402300799) { - return absl::InvalidArgumentError(absl::StrCat("seconds=", seconds)); - } - const int64_t ns = proto.nanos(); - if (ns < 0 || ns > 999999999) { - return absl::InvalidArgumentError(absl::StrCat("nanos=", ns)); - } - return proto; -} - -} // namespace anonymous_tokens -} // namespace private_membership
diff --git a/quiche/blind_sign_auth/anonymous_tokens/cpp/shared/proto_utils.h b/quiche/blind_sign_auth/anonymous_tokens/cpp/shared/proto_utils.h deleted file mode 100644 index f510516..0000000 --- a/quiche/blind_sign_auth/anonymous_tokens/cpp/shared/proto_utils.h +++ /dev/null
@@ -1,53 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef THIRD_PARTY_ANONYMOUS_TOKENS_CPP_SHARED_PROTO_UTILS_H_ -#define THIRD_PARTY_ANONYMOUS_TOKENS_CPP_SHARED_PROTO_UTILS_H_ - -#include "quiche/blind_sign_auth/anonymous_tokens/proto/anonymous_tokens.pb.h" -#include "absl/status/statusor.h" -#include "absl/strings/string_view.h" -#include "absl/time/time.h" -#include "quiche/blind_sign_auth/anonymous_tokens/proto/anonymous_tokens.pb.h" -#include "quiche/common/platform/api/quiche_export.h" -// copybara:strip_begin(internal comment) -// The QUICHE_EXPORT annotation is necessary for some classes and functions -// to link correctly on Windows. Please do not remove them! -// copybara:strip_end - -namespace private_membership { -namespace anonymous_tokens { - -// Returns AnonymousTokensUseCase parsed from a string_view. -absl::StatusOr<AnonymousTokensUseCase> QUICHE_EXPORT ParseUseCase( - absl::string_view use_case); - -// Takes in private_membership::anonymous_tokens::Timestamp and converts it to absl::Time. -// -// Timestamp is defined here: -// https://developers.google.com/protocol-buffers/docs/reference/private_membership.anonymous_tokens#timestamp -absl::StatusOr<absl::Time> QUICHE_EXPORT TimeFromProto( - const private_membership::anonymous_tokens::Timestamp& proto); - -// Takes in absl::Time and converts it to private_membership::anonymous_tokens::Timestamp. -// -// Timestamp is defined here: -// https://developers.google.com/protocol-buffers/docs/reference/private_membership.anonymous_tokens#timestamp -absl::StatusOr<private_membership::anonymous_tokens::Timestamp> QUICHE_EXPORT TimeToProto( - absl::Time time); - -} // namespace anonymous_tokens -} // namespace private_membership - -#endif // THIRD_PARTY_ANONYMOUS_TOKENS_CPP_SHARED_PROTO_UTILS_H_
diff --git a/quiche/blind_sign_auth/anonymous_tokens/cpp/shared/proto_utils_test.cc b/quiche/blind_sign_auth/anonymous_tokens/cpp/shared/proto_utils_test.cc deleted file mode 100644 index 5018734..0000000 --- a/quiche/blind_sign_auth/anonymous_tokens/cpp/shared/proto_utils_test.cc +++ /dev/null
@@ -1,93 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/shared/proto_utils.h" - -#include "quiche/blind_sign_auth/anonymous_tokens/proto/anonymous_tokens.pb.h" -#include "quiche/common/platform/api/quiche_test.h" -#include "quiche/common/test_tools/quiche_test_utils.h" -#include "absl/status/status.h" -#include "absl/status/statusor.h" -#include "absl/time/time.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/testing/utils.h" -#include "quiche/blind_sign_auth/anonymous_tokens/proto/anonymous_tokens.pb.h" - -namespace private_membership { -namespace anonymous_tokens { -namespace { - -TEST(ProtoUtilsTest, EmptyUseCase) { - EXPECT_THAT(ParseUseCase("").status().code(), - absl::StatusCode::kInvalidArgument); -} - -TEST(ProtoUtilsTest, InvalidUseCase) { - EXPECT_THAT(ParseUseCase("NOT_A_USE_CASE").status().code(), - absl::StatusCode::kInvalidArgument); -} - -TEST(ProtoUtilsTest, UndefinedUseCase) { - EXPECT_THAT( - ParseUseCase("ANONYMOUS_TOKENS_USE_CASE_UNDEFINED").status().code(), - absl::StatusCode::kInvalidArgument); -} - -TEST(ProtoUtilsTest, ValidUseCase) { - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(AnonymousTokensUseCase use_case, - ParseUseCase("TEST_USE_CASE")); - EXPECT_EQ(use_case, AnonymousTokensUseCase::TEST_USE_CASE); -} - -TEST(ProtoUtilsTest, TimeFromProtoGood) { - private_membership::anonymous_tokens::Timestamp timestamp; - timestamp.set_seconds(1234567890); - timestamp.set_nanos(12345); - ANON_TOKENS_ASSERT_OK_AND_ASSIGN(absl::Time time, TimeFromProto(timestamp)); - ASSERT_EQ(time, absl::FromUnixNanos(1234567890000012345)); -} - -TEST(ProtoUtilsTest, TimeFromProtoBad) { - private_membership::anonymous_tokens::Timestamp proto; - proto.set_nanos(-1); - EXPECT_THAT(TimeFromProto(proto).status().code(), - absl::StatusCode::kInvalidArgument); - - proto.set_nanos(0); - proto.set_seconds(253402300800); - EXPECT_THAT(TimeFromProto(proto).status().code(), - absl::StatusCode::kInvalidArgument); -} - -TEST(ProtoUtilsTest, TimeToProtoGood) { - private_membership::anonymous_tokens::Timestamp proto; - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - proto, TimeToProto(absl::FromUnixSeconds(1596762373))); - EXPECT_EQ(proto.seconds(), 1596762373); - EXPECT_EQ(proto.nanos(), 0); - - ANON_TOKENS_ASSERT_OK_AND_ASSIGN( - proto, TimeToProto(absl::FromUnixMillis(1596762373123L))); - EXPECT_EQ(proto.seconds(), 1596762373); - EXPECT_EQ(proto.nanos(), 123000000); -} - -TEST(ProtoUtilsTest, TimeToProtoBad) { - absl::StatusOr<private_membership::anonymous_tokens::Timestamp> proto; - proto = TimeToProto(absl::FromUnixSeconds(253402300800)); - EXPECT_THAT(proto.status().code(), absl::StatusCode::kInvalidArgument); -} - -} // namespace -} // namespace anonymous_tokens -} // namespace private_membership
diff --git a/quiche/blind_sign_auth/anonymous_tokens/cpp/shared/status_utils.h b/quiche/blind_sign_auth/anonymous_tokens/cpp/shared/status_utils.h deleted file mode 100644 index bcdddf6..0000000 --- a/quiche/blind_sign_auth/anonymous_tokens/cpp/shared/status_utils.h +++ /dev/null
@@ -1,49 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef THIRD_PARTY_ANONYMOUS_TOKENS_CPP_SHARED_STATUS_UTILS_H_ -#define THIRD_PARTY_ANONYMOUS_TOKENS_CPP_SHARED_STATUS_UTILS_H_ - -#include "absl/base/optimization.h" -#include "absl/status/status.h" - -namespace private_membership { -namespace anonymous_tokens { - -#define _ANON_TOKENS_STATUS_MACROS_CONCAT_NAME(x, y) \ - _ANON_TOKENS_STATUS_MACROS_CONCAT_IMPL(x, y) -#define _ANON_TOKENS_STATUS_MACROS_CONCAT_IMPL(x, y) x##y - -#define ANON_TOKENS_ASSIGN_OR_RETURN(lhs, rexpr) \ - _ANON_TOKENS_ASSIGN_OR_RETURN_IMPL( \ - _ANON_TOKENS_STATUS_MACROS_CONCAT_NAME(_status_or_val, __LINE__), lhs, \ - rexpr) - -#define _ANON_TOKENS_ASSIGN_OR_RETURN_IMPL(statusor, lhs, rexpr) \ - auto statusor = (rexpr); \ - if (ABSL_PREDICT_FALSE(!statusor.ok())) { \ - return statusor.status(); \ - } \ - lhs = *std::move(statusor) - -#define ANON_TOKENS_RETURN_IF_ERROR(expr) \ - do { \ - auto _status = (expr); \ - if (ABSL_PREDICT_FALSE(!_status.ok())) return _status; \ - } while (0) - -} // namespace anonymous_tokens -} // namespace private_membership - -#endif // THIRD_PARTY_ANONYMOUS_TOKENS_CPP_SHARED_STATUS_UTILS_H_
diff --git a/quiche/blind_sign_auth/anonymous_tokens/cpp/testing/proto_utils.cc b/quiche/blind_sign_auth/anonymous_tokens/cpp/testing/proto_utils.cc deleted file mode 100644 index 0f1daf7..0000000 --- a/quiche/blind_sign_auth/anonymous_tokens/cpp/testing/proto_utils.cc +++ /dev/null
@@ -1,293 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/testing/proto_utils.h" - -#include <cstdint> -#include <fstream> -#include <ios> -#include <sstream> -#include <string> -#include <utility> -#include <vector> - -#include "absl/status/status.h" -#include "absl/status/statusor.h" -#include "absl/strings/str_cat.h" -#include "absl/strings/string_view.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/constants.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/crypto_utils.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/shared/status_utils.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/testing/testdata_utils.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/testing/utils.h" -#include "quiche/blind_sign_auth/anonymous_tokens/proto/anonymous_tokens.pb.h" -#include "openssl/base.h" -#include "openssl/bn.h" -#include "openssl/rsa.h" - -namespace private_membership { -namespace anonymous_tokens { - -namespace { - -absl::StatusOr<std::string> ReadFileToString(absl::string_view path) { - std::ifstream file(std::string(path), std::ios::binary); - if (!file.is_open()) { - return absl::InternalError("Reading file failed."); - } - std::ostringstream ss(std::ios::binary); - ss << file.rdbuf(); - return ss.str(); -} - -absl::StatusOr<std::pair<RSAPublicKey, RSAPrivateKey>> ParseRsaKeysFromFile( - absl::string_view path) { - ANON_TOKENS_ASSIGN_OR_RETURN(std::string binary_proto, - ReadFileToString(path)); - RSAPrivateKey private_key; - if (!private_key.ParseFromString(binary_proto)) { - return absl::InternalError("Parsing binary proto failed."); - } - RSAPublicKey public_key; - public_key.set_n(private_key.n()); - public_key.set_e(private_key.e()); - return std::make_pair(std::move(public_key), std::move(private_key)); -} - -absl::StatusOr<bssl::UniquePtr<RSA>> GenerateRSAKey(int modulus_bit_size, - const BIGNUM& e) { - bssl::UniquePtr<RSA> rsa(RSA_new()); - if (!rsa.get()) { - return absl::InternalError( - absl::StrCat("RSA_new failed: ", GetSslErrors())); - } - if (RSA_generate_key_ex(rsa.get(), modulus_bit_size, &e, - /*cb=*/nullptr) != kBsslSuccess) { - return absl::InternalError( - absl::StrCat("Error generating private key: ", GetSslErrors())); - } - return rsa; -} - -absl::StatusOr<std::pair<RSAPublicKey, RSAPrivateKey>> PopulateTestVectorKeys( - const std::string& n, const std::string& e, const std::string& d, - const std::string& p, const std::string& q) { - RSAPublicKey public_key; - RSAPrivateKey private_key; - - public_key.set_n(n); - public_key.set_e(e); - - private_key.set_n(n); - private_key.set_e(e); - private_key.set_d(d); - private_key.set_p(p); - private_key.set_q(q); - - // Computing CRT parameters - ANON_TOKENS_ASSIGN_OR_RETURN(BnCtxPtr bn_ctx, GetAndStartBigNumCtx()); - ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> dp_bn, NewBigNum()); - ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> dq_bn, NewBigNum()); - ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> crt_bn, NewBigNum()); - - // p - 1 - ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> pm1, StringToBignum(p)); - BN_sub_word(pm1.get(), 1); - // q - 1 - ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> qm1, StringToBignum(q)); - BN_sub_word(qm1.get(), 1); - // d mod p-1 - ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> d_bn, StringToBignum(d)); - BN_mod(dp_bn.get(), d_bn.get(), pm1.get(), bn_ctx.get()); - // d mod q-1 - BN_mod(dq_bn.get(), d_bn.get(), qm1.get(), bn_ctx.get()); - // crt q^(-1) mod p - ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> q_bn, StringToBignum(q)); - ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> p_bn, StringToBignum(p)); - BN_mod_inverse(crt_bn.get(), q_bn.get(), p_bn.get(), bn_ctx.get()); - - // Populating crt params in private key - ANON_TOKENS_ASSIGN_OR_RETURN( - std::string dp_str, BignumToString(*dp_bn, BN_num_bytes(dp_bn.get()))); - ANON_TOKENS_ASSIGN_OR_RETURN( - std::string dq_str, BignumToString(*dq_bn, BN_num_bytes(dq_bn.get()))); - ANON_TOKENS_ASSIGN_OR_RETURN( - std::string crt_str, BignumToString(*crt_bn, BN_num_bytes(crt_bn.get()))); - private_key.set_dp(dp_str); - private_key.set_dq(dq_str); - private_key.set_crt(crt_str); - - return std::make_pair(std::move(public_key), std::move(private_key)); -} - -} // namespace - -absl::StatusOr<std::pair<bssl::UniquePtr<RSA>, RSABlindSignaturePublicKey>> -CreateTestKey(int key_size, HashType sig_hash, MaskGenFunction mfg1_hash, - int salt_length, MessageMaskType message_mask_type, - int message_mask_size) { - ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> rsa_f4, NewBigNum()); - BN_set_u64(rsa_f4.get(), RSA_F4); - - ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<RSA> rsa_key, - GenerateRSAKey(key_size * 8, *rsa_f4)); - - RSAPublicKey rsa_public_key; - ANON_TOKENS_ASSIGN_OR_RETURN( - *rsa_public_key.mutable_n(), - BignumToString(*RSA_get0_n(rsa_key.get()), key_size)); - ANON_TOKENS_ASSIGN_OR_RETURN( - *rsa_public_key.mutable_e(), - BignumToString(*RSA_get0_e(rsa_key.get()), key_size)); - - RSABlindSignaturePublicKey public_key; - public_key.set_serialized_public_key(rsa_public_key.SerializeAsString()); - public_key.set_sig_hash_type(sig_hash); - public_key.set_mask_gen_function(mfg1_hash); - public_key.set_salt_length(salt_length); - public_key.set_key_size(key_size); - public_key.set_message_mask_type(message_mask_type); - public_key.set_message_mask_size(message_mask_size); - - return std::make_pair(std::move(rsa_key), std::move(public_key)); -} - -absl::StatusOr<std::string> EncodeMessageForTests(absl::string_view message, - RSAPublicKey public_key, - const EVP_MD* sig_hasher, - const EVP_MD* mgf1_hasher, - int32_t salt_length) { - ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> rsa_modulus, - StringToBignum(public_key.n())); - ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> e, - StringToBignum(public_key.e())); - // Convert to OpenSSL RSA. - bssl::UniquePtr<RSA> rsa_public_key(RSA_new()); - if (!rsa_public_key.get()) { - return absl::InternalError( - absl::StrCat("RSA_new failed: ", GetSslErrors())); - } else if (RSA_set0_key(rsa_public_key.get(), rsa_modulus.release(), - e.release(), nullptr) != kBsslSuccess) { - return absl::InternalError( - absl::StrCat("RSA_set0_key failed: ", GetSslErrors())); - } - - const int padded_len = RSA_size(rsa_public_key.get()); - std::vector<uint8_t> padded(padded_len); - ANON_TOKENS_ASSIGN_OR_RETURN(std::string digest, - ComputeHash(message, *sig_hasher)); - if (RSA_padding_add_PKCS1_PSS_mgf1( - /*rsa=*/rsa_public_key.get(), /*EM=*/padded.data(), - /*mHash=*/reinterpret_cast<uint8_t*>(&digest[0]), /*Hash=*/sig_hasher, - /*mgf1Hash=*/mgf1_hasher, - /*sLen=*/salt_length) != kBsslSuccess) { - return absl::InternalError( - "RSA_padding_add_PKCS1_PSS_mgf1 failed when called from " - "testing_utils"); - } - std::string encoded_message(padded.begin(), padded.end()); - return encoded_message; -} - -absl::StatusOr<std::pair<RSAPublicKey, RSAPrivateKey>> GetStandardRsaKeyPair( - int modulus_size_in_bytes) { - ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> rsa_f4, NewBigNum()); - BN_set_u64(rsa_f4.get(), RSA_F4); - ANON_TOKENS_ASSIGN_OR_RETURN( - bssl::UniquePtr<RSA> rsa_key, - GenerateRSAKey(modulus_size_in_bytes * 8, *rsa_f4)); - - RSAPublicKey rsa_public_key; - ANON_TOKENS_ASSIGN_OR_RETURN( - *rsa_public_key.mutable_n(), - BignumToString(*RSA_get0_n(rsa_key.get()), modulus_size_in_bytes)); - ANON_TOKENS_ASSIGN_OR_RETURN( - *rsa_public_key.mutable_e(), - BignumToString(*RSA_get0_e(rsa_key.get()), modulus_size_in_bytes)); - - RSAPrivateKey rsa_private_key; - ANON_TOKENS_ASSIGN_OR_RETURN( - *rsa_private_key.mutable_n(), - BignumToString(*RSA_get0_n(rsa_key.get()), modulus_size_in_bytes)); - ANON_TOKENS_ASSIGN_OR_RETURN( - *rsa_private_key.mutable_e(), - BignumToString(*RSA_get0_e(rsa_key.get()), modulus_size_in_bytes)); - ANON_TOKENS_ASSIGN_OR_RETURN( - *rsa_private_key.mutable_d(), - BignumToString(*RSA_get0_d(rsa_key.get()), modulus_size_in_bytes)); - ANON_TOKENS_ASSIGN_OR_RETURN( - *rsa_private_key.mutable_p(), - BignumToString(*RSA_get0_p(rsa_key.get()), modulus_size_in_bytes)); - ANON_TOKENS_ASSIGN_OR_RETURN( - *rsa_private_key.mutable_q(), - BignumToString(*RSA_get0_q(rsa_key.get()), modulus_size_in_bytes)); - ANON_TOKENS_ASSIGN_OR_RETURN( - *rsa_private_key.mutable_dp(), - BignumToString(*RSA_get0_dmp1(rsa_key.get()), modulus_size_in_bytes)); - ANON_TOKENS_ASSIGN_OR_RETURN( - *rsa_private_key.mutable_dq(), - BignumToString(*RSA_get0_dmq1(rsa_key.get()), modulus_size_in_bytes)); - ANON_TOKENS_ASSIGN_OR_RETURN( - *rsa_private_key.mutable_crt(), - BignumToString(*RSA_get0_iqmp(rsa_key.get()), modulus_size_in_bytes)); - - return std::make_pair(std::move(rsa_public_key), std::move(rsa_private_key)); -} - -absl::StatusOr<std::pair<RSAPublicKey, RSAPrivateKey>> GetStrongRsaKeys2048() { - std::string path = absl::StrCat(::anonymous_tokens::GetTestdataPath(), - "/anonymous_tokens/testdata/strong_rsa_modulus2048_example.binarypb"); - ANON_TOKENS_ASSIGN_OR_RETURN(auto key_pair, ParseRsaKeysFromFile(path)); - return std::make_pair(std::move(key_pair.first), std::move(key_pair.second)); -} - -absl::StatusOr<std::pair<RSAPublicKey, RSAPrivateKey>> -GetAnotherStrongRsaKeys2048() { - std::string path = absl::StrCat(::anonymous_tokens::GetTestdataPath(), - "/anonymous_tokens/testdata/strong_rsa_modulus2048_example_2.binarypb"); - ANON_TOKENS_ASSIGN_OR_RETURN(auto key_pair, ParseRsaKeysFromFile(path)); - return std::make_pair(std::move(key_pair.first), std::move(key_pair.second)); -} - -absl::StatusOr<std::pair<RSAPublicKey, RSAPrivateKey>> GetStrongRsaKeys3072() { - std::string path = absl::StrCat(::anonymous_tokens::GetTestdataPath(), - "/anonymous_tokens/testdata/strong_rsa_modulus3072_example.binarypb"); - ANON_TOKENS_ASSIGN_OR_RETURN(auto key_pair, ParseRsaKeysFromFile(path)); - return std::make_pair(std::move(key_pair.first), std::move(key_pair.second)); -} - -absl::StatusOr<std::pair<RSAPublicKey, RSAPrivateKey>> GetStrongRsaKeys4096() { - std::string path = absl::StrCat(::anonymous_tokens::GetTestdataPath(), - "/anonymous_tokens/testdata/strong_rsa_modulus4096_example.binarypb"); - ANON_TOKENS_ASSIGN_OR_RETURN(auto key_pair, ParseRsaKeysFromFile(path)); - return std::make_pair(std::move(key_pair.first), std::move(key_pair.second)); -} - -absl::StatusOr<std::pair<RSAPublicKey, RSAPrivateKey>> -GetIetfStandardRsaBlindSignatureTestKeys() { - IetfStandardRsaBlindSignatureTestVector test_vector = - GetIetfStandardRsaBlindSignatureTestVector(); - return PopulateTestVectorKeys(test_vector.n, test_vector.e, test_vector.d, - test_vector.p, test_vector.q); -} - -absl::StatusOr<std::pair<RSAPublicKey, RSAPrivateKey>> -GetIetfRsaBlindSignatureWithPublicMetadataTestKeys() { - auto test_vectors = GetIetfRsaBlindSignatureWithPublicMetadataTestVectors(); - return PopulateTestVectorKeys(test_vectors[0].n, test_vectors[0].e, - test_vectors[0].d, test_vectors[0].p, - test_vectors[0].q); -} - -} // namespace anonymous_tokens -} // namespace private_membership
diff --git a/quiche/blind_sign_auth/anonymous_tokens/cpp/testing/proto_utils.h b/quiche/blind_sign_auth/anonymous_tokens/cpp/testing/proto_utils.h deleted file mode 100644 index 1c4c193..0000000 --- a/quiche/blind_sign_auth/anonymous_tokens/cpp/testing/proto_utils.h +++ /dev/null
@@ -1,88 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef THIRD_PARTY_ANONYMOUS_TOKENS_CPP_TESTING_PROTO_UTILS_H_ -#define THIRD_PARTY_ANONYMOUS_TOKENS_CPP_TESTING_PROTO_UTILS_H_ - -#include <cstdint> -#include <string> -#include <utility> - -#include "absl/status/statusor.h" -#include "absl/strings/string_view.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/constants.h" -#include "quiche/blind_sign_auth/anonymous_tokens/proto/anonymous_tokens.pb.h" -#include "openssl/base.h" - -namespace private_membership { -namespace anonymous_tokens { - -// Creates a pair containing a standard RSA Private key and an Anonymous Tokens -// RSABlindSignaturePublicKey using RSA_F4 (65537) as the public exponent and -// other input parameters. -// -// The standard key pair produced by this method should only be used to test -// standard RSA Blind Signatures. For testing RSA Blind Signatures with Public -// Metadata please use RSA keys with strong RSA moduli. -absl::StatusOr<std::pair<bssl::UniquePtr<RSA>, RSABlindSignaturePublicKey>> -CreateTestKey(int key_size = 512, HashType sig_hash = AT_HASH_TYPE_SHA384, - MaskGenFunction mfg1_hash = AT_MGF_SHA384, int salt_length = 48, - MessageMaskType message_mask_type = AT_MESSAGE_MASK_CONCAT, - int message_mask_size = kRsaMessageMaskSizeInBytes32); - -// Prepares message for signing by computing its hash and then applying the PSS -// padding to the result by executing RSA_padding_add_PKCS1_PSS_mgf1 from the -// openssl library, using the input parameters. -// -// This is a test function and it skips the message blinding part. -absl::StatusOr<std::string> EncodeMessageForTests(absl::string_view message, - RSAPublicKey public_key, - const EVP_MD* sig_hasher, - const EVP_MD* mgf1_hasher, - int32_t salt_length); - -// This method returns a newly generated RSA key pair, setting the public -// exponent to be the standard RSA_F4 (65537) and the default modulus size to -// 512 bytes. -absl::StatusOr<std::pair<RSAPublicKey, RSAPrivateKey>> GetStandardRsaKeyPair( - int modulus_size_in_bytes = kRsaModulusSizeInBytes512); - -// Method returns fixed 2048-bit strong RSA modulus for testing. -absl::StatusOr<std::pair<RSAPublicKey, RSAPrivateKey>> GetStrongRsaKeys2048(); - -// Method returns another fixed 2048-bit strong RSA modulus for testing. -absl::StatusOr<std::pair<RSAPublicKey, RSAPrivateKey>> -GetAnotherStrongRsaKeys2048(); - -// Method returns fixed 3072-bit strong RSA modulus for testing. -absl::StatusOr<std::pair<RSAPublicKey, RSAPrivateKey>> GetStrongRsaKeys3072(); - -// Method returns fixed 4096-bit strong RSA modulus for testing. -absl::StatusOr<std::pair<RSAPublicKey, RSAPrivateKey>> GetStrongRsaKeys4096(); - -// This method returns a RSA key pair as described in the IETF test example -// above. -absl::StatusOr<std::pair<RSAPublicKey, RSAPrivateKey>> -GetIetfStandardRsaBlindSignatureTestKeys(); - -// This method returns a RSA key pair as described in the IETF test with Public -// Metadata example. It can be used for all test vectors returned by -// GetIetfRsaBlindSignatureWithPublicMetadataTestVectors. -absl::StatusOr<std::pair<RSAPublicKey, RSAPrivateKey>> -GetIetfRsaBlindSignatureWithPublicMetadataTestKeys(); - -} // namespace anonymous_tokens -} // namespace private_membership - -#endif // THIRD_PARTY_ANONYMOUS_TOKENS_CPP_TESTING_PROTO_UTILS_H_
diff --git a/quiche/blind_sign_auth/anonymous_tokens/cpp/testing/testdata_utils.h b/quiche/blind_sign_auth/anonymous_tokens/cpp/testing/testdata_utils.h deleted file mode 100644 index b9ad465..0000000 --- a/quiche/blind_sign_auth/anonymous_tokens/cpp/testing/testdata_utils.h +++ /dev/null
@@ -1,33 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef THIRD_PARTY_ANONYMOUS_TOKENS_CPP_TESTING_TESTDATA_UTILS_H_ -#define THIRD_PARTY_ANONYMOUS_TOKENS_CPP_TESTING_TESTDATA_UTILS_H_ - -#include <string> - -#include "quiche/common/platform/api/quiche_test.h" - -namespace anonymous_tokens { - -// Note: This function is defined in a separate header so that other projects -// that use this library can easily provide their own implementation if the test -// data path is different. -inline std::string GetTestdataPath() { - return quiche::test::QuicheGetCommonSourcePath(); -} - -} // namespace anonymous_tokens - -#endif // THIRD_PARTY_ANONYMOUS_TOKENS_CPP_TESTING_TESTDATA_UTILS_H_
diff --git a/quiche/blind_sign_auth/anonymous_tokens/cpp/testing/utils.cc b/quiche/blind_sign_auth/anonymous_tokens/cpp/testing/utils.cc deleted file mode 100644 index 572f717..0000000 --- a/quiche/blind_sign_auth/anonymous_tokens/cpp/testing/utils.cc +++ /dev/null
@@ -1,1047 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/testing/utils.h" - -#include <cstddef> -#include <cstdint> -#include <random> -#include <string> -#include <utility> -#include <vector> - -#include "absl/status/status.h" -#include "absl/status/statusor.h" -#include "absl/strings/escaping.h" -#include "absl/strings/str_cat.h" -#include "absl/strings/string_view.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/constants.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/crypto_utils.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/shared/status_utils.h" -#include "quiche/common/platform/api/quiche_file_utils.h" -#include "quiche/common/platform/api/quiche_test.h" -#include "openssl/base.h" -#include "openssl/bn.h" -#include "openssl/rsa.h" - -namespace private_membership { -namespace anonymous_tokens { - -absl::StatusOr<std::string> TestSign(const absl::string_view blinded_data, - RSA* rsa_key) { - if (blinded_data.empty()) { - return absl::InvalidArgumentError("blinded_data string is empty."); - } - const size_t mod_size = RSA_size(rsa_key); - if (blinded_data.size() != mod_size) { - return absl::InternalError(absl::StrCat( - "Expected blind data size = ", mod_size, - " actual blind data size = ", blinded_data.size(), " bytes.")); - } - // Compute a raw RSA signature. - std::string signature(mod_size, 0); - size_t out_len; - if (RSA_sign_raw(/*rsa=*/rsa_key, /*out_len=*/&out_len, - /*out=*/reinterpret_cast<uint8_t*>(&signature[0]), - /*max_out=*/mod_size, - /*in=*/reinterpret_cast<const uint8_t*>(&blinded_data[0]), - /*in_len=*/mod_size, - /*padding=*/RSA_NO_PADDING) != kBsslSuccess) { - return absl::InternalError( - "RSA_sign_raw failed when called from RsaBlindSigner::Sign"); - } - if (out_len != mod_size || out_len != signature.size()) { - return absl::InternalError(absl::StrCat( - "Expected value of out_len and signature.size() = ", mod_size, - " bytes, actual value of out_len and signature.size() = ", out_len, - " and ", signature.size(), " bytes.")); - } - return signature; -} - -absl::StatusOr<std::string> TestSignWithPublicMetadata( - const absl::string_view blinded_data, absl::string_view public_metadata, - const RSA& rsa_key, const bool use_rsa_public_exponent) { - if (blinded_data.empty()) { - return absl::InvalidArgumentError("blinded_data string is empty."); - } else if (blinded_data.size() != RSA_size(&rsa_key)) { - return absl::InternalError(absl::StrCat( - "Expected blind data size = ", RSA_size(&rsa_key), - " actual blind data size = ", blinded_data.size(), " bytes.")); - } - // Compute new public exponent using the public metadata. - bssl::UniquePtr<BIGNUM> new_e; - if (use_rsa_public_exponent) { - ANON_TOKENS_ASSIGN_OR_RETURN( - new_e, - ComputeExponentWithPublicMetadataAndPublicExponent( - *RSA_get0_n(&rsa_key), *RSA_get0_e(&rsa_key), public_metadata)); - } else { - ANON_TOKENS_ASSIGN_OR_RETURN( - new_e, ComputeExponentWithPublicMetadata(*RSA_get0_n(&rsa_key), - public_metadata)); - } - - // Compute phi(p) = p-1 - ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> phi_p, NewBigNum()); - if (BN_sub(phi_p.get(), RSA_get0_p(&rsa_key), BN_value_one()) != 1) { - return absl::InternalError( - absl::StrCat("Unable to compute phi(p): ", GetSslErrors())); - } - // Compute phi(q) = q-1 - ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> phi_q, NewBigNum()); - if (BN_sub(phi_q.get(), RSA_get0_q(&rsa_key), BN_value_one()) != 1) { - return absl::InternalError( - absl::StrCat("Unable to compute phi(q): ", GetSslErrors())); - } - // Compute phi(n) = phi(p)*phi(q) - ANON_TOKENS_ASSIGN_OR_RETURN(auto ctx, GetAndStartBigNumCtx()); - ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> phi_n, NewBigNum()); - if (BN_mul(phi_n.get(), phi_p.get(), phi_q.get(), ctx.get()) != 1) { - return absl::InternalError( - absl::StrCat("Unable to compute phi(n): ", GetSslErrors())); - } - // Compute lcm(phi(p), phi(q)). - ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> lcm, NewBigNum()); - if (BN_rshift1(lcm.get(), phi_n.get()) != 1) { - return absl::InternalError(absl::StrCat( - "Could not compute LCM(phi(p), phi(q)): ", GetSslErrors())); - } - - // Compute the new private exponent new_d - ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> new_d, NewBigNum()); - if (!BN_mod_inverse(new_d.get(), new_e.get(), lcm.get(), ctx.get())) { - return absl::InternalError( - absl::StrCat("Could not compute private exponent d: ", GetSslErrors())); - } - - // Compute new_dpm1 = new_d mod p-1 - ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> new_dpm1, NewBigNum()); - BN_mod(new_dpm1.get(), new_d.get(), phi_p.get(), ctx.get()); - // Compute new_dqm1 = new_d mod q-1 - ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> new_dqm1, NewBigNum()); - BN_mod(new_dqm1.get(), new_d.get(), phi_q.get(), ctx.get()); - - bssl::UniquePtr<RSA> derived_private_key(RSA_new_private_key_large_e( - RSA_get0_n(&rsa_key), new_e.get(), new_d.get(), RSA_get0_p(&rsa_key), - RSA_get0_q(&rsa_key), new_dpm1.get(), new_dqm1.get(), - RSA_get0_iqmp(&rsa_key))); - if (!derived_private_key.get()) { - return absl::InternalError( - absl::StrCat("RSA_new_private_key_large_e failed: ", GetSslErrors())); - } - - return TestSign(blinded_data, derived_private_key.get()); -} - -IetfStandardRsaBlindSignatureTestVector -GetIetfStandardRsaBlindSignatureTestVector() { - IetfStandardRsaBlindSignatureTestVector test_vector = { - // n - absl::HexStringToBytes( - "aec4d69addc70b990ea66a5e70603b6fee27aafebd08f2d94cbe1250c556e047a9" - "28d635c3f45ee9b66d1bc628a03bac9b7c3f416fe20dabea8f3d7b4bbf7f963be3" - "35d2328d67e6c13ee4a8f955e05a3283720d3e1f139c38e43e0338ad058a9495c5" - "3377fc35be64d208f89b4aa721bf7f7d3fef837be2a80e0f8adf0bcd1eec5bb040" - "443a2b2792fdca522a7472aed74f31a1ebe1eebc1f408660a0543dfe2a850f106a" - "617ec6685573702eaaa21a5640a5dcaf9b74e397fa3af18a2f1b7c03ba91a63361" - "58de420d63188ee143866ee415735d155b7c2d854d795b7bc236cffd71542df342" - "34221a0413e142d8c61355cc44d45bda94204974557ac2704cd8b593f035a5724b" - "1adf442e78c542cd4414fce6f1298182fb6d8e53cef1adfd2e90e1e4deec52999b" - "dc6c29144e8d52a125232c8c6d75c706ea3cc06841c7bda33568c63a6c03817f72" - "2b50fcf898237d788a4400869e44d90a3020923dc646388abcc914315215fcd1ba" - "e11b1c751fd52443aac8f601087d8d42737c18a3fa11ecd4131ecae017ae0a14ac" - "fc4ef85b83c19fed33cfd1cd629da2c4c09e222b398e18d822f77bb378dea3cb36" - "0b605e5aa58b20edc29d000a66bd177c682a17e7eb12a63ef7c2e4183e0d898f3d" - "6bf567ba8ae84f84f1d23bf8b8e261c3729e2fa6d07b832e07cddd1d14f55325c6" - "f924267957121902dc19b3b32948bdead5"), - // e - absl::HexStringToBytes("010001"), - // d - absl::HexStringToBytes( - "0d43242aefe1fb2c13fbc66e20b678c4336d20b1808c558b6e62ad16a287077180b1" - "77e1f01b12f9c6cd6c52630257ccef26a45135a990928773f3bd2fc01a313f1dac97" - "a51cec71cb1fd7efc7adffdeb05f1fb04812c924ed7f4a8269925dad88bd7dcfbc4e" - "f01020ebfc60cb3e04c54f981fdbd273e69a8a58b8ceb7c2d83fbcbd6f784d052201" - "b88a9848186f2a45c0d2826870733e6fd9aa46983e0a6e82e35ca20a439c5ee7b502" - "a9062e1066493bdadf8b49eb30d9558ed85abc7afb29b3c9bc644199654a4676681a" - "f4babcea4e6f71fe4565c9c1b85d9985b84ec1abf1a820a9bbebee0df1398aae2c85" - "ab580a9f13e7743afd3108eb32100b870648fa6bc17e8abac4d3c99246b1f0ea9f7f" - "93a5dd5458c56d9f3f81ff2216b3c3680a13591673c43194d8e6fc93fc1e37ce2986" - "bd628ac48088bc723d8fbe293861ca7a9f4a73e9fa63b1b6d0074f5dea2a624c5249" - "ff3ad811b6255b299d6bc5451ba7477f19c5a0db690c3e6476398b1483d10314afd3" - "8bbaf6e2fbdbcd62c3ca9797a420ca6034ec0a83360a3ee2adf4b9d4ba29731d131b" - "099a38d6a23cc463db754603211260e99d19affc902c915d7854554aabf608e3ac52" - "c19b8aa26ae042249b17b2d29669b5c859103ee53ef9bdc73ba3c6b537d5c34b6d8f" - "034671d7f3a8a6966cc4543df223565343154140fd7391c7e7be03e241f4ecfeb877" - "a051"), - // p - absl::HexStringToBytes( - "e1f4d7a34802e27c7392a3cea32a262a34dc3691bd87f3f310dc75673488930559c1" - "20fd0410194fb8a0da55bd0b81227e843fdca6692ae80e5a5d414116d4803fca7d8c" - "30eaaae57e44a1816ebb5c5b0606c536246c7f11985d731684150b63c9a3ad9e41b0" - "4c0b5b27cb188a692c84696b742a80d3cd00ab891f2457443dadfeba6d6daf108602" - "be26d7071803c67105a5426838e6889d77e8474b29244cefaf418e381b312048b457" - "d73419213063c60ee7b0d81820165864fef93523c9635c22210956e53a8d96322493" - "ffc58d845368e2416e078e5bcb5d2fd68ae6acfa54f9627c42e84a9d3f2774017e32" - "ebca06308a12ecc290c7cd1156dcccfb2311"), - // q - absl::HexStringToBytes( - "c601a9caea66dc3835827b539db9df6f6f5ae77244692780cd334a006ab353c80642" - "6b60718c05245650821d39445d3ab591ed10a7339f15d83fe13f6a3dfb20b9452c6a" - "9b42eaa62a68c970df3cadb2139f804ad8223d56108dfde30ba7d367e9b0a7a80c4f" - "dba2fd9dde6661fc73fc2947569d2029f2870fc02d8325acf28c9afa19ecf962daa7" - "916e21afad09eb62fe9f1cf91b77dc879b7974b490d3ebd2e95426057f35d0a3c9f4" - "5f79ac727ab81a519a8b9285932d9b2e5ccd347e59f3f32ad9ca359115e7da008ab7" - "406707bd0e8e185a5ed8758b5ba266e8828f8d863ae133846304a2936ad7bc7c9803" - "879d2fc4a28e69291d73dbd799f8bc238385"), - // message - absl::HexStringToBytes("8f3dc6fb8c4a02f4d6352edf0907822c1210a" - "9b32f9bdda4c45a698c80023aa6b5" - "9f8cfec5fdbb36331372ebefedae7d"), - // salt - absl::HexStringToBytes("051722b35f458781397c3a671a7d3bd3096503940e4c4f1aa" - "a269d60300ce449555cd7340100df9d46944c5356825abf"), - // inv - absl::HexStringToBytes( - "80682c48982407b489d53d1261b19ec8627d02b8cda5336750b8cee332ae260de57b" - "02d72609c1e0e9f28e2040fc65b6f02d56dbd6aa9af8fde656f70495dfb723ba0117" - "3d4707a12fddac628ca29f3e32340bd8f7ddb557cf819f6b01e445ad96f874ba2355" - "84ee71f6581f62d4f43bf03f910f6510deb85e8ef06c7f09d9794a008be7ff2529f0" - "ebb69decef646387dc767b74939265fec0223aa6d84d2a8a1cc912d5ca25b4e144ab" - "8f6ba054b54910176d5737a2cff011da431bd5f2a0d2d66b9e70b39f4b050e45c0d9" - "c16f02deda9ddf2d00f3e4b01037d7029cd49c2d46a8e1fc2c0c17520af1f4b5e25b" - "a396afc4cd60c494a4c426448b35b49635b337cfb08e7c22a39b256dd032c00addda" - "fb51a627f99a0e1704170ac1f1912e49d9db10ec04c19c58f420212973e0cb329524" - "223a6aa56c7937c5dffdb5d966b6cd4cbc26f3201dd25c80960a1a111b32947bb789" - "73d269fac7f5186530930ed19f68507540eed9e1bab8b00f00d8ca09b3f099aae461" - "80e04e3584bd7ca054df18a1504b89d1d1675d0966c4ae1407be325cdf623cf13ff1" - "3e4a28b594d59e3eadbadf6136eee7a59d6a444c9eb4e2198e8a974f27a39eb63af2" - "c9af3870488b8adaad444674f512133ad80b9220e09158521614f1faadfe8505ef57" - "b7df6813048603f0dd04f4280177a11380fbfc861dbcbd7418d62155248dad5fdec0" - "991f"), - // encoded_message - absl::HexStringToBytes( - "6e0c464d9c2f9fbc147b43570fc4f238e0d0b38870b3addcf7a4217df912ccef17a7" - "f629aa850f63a063925f312d61d6437be954b45025e8282f9c0b1131bc8ff19a8a92" - "8d859b37113db1064f92a27f64761c181c1e1f9b251ae5a2f8a4047573b67a270584" - "e089beadcb13e7c82337797119712e9b849ff56e04385d144d3ca9d8d92bf78adb20" - "b5bbeb3685f17038ec6afade3ef354429c51c687b45a7018ee3a6966b3af15c9ba8f" - "40e6461ba0a17ef5a799672ad882bab02b518f9da7c1a962945c2e9b0f02f29b31b9" - "cdf3e633f9d9d2a22e96e1de28e25241ca7dd04147112f578973403e0f4fd8086596" - "5475d22294f065e17a1c4a201de93bd14223e6b1b999fd548f2f759f52db71964528" - "b6f15b9c2d7811f2a0a35d534b8216301c47f4f04f412cae142b48c4cdff78bc54df" - "690fd43142d750c671dd8e2e938e6a440b2f825b6dbb3e19f1d7a3c0150428a47948" - "037c322365b7fe6fe57ac88d8f80889e9ff38177bad8c8d8d98db42908b389cb5969" - "2a58ce275aa15acb032ca951b3e0a3404b7f33f655b7c7d83a2f8d1b6bbff49d5fce" - "df2e030e80881aa436db27a5c0dea13f32e7d460dbf01240c2320c2bb5b3225b1714" - "5c72d61d47c8f84d1e19417ebd8ce3638a82d395cc6f7050b6209d9283dc7b93fecc" - "04f3f9e7f566829ac41568ef799480c733c09759aa9734e2013d7640dc6151018ea9" - "02bc"), - // blinded_message - absl::HexStringToBytes( - "10c166c6a711e81c46f45b18e5873cc4f494f003180dd7f115585d871a2893025965" - "4fe28a54dab319cc5011204c8373b50a57b0fdc7a678bd74c523259dfe4fd5ea9f52" - "f170e19dfa332930ad1609fc8a00902d725cfe50685c95e5b2968c9a2828a21207fc" - "f393d15f849769e2af34ac4259d91dfd98c3a707c509e1af55647efaa31290ddf48e" - "0133b798562af5eabd327270ac2fb6c594734ce339a14ea4fe1b9a2f81c0bc230ca5" - "23bda17ff42a377266bc2778a274c0ae5ec5a8cbbe364fcf0d2403f7ee178d77ff28" - "b67a20c7ceec009182dbcaa9bc99b51ebbf13b7d542be337172c6474f2cd3561219f" - "e0dfa3fb207cff89632091ab841cf38d8aa88af6891539f263adb8eac6402c41b6eb" - "d72984e43666e537f5f5fe27b2b5aa114957e9a580730308a5f5a9c63a1eb599f093" - "ab401d0c6003a451931b6d124180305705845060ebba6b0036154fcef3e5e9f9e4b8" - "7e8f084542fd1dd67e7782a5585150181c01eb6d90cb95883837384a5b91dbb606f2" - "66059ecc51b5acbaa280e45cfd2eec8cc1cdb1b7211c8e14805ba683f9b78824b2eb" - "005bc8a7d7179a36c152cb87c8219e5569bba911bb32a1b923ca83de0e03fb10fba7" - "5d85c55907dda5a2606bf918b056c3808ba496a4d95532212040a5f44f37e1097f26" - "dc27b98a51837daa78f23e532156296b64352669c94a8a855acf30533d8e0594ace7" - "c442"), - // blinded_signature - absl::HexStringToBytes( - "364f6a40dbfbc3bbb257943337eeff791a0f290898a6791283bba581d9eac90a6376" - "a837241f5f73a78a5c6746e1306ba3adab6067c32ff69115734ce014d354e2f259d4" - "cbfb890244fd451a497fe6ecf9aa90d19a2d441162f7eaa7ce3fc4e89fd4e76b7ae5" - "85be2a2c0fd6fb246b8ac8d58bcb585634e30c9168a434786fe5e0b74bfe8187b47a" - "c091aa571ffea0a864cb906d0e28c77a00e8cd8f6aba4317a8cc7bf32ce566bd1ef8" - "0c64de041728abe087bee6cadd0b7062bde5ceef308a23bd1ccc154fd0c3a26110df" - "6193464fc0d24ee189aea8979d722170ba945fdcce9b1b4b63349980f3a92dc2e541" - "8c54d38a862916926b3f9ca270a8cf40dfb9772bfbdd9a3e0e0892369c18249211ba" - "857f35963d0e05d8da98f1aa0c6bba58f47487b8f663e395091275f82941830b050b" - "260e4767ce2fa903e75ff8970c98bfb3a08d6db91ab1746c86420ee2e909bf681cac" - "173697135983c3594b2def673736220452fde4ddec867d40ff42dd3da36c84e3e525" - "08b891a00f50b4f62d112edb3b6b6cc3dbd546ba10f36b03f06c0d82aeec3b25e127" - "af545fac28e1613a0517a6095ad18a98ab79f68801e05c175e15bae21f821e80c80a" - "b4fdec6fb34ca315e194502b8f3dcf7892b511aee45060e3994cd15e003861bc7220" - "a2babd7b40eda03382548a34a7110f9b1779bf3ef6011361611e6bc5c0dc851e1509" - "de1a"), - // signature - absl::HexStringToBytes( - "6fef8bf9bc182cd8cf7ce45c7dcf0e6f3e518ae48f06f3c670c649ac737a8b8119" - "a34d51641785be151a697ed7825fdfece82865123445eab03eb4bb91cecf4d6951" - "738495f8481151b62de869658573df4e50a95c17c31b52e154ae26a04067d5ecdc" - "1592c287550bb982a5bb9c30fd53a768cee6baabb3d483e9f1e2da954c7f4cf492" - "fe3944d2fe456c1ecaf0840369e33fb4010e6b44bb1d721840513524d8e9a3519f" - "40d1b81ae34fb7a31ee6b7ed641cb16c2ac999004c2191de0201457523f5a4700d" - "d649267d9286f5c1d193f1454c9f868a57816bf5ff76c838a2eeb616a3fc9976f6" - "5d4371deecfbab29362caebdff69c635fe5a2113da4d4d8c24f0b16a0584fa05e8" - "0e607c5d9a2f765f1f069f8d4da21f27c2a3b5c984b4ab24899bef46c6d9323df4" - "862fe51ce300fca40fb539c3bb7fe2dcc9409e425f2d3b95e70e9c49c5feb6ecc9" - "d43442c33d50003ee936845892fb8be475647da9a080f5bc7f8a716590b3745c22" - "09fe05b17992830ce15f32c7b22cde755c8a2fe50bd814a0434130b807dc1b7218" - "d4e85342d70695a5d7f29306f25623ad1e8aa08ef71b54b8ee447b5f64e73d09bd" - "d6c3b7ca224058d7c67cc7551e9241688ada12d859cb7646fbd3ed8b34312f3b49" - "d69802f0eaa11bc4211c2f7a29cd5c01ed01a39001c5856fab36228f5ee2f2e111" - "0811872fe7c865c42ed59029c706195d52"), - }; - return test_vector; -} - -std::vector<IetfRsaBlindSignatureWithPublicMetadataTestVector> -GetIetfRsaBlindSignatureWithPublicMetadataTestVectors() { - std::string n = absl::HexStringToBytes( - "d6930820f71fe517bf3259d14d40209b02a5c0d3d61991c731dd7da39f8d69821552" - "e2318d6c9ad897e603887a476ea3162c1205da9ac96f02edf31df049bd55f142134c" - "17d4382a0e78e275345f165fbe8e49cdca6cf5c726c599dd39e09e75e0f330a33121" - "e73976e4facba9cfa001c28b7c96f8134f9981db6750b43a41710f51da4240fe0310" - "6c12acb1e7bb53d75ec7256da3fddd0718b89c365410fce61bc7c99b115fb4c3c318" - "081fa7e1b65a37774e8e50c96e8ce2b2cc6b3b367982366a2bf9924c4bafdb3ff5e7" - "22258ab705c76d43e5f1f121b984814e98ea2b2b8725cd9bc905c0bc3d75c2a8db70" - "a7153213c39ae371b2b5dc1dafcb19d6fae9"); - std::string e = absl::HexStringToBytes("010001"); - std::string d = absl::HexStringToBytes( - "4e21356983722aa1adedb084a483401c1127b781aac89eab103e1cfc52215494981d" - "18dd8028566d9d499469c25476358de23821c78a6ae43005e26b394e3051b5ca206a" - "a9968d68cae23b5affd9cbb4cb16d64ac7754b3cdba241b72ad6ddfc000facdb0f0d" - "d03abd4efcfee1730748fcc47b7621182ef8af2eeb7c985349f62ce96ab373d2689b" - "aeaea0e28ea7d45f2d605451920ca4ea1f0c08b0f1f6711eaa4b7cca66d58a6b916f" - "9985480f90aca97210685ac7b12d2ec3e30a1c7b97b65a18d38a93189258aa346bf2" - "bc572cd7e7359605c20221b8909d599ed9d38164c9c4abf396f897b9993c1e805e57" - "4d704649985b600fa0ced8e5427071d7049d"); - std::string p = absl::HexStringToBytes( - "dcd90af1be463632c0d5ea555256a20605af3db667475e190e3af12a34a3324c46a3" - "094062c59fb4b249e0ee6afba8bee14e0276d126c99f4784b23009bf6168ff628ac1" - "486e5ae8e23ce4d362889de4df63109cbd90ef93db5ae64372bfe1c55f832766f21e" - "94ea3322eb2182f10a891546536ba907ad74b8d72469bea396f3"); - std::string q = absl::HexStringToBytes( - "f8ba5c89bd068f57234a3cf54a1c89d5b4cd0194f2633ca7c60b91a795a56fa8c868" - "6c0e37b1c4498b851e3420d08bea29f71d195cfbd3671c6ddc49cf4c1db5b478231e" - "a9d91377ffa98fe95685fca20ba4623212b2f2def4da5b281ed0100b651f6db32112" - "e4017d831c0da668768afa7141d45bbc279f1e0f8735d74395b3"); - - std::vector<IetfRsaBlindSignatureWithPublicMetadataTestVector> test_vectors; - // test_vector 1. - test_vectors.push_back({ - n, - e, - d, - p, - q, - // message - absl::HexStringToBytes("68656c6c6f20776f726c64"), - // public_metadata - absl::HexStringToBytes("6d65746164617461"), - // message_mask - absl::HexStringToBytes( - "64b5c5d2b2ca672690df59bab774a389606d85d56f92a18a57c42eb4cb164d43"), - // blinded_message - absl::HexStringToBytes( - "1b9e1057dd2d05a17ad2feba5f87a4083cc825fe06fc70f0b782062ea0043fa65ec8" - "096ce5d403cfa2aa3b11195b2a655d694386058f6266450715a936b5764f42977c0a" - "0933ff3054d456624734fd2c019def792f00d30b3ac2f27859ea56d835f80564a3ba" - "59f3c876dc926b2a785378ca83f177f7b378513b36a074e7db59448fd4007b54c647" - "91a33b61721ab3b5476165193af30f25164d480684d045a8d0782a53dd73774563e8" - "d29e48b175534f696763abaab49fa03a055ec9246c5e398a5563cc88d02eb57d725d" - "3fc9231ae5139aa7fcb9941060b0bf0192b8c81944fa0c54568b0ab4ea9c4c4c9829" - "d6dbcbf8b48006b322ee51d784ac93e4bf13"), - // blinded_signature - absl::HexStringToBytes( - "7ef75d9887f29f2232602acab43263afaea70313a0c90374388df5a7a7440d2584c4" - "b4e5b886accc065bf4824b4b22370ddde7fea99d4cd67f8ed2e4a6a2b7b5869e8d4d" - "0c52318320c5bf7b9f02bb132af7365c471e799edd111ca9441934c7db76c164b051" - "5afc5607b8ceb584f5b1d2177d5180e57218265c07aec9ebde982f3961e7ddaa432e" - "47297884da8f4512fe3dc9ab820121262e6a73850920299999c293b017cd800c6ec9" - "94f76b6ace35ff4232f9502e6a52262e19c03de7cc27d95ccbf4c381d698fcfe1f20" - "0209814e04ae2d6279883015bbf36cabf3e2350be1e175020ee9f4bb861ba409b467" - "e23d08027a699ac36b2e5ab988390f3c0ee9"), - // signature - absl::HexStringToBytes( - "abd6813bb4bbe3bc8dc9f8978655b22305e5481b35c5bdc4869b60e2d5cc74b84356" - "416abaaca0ca8602cd061248587f0d492fee3534b19a3fe089de18e4df9f3a6ad289" - "afb5323d7934487b8fafd25943766072bab873fa9cd69ce7328a57344c2c529fe969" - "83ca701483ca353a98a1a9610391b7d32b13e14e8ef87d04c0f56a724800655636cf" - "ff280d35d6b468f68f09f56e1b3acdb46bc6634b7a1eab5c25766cec3b5d97c37bbc" - "a302286c17ff557bcf1a4a0e342ea9b2713ab7f935c8174377bace2e5926b3983407" - "9761d9121f5df1fad47a51b03eab3d84d050c99cf1f68718101735267cca3213c0a4" - "6c0537887ffe92ca05371e26d587313cc3f4"), - }); - - // test_vector 2. - test_vectors.push_back({ - n, - e, - d, - p, - q, - // message - absl::HexStringToBytes("68656c6c6f20776f726c64"), - // public_metadata - "", - // message_mask - absl::HexStringToBytes( - "ebb56541b9a1758028033cfb085a4ffe048f072c6c82a71ce21d40842b5c0a89"), - // blinded_message - absl::HexStringToBytes( - "d1fc97f30efbf116fadd9895130cdd55f939211f7db19ce9a85287227a02b33fb698" - "b52399f81be0e1f598482000202ec89968085753eae1810f14676b514e08238c8aa7" - "9d8b999af54e9f4282c6220d4d760716e48e5413f3228cc59ce10b8252916640de7b" - "9b5c7dc9c2bff9f53b4fb5eb4a5f8bab49af3fd1b955d34312073d15030e7fdb44bd" - "b23460d1c5662597f9947092def7fff955a5f3e63419ae9858c6405f9609b63c4331" - "e0cf90d24c196bee554f2b78e0d8f6da3d4308c8d4ae9fbe18a8bb7fa4fc3b9cacd4" - "263e5bd6e12ed891cfdfba8b50d0f37d7a9abe065238367907c685ed2c224924caf5" - "d8fe41f5db898b09a0501d318d9f65d88cb8"), - // blinded_signature - absl::HexStringToBytes( - "400c1bcdfa56624f15d04f6954908b5605dbeff4cd56f384d7531669970290d70652" - "9d44cde4c972a1399635525a2859ef1d914b4130068ed407cfda3bd9d1259790a30f" - "6d8c07d190aa98bf21ae9581e5d61801565d96e9eec134335958b3d0b905739e2fd9" - "f39074da08f869089fe34de2d218062afa16170c1505c67b65af4dcc2f1aeccd4827" - "5c3dacf96116557b7f8c7044d84e296a0501c511ba1e6201703e1dd834bf47a96e1a" - "c4ec9b935233ed751239bd4b514b031522cd51615c1555e520312ed1fa43f55d4abe" - "b222ee48b4746c79006966590004714039bac7fd18cdd54761924d91a4648e871458" - "937061ef6549dd12d76e37ed417634d88914"), - // signature - absl::HexStringToBytes( - "4062960edb71cc071e7d101db4f595aae4a98e0bfe6843aca3e5f48c9dfb46d505e8" - "c19806ffa07f040313d44d0996ef9f69a86fa5946cb818a32627fe2df2a0e8035028" - "8ae4fedfbee4193554cc1433d9d27639db8b4635265504d87dca7054c85e0c882d32" - "887534405e6cc4e7eb4b174383e5ce4eebbfffb217f353102f6d1a0461ef89238de3" - "1b0a0c134dfac0d2a8c533c807ccdd557c6510637596a490d5258b77410421be4076" - "ecdf2d7e9044327e36e349751f3239681bba10fe633f1b246f5a9f694706316898c9" - "00af2294f47267f2e9ad1e61c7f56bf643280258875d29f3745dfdb74b9bbcd5fe3d" - "ea62d9be85e2c6f5aed68bc79f8b4a27b3de"), - }); - - // test_vector 3. - test_vectors.push_back({ - n, - e, - d, - p, - q, - // message - "", - // public_metadata - absl::HexStringToBytes("6d65746164617461"), - // message_mask - absl::HexStringToBytes( - "f2a4ed7c5aa338430c7026d7d92017f994ca1c8b123b236dae8666b1899059d0"), - // blinded_message - absl::HexStringToBytes( - "7756a1f89fa33cfc083567e02fd865d07d6e5cd4943f030a2f94b5c23f3fe79c83c4" - "9c594247d02885e2cd161638cff60803184c9e802a659d76a1c53340972e62e728cc" - "70cf684ef03ce2d05cefc729e6eee2ae46afa17b6b27a64f91e4c46cc12adc58d9cb" - "61a4306dac732c9789199cfe8bd28359d1911678e9709bc159dae34ac7aa59fd0c95" - "962c9f4904bf04aaba8a7e774735bd03be4a02fb0864a53354a2e2f3502506318a5b" - "03961366005c7b120f0e6b87b44bc15658c3e8985d69f6adea38c24fe5e7b4bafa1a" - "d6dc7d729281c26dffc88bd34fcc5a5f9df9b9781f99ea47472ba8bd679aaada5952" - "5b978ebc8a3ea2161de84b7398e4878b751b"), - // blinded_signature - absl::HexStringToBytes( - "2a13f73e4e255a9d5bc6f76cf48dfbf189581c2b170600fd3ab1a3def14884621323" - "9b9d0a981537541cb4f481a602aeebca9ef28c9fcdc63d15d4296f85d864f799edf0" - "8e9045180571ce1f1d3beff293b18aae9d8845068cc0d9a05b822295042dc56a1a2b" - "604c51aa65fd89e6d163fe1eac63cf603774797b7936a8b7494d43fa37039d3777b8" - "e57cf0d95227ab29d0bd9c01b3eae9dde5fca7141919bd83a17f9b1a3b401507f3e3" - "a8e8a2c8eb6c5c1921a781000fee65b6dd851d53c89cba2c3375f0900001c0485594" - "9b7fa499f2a78089a6f0c9b4d36fdfcac2d846076736c5eaedaf0ae70860633e51b0" - "de21d96c8b43c600afa2e4cc64cd66d77a8f"), - // signature - absl::HexStringToBytes( - "67985949f4e7c91edd5647223170d2a9b6611a191ca48ceadb6c568828b4c415b627" - "0b037cd8a68b5bca1992eb769aaef04549422889c8b156b9378c50e8a31c07dc1fe0" - "a80d25b870fadbcc1435197f0a31723740f3084ecb4e762c623546f6bd7d072aa565" - "bc2105b954244a2b03946c7d4093ba1216ec6bb65b8ca8d2f3f3c43468e80b257c54" - "a2c2ea15f640a08183a00488c7772b10df87232ee7879bee93d17e194d6b703aeceb" - "348c1b02ec7ce202086b6494f96a0f2d800f12e855f9c33dcd3abf6bd8044efd69d4" - "594a974d6297365479fe6c11f6ecc5ea333031c57deb6e14509777963a25cdf8db62" - "d6c8c68aa038555e4e3ae4411b28e43c8f57"), - }); - - // test_vector 4. - test_vectors.push_back({ - n, - e, - d, - p, - q, - // message - "", - // public_metadata - "", - // message_mask - absl::HexStringToBytes( - "ba3ea4b1e475eebe11d4bfe3a48521d3ba8cd62f3baed9ec29fbbf7ff0478bc0"), - // blinded_message - absl::HexStringToBytes( - "99d725c5613ff87d16464b0375b0976bf4d47319d6946e85f0d0c2ca79eb02a4c0c2" - "82642e090a910b80fee288f0b3b6777e517b757fc6c96ea44ac570216c8fcd868e15" - "da4b389b0c70898c5a2ed25c1d13451e4d407fe1301c231b4dc76826b1d4cc5e64b0" - "e28fb9c71f928ba48c87e308d851dd07fb5a7e0aa5d0dce61d1348afb4233355374e" - "5898f63adbd5ba215332d3329786fb7c30ef04c181b267562828d8cf1295f2ef4a05" - "ef1e03ed8fee65efb7725d8c8ae476f61a35987e40efc481bcb4b89cb363addfb2ad" - "acf690aff5425107d29b2a75b4665d49f255c5caa856cdc0c5667de93dbf3f500db8" - "fcce246a70a159526729d82c34df69c926a8"), - // blinded_signature - absl::HexStringToBytes( - "a9678acee80b528a836e4784f0690fdddce147e5d4ac506e9ec51c11b16ee2fd5a32" - "e382a3c3d276a681bb638b63040388d53894afab79249e159835cd6bd65849e5d139" - "7666f03d1351aaec3eae8d3e7cba3135e7ec4e7b478ef84d79d81039693adc6b130b" - "0771e3d6f0879723a20b7f72b476fe6fef6f21e00b9e3763a364ed918180f939c351" - "0bb5f46b35c06a00e51f049ade9e47a8e1c3d5689bd5a43df20b73d70dcacfeed9fa" - "23cabfbe750779997da6bc7269d08b2620acaa3daa0d9e9d4b87ef841ebcc06a4c0a" - "f13f1d13f0808f512c50898586b4fc76d2b32858a7ddf715a095b7989d8df50654e3" - "e05120a83cec275709cf79571d8f46af2b8e"), - // signature - absl::HexStringToBytes( - "ba57951810dbea7652209eb73e3b8edafc56ca7061475a048751cbfb995aeb4ccda2" - "e9eb309698b7c61012accc4c0414adeeb4b89cd29ba2b49b1cc661d5e7f30caee7a1" - "2ab36d6b52b5e4d487dbff98eb2d27d552ecd09ca022352c9480ae27e10c3a49a1fd" - "4912699cc01fba9dbbfd18d1adcec76ca4bc44100ea67b9f1e00748d80255a03371a" - "7b8f2c160cf632499cea48f99a6c2322978bd29107d0dffdd2e4934bb7dc81c90dd6" - "3ae744fd8e57bff5e83f98014ca502b6ace876b455d1e3673525ba01687dce998406" - "e89100f55316147ad510e854a064d99835554de8949d3662708d5f1e43bca473c14a" - "8b1729846c6092f18fc0e08520e9309a32de"), - }); - return test_vectors; -} - -std::vector<IetfRsaBlindSignatureWithPublicMetadataTestVector> -GetIetfPartiallyBlindRSASignatureNoPublicExponentTestVectors() { - std::string n = absl::HexStringToBytes( - "d6930820f71fe517bf3259d14d40209b02a5c0d3d61991c731dd7da39f8d69821552" - "e2318d6c9ad897e603887a476ea3162c1205da9ac96f02edf31df049bd55f142134c" - "17d4382a0e78e275345f165fbe8e49cdca6cf5c726c599dd39e09e75e0f330a33121" - "e73976e4facba9cfa001c28b7c96f8134f9981db6750b43a41710f51da4240fe0310" - "6c12acb1e7bb53d75ec7256da3fddd0718b89c365410fce61bc7c99b115fb4c3c318" - "081fa7e1b65a37774e8e50c96e8ce2b2cc6b3b367982366a2bf9924c4bafdb3ff5e7" - "22258ab705c76d43e5f1f121b984814e98ea2b2b8725cd9bc905c0bc3d75c2a8db70" - "a7153213c39ae371b2b5dc1dafcb19d6fae9"); - std::string e = absl::HexStringToBytes("010001"); - std::string d = absl::HexStringToBytes( - "4e21356983722aa1adedb084a483401c1127b781aac89eab103e1cfc52215494981d" - "18dd8028566d9d499469c25476358de23821c78a6ae43005e26b394e3051b5ca206a" - "a9968d68cae23b5affd9cbb4cb16d64ac7754b3cdba241b72ad6ddfc000facdb0f0d" - "d03abd4efcfee1730748fcc47b7621182ef8af2eeb7c985349f62ce96ab373d2689b" - "aeaea0e28ea7d45f2d605451920ca4ea1f0c08b0f1f6711eaa4b7cca66d58a6b916f" - "9985480f90aca97210685ac7b12d2ec3e30a1c7b97b65a18d38a93189258aa346bf2" - "bc572cd7e7359605c20221b8909d599ed9d38164c9c4abf396f897b9993c1e805e57" - "4d704649985b600fa0ced8e5427071d7049d"); - std::string p = absl::HexStringToBytes( - "dcd90af1be463632c0d5ea555256a20605af3db667475e190e3af12a34a3324c46a3" - "094062c59fb4b249e0ee6afba8bee14e0276d126c99f4784b23009bf6168ff628ac1" - "486e5ae8e23ce4d362889de4df63109cbd90ef93db5ae64372bfe1c55f832766f21e" - "94ea3322eb2182f10a891546536ba907ad74b8d72469bea396f3"); - std::string q = absl::HexStringToBytes( - "f8ba5c89bd068f57234a3cf54a1c89d5b4cd0194f2633ca7c60b91a795a56fa8c868" - "6c0e37b1c4498b851e3420d08bea29f71d195cfbd3671c6ddc49cf4c1db5b478231e" - "a9d91377ffa98fe95685fca20ba4623212b2f2def4da5b281ed0100b651f6db32112" - "e4017d831c0da668768afa7141d45bbc279f1e0f8735d74395b3"); - - std::vector<IetfRsaBlindSignatureWithPublicMetadataTestVector> test_vectors; - // test_vector 1. - test_vectors.push_back({ - n, - e, - d, - p, - q, - // message - absl::HexStringToBytes("68656c6c6f20776f726c64"), - // public_metadata - absl::HexStringToBytes("6d65746164617461"), - // message_mask - "", - // blinded_message - absl::HexStringToBytes( - "cfd613e27b8eb15ee0b1df0e1bdda7809a61a29e9b6e9f3ec7c345353437638e8559" - "3a7309467e36396b0515686fe87330b312b6f89df26dc1cc88dd222186ca0bfd4ffa" - "0fd16a9749175f3255425eb299e1807b76235befa57b28f50db02f5df76cf2f8bcb5" - "5c3e2d39d8c4b9a0439e71c5362f35f3db768a5865b864fdf979bc48d4a29ae9e7c2" - "ea259dc557503e2938b9c3080974bd86ad8b0daaf1d103c31549dcf767798079f888" - "33b579424ed5b3d700162136459dc29733256f18ceb74ccf0bc542db8829ca5e0346" - "ad3fe36654715a3686ceb69f73540efd20530a59062c13880827607c68d00993b47a" - "d6ba017b95dfc52e567c4bf65135072b12a4"), - // blinded_signature - absl::HexStringToBytes( - "ca7d4fd21085de92b514fbe423c5745680cace6ddfa864a9bd97d29f3454d5d475c6" - "c1c7d45f5da2b7b6c3b3bc68978bb83929317da25f491fee86ef7e051e7195f35586" - "79b18d6cd3788ac989a3960429ad0b7086945e8c4d38a1b3b52a3903381d9b1bf9f3" - "d48f75d9bb7a808d37c7ecebfd2fea5e89df59d4014a1a149d5faecfe287a3e9557e" - "f153299d49a4918a6dbdef3e086eeb264c0c3621bcd73367195ae9b14e67597eaa9e" - "3796616e30e264dc8c86897ae8a6336ed2cd93416c589a058211688cf35edbd22d16" - "e31c28ff4a5c20f1627d09a71c71af372edc18d2d7a6e39df9365fe58a34605fa1d9" - "dc53efd5a262de849fb083429e20586e210e"), - // signature - absl::HexStringToBytes( - "cdc6243cd9092a8db6175b346912f3cc55e0cf3e842b4582802358dddf6f61decc37" - "b7a9ded0a108e0c857c12a8541985a6efad3d17f7f6cce3b5ee20016e5c36c7d552c" - "8e8ff6b5f3f7b4ed60d62eaec7fc11e4077d7e67fc6618ee092e2005964b8cf394e3" - "e409f331dca20683f5a631b91cae0e5e2aa89eeef4504d24b45127abdb3a79f9c71d" - "2f95e4d16c9db0e7571a7f524d2f64438dfb32001c00965ff7a7429ce7d26136a36e" - "be14644559d3cefc477859dcd6908053907b325a34aaf654b376fade40df4016ecb3" - "f5e1c89fe3ec500a04dfe5c8a56cad5b086047d2f963ca73848e74cf24bb8bf1720c" - "c9de4c78c64449e8af3e7cddb0dab1821998"), - }); - - // test_vector 2. - test_vectors.push_back({ - n, - e, - d, - p, - q, - // message - absl::HexStringToBytes("68656c6c6f20776f726c64"), - // public_metadata - "", - // message_mask - "", - // blinded_message - absl::HexStringToBytes( - "5e6568cd0bf7ea71ad91e0a9708abb5e97661c41812eb994b672f10aa8983151113a" - "eaabcf1306fa5a493e3dbdd58fc8bdb61aac934fae832676bcab7abacdcc1b9c1f2a" - "f3586ae009042293b6945fee0aeffb2d2b8a24f82614b8be39bab71a535f6d65f163" - "1e927dbd471b0753e7a63a201c7ecd26e7fbbb5e21e02f865b64e20731004c395b0e" - "059a92fffa4c636ac4c00db9aa086b5dd1a3dd101bb04970b12ca3f4936f246e32d3" - "94f328cea2510554060e8d291acdbee04b8bc91e967241ba45f3509d63ded5f9b358" - "f4216f37a885e563b7baa93a717ca7cdbe10e398d14bb2d5a1376b4a5f83226ce2c5" - "75087bc28d743caeff9c1b11cc8bd02f5f14"), - // blinded_signature - absl::HexStringToBytes( - "72c4e0f4f677aa1dbb686e23b5944b3afdc7f824711a1f7486d1ed6fa20aad255a14" - "12885aee04c64359964e694a713da2a1684325c1c31401cac1ea39a9e454675b55f7" - "43ff144ac605d0ed254b12d9bdd43b0e8a17c0d4711239732e45e4166261d0b16d2f" - "29403c5f2584a29b225daa7530ba15fc9af15ed2ce8fcb126ad0b0758fd522fbf99a" - "83e4cfe0539aa264d06a1633deee0053f45fc8a944f1468a0c0c449155139779a323" - "0c8fa41a81858418151fa195f57ea645699f550d3cb37c549542d436071d1af74e62" - "9f938fa4717ca9def382fc35089e4caec9e5d740c38ecb2aa88c90176d2f322866ac" - "fd50e2b92313161e81327f889aca0c94bcb8"), - // signature - absl::HexStringToBytes( - "a7ace477c1f416a40e93ddf8a454f9c626b33c5a20067d81bdfef7b88bc15de2b046" - "24478b2134b4b23d91285d72ca4eb9c6c911cd7be2437f4e3b24426bce1a1cb52e2c" - "8a4d13f7fd5c9b0f943b92b8bbcba805b847a0ea549dbc249f2e812bf03dd6b2588c" - "8af22bf8b6bba56ffd8d2872b2f0ebd42ac8bd8339e5e63806199deec3cf392c078f" - "66e72d9be817787d4832c45c1f192465d87f6f6c333ce1e8c5641c7069280443d222" - "7f6f28ff2045acdc368f2f94c38a3c909591a27c93e1778630aeeeb623805f37c575" - "213091f096be14ffa739ee55b3f264450210a4b2e61a9b12141ca36dd45e3b81116f" - "c286e469b707864b017634b8a409ae99c9f1"), - }); - - // test_vector 3. - test_vectors.push_back({ - n, - e, - d, - p, - q, - // message - "", - // public_metadata - absl::HexStringToBytes("6d65746164617461"), - // message_mask - "", - // blinded_message - absl::HexStringToBytes( - "92d5456738e0cfe0fa770b51e6a72d633d7cec3a945459f1db96dbc500a5d1bca34a" - "839059579759301c098231b102fb1e114bf9f892f42f902a336f4a3585b23efa906d" - "fcb94213f4d3b39951551cedecbf51efa213ad030cf821ee3fa46a57d67429f838ff" - "728f47111f7f1b22000a979c0f56cc581396935780d76173410d2a8a5688cd596229" - "03008fe50af1fcc5e7cf96affad7e60fbed67996c7a377effa0f08d9273cd33536b2" - "625c9575d10636cc964636a1500f4fcb22aabbef77fe415cbc7245c1032d34bd480e" - "e338f55be0a79c0076d9cf9c94c0db3003a33b23c62dbd1a85f2b15db5d153b318cc" - "a53c6d68e1e63bafa39c9a43be72f36d2569"), - // blinded_signature - absl::HexStringToBytes( - "a76a1c53566a9781de04d87e8c3a0bc902b47819e7b900580654215b0a710cb563b0" - "85b5e9fff150791f759da03a139dfc9159c21410f1e3d345b8c5dcca35211772900f" - "85c5eec065987cbdbf303e9651196223263a713e4135d6b20bfa8fb8212341665647" - "a9a7e07a831ccbf9e62d9366ec9ac0bbe96228e6fbb848f8f6f474cce68e3556dc88" - "2847e9e61b5b5e02bbfd6152aeca74e8782a54ffe6552d63fb837738a05044b38f7e" - "908c4989b202bd858695c61e12cf9d47ef276a17917e39f942871defd9747541957b" - "1e2f8950da43c9a05ba4835bded23c24cf64edfee10dd0c70b071427cfcbb8b5eb22" - "5daf149a6b4d42bebcc536380a9d753a8b1e"), - // signature - absl::HexStringToBytes( - "02bc0f2728e2b8cd1c1b9873d4b7f5a62017430398165a6f8964842eaa19c1de2922" - "07b74dc25ee0aa90493216d3fbf8e1b2947fd64335277b34767f987c482c69262967" - "c8a8aaf180a4006f456c804cdc7b92d956a351ad89703cc76f69ed45f24d68e1ae03" - "61479e0f6faf10c3b1582de2dcd2af432d57c0c89c8efb1cf3ac5f991fe9c4f0ad24" - "473939b053674a2582518b4bd57da109f4f37bc91a2f806e82bb2b80d486d0694e66" - "3992c9517c946607b978f557bbb769d4cd836d693c77da480cd89b916e5e4190f317" - "711d9c7e64528a314a14bf0b9256f4c60e9ddb550583c21755ab882bdfdf22dc8402" - "49389b1e0a2189f58e19b41c5f313cddce29"), - }); - - // test_vector 4. - test_vectors.push_back({ - n, - e, - d, - p, - q, - // message - "", - // public_metadata - "", - // message_mask - "", - // blinded_message - absl::HexStringToBytes( - "ba562cba0e69070dc50384456391defa410d36fa853fd235902ff5d015d688a44def" - "6b6a7e71a69bff8ee510f5a9aa44e9afddd3e766f2423b3fc783fd1a9ab618586110" - "987c1b3ddce62d25cae500aa92a6b886cb609829d06e67fbf28fbbf3ee7d5cc12548" - "1dd002b908097732e0df06f288cc6eb54565f8153d480085b56ab6cb5801b482d12f" - "50558eb3cb0eb7a4ff8fcc54d4d7fcc2f8913a401ae1d1303ead7964f2746e4804e2" - "848bba87f53cf1412afedc82d9c383dd095e0eb6f90cc74bc4bb5ea7529ded9cde2d" - "489575d549b884379abe6d7b71969e6a9c09f1963d2719eefccd5f2a407845961ccc" - "1fa580a93c72902b2499d96f89e6c53fc888"), - // blinded_signature - absl::HexStringToBytes( - "280c5934022fd17f7f810d4f7adf1d29ced47d098834411d672163cc793bcaad239d" - "07c4c45048a682995950ce84703064cd8c16d6f2579f7a65b66c274faccc6c73c9d2" - "99dcf35c96338c9b81af2f93554a78528551e04be931c8502ee6a21ef65d1fa3cd04" - "9a993e261f85c841b75857d6bf02dd4532e14702f8f5e1261f7543535cdf9379243b" - "5b8ca5cd69d2576276a6c25b78ab7c69d2b0c568eb57cf1731983016dece5b59e753" - "01ca1a148154f2592c8406fee83a434f7b3192649c5be06000866ff40bf09b558c7a" - "f4bbb9a79d5d13151e7b6e602e30c4ab70bbbce9c098c386e51b98aefab67b8efc03" - "f048210a785fd538ee6b75ecd484c1340d91"), - // signature - absl::HexStringToBytes( - "b7d45ec4db11f9b74a6b33806e486f7ee5f87c4fa7c57d08caf0ca6d3ba55e66bf07" - "69c84b9187b9a86e49ba0cb58348f01156ac5bc2e9570fe0a8c33d0ad049a965aeb2" - "a8d8a3cbb30f89a3da6732a9bb3d9415141be4e9052f49d422301a9cfce49947db7d" - "52a1c620b7106ae43afbcb7cb29b9c215e0c2b4cf8d62db67224dd3de9f448f7b660" - "7977c608595d29380b591a2bff2dff57ea2c77e9cdf69c1821ff183a7626d45bbe11" - "97767ac577715473d18571790b1cf59ee35e64362c826246ae83923d749117b7ec1b" - "4478ee15f990dc200745a45f175d23c8a13d2dbe58b1f9d10db71917708b19eeeab2" - "30fe6026c249342216ee785d9422c3a8dc89"), - }); - return test_vectors; -} - -std::string RandomString(int n, std::uniform_int_distribution<int>* distr_u8, - std::mt19937_64* generator) { - std::string rand(n, 0); - for (int i = 0; i < n; ++i) { - rand[i] = static_cast<uint8_t>((*distr_u8)(*generator)); - } - return rand; -} - -std::pair<anonymous_tokens::TestRsaPublicKey, - anonymous_tokens::TestRsaPrivateKey> -GetStrongTestRsaKeyPair2048() { - anonymous_tokens::TestRsaPublicKey public_key = { - /*n=*/ - absl::HexStringToBytes( - "b31928fd04c205d364cab9f7a5620dd8db9992dfaa41c1d29b11df91204ddc0d28a5" - "869cfc4c8ee2fca229c487b0f529c7d782303d4f5b9d85019031b159e4a7ad7d172c" - "cd73915f10550a7f19d63bfe438d6801a226dedc054bee2958c599cfd8513ed26ae2" - "9a5521f6ab7ae4991404b6888d60a76eadec189492a988e4c941d3ffd8feb7bdf715" - "ec0ceaf53707d83e3cc743ec3b7d88d5dc46b615a63d4fee9a0a391546069b811e29" - "095d5a1319fbb70248c35711a46d3c16f1444be285aeddb33256ca775562e755ac94" - "49bfec12cdd099c8dac96b3469764c474a88bc7e1dd19db68e9275606a8142861655" - "4a918a951bde14ee093dbdbdbbd0892486f9"), - /*e=*/absl::HexStringToBytes("010001")}; - anonymous_tokens::TestRsaPrivateKey private_key = { - public_key.n, public_key.e, - /*d=*/ - absl::HexStringToBytes( - "1bcda61d5165c57dc1c1ef08d0f5ddec727aeee026103b44b4aa1ba8edf8e8566a9e" - "f7bcdb360f609193a3244d645d4af529319ec785d0552dd6c649d09c81f0bdf0136e" - "f31e23cd3c3dd7794fcb8058c2a7eb2385c6bf062d14528ebca7406f91c75b17535c" - "8654fd06cc2c31dcc9ccc9817d6129dcf6c71631ca6ae3439132921a9c18111b4b11" - "b421868feac7c9ed6c73c437a24dbc5b364790cf4e7ac1573e72bab1b1e456b55e2e" - "a0a673986f2305c50122ba924db6d281a5e3efc6c03d0fdc690d4d8e4fb5f45a1c4c" - "e5c4595fde5563e8be01170e6e7ef6396bd8d435a14028748d4ef182fbffcc4aa1b9" - "9f86a6155cd26da9bb218a1e3b2cdce38e19"), - /*p=*/ - absl::HexStringToBytes( - "edec7eb7cca858e3fc1c0f4eef5f4574216c96614d3bdee1830930a0036f85f277eb" - "6ff33a757fcf6323325b1967eae0f802dffd2a79c2c222f17c6378bc8d08e3d6ba97" - "5e13c62e5b93e2bb561fb1587dfeb14b20cf5cce9f4518b8eb052c8e48c0b891dd94" - "fa2fef904d45ffe00f7a1a8e77c3c34e337612eba4b40a16078f"), - /*q=*/ - absl::HexStringToBytes( - "c0b4895d14c4e4aca5eee0bf0e58b0da5a210a2793ca06ba8f6b8a6b70202cabc545" - "c220922f02ca849f4ee79313e3fbdfdbdb85367b307f8fe663e108d3bdac4399836e" - "225f1956c3d112167f24db0e429a71d2ad191465f3b99cd3370bfd7b3e8d1a5e5e78" - "8dcfab21ddb00f1aaa73d7cb62f0228449a51d032c9f636b04f7"), - /*dp=*/ - absl::HexStringToBytes( - "2707b7d5f105e0e72d9170d573213ee48923261c3a2e4b26d5772979e6766213dfa6" - "48cc2ed7ddaaa8c9ba560579eda710287094386697137fe5fb90d9da9c8c4bcc0afa" - "0fddd0920445e358f60ce6ebec675eb04366a103e84ece7a6f5b7eeeac72a9148cb4" - "06c2dc5ae0c24df274b78429c0ede5592bc9ffda963f4eb44473"), - /*dq=*/ - absl::HexStringToBytes( - "22c0ac41201cbe0cb0c41abdf9ed5ebf921f81404ff3d030d6ea9304fb2ca241bc0a" - "ef8e862e7a3761a1854e5804ef499e3e7d215208f75f19e977bbbea6c8ff0715e950" - "f45be82af09784c68fd96ab3f0a8ffbbf9c19b1f23cc268f24cf41c07730653ffd93" - "8a27987a3c0ba33db0ddc15e0992baf6d67d33753e17e48b0953"), - /*crt=*/ - absl::HexStringToBytes( - "29402f48481599b7e44c7ab9f0cfc673266dfd9ff0e2d7f9f40b6b1d8061808eb631" - "935fd5c1e536dd99266d79c04842b121adf361e8c7a8bc04fdb7c5ad053a8b9117cf" - "2068142e117bdda6d2a5a01ff8f0ba28d42287612c35e5ff267a20b5da454205cdf6" - "d24d22d4968511c16b0f1a1e55865d0b5ace0beaae0ba3bbd68e")}; - return std::make_pair(public_key, private_key); -} - -std::pair<anonymous_tokens::TestRsaPublicKey, - anonymous_tokens::TestRsaPrivateKey> -GetAnotherStrongTestRsaKeyPair2048() { - anonymous_tokens::TestRsaPublicKey public_key = { - /*n=*/ - absl::HexStringToBytes( - "cfe2049a15de49dd75e828eb8f5321b44f3d4169f53f9b58b37f1aba52f87ea749b8" - "30284857eab7f0ea3bac6b866e5f485be31cea03a7ff2c0ba7cfdbe6f070fc49e37e" - "28f2afe90b61e12a877febb1d4ba6fc0932df332afe51e8fa702a762b944a3f80a5f" - "ea2612cc75c59400e00df62ba4be83cc50198c39b6ac4bc6a5b4f6edaf0bdeac025d" - "6dd03d9f0f7c2127cf3c046a7e4e7cc7bc33f246f52408df49b29696d994e190076a" - "78142cd353c4d5fe38d9708466e49131efa416d35218cde5c380d548599b8ce39a9e" - "fcfe04df6aa317e122ac981346dbde6af84544d8f04e1c19749e6a8fb1efff4b3c3d" - "c3d7d2c95eefc1acd2dd80b5ff585eabfb09"), - /*e=*/absl::HexStringToBytes("010001")}; - anonymous_tokens::TestRsaPrivateKey private_key = { - public_key.n, public_key.e, - /*d=*/ - absl::HexStringToBytes( - "1176a1bf55fdf603922f9e1c67ce6a82ecb32f271910ae5aadbd8c3fc1cf99483163" - "b53bf513d9a679291c393851333d72e53137911b1c864dab6efe01b1ad5a387f768a" - "7723280ef24357388ce87ca2d4459334c0c877e936a88f402f1e0474c12e987db255" - "6b64a668a1ae26e849ea325769400def607d3cefee3e1c218472ffea639163dd7e80" - "2b20e35b3d0cd7c11229cde6ad4d73cb097c1b348f5586585d2727ff62789385665d" - "11b16eceffd85582b58a858ca356d7011bb5e4777bf3b67fef77cc528c56a147d6d7" - "229398bb7bb057139a9b9e7d33e5ac6f302c538b4c81901ef28adb6c530cd549d61e" - "c78e9402fb0deaab176027fda9b0801403e7"), - /*p=*/ - absl::HexStringToBytes( - "fda22fbc727c67fa8b5c72c54bf5136a564de2f46697f1953f751da1cc5bde428f5a" - "5f7007c775a14ab25d1b6996b374bfc1df6665b8e9d2914754ad1a3cebd8bf6da17e" - "9ea0a98d289e609681fd295500d0803522696662a1564eb6d4f1422db8d8da48826d" - "f937cd19176e41889481d1309086aee3968c2692dd893f59288b"), - /*q=*/ - absl::HexStringToBytes( - "d1d28de5df823cea723f6979d73d44d86c202328cd4914abffd7b2e11245c075d4e5" - "01dca7b90249bdb273fe6f78dbc4fdf0229dcb333b9fc24ec6ffd02fcda1a8fa788e" - "3b49f0376be5ce222ccdf92e17e651a5a53507d9687f62835b08825f53f7e3d760e9" - "8e83533e71721b10cd8832dc1c471875655d66cb19e58bb0493b"), - /*dp=*/ - absl::HexStringToBytes( - "8d8e547827a9795ae326e0c36ec64464c7f04667c34eb03d6d224f3c7b5316b42d4f" - "f20e13b965d4745d220be79d7d60fe9914b710b4e8836623da85962c44313f7dcf71" - "5cd52c6c252c6799f8c8b3a5c68397da8fef257e8caf1fd578f981c704f0babb5758" - "4b8cb2427bca447716f3712e5aab60b692d27bc0e235f48e2d4b"), - /*dq=*/ - absl::HexStringToBytes( - "72c12850379ca03a4cffb76d26b5e0a849028e982b26340319eadb6f533208dfa8ef" - "12c49e8a85e0d4b9fbcc8524e1756cb8e005d2f393417de0dddf5cfa380999445b98" - "d67e4abdd4ea1b81ff652b49f55247074442aba7510a92536aff4d665ba330de43a7" - "9904e40b3bba7f69022fe23915d220635c6be7e35ea7776d93af"), - /*crt=*/ - absl::HexStringToBytes( - "6b7f1d159c6be9a9c4d6d4171f6e90b3c9d40abee51b891f538a653c06da423ece64" - "7713a6192babbdc8580cfa941f4cc88952f982fe197fd2fcd29d0b6b01960361419a" - "74182cc94acaac94ad88b000677bba8f97f4ba362019a0fe1ffeb64691ca17039ebd" - "6ad5fec8269090d2163b54ca25f4840f46f0395fdfec83cac4eb")}; - return std::make_pair(public_key, private_key); -} - -std::pair<anonymous_tokens::TestRsaPublicKey, - anonymous_tokens::TestRsaPrivateKey> -GetStrongTestRsaKeyPair3072() { - anonymous_tokens::TestRsaPublicKey public_key = { - /*n=*/ - absl::HexStringToBytes( - "bd8be57544c2b43220d80b377fa22d69226e968b9f04e321e7c9e82ec4a4849386d2" - "c4377cf2b8ec93145fbebb6f4508266169e4a83b37671f28285fe91c75a4b721804e" - "71a7eaea97d42cd3055e4e46e78ed10898472f92c61d981d1df20d55f89e0558eb95" - "a13f5f8ae04aa2cbfbf99c4599702b1498ab337fe36396a39a073c5d5dbedf557e6d" - "245f807c28a4c2f44197ae256190d9a410392ede4fdf9d337fc201bb26447fabc442" - "b19c79c531e12922a90bada53615b12e9a54ecb033f9a22be859984e296d632c9eb2" - "87825bb4bfb7f3d16c4f2ba30b2ca5a04512e62c993351c7039a64d865ba49eb960b" - "176dbe7c4853db37911f7bae782732441e428992422754ca3d78a20e9cedbafa8ec2" - "460403997c381772be64b72133c1585b0d1fe5e96a3f7e2388228826989766da37f9" - "949d1040230cb78f88005e5e92796a285b3acdd90733ed4a111d35f4632eda15dc66" - "9e595380331acab1e98cf872126dac05c2d7a7beff889ff39ea60cf7ac69f62bd35e" - "6c2ff193c9037d0f500d"), - /*e=*/absl::HexStringToBytes("010001")}; - anonymous_tokens::TestRsaPrivateKey private_key = { - public_key.n, public_key.e, - /*d=*/ - absl::HexStringToBytes( - "2de57b093b3e1e1de94006ef48537fc56e55f2d41a0c37e754d5da07c10bc92263ca" - "134310594197df4156b1bb7704f3253fff4123cf3aea186c43e27d72abb5d7b61ff8" - "5ea2f74a18bb82a31230b4a98c96535d4e6a2645d6fd0181436801fca837b339c5c9" - "b482c0e2c2ceafbecee3b108555008ce72ed398a25084f488c1a666e812d9fac76f1" - "7c96376958fa144ecab72caed68219811580932db78f80e420725cb2f16032bde7c6" - "f274de3376917bc16dc76b238f060fa226329c214a642417795cc3efa5337b1b89d6" - "b14ac31e681c2e2a8962c086feaf590eb54769d05d5eaa2b96113ab27fd8ecca8e5a" - "c717604af7c9e2572f05859d22b5658ba76206ca3f5a8c780bc664f5448927348427" - "ac08e5713ebe160d2a4968093fad401547669487775baf5c5605cff96e8170e5cde4" - "eab215ee05d3a8a3416426573f2026157aaea1b8626102e969cb7fdfa67d4585d497" - "0dd708308a6bd7f1cad1bc916ae3e8be82f2a9444a43cd171ad636f62b5c5b76d970" - "9c39ae36f03ec6bbceed"), - /*p=*/ - absl::HexStringToBytes( - "e9ca59fe1ddb5c5050192692145220e04623867aff99f70a0224c11144c167dc79f2" - "1df61b64c378c82940b78dd5608ff07a00bb83261e6f328ddea1f53a40a7b9a6bc97" - "02e05afd1717456416f26b199cdb704d0d5b555deaf4d1d6e738b86db8096fc57c4d" - "3c8cd3b510a6d5fa90c05135aec2dc161fd9e38771b7f4d26ff0e8a1d0ec0dd4d832" - "128df1adbdf33125f723717efe947c65539ddeadc95e8960b79f0c77ec8761c38bce" - "d50a76f145176c0b5dace6b7e3aa0b2ba16646357ec3"), - /*q=*/ - absl::HexStringToBytes( - "cf8d8e9c9102b69b76e28aa06431c177320e8ae147db85432507d51a68c587ac5481" - "97cc73666ae65ba4de3c5a974a4344f1f804969431537ff31e3f23f3cc50f90d69b4" - "f994b41040aef3072b2cf2679094860924a6404b7196386463a074a6fd1b0b4bfcbc" - "ab82f81549f44a65ff33a6ce5788fc1a7710759ca59c2040c21f1c97d66ee0f110c4" - "f37da1c07508b0e60ea1878ea6133ddf8ba4b29fc1761e5b43b7830ab87768058eec" - "47c22a3ff8bbde4f6b10849b78daa6a072c30f7aa8ef"), - /*dp=*/ - absl::HexStringToBytes( - "65203e25094d257527f0791a9ee79788eb4dda91c1961ba19ca3c14f72ea25bedc90" - "ba1d066463990f1ba8febcbf1b71a7975e51bdbcf3552e0ce7cc2e82f00c9ce55e96" - "038c804f1179e36e13eef01cb818c34ed1043cbccf30eec38268aa7deb2949cba6a4" - "d218284b1dd4cca20192ee8dc5f64bb4d63a2d8d1cc77182c520f3bf6adb70702cc4" - "1bfa821ba11a5c9c0b76ad553d51852d5f29de7455b22ac2472ae8fdc6b618b7b8f5" - "d2792051e48ce9135185c496ae4793655fff19477279"), - /*dq=*/ - absl::HexStringToBytes( - "1d4340102301d6ed245ddc5db0c2b31c331a89ca296f71e27d9e15159c1ffd78f691" - "2eedcc776c2afe50c8648a013a9f31614c2e996c5b68026a2ca18a581d3e6d5ecec0" - "8d4fc1f368ab41e888d5d5777492fc32ddcff2d0b03b15c851a395ced570b2af0bfb" - "2dd35156ef0e5a4ef72439286e7f09cc516d28a7e55195da8b84076c00f7b10f4be5" - "f8ce85b7b4c87ce872b7a37d213d25441754293b0cf3b263fbb02bf19f0076d211cc" - "8e7179b37b464199c0e69b4bb04663a7cb8664f04e51"), - /*crt=*/ - absl::HexStringToBytes( - "b5b84f7c4868e4de55d37efe7ada9865b0cc73b4b08e111cb8502b39210b17d81a54" - "2ea793b970d03557c30b5243e066c7ff46e3abfcf3972a9a6199927d05f64fefb7ef" - "bb336d716599e7cf507e87f274541ef5216235fdedfba524879fecedf4455a60071a" - "f52d36a0df37b3f4c64b75e564fbdaadc36356e2382efd783ab4e82f4f708fb1addd" - "288658dfd4afc14c427e2699d8ed178fb343ebef2afd343d0f3aeb30a96dcac9f6a1" - "36d54347a42e318daf23d1d57b1cd964bd665a3f2a67")}; - return std::make_pair(public_key, private_key); -} - -std::pair<anonymous_tokens::TestRsaPublicKey, - anonymous_tokens::TestRsaPrivateKey> -GetStrongTestRsaKeyPair4096() { - anonymous_tokens::TestRsaPublicKey public_key = { - /*n=*/ - absl::HexStringToBytes( - "cd7d928f252a882c2ba68c1705970f61b7f63c5e907ea5f34e650e3c35edd7467873" - "4d626fca38a1230c52147cb8b16e2db9adbfe7ce4647ef2eb49b4ade458c80ef0e29" - "ac4109233d0f512643106fb2e42308fbc2db13c1db24c672a3bfc32acfb429ae5104" - "507f2b342473a9aa5eab8a9c24d7fe08fb59bea4049d14fea781484591460e5eef62" - "bd67d3c28aa8e360c50b936998565ca12fbc647d32c446f3f326fe0a36388bfb3ed7" - "a4c1e8c900a299c88bdaf6dc9ebb032f810f682ddfc2d5fa46e8fa28b8bdfa32131f" - "259615f85bde8a4eb8258ccbda83e62cf12795c0cae1498c2b435e27c31b9ef8a1ef" - "bf9552bc6f929a76d9d3a997bfe6fe11c155a571446decdb5032b80482d0bcb8ab0a" - "23ab82451049a1af692764b69187620005a9d3b5d530d38bfc41938066f505a6e248" - "4795ce70a69e5df5a551b5179ff1ed3a34eceb09834317de137d9c2d6b35c745c67b" - "05a1412fc0f616581a051f41bf14c48dcc8b558f92cdee22f5d0f4a75c232e4acf45" - "d3d2491a2eda3d7ed40fcef81058b8b3b019ef7492453dd3220d5a1ee706abcf4da4" - "4a572376eee594dca796f8be05ba104ea08881e68c09132622f233574bd0c3f9dfaa" - "9ae7c6579b90312851aeec02b2678c5e530cc8fbc30e389799df92a2898c34208367" - "63e199488adc8e5464ff4a67debf35ac2011d4723c3cf1ea1326ce555f80611b2094" - "4a31"), - /*e=*/absl::HexStringToBytes("010001")}; - anonymous_tokens::TestRsaPrivateKey private_key = { - public_key.n, public_key.e, - /*d=*/ - absl::HexStringToBytes( - "1d618f83851a64370094c322058c18486e0fb88902db00ea5d72a88ae66117ef3d08" - "ab6f603187504edd139d5749e720ac4c08b2503817a77064fab0db8f155da60fc834" - "202b7a5d7dfd032ad7daf145a045fc22573590c91e86cf131423b689980218159302" - "ed6989695eaee4faf5a74c5dd00ccc0747bd08bb95e749d9b164944b521eb4ae5147" - "0a72de7dc9eaa4fc30a05b96f50fa015f1e7db6c65465828c842f27ece4ade84f172" - "cedd64e5dc7fe3421ff1126bf00c2843f20d9c6536c1ba6b9b18f3afbfde75f813f0" - "d7a47286bcc8007989ede0884339a9bf124a0928f4392b156e18274dc3215f65086e" - "69b3b58d38dcbad6348605912b80a12233c4c418ab6cedeb313207c2567e0754a9f0" - "b4ac5365cfbc699ccc3a967a668e9ee9c272c4dfac1a7024bd98ccb7e6de98fe5a3a" - "43fcb01e0d354ca7b31c266253a35f7ee1109c59f2523bd03fa6d8c6f03c5b347fc5" - "97c3d0011a0d984105b74a2a406a7ab815657da88c8ee56d78925409df32f8698a75" - "af8fb2b3576b5676c1ffc8026421b73e72698b3d10695f369874fa681df1b4f1e781" - "55ff7238b23a1f1b73541fd4a60831a5d78c6a8b2b86d9a5d24f36c9437f5b8e5e52" - "2d078c9f23c6bbd24e0b261b575b4d31b3d05434afb3b45442f981d33954d0b43380" - "8aa0cacaba9530f3f6083dd059a0ad36ade853997c575a0036a691851f34c391be7e" - "6f43"), - /*p=*/ - absl::HexStringToBytes( - "e6503c05c40a5db99f52ae1ae7ae3a313802821e2d93a431f71c21206e7cf683603d" - "e565b0788038841f761025f4f50b090a2a828240460d5eba1fc49cec36d93cb7ee2a" - "bda6dadeda381b83c3e6f18c1ddea7651a7fe87ee65ce089817baa7998c6db994132" - "850d6b47f9afbf6c6fbf7d813173d2d2f904892288dc603f4b11c96d67228b0591f4" - "9311f227f81cad39161039028b009155a703ea581d3f10b4b668e59d07f0ca90bc26" - "970b854ac17abdd86789ee0d61db5942226f498099076ce05aaa72a52cf6006216a8" - "f7d1afbd64e9449b068c65faeec6cdb3b02a2d0f9320d85d963067c38093ad6a3483" - "a3db7e5964ba29634540de9ed60b8e1423ab"), - /*q=*/ - absl::HexStringToBytes( - "e4689c2d46a1e63dc955942bc34a948b50cc1047cd61b67aec389f7315aac62d9d24" - "971525a1d925a93d4da005280298587b3559aba6c2329c63baaa37ab7fabb88c349a" - "d34f7cfd3a57d5c4dc2c9a623fdb5724af0e808a00ec3a02d503b02905fa8dbb97d4" - "7d588dd9dab46cc03709f54fff79d0c5941372faa9f9b6ff7524b4cb1740b6af34ce" - "d5c39b47ce4902387dffffdb7ab6c38a54e55d42b47359cef31e1d993abdaf15fab9" - "17a15db3a558660ad5fe3bcd298c2625481bc61b3aecfc960c6c7d732c560fcd99cf" - "1d6d56da6c0ed876b2b957d0c2d7e86a1cd57a08380f526f18e4d3ca9000271cbf8e" - "87f66e4f908834df312c6a6d62b9137c6d93"), - /*dp=*/ - absl::HexStringToBytes( - "8d017a7e1d342b85c5e19ceea401ab670edf9a4257ad18cdee78ae5f68c5e13735e9" - "2f553ee1c7bed24560c72a35fb00b29c22c29c74356f621b99ef8a13a4d103b7a87d" - "4a77a970df3192c6ed5dab6d19ac83d8068d610eb08314859b5cd756730eeccbbb7a" - "eeb2f487b07ac53be27ede9c0666df20838d1f58a16a2b131526e2a7b489158c677b" - "d1bf1eff118c9d11624cb45ab637b6c335e9d3c3f6c3f1ba72236ed0e157aeed4604" - "6a5d8751e97af85851abc4af34c652b386d993aac40623c6883beaccede5fefe0ed9" - "8c4038d43fc0015cd87984c64902365658f8b975dba23455b7ea12dd430f2710eaed" - "dd9838970a705f7e839bdfb06763d3acc8d9"), - /*dq=*/ - absl::HexStringToBytes( - "469418a658ec103449715b4ec692d621d27eac0d33e69cb79124d20882ca796080ed" - "5c8e1949d0cab5680f0382746190e7ce72a6d9c6b6bd62dbe24354de769dfe71bc93" - "96f639fe19b828832331d926c0eaab1bd7c8186a0c6cf2640ba48f1bae104519918a" - "048d878fa8e815aeb3932d2d6219272cd65bc82cb2b74a17d7ffd6a9e6ee8544d081" - "9546534635f5136d9769b28b04795324fca4bf53ac64f47c615d8df1da57e0b15eff" - "30d1191e38da7ef59c386a0c34696d241a0b130539091fe7d1c0f866cd6d6e86ae9f" - "744d64082c59ce03a7a863fd4b27e2565fc08b6bdcbec74f33170a66ce666daf9175" - "9e87c4806b7ddb3098864c00aeffd7889c67"), - /*crt=*/ - absl::HexStringToBytes( - "a4e8c9443c2619b6c92c9dd9941422274431e80503dc8a143ce8d97cde3e331fca29" - "e1de60ea50f7520d19192e39d0e106b37e20cc3a084afab1ab09c3205e1d7e59050a" - "b76101ea7bf014dcccc7f948ff5fb14ddd83ee804de5c659672142b4b7e661e0be8e" - "95eddee3b815f1f26741639fd04e5015153375ee1dfaa87ebf5b4340948538d3bfa1" - "b4cdc7e81b68c7c0c85879bd5026ea66735e4c3b56294f6c63ac1ba0709edeefc252" - "c90723039f1fe227086a2b57299d7f7bcd1f09b82985c7710bb43d342167142629a2" - "3094981f3908d0a1be38a5e3f823fad1ef96aa643fb5811cbafe8b134725075d4b66" - "4409de70b2571ea6ef53a44615db16b7bda5")}; - return std::make_pair(public_key, private_key); -} - -} // namespace anonymous_tokens -} // namespace private_membership
diff --git a/quiche/blind_sign_auth/anonymous_tokens/cpp/testing/utils.h b/quiche/blind_sign_auth/anonymous_tokens/cpp/testing/utils.h deleted file mode 100644 index 777e071..0000000 --- a/quiche/blind_sign_auth/anonymous_tokens/cpp/testing/utils.h +++ /dev/null
@@ -1,139 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef THIRD_PARTY_ANONYMOUS_TOKENS_CPP_TESTING_UTILS_H_ -#define THIRD_PARTY_ANONYMOUS_TOKENS_CPP_TESTING_UTILS_H_ - -#include <random> -#include <string> -#include <utility> - -#include "absl/status/statusor.h" -#include "absl/strings/string_view.h" -#include "openssl/base.h" - -namespace private_membership { -namespace anonymous_tokens { - -struct TestRsaPublicKey { - std::string n; - std::string e; -}; - -struct TestRsaPrivateKey { - std::string n; - std::string e; - std::string d; - std::string p; - std::string q; - std::string dp; - std::string dq; - std::string crt; -}; - -struct IetfStandardRsaBlindSignatureTestVector { - std::string n; - std::string e; - std::string d; - std::string p; - std::string q; - std::string message; - std::string salt; - std::string inv; - std::string encoded_message; - std::string blinded_message; - std::string blinded_signature; - std::string signature; -}; - -struct IetfRsaBlindSignatureWithPublicMetadataTestVector { - std::string n; - std::string e; - std::string d; - std::string p; - std::string q; - std::string message; - std::string public_metadata; - std::string message_mask; - std::string blinded_message; - std::string blinded_signature; - std::string signature; -}; - -// TestSign can be removed once rsa_blind_signer is moved to -// anonympous_tokens/public/cpp/crypto -absl::StatusOr<std::string> TestSign(absl::string_view blinded_data, - RSA* rsa_key); - -// TestSignWithPublicMetadata can be removed once rsa_blind_signer is moved to -// anonympous_tokens/public/cpp/crypto -absl::StatusOr<std::string> TestSignWithPublicMetadata( - absl::string_view blinded_data, absl::string_view public_metadata, - const RSA& rsa_key, bool use_rsa_public_exponent); - -// Returns the IETF test example from -// https://datatracker.ietf.org/doc/draft-irtf-cfrg-rsa-blind-signatures/ -IetfStandardRsaBlindSignatureTestVector -GetIetfStandardRsaBlindSignatureTestVector(); - -// Returns the IETF test with Public Metadata examples from -// https://datatracker.ietf.org/doc/draft-amjad-cfrg-partially-blind-rsa/ -// -// Note that all test vectors use the same RSA key pair. -std::vector<IetfRsaBlindSignatureWithPublicMetadataTestVector> -GetIetfRsaBlindSignatureWithPublicMetadataTestVectors(); - -// Returns the IETF test with Public Metadata examples that disregard the RSA -// public exponent during partially blind RSA signatures protocol execution. -// -// Note that all test vectors use the same RSA key pair. -std::vector<IetfRsaBlindSignatureWithPublicMetadataTestVector> -GetIetfPartiallyBlindRSASignatureNoPublicExponentTestVectors(); - -// Method returns fixed 2048-bit strong RSA modulus based key pair for testing. -std::pair<TestRsaPublicKey, TestRsaPrivateKey> GetStrongTestRsaKeyPair2048(); - -// Method returns another fixed 2048-bit strong RSA modulus based key pair for -// testing. -std::pair<TestRsaPublicKey, TestRsaPrivateKey> -GetAnotherStrongTestRsaKeyPair2048(); - -// Method returns fixed 3072-bit strong RSA modulus based key pair for testing. -std::pair<TestRsaPublicKey, TestRsaPrivateKey> GetStrongTestRsaKeyPair3072(); - -// Method returns fixed 4096-bit strong RSA modulus based key pair for testing. -std::pair<TestRsaPublicKey, TestRsaPrivateKey> GetStrongTestRsaKeyPair4096(); - -// Outputs a random string of n characters. -std::string RandomString(int n, std::uniform_int_distribution<int>* distr_u8, - std::mt19937_64* generator); - -#define ANON_TOKENS_ASSERT_OK_AND_ASSIGN(lhs, rexpr) \ - ANON_TOKENS_ASSERT_OK_AND_ASSIGN_IMPL_( \ - ANON_TOKENS_STATUS_TESTING_IMPL_CONCAT_(_status_or_value, __LINE__), \ - lhs, rexpr) - -#define ANON_TOKENS_ASSERT_OK_AND_ASSIGN_IMPL_(statusor, lhs, rexpr) \ - auto statusor = (rexpr); \ - ASSERT_THAT(statusor.ok(), ::testing::Eq(true)); \ - lhs = std::move(statusor).value() - -#define ANON_TOKENS_STATUS_TESTING_IMPL_CONCAT_INNER_(x, y) x##y -#define ANON_TOKENS_STATUS_TESTING_IMPL_CONCAT_(x, y) \ - ANON_TOKENS_STATUS_TESTING_IMPL_CONCAT_INNER_(x, y) - -} // namespace anonymous_tokens -} // namespace private_membership - -#endif // THIRD_PARTY_ANONYMOUS_TOKENS_CPP_TESTING_UTILS_H_
diff --git a/quiche/blind_sign_auth/anonymous_tokens/proto/anonymous_tokens.proto b/quiche/blind_sign_auth/anonymous_tokens/proto/anonymous_tokens.proto deleted file mode 100644 index 1f50fc0..0000000 --- a/quiche/blind_sign_auth/anonymous_tokens/proto/anonymous_tokens.proto +++ /dev/null
@@ -1,356 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package private_membership.anonymous_tokens; - -message Timestamp { - int64 seconds = 1; - int32 nanos = 2; -} - -// Different use cases for the Anonymous Tokens service. -// Next ID: 10 -enum AnonymousTokensUseCase { - // Test use cases here. - ANONYMOUS_TOKENS_USE_CASE_UNDEFINED = 0; - TEST_USE_CASE = 1; - TEST_USE_CASE_2 = 2; - TEST_USE_CASE_3 = 4; - TEST_USE_CASE_4 = 5; - TEST_USE_CASE_5 = 6; - TEST_USE_CASE_6 = 9; - - PROVABLY_PRIVATE_NETWORK = 3; - CHROME_IP_BLINDING = 7; - NOCTOGRAM_PPISSUER = 8; -} - -// An enum describing different types of available hash functions. -enum HashType { - AT_HASH_TYPE_UNDEFINED = 0; - AT_TEST_HASH_TYPE = 1; - AT_HASH_TYPE_SHA256 = 2; - AT_HASH_TYPE_SHA384 = 3; - // Add more hash types if necessary. -} - -// An enum describing different types of hash functions that can be used by the -// mask generation function. -enum MaskGenFunction { - AT_MGF_UNDEFINED = 0; - AT_TEST_MGF = 1; - AT_MGF_SHA256 = 2; - AT_MGF_SHA384 = 3; - // Add more hash types if necessary. -} - -// An enum describing different types of message masking. -enum MessageMaskType { - AT_MESSAGE_MASK_TYPE_UNDEFINED = 0; - AT_MESSAGE_MASK_XOR = 1; - AT_MESSAGE_MASK_CONCAT = 2; - AT_MESSAGE_MASK_NO_MASK = 3; -} - -// Proto representation for RSA private key. -message RSAPrivateKey { - // Modulus. - bytes n = 1; - // Public exponent. - bytes e = 2; - // Private exponent. - bytes d = 3; - // The prime factor p of n. - bytes p = 4; - // The prime factor q of n. - bytes q = 5; - // d mod (p - 1). - bytes dp = 6; - // d mod (q - 1). - bytes dq = 7; - // Chinese Remainder Theorem coefficient q^(-1) mod p. - bytes crt = 8; -} - -// Proto representation for RSA public key. -message RSAPublicKey { - // Modulus. - bytes n = 1; - // Public exponent. - bytes e = 2; -} - -// Next ID: 13 -message RSABlindSignaturePublicKey { - // Use case associated with this public key. - bytes use_case = 9; - - // Version number of public key. - int64 key_version = 1; - - // Serialization of the public key. - bytes serialized_public_key = 2; - - // Timestamp of expiration. - // - // Note that we will not return keys whose expiration times are in the past. - private_membership.anonymous_tokens.Timestamp expiration_time = 3; - - // Key becomes valid at key_validity_start_time. - private_membership.anonymous_tokens.Timestamp key_validity_start_time = 8; - - // Hash function used in computing hash of the signing message - // (see https://tools.ietf.org/html/rfc8017#section-9.1.1) - HashType sig_hash_type = 4; - - // Hash function used in MGF1 (a mask generation function based on a - // hash function) (see https://tools.ietf.org/html/rfc8017#appendix-B.2.1). - MaskGenFunction mask_gen_function = 5; - - // Length in bytes of the salt (see - // https://tools.ietf.org/html/rfc8017#section-9.1.1) - int64 salt_length = 6; - - // Key size: bytes of RSA key. - int64 key_size = 7; - - // Type of masking of message (see https://eprint.iacr.org/2022/895.pdf). - MessageMaskType message_mask_type = 10; - - // Length of message mask in bytes. - int64 message_mask_size = 11; - - // Conveys whether public metadata support is enabled and RSA blind signatures - // with public metadata protocol should be used. If false, standard RSA blind - // signatures are used and all public metadata inputs are ignored. - bool public_metadata_support = 12; -} - -message AnonymousTokensPublicKeysGetRequest { - // Use case associated with this request. - // - // Returns an error if the token type does not support public key verification - // for the requested use_case. - bytes use_case = 1; - - // Key version associated with this request. - // - // Returns an error if the token type does not support public key verification - // for the requested use_case and key_version combination. - // - // If unset, all valid possibilities for the key are returned. - int64 key_version = 2; - - // Public key that becomes valid at or before this requested time and not - // after. More explicitly, we need the requested key to be valid at the - // requested key_validity_start_time. - // - // If unset it will be set to current time. - private_membership.anonymous_tokens.Timestamp key_validity_start_time = 3 - ; - - // Public key that is definitely not valid after this particular time. If - // unset / null, only keys that are indefinitely valid are returned. - // - // Note: It is possible that the key becomes invalid before this time. But the - // key should not be valid after this time. - private_membership.anonymous_tokens.Timestamp key_validity_end_time = 4 - ; -} - -message AnonymousTokensPublicKeysGetResponse { - // List of currently valid RSA public keys. - repeated RSABlindSignaturePublicKey rsa_public_keys = 1; -} - -message AnonymousTokensSignRequest { - // Next ID: 6 - message BlindedToken { - // Use case associated with this request. - bytes use_case = 1; - - // Version of key used to sign and generate the token. - int64 key_version = 2; - - // Public metadata to be tied to the `blinded message` (serialized_token). - // - // The length of public metadata must fit in 4 bytes. - bytes public_metadata = 4; - - // This value is disregarded for standard blind RSA signatures. - // - // For the public metadata protocol, if this value is set to false, the - // final public exponent is derived by using the RSA public exponent, the - // RSA modulus and the public metadata. If this value is set to true, only - // the RSA modulus and the public metadata will be used. - bool do_not_use_rsa_public_exponent = 5; - - // Serialization of the token. - bytes serialized_token = 3; - } - - // Token(s) that have been blinded by the user, not yet signed - repeated BlindedToken blinded_tokens = 1; -} - -message AnonymousTokensSignResponse { - // Next ID: 7 - message AnonymousToken { - // Use case associated with this anonymous token. - bytes use_case = 1; - - // Version of key used to sign and generate the token. - int64 key_version = 2; - - // Public metadata tied to the input (serialized_blinded_message) and the - // `blinded` signature (serialized_token). - // - // The length of public metadata must fit in 4 bytes. - bytes public_metadata = 4; - - // This value is disregarded for standard blind RSA signatures. - // - // For the public metadata protocol, if this value is set to false, the - // final public exponent is derived by using the RSA public exponent, the - // RSA modulus and the public metadata. If this value is set to true, only - // the RSA modulus and the public metadata will be used. - bool do_not_use_rsa_public_exponent = 6; - - // The serialized_token in BlindedToken in the AnonymousTokensSignRequest. - bytes serialized_blinded_message = 5; - - // Serialization of the signed token. This will have to be `unblinded` by - // the user before it can be used / redeemed. - bytes serialized_token = 3; - } - - // Returned anonymous token(s) - repeated AnonymousToken anonymous_tokens = 1; -} - -message AnonymousTokensRedemptionRequest { - // Next ID: 7 - message AnonymousTokenToRedeem { - // Use case associated with this anonymous token that needs to be redeemed. - bytes use_case = 1; - - // Version of key associated with this anonymous token that needs to be - // redeemed. - int64 key_version = 2; - - // Public metadata to be used for redeeming the signature - // (serialized_unblinded_token). - // - // The length of public metadata must fit in 4 bytes. - bytes public_metadata = 4; - - // Serialization of the unblinded anonymous token that needs to be redeemed. - bytes serialized_unblinded_token = 3; - - // Plaintext input message to verify the signature for. - bytes plaintext_message = 5; - - // Nonce used to mask plaintext message before cryptographic verification. - bytes message_mask = 6; - } - - // One or more anonymous tokens to redeem. - repeated AnonymousTokenToRedeem anonymous_tokens_to_redeem = 1; -} - -message AnonymousTokensRedemptionResponse { - // Next ID: 9 - message AnonymousTokenRedemptionResult { - // Use case associated with this redeemed anonymous token. - bytes use_case = 3; - - // Version of key associated with this redeemed anonymous token. - int64 key_version = 4; - - // Public metadata used for verifying the signature - // (serialized_unblinded_token). - // - // The length of public metadata must fit in 4 bytes. - bytes public_metadata = 5; - - // Serialization of this redeemed unblinded anonymous token. - bytes serialized_unblinded_token = 6; - - // Unblinded input message that the signature was verified against. - bytes plaintext_message = 7; - - // Nonce used to mask plaintext message before cryptographic verification. - bytes message_mask = 8; - - // Returns true if and only if the anonymous token was redeemed - // successfully i.e. token was cryptographically verified, all relevant - // state in the server was updated successfully and the token was not - // redeemed already. - // - bool verified = 1; - - // Returns true if and only if the anonymous token has already been - // redeemed. - bool double_spent = 2; - } - - // Redemption response for requested anonymous tokens. - repeated AnonymousTokenRedemptionResult anonymous_token_redemption_results = - 1; -} - -// Plaintext message with public metadata. -message PlaintextMessageWithPublicMetadata { - // Message to be signed. - bytes plaintext_message = 1; - - // Public metadata to be tied to the signature. - bytes public_metadata = 2; -} - -// Proto representing a token created during the blind signing protocol. -message RSABlindSignatureToken { - // Resulting token from the blind signing protocol. - bytes token = 1; - - // Nonce used to mask messages. - bytes message_mask = 2; -} - -// Proto representing a token along with the input. -message RSABlindSignatureTokenWithInput { - // Input consisting of plaintext message and public metadata. - PlaintextMessageWithPublicMetadata input = 1; - - // Resulting token after blind signing protocol. - RSABlindSignatureToken token = 2; -} - -// Proto representing redemption result along with the token and the token -// input. -message RSABlindSignatureRedemptionResult { - // Proto representing a token along with the input. - RSABlindSignatureTokenWithInput token_with_input = 1; - - // This is set to true if and only if the anonymous token was redeemed - // successfully i.e. token was cryptographically verified, all relevant - // state in the redemption server was updated successfully and the token was - // not redeemed already. - bool redeemed = 2; - - // True if and only if the token was redeemed before. - bool double_spent = 3; -}
diff --git a/quiche/blind_sign_auth/blind_sign_auth.cc b/quiche/blind_sign_auth/blind_sign_auth.cc index d321074..0c8ea53 100644 --- a/quiche/blind_sign_auth/blind_sign_auth.cc +++ b/quiche/blind_sign_auth/blind_sign_auth.cc
@@ -16,7 +16,7 @@ #include "absl/strings/escaping.h" #include "absl/strings/str_cat.h" #include "absl/types/span.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/shared/proto_utils.h" +#include "anonymous_tokens/cpp/shared/proto_utils.h" #include "quiche/blind_sign_auth/blind_sign_auth_protos.h" #include "quiche/blind_sign_auth/blind_sign_http_response.h" #include "quiche/common/platform/api/quiche_logging.h" @@ -83,7 +83,7 @@ return; } absl::StatusOr<absl::Time> public_metadata_expiry_time = - private_membership::anonymous_tokens::TimeFromProto( + anonymous_tokens::TimeFromProto( initial_data_response.public_metadata_info() .public_metadata() .expiration()); @@ -95,7 +95,7 @@ // Create RSA BSSA client. auto bssa_client = - private_membership::anonymous_tokens::AnonymousTokensRsaBssaClient:: + anonymous_tokens::AnonymousTokensRsaBssaClient:: Create(initial_data_response.at_public_metadata_public_key()); if (!bssa_client.ok()) { QUICHE_LOG(WARNING) << "Failed to create AT BSSA client: " @@ -107,12 +107,12 @@ // Create plaintext tokens. // Client blinds plaintext tokens (random 32-byte strings) in CreateRequest. std::vector< - private_membership::anonymous_tokens::PlaintextMessageWithPublicMetadata> + anonymous_tokens::PlaintextMessageWithPublicMetadata> plaintext_tokens; QuicheRandom* random = QuicheRandom::GetInstance(); for (int i = 0; i < num_tokens; i++) { // Create random 32-byte string prefixed with "blind:". - private_membership::anonymous_tokens::PlaintextMessageWithPublicMetadata + anonymous_tokens::PlaintextMessageWithPublicMetadata plaintext_message; std::string rand_bytes(32, '\0'); random->RandBytes(rand_bytes.data(), rand_bytes.size()); @@ -136,7 +136,7 @@ } absl::StatusOr< - private_membership::anonymous_tokens::AnonymousTokensSignRequest> + anonymous_tokens::AnonymousTokensSignRequest> at_sign_request = bssa_client.value()->CreateRequest(plaintext_tokens); if (!at_sign_request.ok()) { QUICHE_LOG(WARNING) << "Failed to create AT Sign Request: " @@ -175,10 +175,10 @@ void BlindSignAuth::AuthAndSignCallback( privacy::ppn::PublicMetadataInfo public_metadata_info, absl::Time public_key_expiry_time, - private_membership::anonymous_tokens::AnonymousTokensSignRequest + anonymous_tokens::AnonymousTokensSignRequest at_sign_request, std::unique_ptr< - private_membership::anonymous_tokens::AnonymousTokensRsaBssaClient> + anonymous_tokens::AnonymousTokensRsaBssaClient> bssa_client, SignedTokenCallback callback, absl::StatusOr<BlindSignHttpResponse> response) { @@ -206,7 +206,7 @@ } // Create vector of unblinded anonymous tokens. - private_membership::anonymous_tokens::AnonymousTokensSignResponse + anonymous_tokens::AnonymousTokensSignResponse at_sign_response; if (sign_response.blinded_token_signature_size() != @@ -228,7 +228,7 @@ absl::InternalError("Failed to unescape blinded token signature")); return; } - private_membership::anonymous_tokens::AnonymousTokensSignResponse:: + anonymous_tokens::AnonymousTokensSignResponse:: AnonymousToken anon_token_proto; *anon_token_proto.mutable_use_case() = at_sign_request.blinded_tokens(i).use_case(); @@ -271,7 +271,7 @@ signed_tokens->at(i).token().token(); spend_token_data.set_signing_key_version( at_sign_response.anonymous_tokens(i).key_version()); - auto use_case = private_membership::anonymous_tokens::ParseUseCase( + auto use_case = anonymous_tokens::ParseUseCase( at_sign_response.anonymous_tokens(i).use_case()); if (!use_case.ok()) { QUICHE_LOG(WARNING) << "Failed to parse use case: " << use_case.status();
diff --git a/quiche/blind_sign_auth/blind_sign_auth.h b/quiche/blind_sign_auth/blind_sign_auth.h index 87fbfeb..d678afd 100644 --- a/quiche/blind_sign_auth/blind_sign_auth.h +++ b/quiche/blind_sign_auth/blind_sign_auth.h
@@ -11,7 +11,7 @@ #include "absl/status/status.h" #include "absl/status/statusor.h" #include "absl/time/time.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/client/anonymous_tokens_rsa_bssa_client.h" +#include "anonymous_tokens/cpp/client/anonymous_tokens_rsa_bssa_client.h" #include "quiche/blind_sign_auth/blind_sign_auth_interface.h" #include "quiche/blind_sign_auth/blind_sign_auth_protos.h" #include "quiche/blind_sign_auth/blind_sign_http_interface.h" @@ -44,10 +44,10 @@ void AuthAndSignCallback( privacy::ppn::PublicMetadataInfo public_metadata_info, absl::Time public_key_expiry_time, - private_membership::anonymous_tokens::AnonymousTokensSignRequest + anonymous_tokens::AnonymousTokensSignRequest at_sign_request, std::unique_ptr< - private_membership::anonymous_tokens::AnonymousTokensRsaBssaClient> + anonymous_tokens::AnonymousTokensRsaBssaClient> bssa_client, SignedTokenCallback callback, absl::StatusOr<BlindSignHttpResponse> response);
diff --git a/quiche/blind_sign_auth/blind_sign_auth_protos.h b/quiche/blind_sign_auth/blind_sign_auth_protos.h index 15e3b9a..b77dbe6 100644 --- a/quiche/blind_sign_auth/blind_sign_auth_protos.h +++ b/quiche/blind_sign_auth/blind_sign_auth_protos.h
@@ -1,13 +1,13 @@ #ifndef QUICHE_BLIND_SIGN_AUTH_BLIND_SIGN_AUTH_PROTOS_H_ #define QUICHE_BLIND_SIGN_AUTH_BLIND_SIGN_AUTH_PROTOS_H_ -#include "quiche/blind_sign_auth/anonymous_tokens/proto/anonymous_tokens.pb.h" // IWYU pragma: export +#include "anonymous_tokens/proto/anonymous_tokens.pb.h" // IWYU pragma: export #include "quiche/blind_sign_auth/proto/auth_and_sign.pb.h" // IWYU pragma: export #include "quiche/blind_sign_auth/proto/blind_sign_auth_options.pb.h" // IWYU pragma: export #include "quiche/blind_sign_auth/proto/get_initial_data.pb.h" // IWYU pragma: export #include "quiche/blind_sign_auth/proto/key_services.pb.h" // IWYU pragma: export #include "quiche/blind_sign_auth/proto/public_metadata.pb.h" // IWYU pragma: export #include "quiche/blind_sign_auth/proto/spend_token_data.pb.h" // IWYU pragma: export -#include "quiche/blind_sign_auth/anonymous_tokens/proto/anonymous_tokens.pb.h" // IWYU pragma: export +#include "anonymous_tokens/proto/anonymous_tokens.pb.h" // IWYU pragma: export #endif // QUICHE_BLIND_SIGN_AUTH_BLIND_SIGN_AUTH_PROTOS_H_
diff --git a/quiche/blind_sign_auth/blind_sign_auth_test.cc b/quiche/blind_sign_auth/blind_sign_auth_test.cc index 872d54e..c2e33cd 100644 --- a/quiche/blind_sign_auth/blind_sign_auth_test.cc +++ b/quiche/blind_sign_auth/blind_sign_auth_test.cc
@@ -13,8 +13,8 @@ #include "absl/strings/escaping.h" #include "absl/strings/string_view.h" #include "absl/time/time.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/testing/proto_utils.h" -#include "quiche/blind_sign_auth/anonymous_tokens/cpp/testing/utils.h" +#include "anonymous_tokens/cpp/testing/proto_utils.h" +#include "anonymous_tokens/cpp/testing/utils.h" #include "openssl/base.h" #include "quiche/blind_sign_auth/blind_sign_auth_protos.h" #include "quiche/blind_sign_auth/blind_sign_http_interface.h" @@ -39,7 +39,7 @@ protected: void SetUp() override { // Create public key. - auto keypair = private_membership::anonymous_tokens::CreateTestKey(); + auto keypair = anonymous_tokens::CreateTestKey(); if (!keypair.ok()) { return; } @@ -55,7 +55,7 @@ // Create fake public key response. privacy::ppn::GetInitialDataResponse fake_get_initial_data_response; - private_membership::anonymous_tokens::RSABlindSignaturePublicKey public_key; + anonymous_tokens::RSABlindSignaturePublicKey public_key; ASSERT_TRUE( public_key.ParseFromString(keypair_.second.SerializeAsString())); *fake_get_initial_data_response.mutable_at_public_metadata_public_key() = @@ -64,7 +64,7 @@ // Create public metadata info. privacy::ppn::PublicMetadata::Location location; location.set_country("US"); - private_membership::anonymous_tokens::Timestamp expiration; + anonymous_tokens::Timestamp expiration; expiration.set_seconds(absl::ToUnixSeconds(absl::Now() + absl::Hours(1))); privacy::ppn::PublicMetadata public_metadata; *public_metadata.mutable_exit_location() = location; @@ -113,7 +113,7 @@ std::string decoded_blinded_token; ASSERT_TRUE(absl::Base64Unescape(request_token, &decoded_blinded_token)); absl::StatusOr<std::string> serialized_token = - private_membership::anonymous_tokens::TestSign(decoded_blinded_token, + anonymous_tokens::TestSign(decoded_blinded_token, keypair_.first.get()); QUICHE_EXPECT_OK(serialized_token); response.add_blinded_token_signature( @@ -135,7 +135,7 @@ EXPECT_EQ(spend_token_data.signing_key_version(), keypair_.second.key_version()); EXPECT_NE(spend_token_data.use_case(), - private_membership::anonymous_tokens::AnonymousTokensUseCase:: + anonymous_tokens::AnonymousTokensUseCase:: ANONYMOUS_TOKENS_USE_CASE_UNDEFINED); EXPECT_NE(spend_token_data.message_mask(), ""); } @@ -144,7 +144,7 @@ MockBlindSignHttpInterface mock_http_interface_; std::unique_ptr<BlindSignAuth> blind_sign_auth_; std::pair<bssl::UniquePtr<RSA>, - private_membership::anonymous_tokens::RSABlindSignaturePublicKey> + anonymous_tokens::RSABlindSignaturePublicKey> keypair_; privacy::ppn::PublicMetadataInfo public_metadata_info_; privacy::ppn::AuthAndSignResponse sign_response_;
diff --git a/quiche/blind_sign_auth/proto/attestation.proto b/quiche/blind_sign_auth/proto/attestation.proto index 8e658e9..cb3843d 100644 --- a/quiche/blind_sign_auth/proto/attestation.proto +++ b/quiche/blind_sign_auth/proto/attestation.proto
@@ -29,7 +29,7 @@ // ECDSA( // SHA256( // <random bytes of length [64, 128]>.<expiry time in ms>)). - bytes nonce = 1 ; + bytes nonce = 1; // Nonce signature. bytes sig = 2; @@ -41,8 +41,8 @@ message ValidateDeviceRequest { // Attestation data that is returned by the client. oneof attestation_data { - AndroidAttestationData android_attestation_data = 1 [deprecated = true]; - IosAttestationData ios_attestation_data = 2 [deprecated = true]; + AndroidAttestationData android_attestation_data = 1; + IosAttestationData ios_attestation_data = 2; } AttestationData attestation = 3; @@ -87,16 +87,13 @@ } message PrepareAttestationData { - bytes attestation_nonce = 2 [ - - json_name = "attestation_nonce" - ]; + bytes attestation_nonce = 2; } message AndroidAttestationData { // Play IntegrityToken returned by Play Integrity API is detailed in // https://developer.android.com/google/play/integrity/verdict. - string attestation_token = 1 ; + string attestation_token = 1; // X509 Certificate chain generated by Android Keystore used for // Hardware-Backed Key Attestation. @@ -106,7 +103,7 @@ message IosAttestationData { // AppAttest attestation token. // Encoded in CBOR format. - bytes attestation_token = 1 ; + bytes attestation_token = 1; } message AttestationData {
diff --git a/quiche/blind_sign_auth/proto/auth_and_sign.proto b/quiche/blind_sign_auth/proto/auth_and_sign.proto index 27c3dde..36ac812 100644 --- a/quiche/blind_sign_auth/proto/auth_and_sign.proto +++ b/quiche/blind_sign_auth/proto/auth_and_sign.proto
@@ -27,24 +27,23 @@ // A 'bearer' oauth token to be validated. // https://datatracker.ietf.org/doc/html/rfc6750#section-6.1.1 - string oauth_token = 1 ; + string oauth_token = 1; // A string uniquely identifying the strategy this client should be // authenticated with. - string service_type = 2 ; + string service_type = 2; // A set of blinded tokens to be signed by zinc. b64 encoded. - repeated string blinded_token = 4 - ; + repeated string blinded_token = 4; // A sha256 of the public key PEM used in generated `blinded_token`. This // Ensures the signer signs with the matching key. Only required if key_type // is ZINC_KEY_TYPE. - string public_key_hash = 5 ; + string public_key_hash = 5; oneof attestation_data { - AndroidAttestationData android_attestation_data = 6 [deprecated = true]; - IosAttestationData ios_attestation_data = 7 [deprecated = true]; + AndroidAttestationData android_attestation_data = 6; + IosAttestationData ios_attestation_data = 7; } privacy.ppn.AttestationData attestation = 8; @@ -72,25 +71,15 @@ // A set of signatures corresponding by index to `blinded_token` in the // request. b64 encoded. - repeated string blinded_token_signature = 4 [ - - json_name = "blinded_token_signature" - ]; + repeated string blinded_token_signature = 4; // The marconi server hostname bridge-proxy used to set up tunnel. - string copper_controller_hostname = 5 [ - - json_name = "copper_controller_hostname" - ]; + string copper_controller_hostname = 5; // The base64 encoding of override_region token and signature for white listed // users in the format of "${Region}.${timestamp}.${signature}". - string region_token_and_signature = 6 [ - - json_name = "region_token_and_signature" - ]; + string region_token_and_signature = 6; // The APN type bridge-proxy use to deside which APN to use for connecting. - string apn_type = 7 - [ json_name = "apn_type"]; + string apn_type = 7; }
diff --git a/quiche/blind_sign_auth/proto/get_initial_data.proto b/quiche/blind_sign_auth/proto/get_initial_data.proto index 6b98745..987eceb 100644 --- a/quiche/blind_sign_auth/proto/get_initial_data.proto +++ b/quiche/blind_sign_auth/proto/get_initial_data.proto
@@ -18,18 +18,18 @@ import "quiche/blind_sign_auth/proto/attestation.proto"; import "quiche/blind_sign_auth/proto/public_metadata.proto"; -import "quiche/blind_sign_auth/anonymous_tokens/proto/anonymous_tokens.proto"; +import "anonymous_tokens/proto/anonymous_tokens.proto"; option java_multiple_files = true; // Request data needed to prepare for AuthAndSign. message GetInitialDataRequest { // Whether the client wants to use attestation as part of authentication. - bool use_attestation = 1 ; + bool use_attestation = 1; // A string uniquely identifying the strategy this client should be // authenticated with. - string service_type = 2 ; + string service_type = 2; enum LocationGranularity { UNKNOWN = 0; @@ -38,11 +38,10 @@ CITY_GEOS = 2; } // The user selected granularity of exit IP location. - LocationGranularity location_granularity = 3 - ; + LocationGranularity location_granularity = 3; // Indicates what validation rules the client uses for public metadata. - int64 validation_version = 4 ; + int64 validation_version = 4; } // Contains data needed to perform blind signing and prepare for calling @@ -50,7 +49,7 @@ message GetInitialDataResponse { reserved 4; - private_membership.anonymous_tokens.RSABlindSignaturePublicKey + anonymous_tokens.RSABlindSignaturePublicKey at_public_metadata_public_key = 1; // Version will match the validation version in the request. @@ -63,8 +62,7 @@ // Data needed to support the privacy pass specification. message PrivacyPassData { bytes token_key_id = 1; - bytes public_metadata_extensions = 2 - ; + bytes public_metadata_extensions = 2; } PrivacyPassData privacy_pass_data = 5; }
diff --git a/quiche/blind_sign_auth/proto/public_metadata.proto b/quiche/blind_sign_auth/proto/public_metadata.proto index f9f37d4..78258bb 100644 --- a/quiche/blind_sign_auth/proto/public_metadata.proto +++ b/quiche/blind_sign_auth/proto/public_metadata.proto
@@ -16,7 +16,7 @@ package privacy.ppn; -import "quiche/blind_sign_auth/anonymous_tokens/proto/anonymous_tokens.proto"; +import "anonymous_tokens/proto/anonymous_tokens.proto"; option java_multiple_files = true; @@ -41,7 +41,7 @@ string service_type = 2; // When the token and metadata expire. - private_membership.anonymous_tokens.Timestamp expiration = 3; + anonymous_tokens.Timestamp expiration = 3; // Indicates the debug context of this payload. enum DebugMode {
diff --git a/quiche/blind_sign_auth/proto/spend_token_data.proto b/quiche/blind_sign_auth/proto/spend_token_data.proto index 0fbca27..90b490d 100644 --- a/quiche/blind_sign_auth/proto/spend_token_data.proto +++ b/quiche/blind_sign_auth/proto/spend_token_data.proto
@@ -17,7 +17,7 @@ package privacy.ppn; import "quiche/blind_sign_auth/proto/public_metadata.proto"; -import "quiche/blind_sign_auth/anonymous_tokens/proto/anonymous_tokens.proto"; +import "anonymous_tokens/proto/anonymous_tokens.proto"; message SpendTokenData { // Public metadata associated with the token being spent. @@ -32,7 +32,7 @@ int64 signing_key_version = 4; // A use case identifying the caller. Should be a fixed, hardcoded value to // prevent cross-spending tokens. - private_membership.anonymous_tokens.AnonymousTokensUseCase use_case = 5; + anonymous_tokens.AnonymousTokensUseCase use_case = 5; // Nonce used to mask plaintext message before cryptographic verification. bytes message_mask = 6; // General public metadata. Use deserializer to inspect. Only set one of this
diff --git a/quiche/common/anonymous_tokens/testdata/strong_rsa_modulus2048_example.binarypb b/quiche/common/anonymous_tokens/testdata/strong_rsa_modulus2048_example.binarypb deleted file mode 100644 index c54070b..0000000 --- a/quiche/common/anonymous_tokens/testdata/strong_rsa_modulus2048_example.binarypb +++ /dev/null Binary files differ
diff --git a/quiche/common/anonymous_tokens/testdata/strong_rsa_modulus2048_example_2.binarypb b/quiche/common/anonymous_tokens/testdata/strong_rsa_modulus2048_example_2.binarypb deleted file mode 100644 index 50faa96..0000000 --- a/quiche/common/anonymous_tokens/testdata/strong_rsa_modulus2048_example_2.binarypb +++ /dev/null Binary files differ
diff --git a/quiche/common/anonymous_tokens/testdata/strong_rsa_modulus3072_example.binarypb b/quiche/common/anonymous_tokens/testdata/strong_rsa_modulus3072_example.binarypb deleted file mode 100644 index 3e4bae9..0000000 --- a/quiche/common/anonymous_tokens/testdata/strong_rsa_modulus3072_example.binarypb +++ /dev/null Binary files differ
diff --git a/quiche/common/anonymous_tokens/testdata/strong_rsa_modulus4096_example.binarypb b/quiche/common/anonymous_tokens/testdata/strong_rsa_modulus4096_example.binarypb deleted file mode 100644 index f322a9b..0000000 --- a/quiche/common/anonymous_tokens/testdata/strong_rsa_modulus4096_example.binarypb +++ /dev/null Binary files differ