tofu: Remove expiration timestamp from known hosts
This commit is contained in:
		
							parent
							
								
									bfa3356d3a
								
							
						
					
					
						commit
						8e2ac24830
					
				@ -16,7 +16,6 @@ import (
 | 
			
		||||
	"net/url"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"git.sr.ht/~adnano/go-gemini"
 | 
			
		||||
	"git.sr.ht/~adnano/go-gemini/tofu"
 | 
			
		||||
@ -61,10 +60,9 @@ Otherwise, this should be safe to trust.
 | 
			
		||||
=> `
 | 
			
		||||
 | 
			
		||||
func trustCertificate(hostname string, cert *x509.Certificate) error {
 | 
			
		||||
	host := tofu.NewHost(hostname, cert.Raw, cert.NotAfter)
 | 
			
		||||
 | 
			
		||||
	host := tofu.NewHost(hostname, cert.Raw)
 | 
			
		||||
	knownHost, ok := hosts.Lookup(hostname)
 | 
			
		||||
	if ok && time.Now().Before(knownHost.Expires) {
 | 
			
		||||
	if ok {
 | 
			
		||||
		// Check fingerprint
 | 
			
		||||
		if bytes.Equal(knownHost.Fingerprint, host.Fingerprint) {
 | 
			
		||||
			return nil
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										34
									
								
								tofu/tofu.go
									
									
									
									
									
								
							
							
						
						
									
										34
									
								
								tofu/tofu.go
									
									
									
									
									
								
							@ -14,7 +14,6 @@ import (
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"sync"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// KnownHosts represents a list of known hosts.
 | 
			
		||||
@ -143,22 +142,17 @@ func (k *KnownHosts) Parse(r io.Reader) error {
 | 
			
		||||
// TOFU implements basic trust on first use.
 | 
			
		||||
//
 | 
			
		||||
// If the host is not on file, it is added to the list.
 | 
			
		||||
// If the host on file is expired, a new entry is added to the list.
 | 
			
		||||
// If the fingerprint does not match the one on file, an error is returned.
 | 
			
		||||
func (k *KnownHosts) TOFU(hostname string, cert *x509.Certificate) error {
 | 
			
		||||
	host := NewHost(hostname, cert.Raw, cert.NotAfter)
 | 
			
		||||
 | 
			
		||||
	host := NewHost(hostname, cert.Raw)
 | 
			
		||||
	knownHost, ok := k.Lookup(hostname)
 | 
			
		||||
	if !ok || time.Now().After(knownHost.Expires) {
 | 
			
		||||
	if !ok {
 | 
			
		||||
		k.Add(host)
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Check fingerprint
 | 
			
		||||
	if !bytes.Equal(knownHost.Fingerprint, host.Fingerprint) {
 | 
			
		||||
		return fmt.Errorf("fingerprint for %q does not match", hostname)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -266,21 +260,16 @@ func (p *PersistentHosts) Entries() []Host {
 | 
			
		||||
// TOFU implements trust on first use with a persistent set of known hosts.
 | 
			
		||||
//
 | 
			
		||||
// If the host is not on file, it is added to the list.
 | 
			
		||||
// If the host on file is expired, a new entry is added to the list.
 | 
			
		||||
// If the fingerprint does not match the one on file, an error is returned.
 | 
			
		||||
func (p *PersistentHosts) TOFU(hostname string, cert *x509.Certificate) error {
 | 
			
		||||
	host := NewHost(hostname, cert.Raw, cert.NotAfter)
 | 
			
		||||
 | 
			
		||||
	host := NewHost(hostname, cert.Raw)
 | 
			
		||||
	knownHost, ok := p.Lookup(hostname)
 | 
			
		||||
	if !ok || time.Now().After(knownHost.Expires) {
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return p.Add(host)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Check fingerprint
 | 
			
		||||
	if !bytes.Equal(knownHost.Fingerprint, host.Fingerprint) {
 | 
			
		||||
		return fmt.Errorf("fingerprint for %q does not match", hostname)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -294,19 +283,17 @@ type Host struct {
 | 
			
		||||
	Hostname    string      // hostname
 | 
			
		||||
	Algorithm   string      // fingerprint algorithm e.g. SHA-512
 | 
			
		||||
	Fingerprint Fingerprint // fingerprint
 | 
			
		||||
	Expires     time.Time   // unix time of the fingerprint expiration date
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewHost returns a new host with a SHA-512 fingerprint of
 | 
			
		||||
// the provided raw data.
 | 
			
		||||
func NewHost(hostname string, raw []byte, expires time.Time) Host {
 | 
			
		||||
func NewHost(hostname string, raw []byte) Host {
 | 
			
		||||
	sum := sha512.Sum512(raw)
 | 
			
		||||
 | 
			
		||||
	return Host{
 | 
			
		||||
		Hostname:    hostname,
 | 
			
		||||
		Algorithm:   "SHA-512",
 | 
			
		||||
		Fingerprint: sum[:],
 | 
			
		||||
		Expires:     expires,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -325,8 +312,6 @@ func (h Host) String() string {
 | 
			
		||||
	b.WriteString(h.Algorithm)
 | 
			
		||||
	b.WriteByte(' ')
 | 
			
		||||
	b.WriteString(h.Fingerprint.String())
 | 
			
		||||
	b.WriteByte(' ')
 | 
			
		||||
	b.WriteString(strconv.FormatInt(h.Expires.Unix(), 10))
 | 
			
		||||
	return b.String()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -335,7 +320,7 @@ func (h *Host) UnmarshalText(text []byte) error {
 | 
			
		||||
	const format = "hostname algorithm hex-fingerprint expiry-unix-ts"
 | 
			
		||||
 | 
			
		||||
	parts := bytes.Split(text, []byte(" "))
 | 
			
		||||
	if len(parts) != 4 {
 | 
			
		||||
	if len(parts) != 3 {
 | 
			
		||||
		return fmt.Errorf("expected the format %q", format)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -371,13 +356,6 @@ func (h *Host) UnmarshalText(text []byte) error {
 | 
			
		||||
 | 
			
		||||
	h.Fingerprint = fingerprint
 | 
			
		||||
 | 
			
		||||
	unix, err := strconv.ParseInt(string(parts[3]), 10, 0)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return fmt.Errorf("invalid unix timestamp: %w", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	h.Expires = time.Unix(unix, 0)
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user