mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-06-28 23:37:41 +00:00
Finish Seal/UnsealRequest functions
This commit is contained in:
parent
c6a3c120c6
commit
8a24ac37ab
4 changed files with 133 additions and 28 deletions
|
@ -25,6 +25,7 @@ var responseCache *cache.Cache
|
||||||
var getBacklogUrl string
|
var getBacklogUrl string
|
||||||
|
|
||||||
var backendSharedKey [32]byte
|
var backendSharedKey [32]byte
|
||||||
|
var serverId int
|
||||||
|
|
||||||
var messageBufferPool sync.Pool
|
var messageBufferPool sync.Pool
|
||||||
|
|
||||||
|
@ -38,7 +39,7 @@ func SetupBackend(config *Config) {
|
||||||
|
|
||||||
getBacklogUrl = fmt.Sprintf("%s/backlog", backendUrl)
|
getBacklogUrl = fmt.Sprintf("%s/backlog", backendUrl)
|
||||||
|
|
||||||
messageBufferPool.New = NewByteBuffer
|
messageBufferPool.New = New4KByteBuffer
|
||||||
|
|
||||||
var keys CryptoKeysBuf
|
var keys CryptoKeysBuf
|
||||||
file, err := os.Open(config.NaclKeysFile)
|
file, err := os.Open(config.NaclKeysFile)
|
||||||
|
@ -51,31 +52,18 @@ func SetupBackend(config *Config) {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
box.Precompute(&backendSharedKey, &keys.TheirPublicKey, &keys.OurPrivateKey)
|
var theirPublic, ourPrivate [32]byte
|
||||||
|
copy(theirPublic[:], keys.TheirPublicKey)
|
||||||
|
copy(ourPrivate[:], keys.OurPrivateKey)
|
||||||
|
serverId = keys.ServerId
|
||||||
|
|
||||||
|
box.Precompute(&backendSharedKey, &theirPublic, &ourPrivate)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getCacheKey(remoteCommand, data string) string {
|
func getCacheKey(remoteCommand, data string) string {
|
||||||
return fmt.Sprintf("%s/%s", remoteCommand, data)
|
return fmt.Sprintf("%s/%s", remoteCommand, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func SealRequest(form url.Values) ([]byte, error) {
|
|
||||||
asString := form.Encode()
|
|
||||||
var nonce [24]byte
|
|
||||||
var err error
|
|
||||||
|
|
||||||
err = FillCryptoRandom(nonce[:])
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
message := []byte(asString)
|
|
||||||
out := make([]byte, len(message) + box.Overhead)
|
|
||||||
box.SealAfterPrecomputation(out, message, &nonce, &backendSharedKey)
|
|
||||||
|
|
||||||
// TODO
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func RequestRemoteDataCached(remoteCommand, data string, auth AuthInfo) (string, error) {
|
func RequestRemoteDataCached(remoteCommand, data string, auth AuthInfo) (string, error) {
|
||||||
cached, ok := responseCache.Get(getCacheKey(remoteCommand, data))
|
cached, ok := responseCache.Get(getCacheKey(remoteCommand, data))
|
||||||
if ok {
|
if ok {
|
||||||
|
@ -156,15 +144,16 @@ func GenerateKeys(outputFile, serverId, theirPublicStr string) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
output.OurPublicKey, output.OurPrivateKey = *ourPublic, *ourPrivate
|
output.OurPublicKey, output.OurPrivateKey = ourPublic[:], ourPrivate[:]
|
||||||
|
|
||||||
if theirPublicStr != "" {
|
if theirPublicStr != "" {
|
||||||
reader := base64.NewDecoder(base64.RawURLEncoding, strings.NewReader(theirPublicStr))
|
reader := base64.NewDecoder(base64.StdEncoding, strings.NewReader(theirPublicStr))
|
||||||
theirPublic, err := ioutil.ReadAll(reader)
|
theirPublic, err := ioutil.ReadAll(reader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
copy(output.TheirPublicKey[:], theirPublic)
|
log.Print(theirPublic)
|
||||||
|
output.TheirPublicKey = theirPublic
|
||||||
}
|
}
|
||||||
|
|
||||||
file, err := os.Create(outputFile)
|
file, err := os.Create(outputFile)
|
||||||
|
|
40
socketserver/internal/server/backend_test.go
Normal file
40
socketserver/internal/server/backend_test.go
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
package server
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"net/url"
|
||||||
|
"golang.org/x/crypto/nacl/box"
|
||||||
|
"crypto/rand"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSealRequest(t *testing.T) {
|
||||||
|
senderPublic, senderPrivate, err := box.GenerateKey(rand.Reader)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
receiverPublic, receiverPrivate, err := box.GenerateKey(rand.Reader)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
messageBufferPool.New = New4KByteBuffer
|
||||||
|
|
||||||
|
values := url.Values{
|
||||||
|
"QuickBrownFox": []string{"LazyDog"},
|
||||||
|
}
|
||||||
|
|
||||||
|
box.Precompute(&backendSharedKey, receiverPublic, senderPrivate)
|
||||||
|
sealedValues, err := SealRequest(values)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
box.Precompute(&backendSharedKey, senderPublic, receiverPrivate)
|
||||||
|
unsealedValues, err := UnsealRequest(sealedValues)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if unsealedValues.Get("QuickBrownFox") != "LazyDog" {
|
||||||
|
t.Errorf("Failed to round-trip, got back %v", unsealedValues)
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,9 +9,9 @@ import (
|
||||||
const CryptoBoxKeyLength = 32
|
const CryptoBoxKeyLength = 32
|
||||||
|
|
||||||
type CryptoKeysBuf struct {
|
type CryptoKeysBuf struct {
|
||||||
OurPrivateKey [CryptoBoxKeyLength]byte
|
OurPrivateKey []byte
|
||||||
OurPublicKey [CryptoBoxKeyLength]byte
|
OurPublicKey []byte
|
||||||
TheirPublicKey [CryptoBoxKeyLength]byte
|
TheirPublicKey []byte
|
||||||
ServerId int
|
ServerId int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,14 @@ package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
|
"net/url"
|
||||||
|
"golang.org/x/crypto/nacl/box"
|
||||||
|
"bytes"
|
||||||
|
"encoding/base64"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"errors"
|
||||||
|
"log"
|
||||||
)
|
)
|
||||||
|
|
||||||
func FillCryptoRandom(buf []byte) error {
|
func FillCryptoRandom(buf []byte) error {
|
||||||
|
@ -16,8 +24,76 @@ func FillCryptoRandom(buf []byte) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewByteBuffer() interface{} {
|
func New4KByteBuffer() interface{} {
|
||||||
return make([]byte, 1024)
|
return make([]byte, 0, 4096)
|
||||||
|
}
|
||||||
|
|
||||||
|
func 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, &backendSharedKey)
|
||||||
|
|
||||||
|
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(serverId)},
|
||||||
|
}
|
||||||
|
|
||||||
|
return retval, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var ErrorShortNonce = errors.New("Nonce too short.")
|
||||||
|
var ErrorInvalidSignature = errors.New("Invalid signature or contents")
|
||||||
|
|
||||||
|
func 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 {
|
||||||
|
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, &backendSharedKey)
|
||||||
|
if !ok {
|
||||||
|
return nil, ErrorInvalidSignature
|
||||||
|
}
|
||||||
|
|
||||||
|
retValues, err := url.ParseQuery(string(message))
|
||||||
|
if err != nil {
|
||||||
|
// Assume that the signature was accidentally correct but the contents were garbage
|
||||||
|
log.Print(err)
|
||||||
|
return nil, ErrorInvalidSignature
|
||||||
|
}
|
||||||
|
|
||||||
|
return retValues, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func AddToSliceS(ary *[]string, val string) bool {
|
func AddToSliceS(ary *[]string, val string) bool {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue