Commit 11ac4cec authored by Sietse Ringers's avatar Sietse Ringers
Browse files

Keyshare registration

parent 269cfe5f
......@@ -25,6 +25,10 @@ func TestMain(m *testing.M) {
os.Exit(retCode)
}
type IgnoringKeyshareHandler struct{}
func (i *IgnoringKeyshareHandler) StartKeyshareRegistration(m *SchemeManager) {}
func parseMetaStore(t *testing.T) {
require.NoError(t, MetaStore.ParseFolder("testdata/irma_configuration"), "MetaStore.ParseFolder() failed")
}
......@@ -35,8 +39,7 @@ func parseStorage(t *testing.T) {
if !exists {
require.NoError(t, os.Mkdir("testdata/storage/test", 0755), "Could not create test storage")
}
require.NoError(t, Manager.Init("testdata/storage/test"), "Manager.Init() failed")
require.NoError(t, Manager.Init("testdata/storage/test", &IgnoringKeyshareHandler{}), "Manager.Init() failed")
}
func teardown(t *testing.T) {
......@@ -113,7 +116,7 @@ func TestUnmarshaling(t *testing.T) {
parseAndroidStorage(t)
Manager = newCredentialManager()
err := Manager.Init("testdata/storage/test")
err := Manager.Init("testdata/storage/test", nil)
require.NoError(t, err)
verifyStoreIsUnmarshaled(t)
......
......@@ -4,27 +4,30 @@ import (
"crypto/rand"
"crypto/sha256"
"encoding/base64"
"github.com/mcornejo/go-go-gadget-paillier"
)
type keyshareServer struct {
URL string `json:"url"`
Username string `json:"username"`
Nonce []byte `json:"nonce"`
PrivateKey *paillierPrivateKey `json:"keyPair"`
keyGenerator paillierKeygen
URL string `json:"url"`
Username string `json:"username"`
Nonce []byte `json:"nonce"`
PrivateKey *paillierPrivateKey `json:"keyPair"`
}
type keyshareRegistration struct {
Username string `json:"username"`
Pin string `json:"pin"`
PublicKey paillier.PublicKey `json:"publicKey"`
PublicKey *paillierPublicKey `json:"publicKey"`
}
type KeyshareHandler interface {
StartKeyshareRegistration(manager *SchemeManager)
}
func newKeyshareServer(keygen paillierKeygen) (ks *keyshareServer, err error) {
func newKeyshareServer(privatekey *paillierPrivateKey, url, email string) (ks *keyshareServer, err error) {
ks.Nonce = make([]byte, 0, 32)
ks.keyGenerator = keygen
ks.URL = url
ks.Username = email
ks.PrivateKey = privatekey
_, err = rand.Read(ks.Nonce)
return
}
......@@ -34,13 +37,23 @@ func (ks *keyshareServer) HashedPin(pin string) string {
return base64.RawStdEncoding.EncodeToString(hash[:])
}
func (ks *keyshareServer) GetKey() *paillierPrivateKey {
if ks.PrivateKey == nil {
ks.PrivateKey = ks.keyGenerator.paillierKey()
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),
}
return ks.PrivateKey
}
func KeyshareEnroll(manager *SchemeManager, email, pin string) error {
//NewHTTPTransport(qr.URL)
// 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)
}
......@@ -322,3 +322,8 @@ func (cm *CredentialManager) unenrolledKeyshareServers() []*SchemeManager {
}
return list
}
func (cm *CredentialManager) addKeyshareServer(manager *SchemeManager, kss *keyshareServer) error {
cm.keyshareServers[manager.Identifier()] = kss
return cm.storeKeyshareServers()
}
......@@ -11,10 +11,6 @@ import (
type paillierPrivateKey paillier.PrivateKey
type paillierPublicKey paillier.PublicKey
type paillierKeygen interface {
paillierKey() *paillierPrivateKey
}
func (psk *paillierPrivateKey) UnmarshalJSON(bytes []byte) (err error) {
// First try to unmarshal it as a keypair serialized in the old Android format
oldFormat := &struct {
......
......@@ -3,7 +3,6 @@ package protocol
import (
"encoding/json"
"errors"
"fmt"
"math/big"
"github.com/credentials/irmago"
......
......@@ -36,7 +36,7 @@ func parseStorage(t *testing.T) {
if !exists {
require.NoError(t, os.Mkdir("../testdata/storage/test", 0755), "Could not create test storage")
}
require.NoError(t, irmago.Manager.Init("../testdata/storage/test"), "Manager.Init() failed")
require.NoError(t, irmago.Manager.Init("../testdata/storage/test", &IgnoringKeyshareHandler{}), "Manager.Init() failed")
}
func parseAndroidStorage(t *testing.T) {
......@@ -89,6 +89,10 @@ func (th TestHandler) AskSignaturePermission(request irmago.SignatureRequest, Se
th.AskVerificationPermission(request.DisclosureRequest, ServerName, callback)
}
type IgnoringKeyshareHandler struct{}
func (i *IgnoringKeyshareHandler) StartKeyshareRegistration(m *irmago.SchemeManager) {}
func getDisclosureJwt(name string, id irmago.AttributeTypeIdentifier) interface{} {
return NewServiceProviderJwt(name, &irmago.DisclosureRequest{
Content: irmago.AttributeDisjunctionList([]*irmago.AttributeDisjunction{{
......
......@@ -40,7 +40,7 @@ func PathExists(path string) (bool, error) {
}
// Init deserializes the credentials from storage.
func (cm *CredentialManager) Init(path string) (err error) {
func (cm *CredentialManager) Init(path string, pinProvider KeyshareHandler) (err error) {
cm.storagePath = path
err = cm.ensureStorageExists()
......@@ -55,12 +55,30 @@ func (cm *CredentialManager) Init(path string) (err error) {
if err != nil {
return
}
cm.paillierKeyCache, err = cm.loadPaillierKeys()
if err != nil {
return
}
cm.keyshareServers, err = cm.loadKeyshareServers()
if err != nil {
return
}
cm.paillierKeyCache, err = cm.loadPaillierKeys()
return
unenrolled := cm.unenrolledKeyshareServers()
switch len(unenrolled) {
case 0:
return
case 1:
if pinProvider == nil {
return errors.New("Keyshare server found but no PinPovider was given")
}
pinProvider.StartKeyshareRegistration(unenrolled[0])
default:
return errors.New("Too many keyshare servers")
}
return nil
}
// ParseAndroidStorage parses an Android cardemu.xml shared preferences file
......@@ -108,7 +126,6 @@ func (cm *CredentialManager) ParseAndroidStorage() (err error) {
}
for name, kss := range parsedksses {
kss.keyGenerator = cm
cm.keyshareServers[NewSchemeManagerIdentifier(name)] = kss
}
......@@ -355,7 +372,6 @@ func (cm *CredentialManager) loadKeyshareServers() (ksses map[SchemeManagerIdent
return nil, err
}
for name, kss := range temp {
kss.keyGenerator = cm
ksses[NewSchemeManagerIdentifier(name)] = kss
}
return
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment