mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-08-06 14:20:56 +00:00
Extract form sealing to a package
This commit is contained in:
parent
ced892fd1a
commit
1c55e8fca7
9 changed files with 119 additions and 117 deletions
|
@ -15,6 +15,7 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/FrankerFaceZ/FrankerFaceZ/socketserver/server/naclform"
|
||||||
cache "github.com/patrickmn/go-cache"
|
cache "github.com/patrickmn/go-cache"
|
||||||
"golang.org/x/crypto/nacl/box"
|
"golang.org/x/crypto/nacl/box"
|
||||||
)
|
)
|
||||||
|
@ -33,8 +34,7 @@ type backendInfo struct {
|
||||||
addTopicURL string
|
addTopicURL string
|
||||||
announceStartupURL string
|
announceStartupURL string
|
||||||
|
|
||||||
sharedKey [32]byte
|
secureForm naclform.ServerInfo
|
||||||
serverID int
|
|
||||||
|
|
||||||
lastSuccess map[string]time.Time
|
lastSuccess map[string]time.Time
|
||||||
lastSuccessLock sync.Mutex
|
lastSuccessLock sync.Mutex
|
||||||
|
@ -45,7 +45,7 @@ var Backend *backendInfo
|
||||||
func setupBackend(config *ConfigFile) *backendInfo {
|
func setupBackend(config *ConfigFile) *backendInfo {
|
||||||
b := new(backendInfo)
|
b := new(backendInfo)
|
||||||
Backend = b
|
Backend = b
|
||||||
b.serverID = config.ServerID
|
b.secureForm.ServerID = config.ServerID
|
||||||
|
|
||||||
b.HTTPClient.Timeout = 60 * time.Second
|
b.HTTPClient.Timeout = 60 * time.Second
|
||||||
b.baseURL = config.BackendURL
|
b.baseURL = config.BackendURL
|
||||||
|
@ -68,7 +68,7 @@ func setupBackend(config *ConfigFile) *backendInfo {
|
||||||
copy(theirPublic[:], config.BackendPublicKey)
|
copy(theirPublic[:], config.BackendPublicKey)
|
||||||
copy(ourPrivate[:], config.OurPrivateKey)
|
copy(ourPrivate[:], config.OurPrivateKey)
|
||||||
|
|
||||||
box.Precompute(&b.sharedKey, &theirPublic, &ourPrivate)
|
box.Precompute(&b.secureForm.SharedKey, &theirPublic, &ourPrivate)
|
||||||
|
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
@ -119,7 +119,7 @@ func (backend *backendInfo) SendRemoteCommand(remoteCommand, data string, auth A
|
||||||
formData.Set("authenticated", "0")
|
formData.Set("authenticated", "0")
|
||||||
}
|
}
|
||||||
|
|
||||||
sealedForm, err := backend.SealRequest(formData)
|
sealedForm, err := backend.secureForm.Seal(formData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
@ -171,7 +171,7 @@ func (backend *backendInfo) SendRemoteCommand(remoteCommand, data string, auth A
|
||||||
|
|
||||||
// SendAggregatedData sends aggregated emote usage and following data to the backend server.
|
// SendAggregatedData sends aggregated emote usage and following data to the backend server.
|
||||||
func (backend *backendInfo) SendAggregatedData(form url.Values) error {
|
func (backend *backendInfo) SendAggregatedData(form url.Values) error {
|
||||||
sealedForm, err := backend.SealRequest(form)
|
sealedForm, err := backend.secureForm.Seal(form)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -228,7 +228,7 @@ func (backend *backendInfo) sendTopicNotice(topic string, added bool) error {
|
||||||
formData.Set("added", "f")
|
formData.Set("added", "f")
|
||||||
}
|
}
|
||||||
|
|
||||||
sealedForm, err := backend.SealRequest(formData)
|
sealedForm, err := backend.secureForm.Seal(formData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,14 +18,14 @@ func TestSealRequest(t *testing.T) {
|
||||||
"QuickBrownFox": []string{"LazyDog"},
|
"QuickBrownFox": []string{"LazyDog"},
|
||||||
}
|
}
|
||||||
|
|
||||||
sealedValues, err := b.SealRequest(values)
|
sealedValues, err := b.secureForm.Seal(values)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
// sealedValues.Encode()
|
// sealedValues.Encode()
|
||||||
// id=0&msg=KKtbng49dOLLyjeuX5AnXiEe6P0uZwgeP_7mMB5vhP-wMAAPZw%3D%3D&nonce=-wRbUnifscisWUvhm3gBEXHN5QzrfzgV
|
// id=0&msg=KKtbng49dOLLyjeuX5AnXiEe6P0uZwgeP_7mMB5vhP-wMAAPZw%3D%3D&nonce=-wRbUnifscisWUvhm3gBEXHN5QzrfzgV
|
||||||
|
|
||||||
unsealedValues, err := b.UnsealRequest(sealedValues)
|
unsealedValues, err := b.secureForm.Unseal(sealedValues)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -184,7 +184,7 @@ func C2SPing(*websocket.Conn, *ClientInfo, ClientMessage) (ClientMessage, error)
|
||||||
func C2SSetUser(_ *websocket.Conn, client *ClientInfo, msg ClientMessage) (ClientMessage, error) {
|
func C2SSetUser(_ *websocket.Conn, client *ClientInfo, msg ClientMessage) (ClientMessage, error) {
|
||||||
username, err := msg.ArgumentsAsString()
|
username, err := msg.ArgumentsAsString()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return ClientMessage{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
username = copyString(username)
|
username = copyString(username)
|
||||||
|
@ -221,7 +221,7 @@ func C2SReady(_ *websocket.Conn, client *ClientInfo, msg ClientMessage) (ClientM
|
||||||
func C2SSubscribe(_ *websocket.Conn, client *ClientInfo, msg ClientMessage) (ClientMessage, error) {
|
func C2SSubscribe(_ *websocket.Conn, client *ClientInfo, msg ClientMessage) (ClientMessage, error) {
|
||||||
channel, err := msg.ArgumentsAsString()
|
channel, err := msg.ArgumentsAsString()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return ClientMessage{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
channel = PubSubChannelPool.Intern(channel)
|
channel = PubSubChannelPool.Intern(channel)
|
||||||
|
@ -248,7 +248,7 @@ func C2SSubscribe(_ *websocket.Conn, client *ClientInfo, msg ClientMessage) (Cli
|
||||||
func C2SUnsubscribe(_ *websocket.Conn, client *ClientInfo, msg ClientMessage) (ClientMessage, error) {
|
func C2SUnsubscribe(_ *websocket.Conn, client *ClientInfo, msg ClientMessage) (ClientMessage, error) {
|
||||||
channel, err := msg.ArgumentsAsString()
|
channel, err := msg.ArgumentsAsString()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return ClientMessage{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
channel = PubSubChannelPool.Intern(channel)
|
channel = PubSubChannelPool.Intern(channel)
|
||||||
|
|
|
@ -104,7 +104,7 @@ func SetupServerAndHandle(config *ConfigFile, serveMux *http.ServeMux) {
|
||||||
serveMux.HandleFunc("/cached_pub", HTTPBackendCachedPublish)
|
serveMux.HandleFunc("/cached_pub", HTTPBackendCachedPublish)
|
||||||
serveMux.HandleFunc("/get_sub_count", HTTPGetSubscriberCount)
|
serveMux.HandleFunc("/get_sub_count", HTTPGetSubscriberCount)
|
||||||
|
|
||||||
announceForm, err := Backend.SealRequest(url.Values{
|
announceForm, err := Backend.secureForm.Seal(url.Values{
|
||||||
"startup": []string{"1"},
|
"startup": []string{"1"},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
96
socketserver/server/naclform/seal.go
Normal file
96
socketserver/server/naclform/seal.go
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
package naclform
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"crypto/rand"
|
||||||
|
"encoding/base64"
|
||||||
|
"errors"
|
||||||
|
"net/url"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"golang.org/x/crypto/nacl/box"
|
||||||
|
)
|
||||||
|
|
||||||
|
var ErrorShortNonce = errors.New("Nonce too short.")
|
||||||
|
var ErrorInvalidSignature = errors.New("Invalid signature or contents")
|
||||||
|
|
||||||
|
type ServerInfo struct {
|
||||||
|
SharedKey [32]byte
|
||||||
|
ServerID int
|
||||||
|
}
|
||||||
|
|
||||||
|
func fillCryptoRandom(buf []byte) error {
|
||||||
|
remaining := len(buf)
|
||||||
|
for remaining > 0 {
|
||||||
|
count, err := rand.Read(buf)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
remaining -= count
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *ServerInfo) Seal(form url.Values) (url.Values, error) {
|
||||||
|
var nonce [24]byte
|
||||||
|
var err error
|
||||||
|
|
||||||
|
err = fillCryptoRandom(nonce[:])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
cipherMsg := box.SealAfterPrecomputation(nil, []byte(form.Encode()), &nonce, &i.SharedKey)
|
||||||
|
|
||||||
|
bufMessage := new(bytes.Buffer)
|
||||||
|
enc := base64.NewEncoder(base64.URLEncoding, bufMessage)
|
||||||
|
enc.Write(cipherMsg)
|
||||||
|
enc.Close()
|
||||||
|
cipherString := bufMessage.String()
|
||||||
|
|
||||||
|
bufNonce := new(bytes.Buffer)
|
||||||
|
enc = base64.NewEncoder(base64.URLEncoding, bufNonce)
|
||||||
|
enc.Write(nonce[:])
|
||||||
|
enc.Close()
|
||||||
|
nonceString := bufNonce.String()
|
||||||
|
|
||||||
|
retval := url.Values{
|
||||||
|
"nonce": []string{nonceString},
|
||||||
|
"msg": []string{cipherString},
|
||||||
|
"id": []string{strconv.Itoa(i.ServerID)},
|
||||||
|
}
|
||||||
|
|
||||||
|
return retval, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *ServerInfo) Unseal(form url.Values) (url.Values, error) {
|
||||||
|
var nonce [24]byte
|
||||||
|
|
||||||
|
nonceString := form.Get("nonce")
|
||||||
|
dec := base64.NewDecoder(base64.URLEncoding, strings.NewReader(nonceString))
|
||||||
|
count, err := dec.Read(nonce[:])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if count != 24 {
|
||||||
|
return nil, ErrorShortNonce
|
||||||
|
}
|
||||||
|
|
||||||
|
cipherString := form.Get("msg")
|
||||||
|
dec = base64.NewDecoder(base64.URLEncoding, strings.NewReader(cipherString))
|
||||||
|
cipherBuffer := new(bytes.Buffer)
|
||||||
|
cipherBuffer.ReadFrom(dec)
|
||||||
|
|
||||||
|
message, ok := box.OpenAfterPrecomputation(nil, cipherBuffer.Bytes(), &nonce, &i.SharedKey)
|
||||||
|
if !ok {
|
||||||
|
return nil, ErrorInvalidSignature
|
||||||
|
}
|
||||||
|
|
||||||
|
retValues, err := url.ParseQuery(string(message))
|
||||||
|
if err != nil {
|
||||||
|
return nil, ErrorInvalidSignature
|
||||||
|
}
|
||||||
|
|
||||||
|
return retValues, nil
|
||||||
|
}
|
|
@ -123,7 +123,7 @@ func saveLastMessage(cmd Command, channel string, expires time.Time, data string
|
||||||
|
|
||||||
func HTTPBackendDropBacklog(w http.ResponseWriter, r *http.Request) {
|
func HTTPBackendDropBacklog(w http.ResponseWriter, r *http.Request) {
|
||||||
r.ParseForm()
|
r.ParseForm()
|
||||||
formData, err := Backend.UnsealRequest(r.Form)
|
formData, err := Backend.secureForm.Unseal(r.Form)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(403)
|
w.WriteHeader(403)
|
||||||
fmt.Fprintf(w, "Error: %v", err)
|
fmt.Fprintf(w, "Error: %v", err)
|
||||||
|
@ -160,7 +160,7 @@ func rateLimitFromRequest(r *http.Request) (rate.Limiter, error) {
|
||||||
// If the 'expires' parameter is not specified, the message will not expire (though it is only kept in-memory).
|
// If the 'expires' parameter is not specified, the message will not expire (though it is only kept in-memory).
|
||||||
func HTTPBackendCachedPublish(w http.ResponseWriter, r *http.Request) {
|
func HTTPBackendCachedPublish(w http.ResponseWriter, r *http.Request) {
|
||||||
r.ParseForm()
|
r.ParseForm()
|
||||||
formData, err := Backend.UnsealRequest(r.Form)
|
formData, err := Backend.secureForm.Unseal(r.Form)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(403)
|
w.WriteHeader(403)
|
||||||
fmt.Fprintf(w, "Error: %v", err)
|
fmt.Fprintf(w, "Error: %v", err)
|
||||||
|
@ -227,7 +227,7 @@ func HTTPBackendCachedPublish(w http.ResponseWriter, r *http.Request) {
|
||||||
// If "scope" is "global", then "channel" is not used.
|
// If "scope" is "global", then "channel" is not used.
|
||||||
func HTTPBackendUncachedPublish(w http.ResponseWriter, r *http.Request) {
|
func HTTPBackendUncachedPublish(w http.ResponseWriter, r *http.Request) {
|
||||||
r.ParseForm()
|
r.ParseForm()
|
||||||
formData, err := Backend.UnsealRequest(r.Form)
|
formData, err := Backend.secureForm.Unseal(r.Form)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(403)
|
w.WriteHeader(403)
|
||||||
fmt.Fprintf(w, "Error: %v", err)
|
fmt.Fprintf(w, "Error: %v", err)
|
||||||
|
@ -292,7 +292,7 @@ func HTTPBackendUncachedPublish(w http.ResponseWriter, r *http.Request) {
|
||||||
// A "global" option is not available, use fetch(/stats).CurrentClientCount instead.
|
// A "global" option is not available, use fetch(/stats).CurrentClientCount instead.
|
||||||
func HTTPGetSubscriberCount(w http.ResponseWriter, r *http.Request) {
|
func HTTPGetSubscriberCount(w http.ResponseWriter, r *http.Request) {
|
||||||
r.ParseForm()
|
r.ParseForm()
|
||||||
formData, err := Backend.UnsealRequest(r.Form)
|
formData, err := Backend.secureForm.Unseal(r.Form)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(403)
|
w.WriteHeader(403)
|
||||||
fmt.Fprintf(w, "Error: %v", err)
|
fmt.Fprintf(w, "Error: %v", err)
|
||||||
|
|
|
@ -97,7 +97,7 @@ func (er *TExpectedBackendRequest) String() string {
|
||||||
if MethodIsPost == "" {
|
if MethodIsPost == "" {
|
||||||
return er.Path
|
return er.Path
|
||||||
}
|
}
|
||||||
return fmt.Sprint("%s %s: %s", MethodIsPost, er.Path, er.PostForm.Encode())
|
return fmt.Sprintf("%s %s: %s", MethodIsPost, er.Path, er.PostForm.Encode())
|
||||||
}
|
}
|
||||||
|
|
||||||
type TBackendRequestChecker struct {
|
type TBackendRequestChecker struct {
|
||||||
|
@ -123,7 +123,7 @@ func (backend *TBackendRequestChecker) ServeHTTP(w http.ResponseWriter, r *http.
|
||||||
|
|
||||||
r.ParseForm()
|
r.ParseForm()
|
||||||
|
|
||||||
unsealedForm, err := Backend.UnsealRequest(r.PostForm)
|
unsealedForm, err := Backend.secureForm.Unseal(r.PostForm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
backend.tb.Errorf("Failed to unseal backend request: %v", err)
|
backend.tb.Errorf("Failed to unseal backend request: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -276,7 +276,7 @@ func TSealForSavePubMsg(tb testing.TB, cmd Command, channel string, arguments in
|
||||||
}
|
}
|
||||||
form.Set("time", strconv.FormatInt(time.Now().Unix(), 10))
|
form.Set("time", strconv.FormatInt(time.Now().Unix(), 10))
|
||||||
|
|
||||||
sealed, err := Backend.SealRequest(form)
|
sealed, err := Backend.secureForm.Seal(form)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tb.Error(err)
|
tb.Error(err)
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -300,7 +300,7 @@ func TSealForUncachedPubMsg(tb testing.TB, cmd Command, channel string, argument
|
||||||
form.Set("time", time.Now().Format(time.UnixDate))
|
form.Set("time", time.Now().Format(time.UnixDate))
|
||||||
form.Set("scope", scope)
|
form.Set("scope", scope)
|
||||||
|
|
||||||
sealed, err := Backend.SealRequest(form)
|
sealed, err := Backend.secureForm.Seal(form)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tb.Error(err)
|
tb.Error(err)
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -64,7 +64,7 @@ type ClientMessage struct {
|
||||||
origArguments string
|
origArguments string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cm ClientMessage) Reply(cmd string, args interface{}) ClientMessage {
|
func (cm ClientMessage) Reply(cmd Command, args interface{}) ClientMessage {
|
||||||
return ClientMessage{
|
return ClientMessage{
|
||||||
MessageID: cm.MessageID,
|
MessageID: cm.MessageID,
|
||||||
Command: cmd,
|
Command: cmd,
|
||||||
|
@ -72,7 +72,7 @@ func (cm ClientMessage) Reply(cmd string, args interface{}) ClientMessage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cm ClientMessage) ReplyJSON(cmd string, argsJSON string) ClientMessage {
|
func (cm ClientMessage) ReplyJSON(cmd Command, argsJSON string) ClientMessage {
|
||||||
n := ClientMessage{
|
n := ClientMessage{
|
||||||
MessageID: cm.MessageID,
|
MessageID: cm.MessageID,
|
||||||
Command: cmd,
|
Command: cmd,
|
||||||
|
|
|
@ -1,103 +1,9 @@
|
||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"crypto/rand"
|
|
||||||
"encoding/base64"
|
|
||||||
"errors"
|
|
||||||
"net/url"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"golang.org/x/crypto/nacl/box"
|
|
||||||
)
|
|
||||||
|
|
||||||
func FillCryptoRandom(buf []byte) error {
|
|
||||||
remaining := len(buf)
|
|
||||||
for remaining > 0 {
|
|
||||||
count, err := rand.Read(buf)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
remaining -= count
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func copyString(s string) string {
|
func copyString(s string) string {
|
||||||
return string([]byte(s))
|
return string([]byte(s))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (backend *backendInfo) SealRequest(form url.Values) (url.Values, error) {
|
|
||||||
var nonce [24]byte
|
|
||||||
var err error
|
|
||||||
|
|
||||||
err = FillCryptoRandom(nonce[:])
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
cipherMsg := box.SealAfterPrecomputation(nil, []byte(form.Encode()), &nonce, &backend.sharedKey)
|
|
||||||
|
|
||||||
bufMessage := new(bytes.Buffer)
|
|
||||||
enc := base64.NewEncoder(base64.URLEncoding, bufMessage)
|
|
||||||
enc.Write(cipherMsg)
|
|
||||||
enc.Close()
|
|
||||||
cipherString := bufMessage.String()
|
|
||||||
|
|
||||||
bufNonce := new(bytes.Buffer)
|
|
||||||
enc = base64.NewEncoder(base64.URLEncoding, bufNonce)
|
|
||||||
enc.Write(nonce[:])
|
|
||||||
enc.Close()
|
|
||||||
nonceString := bufNonce.String()
|
|
||||||
|
|
||||||
retval := url.Values{
|
|
||||||
"nonce": []string{nonceString},
|
|
||||||
"msg": []string{cipherString},
|
|
||||||
"id": []string{strconv.Itoa(Backend.serverID)},
|
|
||||||
}
|
|
||||||
|
|
||||||
return retval, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var ErrorShortNonce = errors.New("Nonce too short.")
|
|
||||||
var ErrorInvalidSignature = errors.New("Invalid signature or contents")
|
|
||||||
|
|
||||||
func (backend *backendInfo) UnsealRequest(form url.Values) (url.Values, error) {
|
|
||||||
var nonce [24]byte
|
|
||||||
|
|
||||||
nonceString := form.Get("nonce")
|
|
||||||
dec := base64.NewDecoder(base64.URLEncoding, strings.NewReader(nonceString))
|
|
||||||
count, err := dec.Read(nonce[:])
|
|
||||||
if err != nil {
|
|
||||||
Statistics.BackendVerifyFails++
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if count != 24 {
|
|
||||||
Statistics.BackendVerifyFails++
|
|
||||||
return nil, ErrorShortNonce
|
|
||||||
}
|
|
||||||
|
|
||||||
cipherString := form.Get("msg")
|
|
||||||
dec = base64.NewDecoder(base64.URLEncoding, strings.NewReader(cipherString))
|
|
||||||
cipherBuffer := new(bytes.Buffer)
|
|
||||||
cipherBuffer.ReadFrom(dec)
|
|
||||||
|
|
||||||
message, ok := box.OpenAfterPrecomputation(nil, cipherBuffer.Bytes(), &nonce, &backend.sharedKey)
|
|
||||||
if !ok {
|
|
||||||
Statistics.BackendVerifyFails++
|
|
||||||
return nil, ErrorInvalidSignature
|
|
||||||
}
|
|
||||||
|
|
||||||
retValues, err := url.ParseQuery(string(message))
|
|
||||||
if err != nil {
|
|
||||||
Statistics.BackendVerifyFails++
|
|
||||||
return nil, ErrorInvalidSignature
|
|
||||||
}
|
|
||||||
|
|
||||||
return retValues, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func AddToSliceS(ary *[]string, val string) bool {
|
func AddToSliceS(ary *[]string, val string) bool {
|
||||||
slice := *ary
|
slice := *ary
|
||||||
for _, v := range slice {
|
for _, v := range slice {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue