Skip to content
Snippets Groups Projects
Commit 5c1addd7 authored by Josh Brooks's avatar Josh Brooks
Browse files

Further clean up authenticated connections' implementation

parent bd39e4fc
No related branches found
No related tags found
3 merge requests!510Release,!216Xx 3895/authenticated connection,!207WIP: Client Restructure
......@@ -37,9 +37,9 @@ type Connection interface {
IsAuthenticated() bool
}
// ConnectionCallback is the callback format required to retrieve
// Callback is the callback format required to retrieve
// new authenticated.Connection objects as they are established.
type ConnectionCallback func(connection Connection)
type Callback func(connection Connection)
// ConnectWithAuthentication is called by the client, ie the one establishing
// connection with the server. Once a connect.Connection has been established
......@@ -86,10 +86,9 @@ func ConnectWithAuthentication(recipient contact.Contact, myId *id.ID,
// Record since we first successfully sen the message
timeStart := netTime.Now()
authConnChan := make(chan Connection, 1)
// Determine that the message is properly sent by tracking the success
// of the round(s)
authConnChan := make(chan Connection, 1)
roundCb := cmix.RoundEventCallback(func(allRoundsSucceeded,
timedOut bool, rounds map[id.Round]cmix.RoundResult) {
if allRoundsSucceeded {
......@@ -102,14 +101,18 @@ func ConnectWithAuthentication(recipient contact.Contact, myId *id.ID,
}
})
// Find the remaining time in the timeout since we first sent the message
remainingTime := e2eParams.Timeout - netTime.Since(timeStart)
// Track the result of the round(s) we sent the
// identity authentication message on
err = net.GetRoundResults(remainingTime,
roundCb, rids...)
if err != nil {
return nil, errors.Errorf("could not track rounds for successful " +
"identity confirmation message delivery")
}
// Block waiting for auth to confirm it timeouts
// Block waiting for confirmation of the round(s) success (or timeout
jww.DEBUG.Printf("Connection waiting for authenticated "+
"connection with %s to be established...", recipient.ID.String())
timeout := time.NewTimer(p.Timeout)
......@@ -134,7 +137,7 @@ func ConnectWithAuthentication(recipient contact.Contact, myId *id.ID,
// will handle authenticated requests and verify the client's attempt to
// authenticate themselves. An established authenticated.Connection will
// be passed via the callback.
func StartServer(cb ConnectionCallback,
func StartServer(cb Callback,
myId *id.ID, privKey *cyclic.Int,
rng *fastRNG.StreamGenerator, grp *cyclic.Group, net cmix.Client,
p connect.Params) error {
......@@ -146,7 +149,7 @@ func StartServer(cb ConnectionCallback,
// message is received and validated, an authenticated connection will
// be passed along via the callback
connection.RegisterListener(catalog.ConnectionAuthenticationRequest,
handleAuthConfirmation(cb, connection))
buildAuthConfirmationHandler(cb, connection))
})
return connect.StartServer(connCb, myId, privKey, rng, grp,
net, p)
......
///////////////////////////////////////////////////////////////////////////////
// Copyright © 2020 xx network SEZC //
// //
// Use of this source code is governed by a license that can be found in the //
// LICENSE file //
///////////////////////////////////////////////////////////////////////////////
package authenticated
import (
......@@ -40,7 +47,6 @@ func makeClientAuthRequest(newPartner partner.Manager,
}
payload, err := proto.Marshal(iar)
if err != nil {
return nil, errors.Errorf("failed to marshal identity request "+
"message: %+v", err)
}
......
......@@ -31,42 +31,40 @@ type server interface {
type serverListener struct {
// connectionCallback allows an authenticated.Connection
// to be passed back upon establishment.
connectionCallback ConnectionCallback
connectionCallback Callback
// conn used to retrieve the connection context with the partner.
conn connect.Connection
}
// handleAuthConfirmation returns a serverListener object.
func handleAuthConfirmation(cb ConnectionCallback,
// buildAuthConfirmationHandler returns a serverListener object.
// This will handle incoming identity authentication confirmations
// via the serverListener.Hear method. A successful authenticated.Connection
// will be passed along via the serverListener.connectionCallback
func buildAuthConfirmationHandler(cb Callback,
connection connect.Connection) server {
return serverListener{
return &serverListener{
connectionCallback: cb,
conn: connection,
}
}
// Hear handles the reception of an IdentityAuthentication by the
// server.
// server. It will attempt to verify the identity confirmation of
// the given client.
func (a serverListener) Hear(item receive.Message) {
// Process the message data into a protobuf
iar := &IdentityAuthentication{}
err := proto.Unmarshal(item.Payload, iar)
if err != nil {
jww.ERROR.Printf("Unable to build connection with "+
"partner %s: %+v", item.Sender, err)
// Send a nil connection to avoid hold-ups down the line
a.connectionCallback(nil)
a.handleAuthConfirmationErr(err, item.Sender)
return
}
// Process the PEM encoded public key to an rsa.PublicKey object
partnerPubKey, err := rsa.LoadPublicKeyFromPem(iar.RsaPubKey)
if err != nil {
jww.ERROR.Printf("Unable to build connection with "+
"partner %s: %+v", item.Sender, err)
// Send a nil connection to avoid hold-ups down the line
a.connectionCallback(nil)
a.handleAuthConfirmationErr(err, item.Sender)
return
}
......@@ -77,18 +75,12 @@ func (a serverListener) Hear(item receive.Message) {
// along the wire
partnerWireId, err := xx.NewID(partnerPubKey, iar.Salt, id.User)
if err != nil {
jww.ERROR.Printf("Unable to parse identity information with "+
"partner %s: %+v", item.Sender, err)
// Send a nil connection to avoid hold-ups down the line
a.connectionCallback(nil)
a.handleAuthConfirmationErr(err, item.Sender)
return
}
if !newPartner.PartnerId().Cmp(partnerWireId) {
jww.ERROR.Printf("Unable to verify identity information with "+
"partner %s: %+v", item.Sender, err)
// Send a nil connection to avoid hold-ups down the line
a.connectionCallback(nil)
a.handleAuthConfirmationErr(err, item.Sender)
return
}
......@@ -105,10 +97,8 @@ func (a serverListener) Hear(item receive.Message) {
// Verify the signature
err = rsa.Verify(partnerPubKey, opts.Hash, nonce, iar.Signature, opts)
if err != nil {
jww.ERROR.Printf("Unable to build connection with "+
"partner %s: %+v", item.Sender, err)
// Send a nil connection to avoid hold-ups down the line
a.connectionCallback(nil)
a.handleAuthConfirmationErr(err, item.Sender)
return
}
// If successful, pass along the established authenticated connection
......@@ -120,6 +110,20 @@ func (a serverListener) Hear(item receive.Message) {
a.connectionCallback(authConn)
}
// handleAuthConfirmationErr is a helper function which will close the connection
// between the server and the client. It will also print out the passed in error.
func (a serverListener) handleAuthConfirmationErr(err error, sender *id.ID) {
jww.ERROR.Printf("Unable to build connection with "+
"partner %s: %+v", sender, err)
// Send a nil connection to avoid hold-ups down the line
a.connectionCallback(nil)
err = a.conn.Close()
if err != nil {
jww.ERROR.Printf("Failed to close connection with partner %s: %v",
sender, err)
}
}
// Name returns the name of this listener. This is typically for
// printing/debugging purposes.
func (a serverListener) Name() string {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment