render context: add asset_download_token

This commit is contained in:
Mikaël Cluseau
2025-07-27 12:40:01 +02:00
parent 7f1193cdda
commit 2b27cc57e3
2 changed files with 51 additions and 26 deletions

View File

@ -14,6 +14,7 @@ import (
"path"
"path/filepath"
"text/template"
"time"
cfsslconfig "github.com/cloudflare/cfssl/config"
restful "github.com/emicklei/go-restful"
@ -237,6 +238,32 @@ func (ctx *renderContext) TemplateFuncs() map[string]any {
}
}
return
},
"asset_download_token": func(asset string, params ...string) (token string, err error) {
now := time.Now()
exp := now.Add(24 * time.Hour) // expire in 24h by default
if len(params) != 0 {
exp, err = parseCertDuration(params[0], now)
if err != nil {
return
}
}
set := DownloadSet{
Expiry: exp,
Items: []DownloadSetItem{
{
Kind: "host",
Name: ctx.Host.Name,
Assets: []string{asset},
},
},
}
privKey, _ := dlsSigningKeys()
token = set.Signed(privKey)
return
},
} {

View File

@ -70,6 +70,28 @@ func (s *DownloadSet) Decode(encoded string) (err error) {
return
}
func (s DownloadSet) Signed(privKey ed25519.PrivateKey) string {
buf := new(bytes.Buffer)
{
setBytes := []byte(s.Encode())
w := lz4.NewWriter(buf)
w.Write(setBytes)
w.Close()
}
setBytes := buf.Bytes()
sig := ed25519.Sign(privKey, setBytes)
buf = bytes.NewBuffer(make([]byte, 0, 1+len(sig)+len(setBytes)))
buf.WriteByte(byte(len(sig)))
buf.Write(sig)
buf.Write(setBytes)
enc := base32.StdEncoding.WithPadding(base32.NoPadding)
return enc.EncodeToString(buf.Bytes())
}
type DownloadSetItem struct {
Kind string
Name string
@ -138,32 +160,8 @@ func wsSignDownloadSet(req *restful.Request, resp *restful.Response) {
Items: setReq.Items,
}
buf := new(bytes.Buffer)
{
setBytes := []byte(set.Encode())
w := lz4.NewWriter(buf)
w.Write(setBytes)
w.Close()
}
setBytes := buf.Bytes()
privkey, pubkey := dlsSigningKeys()
sig := ed25519.Sign(privkey, setBytes)
if !ed25519.Verify(pubkey, setBytes, sig) {
wsError(resp, fmt.Errorf("signature self-check failed"))
return
}
buf = bytes.NewBuffer(make([]byte, 0, 1+len(sig)+len(setBytes)))
buf.WriteByte(byte(len(sig)))
buf.Write(sig)
buf.Write(setBytes)
enc := base32.StdEncoding.WithPadding(base32.NoPadding)
resp.WriteEntity(enc.EncodeToString(buf.Bytes()))
privKey, _ := dlsSigningKeys()
resp.WriteEntity(set.Signed(privKey))
}
func getDlSet(req *restful.Request) (*DownloadSet, *httperr.Error) {