From e4958bb368efe3bd338c4a53a8b8aeab41baa6fa Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Fri, 1 Apr 2022 05:06:36 +0200 Subject: [PATCH] token-validator: Add missing file for tuto3 --- token-validator/remote-challenge.go | 123 ++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 token-validator/remote-challenge.go diff --git a/token-validator/remote-challenge.go b/token-validator/remote-challenge.go new file mode 100644 index 0000000..91dfb4c --- /dev/null +++ b/token-validator/remote-challenge.go @@ -0,0 +1,123 @@ +package main + +import ( + "bytes" + "crypto/ed25519" + "encoding/base64" + "encoding/json" + "errors" + "fmt" + "log" + "net/http" + "time" + + "github.com/julienschmidt/httprouter" + + "git.nemunai.re/srs/adlin/libadlin" +) + +func init() { + router.POST("/remote", rawHandler(responseHandler(remoteChallHandler(receiveRemoteChallenge)))) +} + +type SendMeta struct { + Time time.Time `json:"time"` + Login string `json:"login"` + Test string `json:"test"` +} + +type SendContent struct { + Meta []byte `json:"meta"` + Data []byte `json:"data"` + Sign []byte `json:"sign"` + Key []byte `json:"key"` + KeySign []byte `json:"keysign"` +} + +func remoteChallHandler(f func(*http.Request, *adlin.Student, SendContent) (interface{}, error)) func(*http.Request, httprouter.Params, []byte) (interface{}, error) { + return func(r *http.Request, ps httprouter.Params, body []byte) (v interface{}, err error) { + var data SendContent + err = json.Unmarshal(body, &data) + if err != nil { + return + } + + // Check signatures + if !ed25519.Verify(adlin.GetCollectorPublic(), data.Key, data.KeySign) { + return nil, fmt.Errorf("Bad KSK signature") + } + + if !ed25519.Verify(data.Key, append(data.Meta, data.Data...), data.Sign) { + return nil, fmt.Errorf("Bad DSK signature") + } + + var meta SendMeta + err = json.NewDecoder(base64.NewDecoder(base64.StdEncoding, bytes.NewBuffer(data.Meta))).Decode(&meta) + if err != nil { + return + } + + // Find pubkeys associated with login + var std *adlin.Student + std, err = adlin.GetStudentByLogin(string(meta.Login)) + if err != nil { + return + } + + var tps []ed25519.PublicKey + tps, err = std.GetActivesTunnelsPubKey() + if err != nil { + return + } + + // Check signature + found := false + for _, pubk := range tps { + if pubk.Equal(ed25519.PublicKey(data.Key)) { + found = true + break + } + } + + if !found { + return nil, fmt.Errorf("Unable to find key for user") + } + + return f(r, std, data) + } +} + +func receiveRemoteChallenge(r *http.Request, std *adlin.Student, data SendContent) (interface{}, error) { + var tests map[string]*string + err := json.NewDecoder(base64.NewDecoder(base64.StdEncoding, bytes.NewBuffer(data.Data))).Decode(&tests) + if err != nil { + return nil, err + } + + for k, v := range tests { + var chalid int + switch k { + case "wks-cm1": + chalid = 210 + case "wks-dg1": + chalid = 209 + case "wks-rh1": + chalid = 208 + case "wks-rh2": + chalid = 208 + } + + if chalid != 0 { + if v == nil { + if _, err := std.UnlockChallenge(chalid, ""); err != nil { + log.Printf("Unable to register challenge for %s: %s\n", std.Login, err.Error()) + } + } else if errreg := std.RegisterChallengeError(chalid, errors.New(*v)); errreg != nil { + log.Printf("Unable to register challenge error for %s: %s\n", std.Login, errreg) + } + + } + } + + return true, err +}