-
Notifications
You must be signed in to change notification settings - Fork 64
/
verify.go
92 lines (79 loc) · 3.06 KB
/
verify.go
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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
// Copyright 2015 Keybase, Inc. All rights reserved. Use of
// this source code is governed by the included BSD license.
package saltpack
import (
"bytes"
"crypto/sha512"
"io"
)
// NewVerifyStream creates a stream that consumes data from reader
// r. It returns the signer's public key and a reader that only
// contains verified data. If the signer's key is not in keyring,
// it will return an error.
func NewVerifyStream(versionValidator VersionValidator, r io.Reader, keyring SigKeyring) (skey SigningPublicKey, vs io.Reader, err error) {
s, err := newVerifyStream(versionValidator, r, MessageTypeAttachedSignature)
if err != nil {
return nil, nil, err
}
skey = keyring.LookupSigningPublicKey(s.header.SenderPublic)
if skey == nil {
return nil, nil, ErrNoSenderKey{Sender: s.header.SenderPublic}
}
s.publicKey = skey
return skey, newChunkReader(s), nil
}
// Verify checks the signature in signedMsg. It returns the
// signer's public key and a verified message.
func Verify(versionValidator VersionValidator, signedMsg []byte, keyring SigKeyring) (skey SigningPublicKey, verifiedMsg []byte, err error) {
skey, stream, err := NewVerifyStream(versionValidator, bytes.NewReader(signedMsg), keyring)
if err != nil {
return nil, nil, err
}
verifiedMsg, err = io.ReadAll(stream)
if err != nil {
return nil, nil, err
}
return skey, verifiedMsg, nil
}
// VerifyDetachedReader verifies that signature is a valid signature for
// entire message read from message Reader, and that the public key for
// the signer is in keyring. It returns the signer's public key.
func VerifyDetachedReader(versionValidator VersionValidator, message io.Reader, signature []byte, keyring SigKeyring) (skey SigningPublicKey, err error) {
inputBuffer := bytes.NewBuffer(signature)
// Use a verifyStream to parse the header.
s, err := newVerifyStream(versionValidator, inputBuffer, MessageTypeDetachedSignature)
if err != nil {
return nil, err
}
// Reach inside the verifyStream to parse the signature bytes.
var naclSignature []byte
_, err = s.mps.Read(&naclSignature)
if err != nil {
return nil, err
}
// Get the public key.
skey = keyring.LookupSigningPublicKey(s.header.SenderPublic)
if skey == nil {
return nil, ErrNoSenderKey{Sender: s.header.SenderPublic}
}
// Compute the signed text hash, without requiring us to copy the whole
// signed text into memory at once.
hasher := sha512.New()
_, err = hasher.Write(s.headerHash[:])
if err != nil {
return nil, err
}
if _, err := io.Copy(hasher, message); err != nil {
return nil, err
}
if err := skey.Verify(detachedSignatureInputFromHash(hasher.Sum(nil)), naclSignature); err != nil {
return nil, err
}
return skey, nil
}
// VerifyDetached verifies that signature is a valid signature for
// message, and that the public key for the signer is in keyring.
// It returns the signer's public key.
func VerifyDetached(versionValidator VersionValidator, message, signature []byte, keyring SigKeyring) (skey SigningPublicKey, err error) {
return VerifyDetachedReader(versionValidator, bytes.NewReader(message), signature, keyring)
}