1
0
mirror of https://github.com/makew0rld/amfora.git synced 2024-09-23 22:45:54 -04:00

🐛 Use domain from URL for TOFU, not from cert

This commit is contained in:
makeworld 2020-06-24 13:31:01 -04:00
parent 3db81c3ac6
commit e75c539dac
4 changed files with 19 additions and 22 deletions

View File

@ -39,6 +39,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Disabling color in config affects UI elements (#16) - Disabling color in config affects UI elements (#16)
- Keep bold for headings even with color disabled - Keep bold for headings even with color disabled
- Don't make whole link text bold when color is disabled - Don't make whole link text bold when color is disabled
- Get domain from URL for TOFU, not from certificate
## [1.0.0] - 2020-06-18 ## [1.0.0] - 2020-06-18

View File

@ -10,15 +10,15 @@ import (
// Fetch returns response data and an error. // Fetch returns response data and an error.
// The error text is human friendly and should be displayed. // The error text is human friendly and should be displayed.
func Fetch(u string) (*gemini.Response, error) { func Fetch(u string) (*gemini.Response, error) {
resp, err := gemini.Fetch(u) res, err := gemini.Fetch(u)
if err != nil { if err != nil {
return nil, err return nil, err
} }
parsed, _ := url.Parse(u) parsed, _ := url.Parse(u)
ok := handleTofu(resp.Cert, parsed.Port()) ok := handleTofu(parsed.Hostname(), parsed.Port(), res.Cert)
if !ok { if !ok {
return resp, ErrTofu return res, ErrTofu
} }
return resp, err return res, err
} }

View File

@ -62,17 +62,14 @@ func certID(cert *x509.Certificate) string {
// origCertID uses cert.Raw, which was used in v1.0.0 of the app. // origCertID uses cert.Raw, which was used in v1.0.0 of the app.
func origCertID(cert *x509.Certificate) string { func origCertID(cert *x509.Certificate) string {
h := sha256.New() h := sha256.New()
h.Write(cert.Raw) // Better than cert.Raw, see #7 h.Write(cert.Raw)
return fmt.Sprintf("%X", h.Sum(nil)) return fmt.Sprintf("%X", h.Sum(nil))
} }
func saveTofuEntry(cert *x509.Certificate, port string) { func saveTofuEntry(domain, port string, cert *x509.Certificate) {
tofuStore.Set(idKey(cert.Subject.CommonName, port), certID(cert)) tofuStore.Set(idKey(domain, port), certID(cert))
tofuStore.Set(expiryKey(cert.Subject.CommonName, port), cert.NotAfter.UTC()) tofuStore.Set(expiryKey(domain, port), cert.NotAfter.UTC())
err := tofuStore.WriteConfig() tofuStore.WriteConfig()
if err != nil {
panic(err)
}
} }
// handleTofu is the abstracted interface for taking care of TOFU. // handleTofu is the abstracted interface for taking care of TOFU.
@ -80,17 +77,17 @@ func saveTofuEntry(cert *x509.Certificate, port string) {
// It returns a bool indicating if the cert is valid according to // It returns a bool indicating if the cert is valid according to
// the TOFU database. // the TOFU database.
// If false is returned, the connection should not go ahead. // If false is returned, the connection should not go ahead.
func handleTofu(cert *x509.Certificate, port string) bool { func handleTofu(domain, port string, cert *x509.Certificate) bool {
id, expiry, err := loadTofuEntry(cert.Subject.CommonName, port) id, expiry, err := loadTofuEntry(domain, port)
if err != nil { if err != nil {
// Cert isn't in database or data is malformed // Cert isn't in database or data is malformed
// So it can't be checked and anything is valid // So it can't be checked and anything is valid
saveTofuEntry(cert, port) saveTofuEntry(domain, port, cert)
return true return true
} }
if time.Now().After(expiry) { if time.Now().After(expiry) {
// Old cert expired, so anything is valid // Old cert expired, so anything is valid
saveTofuEntry(cert, port) saveTofuEntry(domain, port, cert)
return true return true
} }
if certID(cert) == id { if certID(cert) == id {
@ -99,7 +96,7 @@ func handleTofu(cert *x509.Certificate, port string) bool {
} }
if origCertID(cert) == id { if origCertID(cert) == id {
// Valid but uses old ID type // Valid but uses old ID type
saveTofuEntry(cert, port) saveTofuEntry(domain, port, cert)
return true return true
} }
return false return false
@ -107,7 +104,6 @@ func handleTofu(cert *x509.Certificate, port string) bool {
// ResetTofuEntry forces the cert passed to be valid, overwriting any previous TOFU entry. // ResetTofuEntry forces the cert passed to be valid, overwriting any previous TOFU entry.
// The port string can be empty, to indicate port 1965. // The port string can be empty, to indicate port 1965.
func ResetTofuEntry(cert *x509.Certificate, port string) { func ResetTofuEntry(domain, port string, cert *x509.Certificate) {
tofuStore.Set(idKey(cert.Subject.CommonName, port), "") saveTofuEntry(domain, port, cert)
tofuStore.WriteConfig()
} }

View File

@ -228,8 +228,8 @@ func handleURL(u string) (string, bool) {
if err == client.ErrTofu { if err == client.ErrTofu {
if Tofu(parsed.Host) { if Tofu(parsed.Host) {
// They want to continue anyway // They want to continue anyway
client.ResetTofuEntry(res.Cert, parsed.Port()) client.ResetTofuEntry(parsed.Hostname(), parsed.Port(), res.Cert)
// Response can be used further down // Response can be used further down, no need to reload
} else { } else {
// They don't want to continue // They don't want to continue
// Set the bar back to original URL // Set the bar back to original URL