Implement HTTP Signature Authentication
This CL implements HTTP Signature Authentication as defined in [draft-ietf-httpbis-unprompted-auth-05](https://www.ietf.org/archive/id/draft-ietf-httpbis-unprompted-auth-05.html).
For now this is all inside the MASQUE code to allow easily testing interop at the IETF hackathon without the testing requirements that come with the main HTTP/3 code.
PiperOrigin-RevId: 597238379
diff --git a/quiche/quic/masque/masque_server_backend.cc b/quiche/quic/masque/masque_server_backend.cc
index a40ecc0..8fbeec7 100644
--- a/quiche/quic/masque/masque_server_backend.cc
+++ b/quiche/quic/masque/masque_server_backend.cc
@@ -5,7 +5,9 @@
#include "quiche/quic/masque/masque_server_backend.h"
#include "absl/strings/str_cat.h"
+#include "absl/strings/str_split.h"
#include "absl/strings/string_view.h"
+#include "openssl/curve25519.h"
namespace quic {
@@ -151,4 +153,44 @@
return address;
}
+void MasqueServerBackend::SetSignatureAuth(absl::string_view signature_auth) {
+ signature_auth_credentials_.clear();
+ if (signature_auth.empty()) {
+ return;
+ }
+ for (absl::string_view sp : absl::StrSplit(signature_auth, ';')) {
+ quiche::QuicheTextUtils::RemoveLeadingAndTrailingWhitespace(&sp);
+ if (sp.empty()) {
+ continue;
+ }
+ std::vector<absl::string_view> kv =
+ absl::StrSplit(sp, absl::MaxSplits(':', 1));
+ quiche::QuicheTextUtils::RemoveLeadingAndTrailingWhitespace(&kv[0]);
+ quiche::QuicheTextUtils::RemoveLeadingAndTrailingWhitespace(&kv[1]);
+ SignatureAuthCredential credential;
+ credential.key_id = std::string(kv[0]);
+ std::string public_key = absl::HexStringToBytes(kv[1]);
+ if (public_key.size() != sizeof(credential.public_key)) {
+ QUIC_LOG(FATAL) << "Invalid signature auth public key length "
+ << public_key.size();
+ }
+ memcpy(credential.public_key, public_key.data(),
+ sizeof(credential.public_key));
+ signature_auth_credentials_.push_back(credential);
+ }
+}
+
+bool MasqueServerBackend::GetSignatureAuthKeyForId(
+ absl::string_view key_id,
+ uint8_t out_public_key[ED25519_PUBLIC_KEY_LEN]) const {
+ for (const auto& credential : signature_auth_credentials_) {
+ if (credential.key_id == key_id) {
+ memcpy(out_public_key, credential.public_key,
+ sizeof(credential.public_key));
+ return true;
+ }
+ }
+ return false;
+}
+
} // namespace quic