Table of Contents

Class ServerToken

Namespace
VpnHood.Core.Common.Tokens
Assembly
VpnHood.Core.Common.dll

Represents a server token: how a client finds the servers of a farm or a standalone server, and trusts them. MANAGER calls a farm's its farm token.

public class ServerToken
Inheritance
ServerToken
Inherited Members
Extension Methods

Remarks

It travels inside an access key, and, encrypted (Encrypt(byte[]?)), at its update URLs, from which a client takes a newer one.

Properties

CertificateHash

Gets or sets the hash of the servers' certificate (GetCertHash()), or null. A client accepts a certificate of this hash even when the system's checks of its chain, name or dates fail; any other certificate must pass them, though the client may supply a Let's Encrypt root the system lacks, the other checks still applying.

[JsonPropertyName("ch")]
public byte[]? CertificateHash { get; set; }

Property Value

byte[]

CreatedTime

Gets or sets when the token was made, in UTC, which tells a newer one (IsTokenUpdated(ServerToken, ServerToken)).

[JsonPropertyName("ct")]
public required DateTime CreatedTime { get; set; }

Property Value

DateTime

EndPointsStrategy

Gets or sets how a client orders the host name's addresses and HostEndPoints, when its own setting is Auto.

[JsonPropertyName("ep_st")]
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public EndPointStrategy EndPointsStrategy { get; set; }

Property Value

EndPointStrategy

HostEndPoints

Gets or sets the servers' endpoints, which a client may connect to without DNS, or null.

[JsonPropertyName("ep")]
[JsonConverter(typeof(ArrayConverter<IPEndPoint, IPEndPointConverter>))]
public IPEndPoint[]? HostEndPoints { get; set; }

Property Value

IPEndPoint[]

HostName

Gets or sets the servers' host name, which the client gives in its TLS handshake, and looks up when it is a real one (IsValidHostName).

[JsonPropertyName("hname")]
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public required string HostName { get; set; }

Property Value

string

HostPort

Gets or sets the port of the host name's addresses.

[JsonPropertyName("hport")]
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public required int HostPort { get; set; }

Property Value

int

IsValidHostName

Gets or sets a value indicating whether the host name is a real one, which resolves to the servers: the client then looks it up for their addresses, unless its strategy is IpOnly with HostEndPoints listed. When false, the client uses HostEndPoints alone.

[JsonPropertyName("isv")]
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public required bool IsValidHostName { get; set; }

Property Value

bool

PathBase

Gets or sets the path the servers' requests go under, such as /servers/serverId, or null.

[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
[JsonPropertyName("path")]
public string? PathBase { get; set; }

Property Value

string

Secret

Gets or sets the farm's secret: the AES key of the token at its update URLs, from which the client also derives the key that signs its proofs to the servers. A client of this version refuses an access key whose server token has none.

[JsonPropertyName("sec")]
public required byte[]? Secret { get; set; }

Property Value

byte[]

ServerLocations

Gets or sets the servers' locations, each as Parse(string) reads one, such as US/California [#premium], or null.

[JsonPropertyName("loc2")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
public string[]? ServerLocations { get; set; }

Property Value

string[]

ServerLocationsLegacy

Gets or sets the server locations without their tags, for older clients; setting it sets ServerLocations only while that is empty.

[JsonPropertyName("loc")]
[Obsolete]
public string[]? ServerLocationsLegacy { get; set; }

Property Value

string[]

Url

Gets or sets the first update URL, for clients before Urls; setting it sets Urls only while that is empty.

[JsonPropertyName("url")]
[Obsolete("Use Urls. Version 558 or upper")]
public string? Url { get; set; }

Property Value

string

Urls

Gets or sets the update URLs: where a client finds a newer token, encrypted with Secret, or null.

[JsonPropertyName("urls")]
public string[]? Urls { get; set; }

Property Value

string[]

Methods

Decrypt(byte[], string)

Decrypts a token that Encrypt(byte[]?) made.

public static ServerToken Decrypt(byte[] serverSecret, string base64)

Parameters

serverSecret byte[]

The farm's secret.

base64 string

The encrypted token: the Base64 of the IV, a dot, and the Base64 of the encrypted JSON.

Returns

ServerToken

The token.

Exceptions

FormatException

The text is not two Base64 parts with a dot between, or an endpoint in the token is not valid.

CryptographicException

The secret is wrong, or the data is corrupt.

JsonException

The decrypted text is not a valid token's JSON.

InvalidDataException

The decrypted JSON is null.

Encrypt(byte[]?)

Encrypts the token, for its update URLs: AES in CBC mode with PKCS #7 padding, keyed with Secret, of its JSON with the properties at their defaults left out, but for those marked to be always written, such as IsValidHostName.

public string Encrypt(byte[]? iv = null)

Parameters

iv byte[]

The initialization vector, or null for random bytes as long as the secret.

Returns

string

The Base64 of the IV, a dot, and the Base64 of the encrypted JSON.

Remarks

The IV must be 16 bytes, AES's block, so a random one fits only a 16-byte secret. Nothing authenticates the result.

Exceptions

Exception

The token has no secret.

CryptographicException

The IV is not 16 bytes, or the secret is no AES key's length.