Implemented and integrated ChallengeTaker
This commit is contained in:
parent
4ec064ec9c
commit
4019689df1
|
@ -36,6 +36,7 @@ func makeCookieStore() (*sessions.CookieStore, error) {
|
|||
return sessions.NewCookieStore(auth, enc), nil
|
||||
}
|
||||
|
||||
// ChallengeGiver is responsible for generating challenges and checking challenge responses
|
||||
type ChallengeGiver struct {
|
||||
cookieStore *sessions.CookieStore
|
||||
encryptor *PayloadEncryptor
|
||||
|
@ -50,15 +51,15 @@ func NewChallengeGiver(e *PayloadEncryptor, logger *zap.Logger) (*ChallengeGiver
|
|||
|
||||
return &ChallengeGiver{
|
||||
cookieStore: cs,
|
||||
encryptor: e,
|
||||
encryptor: e.Renew(),
|
||||
logger: logger,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (cg *ChallengeGiver) handleChallengeResponse(w http.ResponseWriter, r *http.Request) *ChallengeError {
|
||||
func (cg *ChallengeGiver) checkChallengeResponse(w http.ResponseWriter, r *http.Request) *ChallengeError {
|
||||
s, err := cg.cookieStore.Get(r, sessionChallenge)
|
||||
if err != nil {
|
||||
cg.logger.Error("handleChallengeResponse: cg.cookieStore.Get(r, sessionChallenge)", zap.Error(err), zap.String("sessionChallenge", sessionChallenge))
|
||||
cg.logger.Error("checkChallengeResponse: cg.cookieStore.Get(r, sessionChallenge)", zap.Error(err), zap.String("sessionChallenge", sessionChallenge))
|
||||
return &ChallengeError{"error", http.StatusInternalServerError}
|
||||
}
|
||||
|
||||
|
@ -75,7 +76,7 @@ func (cg *ChallengeGiver) handleChallengeResponse(w http.ResponseWriter, r *http
|
|||
|
||||
c, err := cg.encryptor.decryptPlain(base58.Decode(pc))
|
||||
if err != nil {
|
||||
cg.logger.Error("handleChallengeResponse: cg.encryptor.decryptPlain(base58.Decode(pc))", zap.Error(err), zap.String("pc", pc))
|
||||
cg.logger.Error("checkChallengeResponse: cg.encryptor.decryptPlain(base58.Decode(pc))", zap.Error(err), zap.String("pc", pc))
|
||||
return &ChallengeError{"error", http.StatusInternalServerError}
|
||||
}
|
||||
|
||||
|
@ -91,7 +92,7 @@ func (cg *ChallengeGiver) handleChallengeResponse(w http.ResponseWriter, r *http
|
|||
s.Values[sessionBlocked] = true
|
||||
err = s.Save(r, w)
|
||||
if err != nil {
|
||||
cg.logger.Error("handleChallengeResponse: err = s.Save(r, w)", zap.Error(err))
|
||||
cg.logger.Error("checkChallengeResponse: err = s.Save(r, w)", zap.Error(err))
|
||||
return &ChallengeError{"error", http.StatusInternalServerError}
|
||||
}
|
||||
|
||||
|
@ -126,6 +127,30 @@ func (cg *ChallengeGiver) getChallenge(w http.ResponseWriter, r *http.Request) (
|
|||
return challenge, nil
|
||||
}
|
||||
|
||||
// ChallengeTaker is responsible for storing and performing server challenges
|
||||
type ChallengeTaker struct {
|
||||
encryptor *PayloadEncryptor
|
||||
serverChallenge []byte
|
||||
}
|
||||
|
||||
func NewChallengeTaker(e *PayloadEncryptor) *ChallengeTaker {
|
||||
return &ChallengeTaker{
|
||||
encryptor: e.Renew(),
|
||||
}
|
||||
}
|
||||
|
||||
func (ct *ChallengeTaker) SetChallenge(challenge []byte) {
|
||||
ct.serverChallenge = challenge
|
||||
}
|
||||
|
||||
func (ct *ChallengeTaker) DoChallenge(req *http.Request) error {
|
||||
if ct.serverChallenge != nil {
|
||||
ec, err := ct.encryptor.encryptPlain(ct.serverChallenge)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
req.Header.Set(sessionChallenge, base58.Encode(ec))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -13,8 +13,6 @@ import (
|
|||
"net/http/cookiejar"
|
||||
"net/url"
|
||||
|
||||
"github.com/btcsuite/btcutil/base58"
|
||||
|
||||
"github.com/status-im/status-go/api"
|
||||
"github.com/status-im/status-go/logutils"
|
||||
"github.com/status-im/status-go/signal"
|
||||
|
@ -33,9 +31,8 @@ import (
|
|||
type BaseClient struct {
|
||||
*http.Client
|
||||
serverCert *x509.Certificate
|
||||
encryptor *PayloadEncryptor
|
||||
baseAddress *url.URL
|
||||
serverChallenge []byte
|
||||
challengeTaker *ChallengeTaker
|
||||
}
|
||||
|
||||
// NewBaseClient returns a fully qualified BaseClient from the given ConnectionParams
|
||||
|
@ -81,7 +78,7 @@ func NewBaseClient(c *ConnectionParams) (*BaseClient, error) {
|
|||
return &BaseClient{
|
||||
Client: &http.Client{Transport: tr, Jar: cj},
|
||||
serverCert: serverCert,
|
||||
encryptor: NewPayloadEncryptor(c.aesKey),
|
||||
challengeTaker: NewChallengeTaker(NewPayloadEncryptor(c.aesKey)),
|
||||
baseAddress: u,
|
||||
}, nil
|
||||
}
|
||||
|
@ -98,20 +95,11 @@ func (c *BaseClient) getChallenge() error {
|
|||
return fmt.Errorf("[client] status not ok when getting challenge, received '%s'", resp.Status)
|
||||
}
|
||||
|
||||
c.serverChallenge, err = ioutil.ReadAll(resp.Body)
|
||||
return err
|
||||
}
|
||||
|
||||
// doChallenge checks if there is a serverChallenge and encrypts the challenge using the shared AES key
|
||||
func (c *BaseClient) doChallenge(req *http.Request) error {
|
||||
if c.serverChallenge != nil {
|
||||
ec, err := c.encryptor.encryptPlain(c.serverChallenge)
|
||||
challenge, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
req.Header.Set(sessionChallenge, base58.Encode(ec))
|
||||
}
|
||||
c.challengeTaker.SetChallenge(challenge)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -322,7 +310,7 @@ func (c *ReceiverClient) receiveAccountData() error {
|
|||
return err
|
||||
}
|
||||
|
||||
err = c.doChallenge(req)
|
||||
err = c.challengeTaker.DoChallenge(req)
|
||||
if err != nil {
|
||||
signal.SendLocalPairingEvent(Event{Type: EventTransferError, Error: err.Error(), Action: ActionPairingAccount})
|
||||
return err
|
||||
|
@ -363,7 +351,7 @@ func (c *ReceiverClient) receiveSyncDeviceData() error {
|
|||
return err
|
||||
}
|
||||
|
||||
err = c.doChallenge(req)
|
||||
err = c.challengeTaker.DoChallenge(req)
|
||||
if err != nil {
|
||||
signal.SendLocalPairingEvent(Event{Type: EventTransferError, Error: err.Error(), Action: ActionSyncDevice})
|
||||
return err
|
||||
|
@ -410,7 +398,7 @@ func (c *ReceiverClient) sendInstallationData() error {
|
|||
}
|
||||
req.Header.Set("Content-Type", "application/octet-stream")
|
||||
|
||||
err = c.doChallenge(req)
|
||||
err = c.challengeTaker.DoChallenge(req)
|
||||
if err != nil {
|
||||
signal.SendLocalPairingEvent(Event{Type: EventTransferError, Error: err.Error(), Action: ActionPairingInstallation})
|
||||
return err
|
||||
|
|
|
@ -187,7 +187,7 @@ func handleSendInstallation(hs HandlerServer, pmr PayloadMounterReceiver) http.H
|
|||
|
||||
func middlewareChallenge(cg *ChallengeGiver, next http.Handler) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
ce := cg.handleChallengeResponse(w, r)
|
||||
ce := cg.checkChallengeResponse(w, r)
|
||||
if ce != nil {
|
||||
http.Error(w, ce.Text, ce.HttpCode)
|
||||
return
|
||||
|
|
Loading…
Reference in New Issue