This repository has been archived by the owner on Mar 27, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
/
nonce.go
95 lines (78 loc) · 2.37 KB
/
nonce.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
package validator
import (
"bytes"
"crypto/rand"
"encoding/hex"
"fmt"
"log"
"text/template"
"github.com/TNG/openpgp-validation-server/gpg"
"github.com/TNG/openpgp-validation-server/mail"
"github.com/TNG/openpgp-validation-server/storage"
)
var signedKeyMessage = template.Must(template.ParseFiles("./templates/signedKeyMail.tmpl"))
// NonceLength in byte
const NonceLength = 32
func generateNonce() ([NonceLength]byte, error) {
var nonce [NonceLength]byte
n, err := rand.Read(nonce[:])
if err != nil {
return nonce, err
}
if n != NonceLength {
panic("Unreachable")
}
return nonce, nil
}
// NonceFromString parses and returns a nonce from a hex string
func NonceFromString(nonceString string) (nonce [NonceLength]byte, err error) {
nonceSlice, err := hex.DecodeString(nonceString)
if err != nil {
return
}
if len(nonceSlice) != NonceLength {
err = fmt.Errorf("Nonce has invalid length: %v", len(nonceSlice))
return
}
copy(nonce[:], nonceSlice)
return
}
// ConfirmNonce checks the given nonce, and if there is associated information, sends an email with the signed key
func ConfirmNonce(nonce [NonceLength]byte, store storage.GetSetDeleter, gpgUtil *gpg.GPG) (*mail.OutgoingMail, error) {
if gpgUtil == nil {
return nil, fmt.Errorf("skipping nonce confirmation, as gpgUtil is not available")
}
if store == nil {
return nil, fmt.Errorf("skipping nonce confirmation, as store is not available")
}
requestInfo := store.Get(nonce)
if requestInfo == nil {
return nil, fmt.Errorf("cannot confirm nonce, %v not found", hex.EncodeToString(nonce[:]))
}
log.Printf("Signing key %v of '%v'.", requestInfo.Key.PrimaryKey.KeyIdString(), requestInfo.Email)
buf := bytes.Buffer{}
err := gpgUtil.SignUserID(requestInfo.Email, requestInfo.Key, &buf)
if err != nil {
return nil, err
}
message := getSignedKeyMessage(requestInfo.Key.PrimaryKey.KeyIdString())
mail := mail.OutgoingMail{
Message: message,
RecipientEmail: requestInfo.Email,
RecipientKey: requestInfo.Key,
Attachment: buf.Bytes(),
GPG: gpgUtil,
}
return &mail, nil
}
func getSignedKeyMessage(fingerprint string) string {
message := new(bytes.Buffer)
err := signedKeyMessage.Execute(message, struct{ Fingerprint string }{
Fingerprint: fingerprint,
})
if err != nil {
log.Panicf("cannot generate signed-key message: %v", err)
return ""
}
return message.String()
}