commit 9fd3f55c3b44c76ad15cafaadd05f54c17566f9b
parent d96386f9b16696fc9d883aecdbf6d8410a57ea95
Author: Martin Schanzenbach <schanzen@gnunet.org>
Date: Mon, 11 Jul 2022 19:01:49 +0200
s/code/challenge
Diffstat:
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]