taldir

Directory service to resolve wallet mailboxes by messenger addresses
Log | Files | Refs | Submodules | README | LICENSE

commit 9fd3f55c3b44c76ad15cafaadd05f54c17566f9b
parent d96386f9b16696fc9d883aecdbf6d8410a57ea95
Author: Martin Schanzenbach <schanzen@gnunet.org>
Date:   Mon, 11 Jul 2022 19:01:49 +0200

s/code/challenge

Diffstat:
Mpkg/rest/taldir.go | 35++++++++++++++++++++---------------
Mpkg/util/helper.go | 8++++----
Mtaldir.conf | 4++--
3 files changed, 26 insertions(+), 21 deletions(-)

diff --git a/pkg/rest/taldir.go b/pkg/rest/taldir.go @@ -75,8 +75,8 @@ type Taldir struct { // Request frequency RequestFrequency int64 - // Code TTL - CodeTtl time.Duration + // Challence TTL + ChallengeTtl time.Duration // How often may a challenge be requested ValidationInitiationMax int @@ -88,8 +88,8 @@ type Taldir struct { SolutionTimeframe time.Duration - // Code length in bytes before encoding - CodeBytes int + // Challenge length in bytes before encoding + ChallengeBytes int } type VersionResponse struct { @@ -194,7 +194,7 @@ type Validation struct { Inbox string `json:"inbox_url"` // The activation code sent to the client - Code string `json:"activation_code"` + Challenge string `json:"-"` // Public key of the user to register PublicKey string `json:"public_key"` @@ -251,6 +251,11 @@ type ErrorDetail struct { } type ValidationConfirmation struct { + // The solution is the SHA-512 hash of the challenge value + // chosen by TalDir (encoded as string just as given in the URL, but + // excluding the 0-termination) concatenated with the binary 32-byte + // value representing the wallet's EdDSA public key. + // The hash is provided as string in Crockford base32 encoding. Solution string `json:"solution"` } @@ -325,7 +330,7 @@ func (t *Taldir) validationRequest(w http.ResponseWriter, r *http.Request){ validation.SolutionAttemptCount = 1 } t.Db.Save(&validation) - expectedSolution := util.GenerateSolution(validation.PublicKey, validation.Code) + expectedSolution := util.GenerateSolution(validation.PublicKey, validation.Challenge) if confirm.Solution != expectedSolution { w.WriteHeader(http.StatusForbidden) return @@ -407,7 +412,7 @@ func (t *Taldir) registerRequest(w http.ResponseWriter, r *http.Request){ } } err = t.Db.First(&validation, "h_address = ?", h_address).Error - validation.Code = util.GenerateCode(t.CodeBytes) + validation.Challenge = util.GenerateChallenge(t.ChallengeBytes) validation.Inbox = req.Inbox validation.Duration = req.Duration validation.PublicKey = req.PublicKey @@ -416,7 +421,7 @@ func (t *Taldir) registerRequest(w http.ResponseWriter, r *http.Request){ if err == nil { // Limit re-initiation attempts validation.InitiationCount++ - if time.Now().Before(validation.TimeframeStart.Add(t.CodeTtl)) { + if time.Now().Before(validation.TimeframeStart.Add(t.ChallengeTtl)) { if validation.InitiationCount > t.ValidationInitiationMax { w.WriteHeader(429) rlResponse := RateLimitedResponse{ @@ -459,7 +464,7 @@ func (t *Taldir) registerRequest(w http.ResponseWriter, r *http.Request){ w.WriteHeader(500) return } - out, err := exec.Command(path, req.Address, validation.Code).Output() + out, err := exec.Command(path, req.Address, validation.Challenge).Output() if err != nil { log.Println(err) t.Db.Delete(&validation) @@ -499,7 +504,7 @@ func (t *Taldir) validationPage(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) w.Header().Set("Content-Type", "text/html; charset=utf-8") var walletLink string - walletLink = "taler://taldir/" + vars["h_address"] + "/" + vars["validation_code"] + "-wallet" + walletLink = "taler://taldir/" + vars["h_address"] + "/" + vars["challenge"] + "-wallet" var png []byte png, err := qrcode.Encode(walletLink, qrcode.Medium, 256) if err != nil { @@ -648,7 +653,7 @@ func (t *Taldir) setupHandlers() { /* Registration API */ t.Router.HandleFunc("/{h_address}", t.getSingleEntry).Methods("GET") t.Router.HandleFunc("/register/{method}", t.registerRequest).Methods("POST") - t.Router.HandleFunc("/register/{h_address}/{validation_code}", t.validationPage).Methods("GET") + t.Router.HandleFunc("/register/{h_address}/{challenge}", t.validationPage).Methods("GET") t.Router.HandleFunc("/{h_address}", t.validationRequest).Methods("POST") } @@ -672,17 +677,17 @@ func (t *Taldir) Initialize(cfgfile string) { for _, a := range strings.Split(t.Cfg.Section("taldir").Key("validators").String(), " ") { t.Validators[a] = true } - t.CodeBytes = t.Cfg.Section("taldir").Key("activation_code_bytes").MustInt(16) + t.ChallengeBytes = t.Cfg.Section("taldir").Key("challenge_bytes").MustInt(16) t.ValidationInitiationMax = t.Cfg.Section("taldir").Key("validation_initiation_max").MustInt(3) t.SolutionAttemptsMax = t.Cfg.Section("taldir").Key("solution_attempt_max").MustInt(3) - validationTtlStr := t.Cfg.Section("taldir").Key("activation_code_ttl").MustString("5m") - t.CodeTtl, err = time.ParseDuration(validationTtlStr) + validationTtlStr := t.Cfg.Section("taldir").Key("challenge_ttl").MustString("5m") + t.ChallengeTtl, err = time.ParseDuration(validationTtlStr) if err != nil { log.Fatal(err) } - retryTimeframeStr := t.Cfg.Section("taldir").Key("code_attempt_timeframe").MustString("1h") + retryTimeframeStr := t.Cfg.Section("taldir").Key("solution_attempt_timeframe").MustString("1h") t.SolutionTimeframe, err = time.ParseDuration(retryTimeframeStr) if err != nil { log.Fatal(err) diff --git a/pkg/util/helper.go b/pkg/util/helper.go @@ -26,21 +26,21 @@ import ( ) -// Generates a solution from a code and pubkey -func GenerateSolution(pubkeyEncoded string, code string) string { +// Generates a solution from a challenge and pubkey +func GenerateSolution(pubkeyEncoded string, challenge string) string { pubkey, err := DecodeStringToBinary(pubkeyEncoded, 36) if err != nil { fmt.Println("error decoding pubkey:", err) return "" } h := sha512.New() - h.Write([]byte(code)) + h.Write([]byte(challenge)) h.Write(pubkey) return EncodeBinaryToString(h.Sum(nil)) } // Generates random reference token used in the validation flow. -func GenerateCode(bytes int) string { +func GenerateChallenge(bytes int) string { randBytes := make([]byte, bytes) _, err := rand.Read(randBytes) if err != nil { diff --git a/taldir.conf b/taldir.conf @@ -10,10 +10,10 @@ default_doc_filetype = text/markdown default_doc_lang = en-US default_tos_path = terms/ default_pp_path = privacy/ -activation_code_bytes = 16 +challenge_bytes = 16 validation_initiation_max = 3 solution_attempt_max = 3 -activation_code_ttl = 10m +challenge_ttl = 10m solution_attempt_timeframe = 1h [taldir-email]