aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdnan Maolood <[email protected]>2021-03-06 15:24:14 -0500
committerAdnan Maolood <[email protected]>2021-03-06 15:24:15 -0500
commit6e5c2473e736a90b06124bda3ded6a2c6248f855 (patch)
tree41d9c28df19a51697d56dfddb28b630da65b41bf
parenttofu: Fix format in error message (diff)
downloadgo-gemini-6e5c2473e736a90b06124bda3ded6a2c6248f855.tar.xz
go-gemini-6e5c2473e736a90b06124bda3ded6a2c6248f855.zip
tofu: Use base64-encoded sha256 fingerprints
-rw-r--r--examples/client.go3
-rw-r--r--tofu/tofu.go82
2 files changed, 18 insertions, 67 deletions
diff --git a/examples/client.go b/examples/client.go
index 69a928f..ad114f0 100644
--- a/examples/client.go
+++ b/examples/client.go
@@ -6,7 +6,6 @@ package main
import (
"bufio"
- "bytes"
"context"
"crypto/x509"
"errors"
@@ -64,7 +63,7 @@ func trustCertificate(hostname string, cert *x509.Certificate) error {
knownHost, ok := hosts.Lookup(hostname)
if ok {
// Check fingerprint
- if bytes.Equal(knownHost.Fingerprint, host.Fingerprint) {
+ if knownHost.Fingerprint != host.Fingerprint {
return nil
}
return errors.New("error: fingerprint does not match!")
diff --git a/tofu/tofu.go b/tofu/tofu.go
index fb7361b..554b260 100644
--- a/tofu/tofu.go
+++ b/tofu/tofu.go
@@ -4,14 +4,14 @@ package tofu
import (
"bufio"
"bytes"
- "crypto/sha512"
+ "crypto/sha256"
"crypto/x509"
+ "encoding/base64"
"errors"
"fmt"
"io"
"os"
"sort"
- "strconv"
"strings"
"sync"
)
@@ -150,7 +150,7 @@ func (k *KnownHosts) TOFU(hostname string, cert *x509.Certificate) error {
k.Add(host)
return nil
}
- if !bytes.Equal(knownHost.Fingerprint, host.Fingerprint) {
+ if host.Fingerprint != knownHost.Fingerprint {
return fmt.Errorf("fingerprint for %q does not match", hostname)
}
return nil
@@ -267,7 +267,7 @@ func (p *PersistentHosts) TOFU(hostname string, cert *x509.Certificate) error {
if !ok {
return p.Add(host)
}
- if !bytes.Equal(knownHost.Fingerprint, host.Fingerprint) {
+ if host.Fingerprint != knownHost.Fingerprint {
return fmt.Errorf("fingerprint for %q does not match", hostname)
}
return nil
@@ -280,20 +280,20 @@ func (p *PersistentHosts) Close() error {
// Host represents a host entry with a fingerprint using a certain algorithm.
type Host struct {
- Hostname string // hostname
- Algorithm string // fingerprint algorithm e.g. SHA-512
- Fingerprint Fingerprint // fingerprint
+ Hostname string // hostname
+ Algorithm string // fingerprint algorithm e.g. sha256
+ Fingerprint string // fingerprint
}
-// NewHost returns a new host with a SHA-512 fingerprint of
+// NewHost returns a new host with a SHA256 fingerprint of
// the provided raw data.
func NewHost(hostname string, raw []byte) Host {
- sum := sha512.Sum512(raw)
+ sum := sha256.Sum256(raw)
return Host{
Hostname: hostname,
- Algorithm: "SHA-512",
- Fingerprint: sum[:],
+ Algorithm: "sha256",
+ Fingerprint: base64.StdEncoding.EncodeToString(sum[:]),
}
}
@@ -311,7 +311,7 @@ func (h Host) String() string {
b.WriteByte(' ')
b.WriteString(h.Algorithm)
b.WriteByte(' ')
- b.WriteString(h.Fingerprint.String())
+ b.WriteString(h.Fingerprint)
return b.String()
}
@@ -331,66 +331,18 @@ func (h *Host) UnmarshalText(text []byte) error {
h.Hostname = string(parts[0])
algorithm := string(parts[1])
- if algorithm != "SHA-512" {
+ if algorithm != "sha256" {
return fmt.Errorf("unsupported algorithm %q", algorithm)
}
h.Algorithm = algorithm
- fingerprint := make([]byte, 0, sha512.Size)
- scanner := bufio.NewScanner(bytes.NewReader(parts[2]))
- scanner.Split(scanFingerprint)
-
- for scanner.Scan() {
- b, err := strconv.ParseUint(scanner.Text(), 16, 8)
- if err != nil {
- return fmt.Errorf("failed to parse fingerprint hash: %w", err)
- }
- fingerprint = append(fingerprint, byte(b))
- }
-
- if len(fingerprint) != sha512.Size {
- return fmt.Errorf("invalid fingerprint size %d, expected %d",
- len(fingerprint), sha512.Size)
+ fingerprint, err := base64.StdEncoding.DecodeString(string(parts[2]))
+ if err != nil {
+ return err
}
- h.Fingerprint = fingerprint
+ h.Fingerprint = string(fingerprint)
return nil
}
-
-func scanFingerprint(data []byte, atEOF bool) (advance int, token []byte, err error) {
- if atEOF && len(data) == 0 {
- return 0, nil, nil
- }
- if i := bytes.IndexByte(data, ':'); i >= 0 {
- // We have a full newline-terminated line.
- return i + 1, data[0:i], nil
- }
-
- // If we're at EOF, we have a final, non-terminated hex byte
- if atEOF {
- return len(data), data, nil
- }
-
- // Request more data.
- return 0, nil, nil
-}
-
-// Fingerprint represents a fingerprint.
-type Fingerprint []byte
-
-// String returns a string representation of the fingerprint.
-func (f Fingerprint) String() string {
- var sb strings.Builder
-
- for i, b := range f {
- if i > 0 {
- sb.WriteByte(':')
- }
-
- fmt.Fprintf(&sb, "%02X", b)
- }
-
- return sb.String()
-}