Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
client
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Automate
Agent sessions
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Terraform modules
Analyze
Contributor analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
elixxir
client
Commits
20875a63
Commit
20875a63
authored
Nov 22, 2019
by
Sydney Anne Erickson
Browse files
Options
Downloads
Plain Diff
Merge branch 'revertRearrangements' into 'release'
Revert register.go See merge request
!288
parents
ea2cb870
6d587dc2
Branches
Branches containing commit
Tags
Tags containing commit
No related merge requests found
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
api/client.go
+330
-0
330 additions, 0 deletions
api/client.go
api/register.go
+0
-351
0 additions, 351 deletions
api/register.go
with
330 additions
and
351 deletions
api/client.go
+
330
−
0
View file @
20875a63
...
...
@@ -9,6 +9,7 @@ package api
import
(
"bufio"
"crypto"
"crypto/rand"
gorsa
"crypto/rsa"
"crypto/sha256"
"encoding/base64"
...
...
@@ -23,8 +24,11 @@ import (
"gitlab.com/elixxir/client/parse"
"gitlab.com/elixxir/client/rekey"
"gitlab.com/elixxir/client/user"
"gitlab.com/elixxir/crypto/csprng"
"gitlab.com/elixxir/crypto/cyclic"
"gitlab.com/elixxir/crypto/hash"
"gitlab.com/elixxir/crypto/large"
"gitlab.com/elixxir/crypto/registration"
"gitlab.com/elixxir/crypto/signature/rsa"
"gitlab.com/elixxir/crypto/tls"
"gitlab.com/elixxir/primitives/circuit"
...
...
@@ -33,6 +37,7 @@ import (
"gitlab.com/elixxir/primitives/switchboard"
goio
"io"
"strings"
"sync"
"time"
)
...
...
@@ -447,6 +452,331 @@ type SearchCallback interface {
Callback
(
userID
,
pubKey
[]
byte
,
err
error
)
}
const
SaltSize
=
256
// RegisterWithPermissioning registers user with permissioning and returns the
// User ID. Returns an error if registration fails.
func
(
cl
*
Client
)
RegisterWithPermissioning
(
preCan
bool
,
registrationCode
,
nick
,
email
,
password
string
,
privateKeyRSA
*
rsa
.
PrivateKey
)
(
*
id
.
User
,
error
)
{
if
!
preCan
&&
cl
.
commManager
.
GetConnectionStatus
()
!=
io
.
Online
{
return
nil
,
errors
.
New
(
"Cannot register when disconnected from the network"
)
}
var
err
error
var
u
*
user
.
User
var
UID
*
id
.
User
cl
.
opStatus
(
globals
.
REG_KEYGEN
)
largeIntBits
:=
16
cmixGrp
:=
cyclic
.
NewGroup
(
large
.
NewIntFromString
(
cl
.
ndf
.
CMIX
.
Prime
,
largeIntBits
),
large
.
NewIntFromString
(
cl
.
ndf
.
CMIX
.
Generator
,
largeIntBits
))
e2eGrp
:=
cyclic
.
NewGroup
(
large
.
NewIntFromString
(
cl
.
ndf
.
E2E
.
Prime
,
largeIntBits
),
large
.
NewIntFromString
(
cl
.
ndf
.
E2E
.
Generator
,
largeIntBits
))
// Make CMIX keys array
nk
:=
make
(
map
[
id
.
Node
]
user
.
NodeKeys
)
// GENERATE CLIENT RSA KEYS
if
privateKeyRSA
==
nil
{
privateKeyRSA
,
err
=
rsa
.
GenerateKey
(
rand
.
Reader
,
rsa
.
DefaultRSABitLen
)
if
err
!=
nil
{
return
nil
,
err
}
}
publicKeyRSA
:=
privateKeyRSA
.
GetPublic
()
cmixPrivKeyDHByte
,
err
:=
csprng
.
GenerateInGroup
(
cmixGrp
.
GetPBytes
(),
256
,
csprng
.
NewSystemRNG
())
if
err
!=
nil
{
return
nil
,
errors
.
Errorf
(
"Could not generate cmix DH private key: %s"
,
err
.
Error
())
}
cmixPrivateKeyDH
:=
cmixGrp
.
NewIntFromBytes
(
cmixPrivKeyDHByte
)
cmixPublicKeyDH
:=
cmixGrp
.
ExpG
(
cmixPrivateKeyDH
,
cmixGrp
.
NewMaxInt
())
e2ePrivKeyDHByte
,
err
:=
csprng
.
GenerateInGroup
(
cmixGrp
.
GetPBytes
(),
256
,
csprng
.
NewSystemRNG
())
if
err
!=
nil
{
return
nil
,
errors
.
Errorf
(
"Could not generate e2e DH private key: %s"
,
err
.
Error
())
}
e2ePrivateKeyDH
:=
e2eGrp
.
NewIntFromBytes
(
e2ePrivKeyDHByte
)
e2ePublicKeyDH
:=
e2eGrp
.
ExpG
(
e2ePrivateKeyDH
,
e2eGrp
.
NewMaxInt
())
// Initialized response from Registration Server
regValidationSignature
:=
make
([]
byte
,
0
)
var
salt
[]
byte
// Handle precanned registration
if
preCan
{
cl
.
opStatus
(
globals
.
REG_PRECAN
)
globals
.
Log
.
INFO
.
Printf
(
"Registering precanned user..."
)
u
,
UID
,
nk
,
err
=
cl
.
precannedRegister
(
registrationCode
,
nick
,
nk
)
if
err
!=
nil
{
errMsg
:=
errors
.
Errorf
(
"Unable to complete precanned registration: %+v"
,
err
)
return
id
.
ZeroID
,
errMsg
}
}
else
{
cl
.
opStatus
(
globals
.
REG_UID_GEN
)
globals
.
Log
.
INFO
.
Printf
(
"Registering dynamic user..."
)
// Generate salt for UserID
salt
=
make
([]
byte
,
SaltSize
)
_
,
err
=
csprng
.
NewSystemRNG
()
.
Read
(
salt
)
if
err
!=
nil
{
errMsg
:=
errors
.
Errorf
(
"Register: Unable to generate salt! %s"
,
err
)
return
id
.
ZeroID
,
errMsg
}
// Generate UserID by hashing salt and public key
UID
=
registration
.
GenUserID
(
publicKeyRSA
,
salt
)
// If Registration Server is specified, contact it
// Only if registrationCode is set
globals
.
Log
.
INFO
.
Println
(
"Register: Contacting registration server"
)
if
cl
.
ndf
.
Registration
.
Address
!=
""
&&
registrationCode
!=
""
{
cl
.
opStatus
(
globals
.
REG_PERM
)
regValidationSignature
,
err
=
cl
.
sendRegistrationMessage
(
registrationCode
,
publicKeyRSA
)
if
err
!=
nil
{
err
=
errors
.
Errorf
(
"Register: Unable to send registration message: %+v"
,
err
)
return
id
.
ZeroID
,
err
}
}
globals
.
Log
.
INFO
.
Println
(
"Register: successfully passed Registration message"
)
var
actualNick
string
if
nick
!=
""
{
actualNick
=
nick
}
else
{
actualNick
=
base64
.
StdEncoding
.
EncodeToString
(
UID
[
:
])
}
u
=
user
.
Users
.
NewUser
(
UID
,
actualNick
)
user
.
Users
.
UpsertUser
(
u
)
}
cl
.
opStatus
(
globals
.
REG_SECURE_STORE
)
u
.
Email
=
email
// Create the user session
newSession
:=
user
.
NewSession
(
cl
.
storage
,
u
,
nk
,
publicKeyRSA
,
privateKeyRSA
,
cmixPublicKeyDH
,
cmixPrivateKeyDH
,
e2ePublicKeyDH
,
e2ePrivateKeyDH
,
salt
,
cmixGrp
,
e2eGrp
,
password
,
regValidationSignature
)
cl
.
opStatus
(
globals
.
REG_SAVE
)
//set the registration state
err
=
newSession
.
SetRegState
(
user
.
PermissioningComplete
)
if
err
!=
nil
{
return
id
.
ZeroID
,
errors
.
Wrap
(
err
,
"Permissioning Registration "
+
"Failed"
)
}
// Store the user session
errStore
:=
newSession
.
StoreSession
()
if
errStore
!=
nil
{
errMsg
:=
errors
.
Errorf
(
"Permissioning Register: could not register due to failed session save"
+
": %s"
,
errStore
.
Error
())
return
id
.
ZeroID
,
errMsg
}
cl
.
session
=
newSession
return
UID
,
nil
}
// RegisterWithUDB uses the account's email to register with the UDB for
// User discovery. Must be called after Register and Connect.
// It will fail if the user has already registered with UDB
func
(
cl
*
Client
)
RegisterWithUDB
(
timeout
time
.
Duration
)
error
{
regState
:=
cl
.
GetSession
()
.
GetRegState
()
if
regState
!=
user
.
PermissioningComplete
{
return
errors
.
New
(
"Cannot register with UDB when registration "
+
"state is not PermissioningComplete"
)
}
status
:=
cl
.
commManager
.
GetConnectionStatus
()
if
status
==
io
.
Connecting
||
status
==
io
.
Offline
{
return
errors
.
New
(
"ERROR: could not RegisterWithUDB - connection is either offline or connecting"
)
}
email
:=
cl
.
session
.
GetCurrentUser
()
.
Email
var
err
error
if
email
!=
""
{
globals
.
Log
.
INFO
.
Printf
(
"Registering user as %s with UDB"
,
email
)
valueType
:=
"EMAIL"
publicKeyBytes
:=
cl
.
session
.
GetE2EDHPublicKey
()
.
Bytes
()
err
=
bots
.
Register
(
valueType
,
email
,
publicKeyBytes
,
cl
.
opStatus
,
timeout
)
if
err
==
nil
{
globals
.
Log
.
INFO
.
Printf
(
"Registered with UDB!"
)
}
else
{
globals
.
Log
.
WARN
.
Printf
(
"Could not register with UDB: %s"
,
err
)
}
}
else
{
globals
.
Log
.
INFO
.
Printf
(
"Not registering with UDB because no "
+
"email found"
)
}
if
err
!=
nil
{
return
errors
.
Wrap
(
err
,
"Could not register with UDB"
)
}
//set the registration state
err
=
cl
.
session
.
SetRegState
(
user
.
UDBComplete
)
if
err
!=
nil
{
return
errors
.
Wrap
(
err
,
"UDB Registration Failed"
)
}
errStore
:=
cl
.
session
.
StoreSession
()
// FIXME If we have an error here, the session that gets created
// doesn't get immolated. Immolation should happen in a deferred
// call instead.
if
errStore
!=
nil
{
errMsg
:=
errors
.
Errorf
(
"UDB Register: could not register due to failed session save"
+
": %s"
,
errStore
.
Error
())
return
errMsg
}
return
nil
}
func
(
cl
*
Client
)
RegisterWithNodes
()
error
{
session
:=
cl
.
GetSession
()
//Load Cmix keys & group
cmixDHPrivKey
:=
session
.
GetCMIXDHPrivateKey
()
cmixDHPubKey
:=
session
.
GetCMIXDHPublicKey
()
cmixGrp
:=
session
.
GetCmixGroup
()
//Load the rsa keys
rsaPubKey
:=
session
.
GetRSAPublicKey
()
rsaPrivKey
:=
session
.
GetRSAPrivateKey
()
//Load the user ID
UID
:=
session
.
GetCurrentUser
()
.
User
//Load the registration signature
regSignature
:=
session
.
GetRegistrationValidationSignature
()
var
wg
sync
.
WaitGroup
errChan
:=
make
(
chan
error
,
len
(
cl
.
ndf
.
Gateways
))
//Get the registered node keys
registeredNodes
:=
session
.
GetNodes
()
salt
:=
session
.
GetSalt
()
// This variable keeps track of whether there were new registrations
// required, thus requiring the state file to be saved again
newRegistrations
:=
false
for
i
:=
range
cl
.
ndf
.
Gateways
{
localI
:=
i
nodeID
:=
*
id
.
NewNodeFromBytes
(
cl
.
ndf
.
Nodes
[
i
]
.
ID
)
//Register with node if the node has not been registered with already
if
_
,
ok
:=
registeredNodes
[
nodeID
];
!
ok
{
wg
.
Add
(
1
)
newRegistrations
=
true
go
func
()
{
cl
.
registerWithNode
(
localI
,
salt
,
regSignature
,
UID
,
rsaPubKey
,
rsaPrivKey
,
cmixDHPubKey
,
cmixDHPrivKey
,
cmixGrp
,
errChan
)
wg
.
Done
()
}()
}
}
wg
.
Wait
()
//See if the registration returned errors at all
var
errs
error
for
len
(
errChan
)
>
0
{
err
:=
<-
errChan
if
errs
!=
nil
{
errs
=
errors
.
Wrap
(
errs
,
err
.
Error
())
}
else
{
errs
=
err
}
}
//If an error every occurred, return with error
if
errs
!=
nil
{
cl
.
opStatus
(
globals
.
REG_FAIL
)
return
errs
}
// Store the user session if there were changes during node registration
if
newRegistrations
{
errStore
:=
session
.
StoreSession
()
if
errStore
!=
nil
{
err
:=
errors
.
Errorf
(
"Register: could not register due to failed session save"
+
": %s"
,
errStore
.
Error
())
return
err
}
}
return
nil
}
//registerWithNode registers a user. It serves as a helper for Register
func
(
cl
*
Client
)
registerWithNode
(
index
int
,
salt
,
registrationValidationSignature
[]
byte
,
UID
*
id
.
User
,
publicKeyRSA
*
rsa
.
PublicKey
,
privateKeyRSA
*
rsa
.
PrivateKey
,
cmixPublicKeyDH
,
cmixPrivateKeyDH
*
cyclic
.
Int
,
cmixGrp
*
cyclic
.
Group
,
errorChan
chan
error
)
{
gatewayID
:=
id
.
NewNodeFromBytes
(
cl
.
ndf
.
Nodes
[
index
]
.
ID
)
.
NewGateway
()
// Initialise blake2b hash for transmission keys and sha256 for reception
// keys
transmissionHash
,
_
:=
hash
.
NewCMixHash
()
receptionHash
:=
sha256
.
New
()
// Request nonce message from gateway
globals
.
Log
.
INFO
.
Printf
(
"Register: Requesting nonce from gateway %v/%v"
,
index
+
1
,
len
(
cl
.
ndf
.
Gateways
))
nonce
,
dhPub
,
err
:=
cl
.
requestNonce
(
salt
,
registrationValidationSignature
,
cmixPublicKeyDH
,
publicKeyRSA
,
privateKeyRSA
,
gatewayID
)
if
err
!=
nil
{
errMsg
:=
errors
.
Errorf
(
"Register: Failed requesting nonce from gateway: %+v"
,
err
)
errorChan
<-
errMsg
}
// Load server DH pubkey
serverPubDH
:=
cmixGrp
.
NewIntFromBytes
(
dhPub
)
// Confirm received nonce
globals
.
Log
.
INFO
.
Println
(
"Register: Confirming received nonce"
)
err
=
cl
.
confirmNonce
(
UID
.
Bytes
(),
nonce
,
privateKeyRSA
,
gatewayID
)
if
err
!=
nil
{
errMsg
:=
errors
.
Errorf
(
"Register: Unable to confirm nonce: %v"
,
err
)
errorChan
<-
errMsg
}
nodeID
:=
cl
.
topology
.
GetNodeAtIndex
(
index
)
key
:=
user
.
NodeKeys
{
TransmissionKey
:
registration
.
GenerateBaseKey
(
cmixGrp
,
serverPubDH
,
cmixPrivateKeyDH
,
transmissionHash
),
ReceptionKey
:
registration
.
GenerateBaseKey
(
cmixGrp
,
serverPubDH
,
cmixPrivateKeyDH
,
receptionHash
),
}
cl
.
session
.
PushNodeKey
(
nodeID
,
key
)
}
// UDB Search API
// Pass a callback function to extract results
func
(
cl
*
Client
)
SearchForUser
(
emailAddress
string
,
...
...
This diff is collapsed.
Click to expand it.
api/register.go
deleted
100644 → 0
+
0
−
351
View file @
ea2cb870
////////////////////////////////////////////////////////////////////////////////
// Copyright © 2019 Privategrity Corporation /
// /
// All rights reserved. /
////////////////////////////////////////////////////////////////////////////////
package
api
import
(
"crypto/rand"
"crypto/sha256"
"encoding/base64"
"github.com/pkg/errors"
"gitlab.com/elixxir/client/bots"
"gitlab.com/elixxir/client/globals"
"gitlab.com/elixxir/client/io"
"gitlab.com/elixxir/client/user"
"gitlab.com/elixxir/crypto/csprng"
"gitlab.com/elixxir/crypto/cyclic"
"gitlab.com/elixxir/crypto/hash"
"gitlab.com/elixxir/crypto/large"
"gitlab.com/elixxir/crypto/registration"
"gitlab.com/elixxir/crypto/signature/rsa"
"gitlab.com/elixxir/primitives/id"
"sync"
"time"
)
const
SaltSize
=
256
// RegisterWithPermissioning registers user with permissioning and returns the
// User ID. Returns an error if registration fails.
func
(
cl
*
Client
)
RegisterWithPermissioning
(
preCan
bool
,
registrationCode
,
nick
,
email
,
password
string
,
privateKeyRSA
*
rsa
.
PrivateKey
)
(
*
id
.
User
,
error
)
{
if
!
preCan
&&
cl
.
commManager
.
GetConnectionStatus
()
!=
io
.
Online
{
return
nil
,
errors
.
New
(
"Cannot register when disconnected from the network"
)
}
var
err
error
var
u
*
user
.
User
var
UID
*
id
.
User
cl
.
opStatus
(
globals
.
REG_KEYGEN
)
largeIntBits
:=
16
cmixGrp
:=
cyclic
.
NewGroup
(
large
.
NewIntFromString
(
cl
.
ndf
.
CMIX
.
Prime
,
largeIntBits
),
large
.
NewIntFromString
(
cl
.
ndf
.
CMIX
.
Generator
,
largeIntBits
))
e2eGrp
:=
cyclic
.
NewGroup
(
large
.
NewIntFromString
(
cl
.
ndf
.
E2E
.
Prime
,
largeIntBits
),
large
.
NewIntFromString
(
cl
.
ndf
.
E2E
.
Generator
,
largeIntBits
))
// Make CMIX keys array
nk
:=
make
(
map
[
id
.
Node
]
user
.
NodeKeys
)
// GENERATE CLIENT RSA KEYS
if
privateKeyRSA
==
nil
{
privateKeyRSA
,
err
=
rsa
.
GenerateKey
(
rand
.
Reader
,
rsa
.
DefaultRSABitLen
)
if
err
!=
nil
{
return
nil
,
err
}
}
publicKeyRSA
:=
privateKeyRSA
.
GetPublic
()
cmixPrivKeyDHByte
,
err
:=
csprng
.
GenerateInGroup
(
cmixGrp
.
GetPBytes
(),
256
,
csprng
.
NewSystemRNG
())
if
err
!=
nil
{
return
nil
,
errors
.
Errorf
(
"Could not generate cmix DH private key: %s"
,
err
.
Error
())
}
cmixPrivateKeyDH
:=
cmixGrp
.
NewIntFromBytes
(
cmixPrivKeyDHByte
)
cmixPublicKeyDH
:=
cmixGrp
.
ExpG
(
cmixPrivateKeyDH
,
cmixGrp
.
NewMaxInt
())
e2ePrivKeyDHByte
,
err
:=
csprng
.
GenerateInGroup
(
cmixGrp
.
GetPBytes
(),
256
,
csprng
.
NewSystemRNG
())
if
err
!=
nil
{
return
nil
,
errors
.
Errorf
(
"Could not generate e2e DH private key: %s"
,
err
.
Error
())
}
e2ePrivateKeyDH
:=
e2eGrp
.
NewIntFromBytes
(
e2ePrivKeyDHByte
)
e2ePublicKeyDH
:=
e2eGrp
.
ExpG
(
e2ePrivateKeyDH
,
e2eGrp
.
NewMaxInt
())
// Initialized response from Registration Server
regValidationSignature
:=
make
([]
byte
,
0
)
var
salt
[]
byte
// Handle precanned registration
if
preCan
{
cl
.
opStatus
(
globals
.
REG_PRECAN
)
globals
.
Log
.
INFO
.
Printf
(
"Registering precanned user..."
)
u
,
UID
,
nk
,
err
=
cl
.
precannedRegister
(
registrationCode
,
nick
,
nk
)
if
err
!=
nil
{
errMsg
:=
errors
.
Errorf
(
"Unable to complete precanned registration: %+v"
,
err
)
return
id
.
ZeroID
,
errMsg
}
}
else
{
cl
.
opStatus
(
globals
.
REG_UID_GEN
)
globals
.
Log
.
INFO
.
Printf
(
"Registering dynamic user..."
)
// Generate salt for UserID
salt
=
make
([]
byte
,
SaltSize
)
_
,
err
=
csprng
.
NewSystemRNG
()
.
Read
(
salt
)
if
err
!=
nil
{
errMsg
:=
errors
.
Errorf
(
"Register: Unable to generate salt! %s"
,
err
)
return
id
.
ZeroID
,
errMsg
}
// Generate UserID by hashing salt and public key
UID
=
registration
.
GenUserID
(
publicKeyRSA
,
salt
)
// If Registration Server is specified, contact it
// Only if registrationCode is set
globals
.
Log
.
INFO
.
Println
(
"Register: Contacting registration server"
)
if
cl
.
ndf
.
Registration
.
Address
!=
""
&&
registrationCode
!=
""
{
cl
.
opStatus
(
globals
.
REG_PERM
)
regValidationSignature
,
err
=
cl
.
sendRegistrationMessage
(
registrationCode
,
publicKeyRSA
)
if
err
!=
nil
{
err
=
errors
.
Errorf
(
"Register: Unable to send registration message: %+v"
,
err
)
return
id
.
ZeroID
,
err
}
}
globals
.
Log
.
INFO
.
Println
(
"Register: successfully passed Registration message"
)
var
actualNick
string
if
nick
!=
""
{
actualNick
=
nick
}
else
{
actualNick
=
base64
.
StdEncoding
.
EncodeToString
(
UID
[
:
])
}
u
=
user
.
Users
.
NewUser
(
UID
,
actualNick
)
user
.
Users
.
UpsertUser
(
u
)
}
cl
.
opStatus
(
globals
.
REG_SECURE_STORE
)
u
.
Email
=
email
// Create the user session
newSession
:=
user
.
NewSession
(
cl
.
storage
,
u
,
nk
,
publicKeyRSA
,
privateKeyRSA
,
cmixPublicKeyDH
,
cmixPrivateKeyDH
,
e2ePublicKeyDH
,
e2ePrivateKeyDH
,
salt
,
cmixGrp
,
e2eGrp
,
password
,
regValidationSignature
)
cl
.
opStatus
(
globals
.
REG_SAVE
)
//set the registration state
err
=
newSession
.
SetRegState
(
user
.
PermissioningComplete
)
if
err
!=
nil
{
return
id
.
ZeroID
,
errors
.
Wrap
(
err
,
"Permissioning Registration "
+
"Failed"
)
}
// Store the user session
errStore
:=
newSession
.
StoreSession
()
if
errStore
!=
nil
{
errMsg
:=
errors
.
Errorf
(
"Permissioning Register: could not register due to failed session save"
+
": %s"
,
errStore
.
Error
())
return
id
.
ZeroID
,
errMsg
}
cl
.
session
=
newSession
return
UID
,
nil
}
// RegisterWithUDB uses the account's email to register with the UDB for
// User discovery. Must be called after Register and Connect.
// It will fail if the user has already registered with UDB
func
(
cl
*
Client
)
RegisterWithUDB
(
timeout
time
.
Duration
)
error
{
regState
:=
cl
.
GetSession
()
.
GetRegState
()
if
regState
!=
user
.
PermissioningComplete
{
return
errors
.
New
(
"Cannot register with UDB when registration "
+
"state is not PermissioningComplete"
)
}
status
:=
cl
.
commManager
.
GetConnectionStatus
()
if
status
==
io
.
Connecting
||
status
==
io
.
Offline
{
return
errors
.
New
(
"ERROR: could not RegisterWithUDB - connection is either offline or connecting"
)
}
email
:=
cl
.
session
.
GetCurrentUser
()
.
Email
var
err
error
if
email
!=
""
{
globals
.
Log
.
INFO
.
Printf
(
"Registering user as %s with UDB"
,
email
)
valueType
:=
"EMAIL"
publicKeyBytes
:=
cl
.
session
.
GetE2EDHPublicKey
()
.
Bytes
()
err
=
bots
.
Register
(
valueType
,
email
,
publicKeyBytes
,
cl
.
opStatus
,
timeout
)
if
err
==
nil
{
globals
.
Log
.
INFO
.
Printf
(
"Registered with UDB!"
)
}
else
{
globals
.
Log
.
WARN
.
Printf
(
"Could not register with UDB: %s"
,
err
)
}
}
else
{
globals
.
Log
.
INFO
.
Printf
(
"Not registering with UDB because no "
+
"email found"
)
}
if
err
!=
nil
{
return
errors
.
Wrap
(
err
,
"Could not register with UDB"
)
}
//set the registration state
err
=
cl
.
session
.
SetRegState
(
user
.
UDBComplete
)
if
err
!=
nil
{
return
errors
.
Wrap
(
err
,
"UDB Registration Failed"
)
}
errStore
:=
cl
.
session
.
StoreSession
()
// FIXME If we have an error here, the session that gets created
// doesn't get immolated. Immolation should happen in a deferred
// call instead.
if
errStore
!=
nil
{
errMsg
:=
errors
.
Errorf
(
"UDB Register: could not register due to failed session save"
+
": %s"
,
errStore
.
Error
())
return
errMsg
}
return
nil
}
func
(
cl
*
Client
)
RegisterWithNodes
()
error
{
session
:=
cl
.
GetSession
()
//Load Cmix keys & group
cmixDHPrivKey
:=
session
.
GetCMIXDHPrivateKey
()
cmixDHPubKey
:=
session
.
GetCMIXDHPublicKey
()
cmixGrp
:=
session
.
GetCmixGroup
()
//Load the rsa keys
rsaPubKey
:=
session
.
GetRSAPublicKey
()
rsaPrivKey
:=
session
.
GetRSAPrivateKey
()
//Load the user ID
UID
:=
session
.
GetCurrentUser
()
.
User
//Load the registration signature
regSignature
:=
session
.
GetRegistrationValidationSignature
()
var
wg
sync
.
WaitGroup
errChan
:=
make
(
chan
error
,
len
(
cl
.
ndf
.
Gateways
))
//Get the registered node keys
registeredNodes
:=
session
.
GetNodes
()
salt
:=
session
.
GetSalt
()
// This variable keeps track of whether there were new registrations
// required, thus requiring the state file to be saved again
newRegistrations
:=
false
for
i
:=
range
cl
.
ndf
.
Gateways
{
localI
:=
i
nodeID
:=
*
id
.
NewNodeFromBytes
(
cl
.
ndf
.
Nodes
[
i
]
.
ID
)
//Register with node if the node has not been registered with already
if
_
,
ok
:=
registeredNodes
[
nodeID
];
!
ok
{
wg
.
Add
(
1
)
newRegistrations
=
true
go
func
()
{
cl
.
registerWithNode
(
localI
,
salt
,
regSignature
,
UID
,
rsaPubKey
,
rsaPrivKey
,
cmixDHPubKey
,
cmixDHPrivKey
,
cmixGrp
,
errChan
)
wg
.
Done
()
}()
}
}
wg
.
Wait
()
//See if the registration returned errors at all
var
errs
error
for
len
(
errChan
)
>
0
{
err
:=
<-
errChan
if
errs
!=
nil
{
errs
=
errors
.
Wrap
(
errs
,
err
.
Error
())
}
else
{
errs
=
err
}
}
//If an error every occurred, return with error
if
errs
!=
nil
{
cl
.
opStatus
(
globals
.
REG_FAIL
)
return
errs
}
// Store the user session if there were changes during node registration
if
newRegistrations
{
errStore
:=
session
.
StoreSession
()
if
errStore
!=
nil
{
err
:=
errors
.
Errorf
(
"Register: could not register due to failed session save"
+
": %s"
,
errStore
.
Error
())
return
err
}
}
return
nil
}
//registerWithNode registers a user. It serves as a helper for Register
func
(
cl
*
Client
)
registerWithNode
(
index
int
,
salt
,
registrationValidationSignature
[]
byte
,
UID
*
id
.
User
,
publicKeyRSA
*
rsa
.
PublicKey
,
privateKeyRSA
*
rsa
.
PrivateKey
,
cmixPublicKeyDH
,
cmixPrivateKeyDH
*
cyclic
.
Int
,
cmixGrp
*
cyclic
.
Group
,
errorChan
chan
error
)
{
gatewayID
:=
id
.
NewNodeFromBytes
(
cl
.
ndf
.
Nodes
[
index
]
.
ID
)
.
NewGateway
()
// Initialise blake2b hash for transmission keys and sha256 for reception
// keys
transmissionHash
,
_
:=
hash
.
NewCMixHash
()
receptionHash
:=
sha256
.
New
()
// Request nonce message from gateway
globals
.
Log
.
INFO
.
Printf
(
"Register: Requesting nonce from gateway %v/%v"
,
index
+
1
,
len
(
cl
.
ndf
.
Gateways
))
nonce
,
dhPub
,
err
:=
cl
.
requestNonce
(
salt
,
registrationValidationSignature
,
cmixPublicKeyDH
,
publicKeyRSA
,
privateKeyRSA
,
gatewayID
)
if
err
!=
nil
{
errMsg
:=
errors
.
Errorf
(
"Register: Failed requesting nonce from gateway: %+v"
,
err
)
errorChan
<-
errMsg
}
// Load server DH pubkey
serverPubDH
:=
cmixGrp
.
NewIntFromBytes
(
dhPub
)
// Confirm received nonce
globals
.
Log
.
INFO
.
Println
(
"Register: Confirming received nonce"
)
err
=
cl
.
confirmNonce
(
UID
.
Bytes
(),
nonce
,
privateKeyRSA
,
gatewayID
)
if
err
!=
nil
{
errMsg
:=
errors
.
Errorf
(
"Register: Unable to confirm nonce: %v"
,
err
)
errorChan
<-
errMsg
}
nodeID
:=
cl
.
topology
.
GetNodeAtIndex
(
index
)
key
:=
user
.
NodeKeys
{
TransmissionKey
:
registration
.
GenerateBaseKey
(
cmixGrp
,
serverPubDH
,
cmixPrivateKeyDH
,
transmissionHash
),
ReceptionKey
:
registration
.
GenerateBaseKey
(
cmixGrp
,
serverPubDH
,
cmixPrivateKeyDH
,
receptionHash
),
}
cl
.
session
.
PushNodeKey
(
nodeID
,
key
)
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
sign in
to comment