aboutsummaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorHenauxg <19689618+Henauxg@users.noreply.github.com>2022-11-15 17:58:07 +0100
committerHenauxg <19689618+Henauxg@users.noreply.github.com>2022-11-15 17:58:07 +0100
commit0842b723eaee8da25be4628fb0c583dc6925ec89 (patch)
tree2c3cdf6a440bcd2fbd8b574fc2f7b7749a0c1166 /docs
parent6bcc1f2b524d5c2bba78f475b3a6c32b0283e70b (diff)
[doc] Update README, and add docs/certificates for server certificate verification
Diffstat (limited to 'docs')
-rw-r--r--docs/Certificates.md88
1 files changed, 88 insertions, 0 deletions
diff --git a/docs/Certificates.md b/docs/Certificates.md
new file mode 100644
index 0000000..b2cf0ff
--- /dev/null
+++ b/docs/Certificates.md
@@ -0,0 +1,88 @@
+# Certificates and server authentication
+
+## Trust on first use
+
+### Default configuration
+
+Use it like this:
+```rust
+client.connect(/*...*/, CertificateVerificationMode::TrustOnFirstUse(TrustOnFirstUseConfig {
+ ..Default::default()
+ }),
+);
+```
+
+With the default configuration, known hosts and their fingerprints are stored in a file, which defaults to `quinnet/known_hosts`.
+The defaults verifier behaviours are:
+- For an `unknwon` certificate (first time this server is encountered) => the client trusts this certificate, stores its fingerprint and continue the connection;
+- For a `trusted` certificate (the fingerprint matches the one stored for this server) => the client trusts this certificate and continue the connection;
+- For an `untrusted` certificate (the certificate's fingerprint does not match the one in the store) => the client raises an event to the Bevy app and waits for an action to apply.
+
+### Examples configurations
+
+Default verifier behaviours with a custom store file:
+```rust
+client.connect(/*...*/, CertificateVerificationMode::TrustOnFirstUse(TrustOnFirstUseConfig {
+ known_hosts: KnownHosts::HostsFile("MyCustomFile".to_string()),
+ ..Default::default()
+ }),
+);
+```
+
+Custom verifier behaviours with a custom store:
+```rust
+client.connect(/*...*/, CertificateVerificationMode::TrustOnFirstUse(TrustOnFirstUseConfig {
+ known_hosts: KnownHosts::Store(my_cert_store),
+ verifier_behaviour: HashMap::from([
+ (
+ CertVerificationStatus::UnknownCertificate,
+ CertVerifierBehaviour::ImmediateAction(CertVerifierAction::TrustAndStore),
+ ),
+ (
+ CertVerificationStatus::UntrustedCertificate,
+ CertVerifierBehaviour::ImmediateAction(CertVerifierAction::AbortConnection),
+ ),
+ (
+ CertVerificationStatus::TrustedCertificate,
+ CertVerifierBehaviour::ImmediateAction(CertVerifierAction::TrustOnce),
+ ),
+ ]),
+ }),
+);
+```
+
+### Events
+
+The Quinnet client plugin raises Bevy events during the connection process (during the certificate verification).
+
+- `CertInteractionEvent`: a user action is requested before continuing. This event is only raised when the verifier behaviour for a specific certificate status is set to `CertVerifierBehaviour::RequestClientAction`
+- `CertTrustUpdateEvent`: the client plugin encoutered a new trust entry to register. If the store is a file, the client plugin has already updated it. If the store is a custom hashmap given to the client plugin (via `KnownHosts::Store(my_cert_store)`), it is up to the user to update its sotre accordingly.
+- `CertConnectionAbortEvent`: signals that the connection was aborted during the certificate verification (through the `CertVerifierAction::AbortConnection`).
+
+Here is a simple example for a custom handler for `CertInteractionEvent`:
+
+```rust
+fn handle_cert_events(mut cert_action_events: EventReader<CertInteractionEvent>) {
+ for cert_event in cert_action_events.iter() {
+ match cert_event.status {
+ CertVerificationStatus::UntrustedCertificate => cert_event
+ .apply_cert_verifier_action(CertVerifierAction::AbortConnection)
+ .unwrap(),
+ _ => cert_event
+ .apply_cert_verifier_action(CertVerifierAction::TrustOnce)
+ .unwrap(),
+ }
+ }
+}
+```
+
+### Fingerprints
+
+Fingerprints in Quinnet are a SHA-256 hash of the certificate data in DER form.
+
+### Known hosts file format
+
+This hosts file format is really simplistic for now.
+There is one line per entry, and each entry is a server name (as dns or ip) followed by a space, followed by the currently known fingerprint encoded in base64.
+
+This means that if two servers are hosted on the same machine on two different ports, they should currently share the same certificate to avoid any conflict.