From 97dfbf32a0380197321409bf937a913caf036f62 Mon Sep 17 00:00:00 2001 From: Riya Mehta Date: Wed, 4 Dec 2024 09:30:18 -0800 Subject: [PATCH] Change S2A proto package name. --- grpc/gcp/s2a/proto/v2/common.proto | 82 ++++++ grpc/gcp/s2a/proto/v2/s2a.proto | 373 ++++++++++++++++++++++++ grpc/gcp/s2a/proto/v2/s2a_context.proto | 64 ++++ 3 files changed, 519 insertions(+) create mode 100644 grpc/gcp/s2a/proto/v2/common.proto create mode 100644 grpc/gcp/s2a/proto/v2/s2a.proto create mode 100644 grpc/gcp/s2a/proto/v2/s2a_context.proto diff --git a/grpc/gcp/s2a/proto/v2/common.proto b/grpc/gcp/s2a/proto/v2/common.proto new file mode 100644 index 00000000..fe33e2ce --- /dev/null +++ b/grpc/gcp/s2a/proto/v2/common.proto @@ -0,0 +1,82 @@ +// Copyright 2024 The gRPC Authors +// +// 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 +// +// http://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. + +// The canonical version of this proto can be found at +// https://github.com/grpc/grpc-proto/blob/master/grpc/gcp/s2a/common.proto + +syntax = "proto3"; + +package s2a.proto.v2; + +option java_multiple_files = true; +option java_outer_classname = "CommonProto"; +option java_package = "io.grpc.s2a.internal.handshaker"; + +// The TLS 1.0-1.2 ciphersuites that the application can negotiate when using +// S2A. +enum Ciphersuite { + CIPHERSUITE_UNSPECIFIED = 0; + CIPHERSUITE_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 = 1; + CIPHERSUITE_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 = 2; + CIPHERSUITE_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 = 3; + CIPHERSUITE_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 4; + CIPHERSUITE_ECDHE_RSA_WITH_AES_256_GCM_SHA384 = 5; + CIPHERSUITE_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 6; +} + +// The TLS versions supported by S2A's handshaker module. +enum TLSVersion { + TLS_VERSION_UNSPECIFIED = 0; + TLS_VERSION_1_0 = 1; + TLS_VERSION_1_1 = 2; + TLS_VERSION_1_2 = 3; + TLS_VERSION_1_3 = 4; +} + +// The side in the TLS connection. +enum ConnectionSide { + CONNECTION_SIDE_UNSPECIFIED = 0; + CONNECTION_SIDE_CLIENT = 1; + CONNECTION_SIDE_SERVER = 2; +} + +// The ALPN protocols that the application can negotiate during a TLS handshake. +enum AlpnProtocol { + ALPN_PROTOCOL_UNSPECIFIED = 0; + ALPN_PROTOCOL_GRPC = 1; + ALPN_PROTOCOL_HTTP2 = 2; + ALPN_PROTOCOL_HTTP1_1 = 3; +} + +message Identity { + oneof identity_oneof { + // The SPIFFE ID of a connection endpoint. + string spiffe_id = 1; + + // The hostname of a connection endpoint. + string hostname = 2; + + // The UID of a connection endpoint. + string uid = 4; + + // The username of a connection endpoint. + string username = 5; + + // The GCP ID of a connection endpoint. + string gcp_id = 6; + } + + // Additional identity-specific attributes. + map attributes = 3; +} diff --git a/grpc/gcp/s2a/proto/v2/s2a.proto b/grpc/gcp/s2a/proto/v2/s2a.proto new file mode 100644 index 00000000..a95676ae --- /dev/null +++ b/grpc/gcp/s2a/proto/v2/s2a.proto @@ -0,0 +1,373 @@ +// Copyright 2024 The gRPC Authors +// +// 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 +// +// http://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. + +// The canonical version of this proto can be found at +// https://github.com/grpc/grpc-proto/blob/master/grpc/gcp/s2a/s2a.proto + +syntax = "proto3"; + +package s2a.proto.v2; + +import "grpc/gcp/s2a/proto/v2/common.proto"; +import "grpc/gcp/s2a/proto/v2/s2a_context.proto"; + +option java_multiple_files = true; +option java_outer_classname = "S2AProto"; +option java_package = "io.grpc.s2a.internal.handshaker"; + +enum SignatureAlgorithm { + S2A_SSL_SIGN_UNSPECIFIED = 0; + // RSA Public-Key Cryptography Standards #1. + S2A_SSL_SIGN_RSA_PKCS1_SHA256 = 1; + S2A_SSL_SIGN_RSA_PKCS1_SHA384 = 2; + S2A_SSL_SIGN_RSA_PKCS1_SHA512 = 3; + // ECDSA. + S2A_SSL_SIGN_ECDSA_SECP256R1_SHA256 = 4; + S2A_SSL_SIGN_ECDSA_SECP384R1_SHA384 = 5; + S2A_SSL_SIGN_ECDSA_SECP521R1_SHA512 = 6; + // RSA Probabilistic Signature Scheme. + S2A_SSL_SIGN_RSA_PSS_RSAE_SHA256 = 7; + S2A_SSL_SIGN_RSA_PSS_RSAE_SHA384 = 8; + S2A_SSL_SIGN_RSA_PSS_RSAE_SHA512 = 9; + // ED25519. + S2A_SSL_SIGN_ED25519 = 10; +} + +message AlpnPolicy { + // If true, the application MUST perform ALPN negotiation. + bool enable_alpn_negotiation = 1; + + // The ordered list of ALPN protocols that specify how the application SHOULD + // negotiate ALPN during the TLS handshake. + // + // The application MAY ignore any ALPN protocols in this list that are not + // supported by the application. + repeated AlpnProtocol alpn_protocols = 2; +} + +message AuthenticationMechanism { + reserved 1; + + // Applications may specify an identity associated to an authentication + // mechanism. Otherwise, S2A assumes that the authentication mechanism is + // associated with the default identity. If the default identity cannot be + // determined, the request is rejected. + Identity identity = 3; + + oneof mechanism_oneof { + // A token that the application uses to authenticate itself to S2A. + string token = 2; + } +} + +message Status { + // The status code that is specific to the application and the implementation + // of S2A, e.g., gRPC status code. + uint32 code = 1; + + // The status details. + string details = 2; +} + +message GetTlsConfigurationReq { + // The role of the application in the TLS connection. + ConnectionSide connection_side = 1; + + // The server name indication (SNI) extension, which MAY be populated when a + // server is offloading to S2A. The SNI is used to determine the server + // identity if the local identity in the request is empty. + string sni = 2; +} + +message GetTlsConfigurationResp { + // Next ID: 8 + message ClientTlsConfiguration { + reserved 4, 5; + + // The certificate chain that the client MUST use for the TLS handshake. + // It's a list of PEM-encoded certificates, ordered from leaf to root, + // excluding the root. + repeated string certificate_chain = 1; + + // The minimum TLS version number that the client MUST use for the TLS + // handshake. If this field is not provided, the client MUST use the default + // minimum version of the client's TLS library. + TLSVersion min_tls_version = 2; + + // The maximum TLS version number that the client MUST use for the TLS + // handshake. If this field is not provided, the client MUST use the default + // maximum version of the client's TLS library. + TLSVersion max_tls_version = 3; + + // The ordered list of TLS 1.0-1.2 ciphersuites that the client MAY offer to + // negotiate in the TLS handshake. + repeated Ciphersuite ciphersuites = 6; + + // The policy that dictates how the client negotiates ALPN during the TLS + // handshake. + AlpnPolicy alpn_policy = 7; + } + + // Next ID: 12 + message ServerTlsConfiguration { + reserved 4, 5; + + enum RequestClientCertificate { + UNSPECIFIED = 0; + DONT_REQUEST_CLIENT_CERTIFICATE = 1; + REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY = 2; + REQUEST_CLIENT_CERTIFICATE_AND_VERIFY = 3; + REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY = 4; + REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY = 5; + } + + // The certificate chain that the server MUST use for the TLS handshake. + // It's a list of PEM-encoded certificates, ordered from leaf to root, + // excluding the root. + repeated string certificate_chain = 1; + + // The minimum TLS version number that the server MUST use for the TLS + // handshake. If this field is not provided, the server MUST use the default + // minimum version of the server's TLS library. + TLSVersion min_tls_version = 2; + + // The maximum TLS version number that the server MUST use for the TLS + // handshake. If this field is not provided, the server MUST use the default + // maximum version of the server's TLS library. + TLSVersion max_tls_version = 3; + + // The ordered list of TLS 1.0-1.2 ciphersuites that the server MAY offer to + // negotiate in the TLS handshake. + repeated Ciphersuite ciphersuites = 10; + + // Whether to enable TLS resumption. + bool tls_resumption_enabled = 6; + + // Whether the server MUST request a client certificate (i.e. to negotiate + // TLS vs. mTLS). + RequestClientCertificate request_client_certificate = 7; + + // Returns the maximum number of extra bytes that + // |OffloadResumptionKeyOperation| can add to the number of unencrypted + // bytes to form the encrypted bytes. + uint32 max_overhead_of_ticket_aead = 9; + + // The policy that dictates how the server negotiates ALPN during the TLS + // handshake. + AlpnPolicy alpn_policy = 11; + } + + oneof tls_configuration { + ClientTlsConfiguration client_tls_configuration = 1; + ServerTlsConfiguration server_tls_configuration = 2; + } +} + +message OffloadPrivateKeyOperationReq { + enum PrivateKeyOperation { + UNSPECIFIED = 0; + // When performing a TLS 1.2 or 1.3 handshake, the (partial) transcript of + // the TLS handshake must be signed to prove possession of the private key. + // + // See https://www.rfc-editor.org/rfc/rfc8446.html#section-4.4.3. + SIGN = 1; + // When performing a TLS 1.2 handshake using an RSA algorithm, the key + // exchange algorithm involves the client generating a premaster secret, + // encrypting it using the server's public key, and sending this encrypted + // blob to the server in a ClientKeyExchange message. + // + // See https://www.rfc-editor.org/rfc/rfc4346#section-7.4.7.1. + DECRYPT = 2; + } + + // The operation the private key is used for. + PrivateKeyOperation operation = 1; + + // The signature algorithm to be used for signing operations. + SignatureAlgorithm signature_algorithm = 2; + + // The input bytes to be signed or decrypted. + oneof in_bytes { + // Raw bytes to be hashed and signed, or decrypted. + bytes raw_bytes = 4; + // A SHA256 hash to be signed. Must be 32 bytes. + bytes sha256_digest = 5; + // A SHA384 hash to be signed. Must be 48 bytes. + bytes sha384_digest = 6; + // A SHA512 hash to be signed. Must be 64 bytes. + bytes sha512_digest = 7; + } +} + +message OffloadPrivateKeyOperationResp { + // The signed or decrypted output bytes. + bytes out_bytes = 1; +} + +message OffloadResumptionKeyOperationReq { + enum ResumptionKeyOperation { + UNSPECIFIED = 0; + ENCRYPT = 1; + DECRYPT = 2; + } + + // The operation the resumption key is used for. + ResumptionKeyOperation operation = 1; + + // The bytes to be encrypted or decrypted. + bytes in_bytes = 2; +} + +message OffloadResumptionKeyOperationResp { + // The encrypted or decrypted bytes. + bytes out_bytes = 1; +} + +message ValidatePeerCertificateChainReq { + enum VerificationMode { + // The default verification mode supported by S2A. + UNSPECIFIED = 0; + // The SPIFFE verification mode selects the set of trusted certificates to + // use for path building based on the SPIFFE trust domain in the peer's leaf + // certificate. + SPIFFE = 1; + // The connect-to-Google verification mode uses the trust bundle for + // connecting to Google, e.g. *.mtls.googleapis.com endpoints. + CONNECT_TO_GOOGLE = 2; + } + + message ClientPeer { + // The certificate chain to be verified. The chain MUST be a list of + // DER-encoded certificates, ordered from leaf to root, excluding the root. + repeated bytes certificate_chain = 1; + } + + message ServerPeer { + // The certificate chain to be verified. The chain MUST be a list of + // DER-encoded certificates, ordered from leaf to root, excluding the root. + repeated bytes certificate_chain = 1; + + // The expected hostname of the server. + string server_hostname = 2; + + // The UnrestrictedClientPolicy specified by the user. + bytes serialized_unrestricted_client_policy = 3; + } + + // The verification mode that S2A MUST use to validate the peer certificate + // chain. + VerificationMode mode = 1; + + oneof peer_oneof { + ClientPeer client_peer = 2; + ServerPeer server_peer = 3; + } +} + +message ValidatePeerCertificateChainResp { + enum ValidationResult { + UNSPECIFIED = 0; + SUCCESS = 1; + FAILURE = 2; + } + + // The result of validating the peer certificate chain. + ValidationResult validation_result = 1; + + // The validation details. This field is only populated when the validation + // result is NOT SUCCESS. + string validation_details = 2; + + // The S2A context contains information from the peer certificate chain. + // + // The S2A context MAY be populated even if validation of the peer certificate + // chain fails. + S2AContext context = 3; +} + +message SessionReq { + reserved 1; + + // The identity corresponding to the TLS configurations that MUST be used for + // the TLS handshake. + // + // If a managed identity already exists, the local identity and authentication + // mechanisms are ignored. If a managed identity doesn't exist and the local + // identity is not populated, S2A will try to deduce the managed identity to + // use from the SNI extension. If that also fails, S2A uses the default + // identity (if one exists). + Identity local_identity = 7; + + // The authentication mechanisms that the application wishes to use to + // authenticate to S2A, ordered by preference. S2A will always use the first + // authentication mechanism that matches the managed identity. + repeated AuthenticationMechanism authentication_mechanisms = 2; + + oneof req_oneof { + // Requests the certificate chain and TLS configuration corresponding to the + // local identity, which the application MUST use to negotiate the TLS + // handshake. + GetTlsConfigurationReq get_tls_configuration_req = 3; + + // Signs or decrypts the input bytes using a private key corresponding to + // the local identity in the request. + // + // WARNING: More than one OffloadPrivateKeyOperationReq may be sent to the + // S2Av2 by a server during a TLS 1.2 handshake. + OffloadPrivateKeyOperationReq offload_private_key_operation_req = 4; + + // Encrypts or decrypts the input bytes using a resumption key corresponding + // to the local identity in the request. + OffloadResumptionKeyOperationReq offload_resumption_key_operation_req = 5; + + // Verifies the peer's certificate chain using + // (a) trust bundles corresponding to the local identity in the request, and + // (b) the verification mode in the request. + ValidatePeerCertificateChainReq validate_peer_certificate_chain_req = 6; + } +} + +message SessionResp { + // Status of the session response. + // + // The status field is populated so that if an error occurs when making an + // individual request, then communication with the S2A may continue. If an + // error is returned directly (e.g. at the gRPC layer), then it may result + // that the bidirectional stream being closed. + Status status = 1; + + oneof resp_oneof { + // Contains the certificate chain and TLS configurations corresponding to + // the local identity. + GetTlsConfigurationResp get_tls_configuration_resp = 2; + + // Contains the signed or encrypted output bytes using the private key + // corresponding to the local identity. + OffloadPrivateKeyOperationResp offload_private_key_operation_resp = 3; + + // Contains the encrypted or decrypted output bytes using the resumption key + // corresponding to the local identity. + OffloadResumptionKeyOperationResp offload_resumption_key_operation_resp = 4; + + // Contains the validation result, peer identity and fingerprints of peer + // certificates. + ValidatePeerCertificateChainResp validate_peer_certificate_chain_resp = 5; + } +} + +service S2AService { + // SetUpSession is a bidirectional stream used by applications to offload + // operations from the TLS handshake. + rpc SetUpSession(stream SessionReq) returns (stream SessionResp) {} +} diff --git a/grpc/gcp/s2a/proto/v2/s2a_context.proto b/grpc/gcp/s2a/proto/v2/s2a_context.proto new file mode 100644 index 00000000..ebe54200 --- /dev/null +++ b/grpc/gcp/s2a/proto/v2/s2a_context.proto @@ -0,0 +1,64 @@ +// Copyright 2024 The gRPC Authors +// +// 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 +// +// http://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. + +// The canonical version of this proto can be found at +// https://github.com/grpc/grpc-proto/blob/master/grpc/gcp/s2a/s2a_context.proto + +syntax = "proto3"; + +package s2a.proto.v2; + +import "grpc/gcp/s2a/proto/v2/common.proto"; + +option java_multiple_files = true; +option java_outer_classname = "S2AContextProto"; +option java_package = "io.grpc.s2a.internal.handshaker"; + +message S2AContext { + reserved 5, 7, 8; + + // The SPIFFE ID from the peer leaf certificate, if present. + // + // This field is only populated if the leaf certificate is a valid SPIFFE + // SVID; in particular, there is a unique URI SAN and this URI SAN is a valid + // SPIFFE ID. + string leaf_cert_spiffe_id = 1; + + // The URIs that are present in the SubjectAltName extension of the peer leaf + // certificate. + // + // Note that the extracted URIs are not validated and may not be properly + // formatted. + repeated string leaf_cert_uris = 2; + + // The DNSNames that are present in the SubjectAltName extension of the peer + // leaf certificate. + repeated string leaf_cert_dnsnames = 3; + + // The (ordered) list of fingerprints in the certificate chain used to verify + // the given leaf certificate. The order MUST be from leaf certificate + // fingerprint to root certificate fingerprint. + // + // A fingerprint is the base-64 encoding of the SHA256 hash of the + // DER-encoding of a certificate. The list MAY be populated even if the peer + // certificate chain was NOT validated successfully. + repeated string peer_certificate_chain_fingerprints = 4; + + // The local identity used during session setup. + Identity local_identity = 9; + + // The SHA256 hash of the DER-encoding of the local leaf certificate used in + // the handshake. + bytes local_leaf_cert_fingerprint = 6; +}