Gosling Protocol v0.1.0
Richard Pospesel <richard@blueprintforfreespeech.org>
Morgan <morgan@torproject.org>
Gosling is a peer-to-peer authentication and authorisation protocol built on Tor onion-services. For a high-level overview of the protocol and its purpose, please see the design document1.
The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 21192.
Protocol
The Gosling protocol is defined in terms of a remote procedure call (RPC) interface. Specifically, Gosling uses Honk-RPC v0.1.03.
Honk-RPC itself uses BSON4 as the wire format for its messages, so the types in the following function definitions are referring to BSON-types. Any type marked binary
is specifically encoded as the ‘Generic binary subtype’ (\x00
). Any type marked document
is specifically encoded as a BSON document (an encoded set of key/value pairs).
Calling these functions out of order MUST result in an error being returned and the connection being closed.
Identity Handshake
Sequence Diagram
Identity Server RPC API
namespace gosling_identity {
// Begins an identity handshake session.
//
// Parameters:
// - string version : the requested version of the Gosling protocol to use
// - string client_identity : the client's identity server v3 onion service id
// - string endpoint : the application endpoint the client wants to access; this
// value MUST be encodable as ASCII.
//
// return : on success, a document object with the following members
// - binary server_cookie : 32 byte cookie randomly generated by the server
// - document endpoint_challenge : a document object containing any data the
// client needs to calculate the endpoint challenge response. The contents
// of this document are deliberately unspecified and are application-specific.
//
// An error is raised if an invalid version is provided.
begin_handshake(string version,
string client_identity,
string endpoint) -> document
// Submits the client proofs and the challenge response for server verification. If
// this function is called before begin_handshake() an error is returned.
//
// Parameters:
// - binary client_cookie : 32-byte cookie randomly generated by the client
// - binary client_identity_proof_signature : 64-byte ed25519 signature of the
// client proof, signed with the ed25519 private key used to generate the
// client's v3 onion service id (see 'Client Identity Proof Calculation and
// Verification')
// - binary client_authorization_key : 32-byte x25519 public key to be used to encrypt
// the endpoint onion service descriptor
// - bool client_authorization_key_signbit : the signbit of the ed25519 public key to be
// derived from the provided x25519 public key; true => 1, false => 0
// - binary client_authorization_signature : 64-byte ed25519 signature of the client's
// provided v3 onion service id, signed with the ed25519 private key derived
// from the private x25519 key associated with the provided public x25519
// 'client_authorization_key' (see 'Client Authorization Signature Generation
// and Verification')
// - document challenge_response : the calculated challenge response to the
// previous endpoint challenge request. The contents of this document are
// deliberately unspecified and are application-specific.
//
// return : on success, a string containing the v3 onion service id of the
// endpoint server (otherwise an error is raised); the endpoint's onion
// service descriptor will be encrypted with the provided client-authorization key
//
// An error is raised if any of the associated checks or signature verifications fail
send_response(binary client_cookie,
binary client_identity_proof_signature,
binary client_authorization_key,
bool client_authorization_key_signbit,
binary client_authorization_signature,
document challenge_response) -> string;
}
Endpoint Handshake
A client MAY connect an endpoint server multiple times by specifying different channel names. For example, a chat application could have concurrent ‘messaging’ and ‘file transfer’ channels.
Sequence Diagram
Endpoint Server RPC API
namespace gosling_endpoint {
// Begins an identity handshake session.
//
// Parameters:
// - string version : the requested version of the Gosling protocol to use
// - string client_identity : the client's identity server v3 onion service id
// - string channel : the application channel the client wants to open; this
// value MUST be encodable as ASCII.
//
// return : on success, a document object with the following members
// - binary server_cookie: 32 byte cookie randomly generated by the server
//
// An error is raised if an invalid version is provided.
begin_handshake(string version,
string client_identity,
string channel) -> document
// Submits the client proof for server verification. If this function is called
// before begin_handshake() an error is returned.
//
// Parameters:
// - binary client_cookie : 32-byte cookie randomly generated by the client
// - binary client_identity_proof_signature : 64-byte ed25519 signature of the
// client proof, signed with the ed25519 private key used to generate the
// client's v3 onion service id (see 'Client Identity Proof Calculation and
// Verification')
//
// return : on success, returns an empty document
//
// An error is raised if any of the associated checks or signature verifications fail
send_response(binary client_cookie,
binary client_identity_proof_signature) -> document;
}
Proofs and Signatures
Client Identity Proof Calculation and Verification
The purpose of this proof verification is for a connecting identity client or endpoint client to prove it owns the ed25519 private key used to derive the v3 onion-service service-id it claims as its identity. This prevents client impersonation.
The proof is calculated as:
proof = domain_separator +
request +
client_service_id +
server_service_id +
hex_client_cookie +
hex_server_cookie
The +
operator here indicates concatenation with a null byte in-between. For example, "a" + "b" + "c"
would be encoded as the byte array ['a', \x00, 'b', \x00, 'c']
.
Each of the parameters MUST be representable as an ASCII string and do not include an implicit null-terminator. The parameters are defined as:
domain_separator
: an ASCII string; for the identity handshake, this string isgosling-identity
and for the endpoint handshake, this string isgosling-endpoint
request
: an ASCII string; for the identity handshake, this string is the requested endpoint and for the endpoint handshake, this string is the requested channelclient_service_id
: an ASCII string; the base-32 encoded onion-service service-id (without the “.onion” suffix) of the connecting client’s identity serverserver_service_id
: an ASCII string; the base-32 encoded onion-service service-id (without the “.onion” suffix) of the connected server (i.e. when connected to the identity server, that identity server’s onion-service service-id is used; when connected to an endpoint server, that endpoint server’s onion-service service-id is used)client_cookie
: an ASCII string; the cryptographically-randomly generated 32-byte client cookie encoded as lower-case hexadecimal (0-9a-f)server_cookie
: an ASCII string; the cryptographically-randomly generated 32-byte server cookie encoded as lower-case hexadecimal (0-9a-f)
A client signs the above proof with its ed25519 private key. A gosling server MUST verify this signature using the client’s ed25519 public key derived from the client’s provided v3 onion-service service-id .
Client-Authorization Signature Generation and Verification
The purpose of this verification is to verify the connecting identity client owns the x25519 private key used to derive the x25519 public key it provides for endpoint server client-authorisation. This prevents impersonation of other clients.
Generation
The signature is calculated by the identity client by signing its v3 onion-service service-id (without the “.onion” suffix) with the ed25519 private key derived from the x25519 private key used to calculate the provided x25519 public key to use for onion-service client-authorization. The identity server verifies this signature with the ed25519 public key derived from the identity client’s provided x25519 key.
An identity client proves they control the x25519 private key associated with the provided x25519 public key (used for onion service client-authorization) by generating the above signature and sending it to the identity server.
Verification
To verify this signature, the identity server first converts the received x25519 public key + signbit into an ed25519 public key. It then verifies the signature using this derived key.
A gosling identity server MUST verify the validity of the provided signature to prove the identity client controls the private x25519 key used to derive the provided public x25519 key.
Acknowledgements
Creation of innovative free software needs support. We thank the NGI Assure Fund, a fund established by NLnet with financial support from the European Commission’s Next Generation Internet programme, under the aegis of DG Communications Networks, Content and Technology under grant agreement No 957073
Gosling Design and Adversary Model https://gosling.technology/design-doc.xhtml↩︎
Honk-RPC v0.1.0 specification https://gosling.technology/honk-rpc-spec.xtml↩︎
BSON specification https://bsonspec.org/spec.html↩︎