Make the default client generate certificates

This commit is contained in:
adnano 2020-09-28 00:38:11 -04:00
parent 622ea8e0f1
commit cad2d25185
2 changed files with 21 additions and 2 deletions

View File

@ -84,8 +84,8 @@ Gemini takes advantage of client certificates for authentication.
If a server responds with `StatusCertificateRequired`, clients will generate a
certificate for the site and resend the request with the provided certificate.
In order for this to work, clients must specify the fields `CertificateStore`
and `GetCertificate`:
The default client handles this for you. Other clients must specify the fields
`CertificateStore` and `GetCertificate`:
```go
// Initialize the certificate store.
@ -109,6 +109,7 @@ client.GetCertificate = func(hostname string, store gmi.CertificateStore) *tls.C
}
```
Servers can then authenticate their clients with the fingerprint of their
certificates.

View File

@ -2,8 +2,10 @@
package gmi
import (
"crypto/tls"
"crypto/x509"
"sync"
"time"
)
// Status codes.
@ -54,11 +56,27 @@ func init() {
setupDefaultClientOnce.Do(setupDefaultClient)
return knownHosts.Lookup(hostname, cert)
}
DefaultClient.GetCertificate = func(hostname string, store CertificateStore) *tls.Certificate {
// If the certificate is in the store, return it
if cert, ok := store[hostname]; ok {
return cert
}
// Otherwise, generate a certificate
duration := time.Hour
cert, err := NewCertificate(hostname, duration)
if err != nil {
return nil
}
// Store and return the certificate
store[hostname] = &cert
return &cert
}
}
var setupDefaultClientOnce sync.Once
func setupDefaultClient() {
DefaultClient.CertificateStore = NewCertificateStore()
DefaultClient.KnownHosts.Load()
}