core.go 2.84 KB
Newer Older
1
package keysharecore
2
3

import (
4
	"crypto/rand"
5
6
7
8
	"crypto/rsa"
	"sync"

	"github.com/privacybydesign/gabi/big"
9
	"github.com/privacybydesign/gabi/gabikeys"
10
11
12
	irma "github.com/privacybydesign/irmago"
)

13
14
15
16
17
const (
	JWTIssuerDefault    = "keyshare_server"
	JWTPinExpiryDefault = 5 * 60 // seconds
)

18
type (
19
	AESKey [32]byte
20

21
	Core struct {
22
		// Keys used for storage encryption/decryption
23
24
25
		decryptionKeys  map[uint32]AESKey
		decryptionKey   AESKey
		decryptionKeyID uint32
26

27
		// Key used to sign keyshare protocol messages
28
29
30
31
32
		jwtPrivateKey   *rsa.PrivateKey
		jwtPrivateKeyID uint32

		jwtIssuer    string
		jwtPinExpiry int
33

34
		// Commit values generated in first step of keyshare protocol
35
36
37
		commitmentData  map[uint64]*big.Int
		commitmentMutex sync.Mutex

38
39
		// IRMA issuer keys that are allowed to be used in keyshare
		//  sessions
40
		trustedKeys map[irma.PublicKeyIdentifier]*gabikeys.PublicKey
41
	}
42
43

	Configuration struct {
44
45
46
47
48
49
50
51
		// Keys used for storage encryption/decryption
		DecryptionKey   AESKey
		DecryptionKeyID uint32

		// Key used to sign keyshare protocol messages
		JWTPrivateKey   *rsa.PrivateKey
		JWTPrivateKeyID uint32

52
53
		JWTIssuer    string
		JWTPinExpiry int // in seconds
54
	}
55
56
)

57
func NewKeyshareCore(conf *Configuration) *Core {
58
	c := &Core{
59
		decryptionKeys: map[uint32]AESKey{},
60
		commitmentData: map[uint64]*big.Int{},
61
		trustedKeys:    map[irma.PublicKeyIdentifier]*gabikeys.PublicKey{},
62
	}
63

64
65
	c.setDecryptionKey(conf.DecryptionKeyID, conf.DecryptionKey)
	c.setJWTPrivateKey(conf.JWTPrivateKeyID, conf.JWTPrivateKey)
66
67
68
69
70
71
72
73
74
75

	c.jwtIssuer = conf.JWTIssuer
	if c.jwtIssuer == "" {
		c.jwtIssuer = JWTIssuerDefault
	}
	c.jwtPinExpiry = conf.JWTPinExpiry
	if c.jwtPinExpiry == 0 {
		c.jwtPinExpiry = JWTPinExpiryDefault
	}

76
	return c
77
78
}

79
80
func GenerateDecryptionKey() (AESKey, error) {
	var res AESKey
81
82
83
84
	_, err := rand.Read(res[:])
	return res, err
}

85
// DangerousAddDecryptionKey adds an AES key for decryption, with identifier keyID.
86
// Calling this will cause all keyshare secrets generated with the key to be trusted.
87
func (c *Core) DangerousAddDecryptionKey(keyID uint32, key AESKey) {
88
	c.decryptionKeys[keyID] = key
89
90
}

91
92
// Set the aes key for encrypting new/changed keyshare data
// with identifier keyid
93
// Calling this will also cause all keyshare user secrets generated with the key to be trusted
94
func (c *Core) setDecryptionKey(keyID uint32, key AESKey) {
95
	c.decryptionKeys[keyID] = key
96
97
	c.decryptionKey = key
	c.decryptionKeyID = keyID
98
99
}

100
// Set key used to sign keyshare protocol messages
101
102
103
func (c *Core) setJWTPrivateKey(id uint32, key *rsa.PrivateKey) {
	c.jwtPrivateKey = key
	c.jwtPrivateKeyID = id
104
105
}

106
107
// DangerousAddTrustedPublicKey adds a public key as trusted by keysharecore.
// Calling this on incorrectly generated key material WILL compromise keyshare secrets!
108
func (c *Core) DangerousAddTrustedPublicKey(keyID irma.PublicKeyIdentifier, key *gabikeys.PublicKey) {
109
	c.trustedKeys[keyID] = key
110
}