1
0
Fork 0
mirror of https://github.com/FrankerFaceZ/FrankerFaceZ.git synced 2025-06-29 15:55:33 +00:00

Finish Seal/UnsealRequest functions

This commit is contained in:
Kane York 2015-10-25 14:06:56 -07:00
parent c6a3c120c6
commit 8a24ac37ab
4 changed files with 133 additions and 28 deletions

View file

@ -25,6 +25,7 @@ var responseCache *cache.Cache
var getBacklogUrl string
var backendSharedKey [32]byte
var serverId int
var messageBufferPool sync.Pool
@ -38,7 +39,7 @@ func SetupBackend(config *Config) {
getBacklogUrl = fmt.Sprintf("%s/backlog", backendUrl)
messageBufferPool.New = NewByteBuffer
messageBufferPool.New = New4KByteBuffer
var keys CryptoKeysBuf
file, err := os.Open(config.NaclKeysFile)
@ -51,31 +52,18 @@ func SetupBackend(config *Config) {
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 {
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) {
cached, ok := responseCache.Get(getCacheKey(remoteCommand, data))
if ok {
@ -156,15 +144,16 @@ func GenerateKeys(outputFile, serverId, theirPublicStr string) {
if err != nil {
log.Fatal(err)
}
output.OurPublicKey, output.OurPrivateKey = *ourPublic, *ourPrivate
output.OurPublicKey, output.OurPrivateKey = ourPublic[:], ourPrivate[:]
if theirPublicStr != "" {
reader := base64.NewDecoder(base64.RawURLEncoding, strings.NewReader(theirPublicStr))
reader := base64.NewDecoder(base64.StdEncoding, strings.NewReader(theirPublicStr))
theirPublic, err := ioutil.ReadAll(reader)
if err != nil {
log.Fatal(err)
}
copy(output.TheirPublicKey[:], theirPublic)
log.Print(theirPublic)
output.TheirPublicKey = theirPublic
}
file, err := os.Create(outputFile)

View 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)
}
}

View file

@ -9,9 +9,9 @@ import (
const CryptoBoxKeyLength = 32
type CryptoKeysBuf struct {
OurPrivateKey [CryptoBoxKeyLength]byte
OurPublicKey [CryptoBoxKeyLength]byte
TheirPublicKey [CryptoBoxKeyLength]byte
OurPrivateKey []byte
OurPublicKey []byte
TheirPublicKey []byte
ServerId int
}

View file

@ -2,6 +2,14 @@ package server
import (
"crypto/rand"
"net/url"
"golang.org/x/crypto/nacl/box"
"bytes"
"encoding/base64"
"strconv"
"strings"
"errors"
"log"
)
func FillCryptoRandom(buf []byte) error {
@ -16,8 +24,76 @@ func FillCryptoRandom(buf []byte) error {
return nil
}
func NewByteBuffer() interface{} {
return make([]byte, 1024)
func New4KByteBuffer() interface{} {
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 {