keyshare.go 1.61 KB
Newer Older
1
2
3
4
5
6
7
8
9
package irmago

import (
	"crypto/rand"
	"crypto/sha256"
	"encoding/base64"
)

type keyshareServer struct {
Sietse Ringers's avatar
Sietse Ringers committed
10
11
12
13
	URL        string              `json:"url"`
	Username   string              `json:"username"`
	Nonce      []byte              `json:"nonce"`
	PrivateKey *paillierPrivateKey `json:"keyPair"`
14
15
}

Sietse Ringers's avatar
Sietse Ringers committed
16
17
18
type keyshareRegistration struct {
	Username  string             `json:"username"`
	Pin       string             `json:"pin"`
Sietse Ringers's avatar
Sietse Ringers committed
19
20
21
22
23
	PublicKey *paillierPublicKey `json:"publicKey"`
}

type KeyshareHandler interface {
	StartKeyshareRegistration(manager *SchemeManager)
24
25
}

Sietse Ringers's avatar
Sietse Ringers committed
26
func newKeyshareServer(privatekey *paillierPrivateKey, url, email string) (ks *keyshareServer, err error) {
27
	ks.Nonce = make([]byte, 0, 32)
Sietse Ringers's avatar
Sietse Ringers committed
28
29
30
	ks.URL = url
	ks.Username = email
	ks.PrivateKey = privatekey
31
32
33
34
35
36
37
38
39
	_, err = rand.Read(ks.Nonce)
	return
}

func (ks *keyshareServer) HashedPin(pin string) string {
	hash := sha256.Sum256(append(ks.Nonce, []byte(pin)...))
	return base64.RawStdEncoding.EncodeToString(hash[:])
}

Sietse Ringers's avatar
Sietse Ringers committed
40
41
42
43
44
45
46
47
48
49
func KeyshareEnroll(manager *SchemeManager, email, pin string) error {
	transport := NewHTTPTransport(manager.KeyshareServer)
	kss, err := newKeyshareServer(Manager.paillierKey(), manager.URL, email)
	if err != nil {
		return err
	}
	message := keyshareRegistration{
		Username:  email,
		Pin:       kss.HashedPin(pin),
		PublicKey: (*paillierPublicKey)(&kss.PrivateKey.PublicKey),
50
51
	}

Sietse Ringers's avatar
Sietse Ringers committed
52
53
54
55
56
57
58
	// TODO: examine error returned by Post() to see if it tells us that the email address is already in use
	result := &struct{}{}
	err = transport.Post("/web/users/selfenroll", result, message)
	if err != nil {
		return err
	}
	return Manager.addKeyshareServer(manager, kss)
59
}