aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoradnano <[email protected]>2020-09-27 16:21:56 -0400
committeradnano <[email protected]>2020-09-27 16:21:56 -0400
commitc79a1f44842500ac48fb65edd92bc27c6fa75c49 (patch)
tree90b09fe231b3bfd117bc0a1826b101dabbbde7e7
parentMake TrustCertificate accept hostname instead of request (diff)
downloadgo-gemini-c79a1f44842500ac48fb65edd92bc27c6fa75c49.tar.xz
go-gemini-c79a1f44842500ac48fb65edd92bc27c6fa75c49.zip
Update documentation
-rw-r--r--README.md30
-rw-r--r--examples/client/client.go6
2 files changed, 25 insertions, 11 deletions
diff --git a/README.md b/README.md
index e0c3501..ba047d3 100644
--- a/README.md
+++ b/README.md
@@ -34,8 +34,7 @@ The way this is implemented in this package is like so:
1. Client makes a request with `NewRequest`. The client then sends the request
with `(*Client).Send(*Request) (*Response, error)`. The client then determines whether
- to trust the certificate in `TrustCertificte(*x509.Certificate, *KnownHosts) bool`.
- (See [TOFU](#tofu)).
+ to trust the certificate (see [TOFU](#tofu)).
2. Server recieves the request and constructs a response.
The server calls the `Serve(*ResponseWriter, *Request)` method on the
`Handler` field. The handler writes the response. The server then closes
@@ -47,37 +46,46 @@ The way this is implemented in this package is like so:
`go-gemini` makes it easy to implement Trust On First Use in your clients.
-Clients can load the default list of known hosts:
+The default client loads known hosts from `$XDG_DATA_HOME/gemini/known_hosts`.
+If that is all you need, you can simply use the top-level `Send` function:
+
+```go
+// Send uses the default client, which will load the default list of known
+hosts.
+req := gemini.NewRequest("gemini://example.com")
+gemini.Send(req)
+```
+
+Clients can also load their own list of known hosts:
```go
client := &Client{}
-knownHosts, err := gemini.LoadKnownHosts()
-if err != nil {
+if err := client.KnownHosts.LoadFrom("path/to/my/known_hosts"); err != nil {
log.Fatal(err)
}
-client.KnownHosts = knownHosts
```
Clients can then specify how to trust certificates in the `TrustCertificate`
field:
```go
-client.TrustCertificate = func(cert *x509.Certificate, knownHosts *gemini.KnownHosts) error {
+client.TrustCertificate = func(hostname string, cert *x509.Certificate, knownHosts *gemini.KnownHosts) error {
// If the certificate is in the known hosts list, allow the connection
- return knownHosts.Lookup(cert)
+ return knownHosts.Lookup(hostname, cert)
}
```
Advanced clients can prompt the user for what to do when encountering an unknown certificate:
```go
-client.TrustCertificate = func(cert *x509.Certificate, knownHosts *gemini.KnownHosts) error {
+client.TrustCertificate = func(hostname string, cert *x509.Certificate, knownHosts *gemini.KnownHosts) error {
err := knownHosts.Lookup(cert)
if err != nil {
switch err {
case gemini.ErrCertificateNotTrusted:
// Alert the user that the certificate is not trusted
- alertUser()
+ fmt.Printf("Warning: certificate for %s is not trusted!\n", hostname)
+ fmt.Println("This could indicate a Man-in-the-Middle attack.")
case gemini.ErrCertificateUnknown:
// Prompt the user to trust the certificate
if userTrustsCertificateTemporarily() {
@@ -93,3 +101,5 @@ client.TrustCertificate = func(cert *x509.Certificate, knownHosts *gemini.KnownH
return err
}
```
+
+See `examples/client` for an example client.
diff --git a/examples/client/client.go b/examples/client/client.go
index 5b853de..5c1c104 100644
--- a/examples/client/client.go
+++ b/examples/client/client.go
@@ -28,7 +28,7 @@ func init() {
switch err {
case gemini.ErrCertificateNotTrusted:
// Alert the user that the certificate is not trusted
- fmt.Println("error: certificate is not trusted!")
+ fmt.Printf("Warning: certificate for %s is not trusted!\n", hostname)
fmt.Println("This could indicate a Man-in-the-Middle attack.")
case gemini.ErrCertificateUnknown:
// Prompt the user to trust the certificate
@@ -45,6 +45,10 @@ func init() {
return err
}
+ client.GetCertificate = func(req *gemini.Request, store *gemini.CertificateStore) *tls.Certificate {
+ return &cert
+ }
+
// Configure a client side certificate.
// To generate a TLS key pair, run:
//