/
sign.go
97 lines (79 loc) 路 2.25 KB
/
sign.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
93
94
95
96
97
package voucher
import (
"bytes"
"crypto"
"errors"
"fmt"
"io/ioutil"
"golang.org/x/crypto/openpgp"
"golang.org/x/crypto/openpgp/armor"
"golang.org/x/crypto/openpgp/packet"
)
var errNotSigned = errors.New("contents were not signed")
var errNoSigner = errors.New("signer is not in keyring")
// signConfig is used for our Signer.
var signConfig = packet.Config{
DefaultHash: crypto.SHA512,
DefaultCipher: packet.CipherAES256,
DefaultCompressionAlgo: packet.CompressionZLIB,
CompressionConfig: &packet.CompressionConfig{
Level: 9,
},
RSABits: 4096,
}
// Sign creates the signature for the attestation
func Sign(signer *openpgp.Entity, msg string) (string, error) {
if nil == signer {
return "", fmt.Errorf("nil cannot be used as a signer")
}
buf := new(bytes.Buffer)
armor, err := armor.Encode(buf, openpgp.SignatureType, make(map[string]string))
defer armor.Close()
if err != nil {
return "", fmt.Errorf("creating armor writer failed: %s", err)
}
signature, err := openpgp.Sign(armor, signer, nil, &signConfig)
defer signature.Close()
if nil != err {
return "", err
}
_, err = signature.Write([]byte(msg))
if nil != err {
return "", fmt.Errorf("writing to signature writer failed: %s", err)
}
if cerr := signature.Close(); nil != cerr {
return "", cerr
}
if cerr := armor.Close(); nil != cerr {
return "", cerr
}
return buf.String(), nil
}
// Verify verifies a signed message's signature, and returns the message
// that was signed as well as an error if applicable.
func Verify(keyring openpgp.KeyRing, signed string) (string, error) {
if nil == keyring {
return "", fmt.Errorf("cannot verify signature: %s", errEmptyKeyring)
}
armoredBlock, err := armor.Decode(bytes.NewBufferString(signed))
if nil != err {
return "", fmt.Errorf("could not decode armor: %s", err)
}
messageDetails, err := openpgp.ReadMessage(armoredBlock.Body, keyring, nil, &signConfig)
if nil != err {
return "", err
}
if !messageDetails.IsSigned {
return "", errNotSigned
}
if nil == messageDetails.SignedBy {
return "", errNoSigner
}
body, err := ioutil.ReadAll(messageDetails.UnverifiedBody)
if nil != err {
if nil != messageDetails.SignatureError {
err = messageDetails.SignatureError
}
}
return string(body), err
}