Make the default client generate certificates
This commit is contained in:
parent
622ea8e0f1
commit
cad2d25185
|
@ -84,8 +84,8 @@ Gemini takes advantage of client certificates for authentication.
|
||||||
|
|
||||||
If a server responds with `StatusCertificateRequired`, clients will generate a
|
If a server responds with `StatusCertificateRequired`, clients will generate a
|
||||||
certificate for the site and resend the request with the provided certificate.
|
certificate for the site and resend the request with the provided certificate.
|
||||||
In order for this to work, clients must specify the fields `CertificateStore`
|
The default client handles this for you. Other clients must specify the fields
|
||||||
and `GetCertificate`:
|
`CertificateStore` and `GetCertificate`:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// Initialize the certificate store.
|
// 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
|
Servers can then authenticate their clients with the fingerprint of their
|
||||||
certificates.
|
certificates.
|
||||||
|
|
||||||
|
|
18
gemini.go
18
gemini.go
|
@ -2,8 +2,10 @@
|
||||||
package gmi
|
package gmi
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/tls"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"sync"
|
"sync"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Status codes.
|
// Status codes.
|
||||||
|
@ -54,11 +56,27 @@ func init() {
|
||||||
setupDefaultClientOnce.Do(setupDefaultClient)
|
setupDefaultClientOnce.Do(setupDefaultClient)
|
||||||
return knownHosts.Lookup(hostname, cert)
|
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
|
var setupDefaultClientOnce sync.Once
|
||||||
|
|
||||||
func setupDefaultClient() {
|
func setupDefaultClient() {
|
||||||
|
DefaultClient.CertificateStore = NewCertificateStore()
|
||||||
DefaultClient.KnownHosts.Load()
|
DefaultClient.KnownHosts.Load()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user