File: verify.go

package info (click to toggle)
golang-github-hiddeco-sshsig 0.1.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 176 kB
  • sloc: makefile: 17
file content (59 lines) | stat: -rw-r--r-- 1,981 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
package sshsig

import (
	"errors"
	"io"

	"golang.org/x/crypto/ssh"
)

var (
	// ErrPublicKeyMismatch is returned by Verify if the public key in the signature
	// does not match the public key used to verify the signature.
	ErrPublicKeyMismatch = errors.New("public key does not match")

	// ErrNamespaceMismatch is returned by Verify if the namespace in the signature
	// does not match the namespace used to verify the signature.
	ErrNamespaceMismatch = errors.New("namespace does not match")
)

// Verify verifies the message from the io.Reader matches the Signature using
// the given ssh.PublicKey and HashAlgorithm.
//
// The purpose of the namespace value is to specify an unambiguous interpretation
// domain for the signature, e.g. file signing. This prevents cross-protocol
// attacks caused by signatures intended for one intended domain being accepted
// in another. Unlike Sign, the namespace value is not required to allow
// verification of signatures created by looser implementations.
//
// Verify returns an error if the verification process fails.
func Verify(m io.Reader, sig *Signature, pub ssh.PublicKey, h HashAlgorithm, namespace string) error {
	// Check that the public key in the signature matches the public key used to
	// verify the signature. If this is e.g. tricked in to a hash collision, it
	// will still be caught by the verification.
	if ssh.FingerprintSHA256(pub) != ssh.FingerprintSHA256(sig.PublicKey) {
		return ErrPublicKeyMismatch
	}

	// Check that namespace matches the namespace in the Signature.
	// If this is malformed, it will still be caught by the verification.
	if sig.Namespace != namespace {
		return ErrNamespaceMismatch
	}

	if err := h.Available(); err != nil {
		return err
	}

	hf := h.Hash()
	if _, err := io.Copy(hf, m); err != nil {
		return err
	}
	mh := hf.Sum(nil)

	return pub.Verify(signedData{
		Namespace:     namespace,
		HashAlgorithm: h.String(),
		Hash:          string(mh),
	}.Marshal(), sig.Signature)
}