add file tests, refactor public methods
This commit is contained in:
parent
719a79a548
commit
cd036e9607
12 changed files with 158 additions and 48 deletions
12
decrypt.go
12
decrypt.go
|
@ -2,17 +2,27 @@ package bloat
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"filippo.io/age"
|
"filippo.io/age"
|
||||||
|
"filippo.io/age/armor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (b *Bloat[T]) decrypt(src []byte) ([]byte, error) {
|
func (b *Bloat[T]) decrypt(src []byte) ([]byte, error) {
|
||||||
|
|
||||||
input := bytes.NewReader(src)
|
input := bytes.NewReader(src)
|
||||||
out, err := age.Decrypt(input, &b.encPriv)
|
deArmored := armor.NewReader(input)
|
||||||
|
out, err := age.Decrypt(deArmored, &b.Enc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
fmt.Println("decrypt error")
|
||||||
|
fmt.Println(err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
res, err := io.ReadAll(out)
|
res, err := io.ReadAll(out)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("io readall error")
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
18
encrypt.go
18
encrypt.go
|
@ -3,14 +3,16 @@ package bloat
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
|
|
||||||
"filippo.io/age"
|
"filippo.io/age"
|
||||||
|
"filippo.io/age/armor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (b *Bloat[T]) encrypt(plain []byte) ([]byte, error) {
|
func (b *Bloat[T]) encrypt(plain []byte) ([]byte, error) {
|
||||||
buf := &bytes.Buffer{}
|
buf := &bytes.Buffer{}
|
||||||
w, err := age.Encrypt(buf, &b.EncPub) // my wrapper doesn't support multiple recipients yet
|
|
||||||
|
armorWriter := armor.NewWriter(buf)
|
||||||
|
w, err := age.Encrypt(armorWriter, b.Enc.Recipient()) // my wrapper doesn't support multiple recipients yet
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return []byte{}, err
|
return []byte{}, err
|
||||||
}
|
}
|
||||||
|
@ -19,7 +21,13 @@ func (b *Bloat[T]) encrypt(plain []byte) ([]byte, error) {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
return []byte{}, err
|
return []byte{}, err
|
||||||
}
|
}
|
||||||
var r string
|
if err := w.Close(); err != nil {
|
||||||
_, err = io.WriteString(w, r)
|
fmt.Println("failed to close")
|
||||||
return []byte(r), err
|
return []byte{}, err
|
||||||
|
}
|
||||||
|
if err := armorWriter.Close(); err != nil {
|
||||||
|
return []byte{}, err
|
||||||
|
}
|
||||||
|
// return armored bytes
|
||||||
|
return buf.Bytes(), err
|
||||||
}
|
}
|
||||||
|
|
32
file_test.go
Normal file
32
file_test.go
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
package bloat_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"git.bivouac.wiki/go/bloat"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestFile(t *testing.T) {
|
||||||
|
type txttype struct {
|
||||||
|
Abc int
|
||||||
|
Test bool
|
||||||
|
}
|
||||||
|
recip, err := bloat.NewEncBloat[txttype]()
|
||||||
|
sender, err := bloat.NewEncBloat[txttype]()
|
||||||
|
plaindata := txttype{Abc: 100, Test: true}
|
||||||
|
data, err := sender.WriteEnc(plaindata, recip)
|
||||||
|
err = os.WriteFile("test/data.txttype.bloat", data, 0664)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("writing failed")
|
||||||
|
}
|
||||||
|
content, err := os.ReadFile("test/data.txttype.bloat")
|
||||||
|
dec, err := recip.ReadEnc(content, sender)
|
||||||
|
if dec.Test != plaindata.Test {
|
||||||
|
t.Errorf("not equal")
|
||||||
|
}
|
||||||
|
if dec.Abc != plaindata.Abc {
|
||||||
|
t.Errorf("not equal")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,8 +1,15 @@
|
||||||
package bloat
|
package bloat
|
||||||
|
|
||||||
import "encoding/xml"
|
import (
|
||||||
|
"encoding/xml"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
func (b *Bloat[T]) marshal(body T) ([]byte, error) {
|
func (b *Bloat[T]) marshal(body T) ([]byte, error) {
|
||||||
final, err := xml.Marshal(body)
|
final, err := xml.Marshal(body)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("marshal error")
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
return final, err
|
return final, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,33 +9,33 @@ import (
|
||||||
|
|
||||||
func TestItem(t *testing.T) {
|
func TestItem(t *testing.T) {
|
||||||
type typ struct {
|
type typ struct {
|
||||||
A int
|
A int `xml:"A"`
|
||||||
B string
|
B string `xml:"B"`
|
||||||
}
|
}
|
||||||
data := typ{
|
data := typ{
|
||||||
A: 1,
|
A: 1,
|
||||||
B: "hello",
|
B: "hello",
|
||||||
}
|
}
|
||||||
trySender, err := bloat.NewBloat[typ](false)
|
trySender, err := bloat.NewEncBloat[typ]()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
t.Log(err.Error())
|
||||||
t.Errorf("error on newbloat")
|
t.Errorf("error on newbloat")
|
||||||
}
|
}
|
||||||
tryReceiver, err := bloat.NewBloat[typ](false)
|
tryReceiver, err := bloat.NewEncBloat[typ]()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
t.Log(err.Error())
|
||||||
t.Errorf("error on newbloat")
|
t.Errorf("error on newbloat")
|
||||||
}
|
}
|
||||||
cyphertext, err := trySender.Write(data, tryReceiver)
|
cyphertext, err := trySender.WriteEnc(data, tryReceiver)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
t.Log(err.Error())
|
||||||
t.Errorf("error on write")
|
t.Errorf("error on write")
|
||||||
}
|
}
|
||||||
fmt.Println(cyphertext)
|
// t.Log(string(cyphertext))
|
||||||
plainobj, err := tryReceiver.Read(cyphertext, trySender)
|
plainobj, err := tryReceiver.ReadEnc(cyphertext, trySender)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
|
||||||
t.Errorf("error on read")
|
t.Errorf("error on read")
|
||||||
|
t.Errorf(err.Error())
|
||||||
}
|
}
|
||||||
if plainobj.A != 1 {
|
if plainobj.A != 1 {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
|
|
45
obj.go
45
obj.go
|
@ -2,6 +2,7 @@ package bloat
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"aead.dev/minisign"
|
"aead.dev/minisign"
|
||||||
"filippo.io/age"
|
"filippo.io/age"
|
||||||
|
@ -11,28 +12,42 @@ type Bloat[T any] struct {
|
||||||
SignPub minisign.PublicKey
|
SignPub minisign.PublicKey
|
||||||
signPriv minisign.PrivateKey
|
signPriv minisign.PrivateKey
|
||||||
RequireEnc bool
|
RequireEnc bool
|
||||||
EncPub age.X25519Recipient
|
Enc age.X25519Identity
|
||||||
encPriv age.X25519Identity // Scrypt is the password one?
|
// EncPub age.X25519Recipient
|
||||||
|
// encPriv age.X25519Identity // Scrypt is the password one?
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewBloat[T any](noEnc bool) (Bloat[T], error) {
|
func NewPlainBloat[T any]() (Bloat[T], error) {
|
||||||
|
|
||||||
pub, sign, err := minisign.GenerateKey(rand.Reader)
|
pub, sign, err := minisign.GenerateKey(rand.Reader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
fmt.Println("problem generating minisign")
|
||||||
|
fmt.Println(err)
|
||||||
return Bloat[T]{}, err
|
return Bloat[T]{}, err
|
||||||
}
|
}
|
||||||
res := Bloat[T]{
|
res := Bloat[T]{
|
||||||
SignPub: pub,
|
SignPub: pub,
|
||||||
signPriv: sign,
|
signPriv: sign,
|
||||||
}
|
RequireEnc: false,
|
||||||
if !noEnc {
|
|
||||||
enc, err := age.GenerateX25519Identity()
|
|
||||||
if err != nil {
|
|
||||||
return Bloat[T]{}, err
|
|
||||||
}
|
|
||||||
recip := enc.Recipient()
|
|
||||||
res.encPriv = *enc
|
|
||||||
res.EncPub = *recip
|
|
||||||
}
|
}
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
func NewEncBloat[T any]() (Bloat[T], error) {
|
||||||
|
res, err := NewPlainBloat[T]()
|
||||||
|
res.RequireEnc = true
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("problem generating signing part")
|
||||||
|
}
|
||||||
|
enc, err := age.GenerateX25519Identity()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("unable to generate")
|
||||||
|
fmt.Println(err)
|
||||||
|
return Bloat[T]{}, err
|
||||||
|
}
|
||||||
|
// recip := enc.Recipient()
|
||||||
|
res.Enc = *enc
|
||||||
|
// res.encPriv = *enc
|
||||||
|
// res.EncPub = *recip
|
||||||
|
// fmt.Printf("made age key: %s\n", enc.Recipient().String())
|
||||||
|
return res, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package bloat_test
|
package bloat_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.bivouac.wiki/go/bloat"
|
"git.bivouac.wiki/go/bloat"
|
||||||
|
@ -10,31 +9,35 @@ import (
|
||||||
// TestPlain without keys...
|
// TestPlain without keys...
|
||||||
func TestPlain(t *testing.T) {
|
func TestPlain(t *testing.T) {
|
||||||
type foo struct {
|
type foo struct {
|
||||||
Abc bool
|
Abc bool `xml:"Abc"`
|
||||||
Plain string
|
Plain string `xml:"Plain"`
|
||||||
}
|
}
|
||||||
sender, err := bloat.NewBloat[foo](true)
|
sender, err := bloat.NewPlainBloat[foo]()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
t.Log(err.Error())
|
||||||
t.Errorf("init failed")
|
t.Errorf("init failed")
|
||||||
}
|
}
|
||||||
data := foo{
|
data := foo{
|
||||||
Abc: true,
|
Abc: true,
|
||||||
Plain: "this is plain",
|
Plain: "this is plain",
|
||||||
}
|
}
|
||||||
recipient, err := bloat.NewBloat[foo](true)
|
recipient, err := bloat.NewPlainBloat[foo]()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
t.Log(err.Error())
|
||||||
t.Errorf("recipient init failed")
|
t.Errorf("recipient init failed")
|
||||||
}
|
}
|
||||||
plain, err := sender.Write(data, recipient)
|
plain, err := sender.WritePlain(data, recipient)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
t.Log(err.Error())
|
||||||
t.Errorf("writing plain failed")
|
t.Errorf("writing plain failed")
|
||||||
}
|
}
|
||||||
fmt.Println(plain)
|
// t.Log(string(plain))
|
||||||
res, err := recipient.Read(plain, sender)
|
res, err := recipient.ReadPlain(plain, sender)
|
||||||
if res.Plain != "this is plain" {
|
if res.Plain != "this is plain" {
|
||||||
t.Errorf("text does not match")
|
t.Errorf("text does not match")
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
t.Log(err.Error())
|
||||||
t.Errorf("verification failed")
|
t.Errorf("verification failed")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
16
read.go
16
read.go
|
@ -5,20 +5,32 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (b *Bloat[T]) Read(packed []byte, author Bloat[T]) (T, error) {
|
func (b *Bloat[T]) ReadEnc(packed []byte, author Bloat[T]) (T, error) {
|
||||||
var final T
|
var final T
|
||||||
decrypted, err := b.decrypt(packed) // our own key
|
decrypted, err := b.decrypt(packed) // our own key
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
fmt.Println("decrypt failed")
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
return final, err
|
return final, err
|
||||||
}
|
}
|
||||||
body, verified, err := author.verify(decrypted) // author's key
|
final, err = b.ReadPlain(decrypted, author)
|
||||||
|
return final, err
|
||||||
|
}
|
||||||
|
func (b *Bloat[T]) ReadPlain(plain []byte, author Bloat[T]) (T, error) {
|
||||||
|
var final T
|
||||||
|
body, verified, err := author.verify(plain) // author's key
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
fmt.Println("verification failed")
|
||||||
|
fmt.Println(err)
|
||||||
return final, err
|
return final, err
|
||||||
}
|
}
|
||||||
if !verified {
|
if !verified {
|
||||||
return final, errors.New("not verified")
|
return final, errors.New("not verified")
|
||||||
}
|
}
|
||||||
final, err = b.unmarshal(body)
|
final, err = b.unmarshal(body)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("unmarshal failed")
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
return final, err
|
return final, err
|
||||||
}
|
}
|
||||||
|
|
2
test/.gitignore
vendored
Normal file
2
test/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
data.txttype.bloat
|
||||||
|
*.bloat
|
11
unmarshal.go
11
unmarshal.go
|
@ -1,6 +1,9 @@
|
||||||
package bloat
|
package bloat
|
||||||
|
|
||||||
import "encoding/xml"
|
import (
|
||||||
|
"encoding/xml"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
types to decode:
|
types to decode:
|
||||||
|
@ -14,6 +17,10 @@ types to decode:
|
||||||
|
|
||||||
func (b *Bloat[T]) unmarshal(plain []byte) (T, error) {
|
func (b *Bloat[T]) unmarshal(plain []byte) (T, error) {
|
||||||
var res T
|
var res T
|
||||||
err := xml.Unmarshal(plain, res)
|
err := xml.Unmarshal(plain, &res)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("unmarshal error")
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,8 +10,11 @@ import (
|
||||||
func (b *Bloat[T]) verify(message []byte) ([]byte, bool, error) {
|
func (b *Bloat[T]) verify(message []byte) ([]byte, bool, error) {
|
||||||
// signature is last 4 lines:
|
// signature is last 4 lines:
|
||||||
separated := bytes.Split(message, []byte("\n"))
|
separated := bytes.Split(message, []byte("\n"))
|
||||||
signature := bytes.Join(separated[len(separated)-4:len(separated)], []byte("\n"))
|
signature := bytes.Join(separated[len(separated)-5:len(separated)], []byte("\n"))
|
||||||
body := bytes.Join(separated[:len(separated)-4], []byte("\n"))
|
body := bytes.Join(separated[:len(separated)-5], []byte("\n"))
|
||||||
|
// fmt.Println("signature:", string(signature))
|
||||||
|
// fmt.Println("body:", string(body))
|
||||||
|
// fmt.Println("end")
|
||||||
if !minisign.Verify(b.SignPub, body, signature) {
|
if !minisign.Verify(b.SignPub, body, signature) {
|
||||||
return []byte(""), false, nil
|
return []byte(""), false, nil
|
||||||
}
|
}
|
||||||
|
|
13
write.go
13
write.go
|
@ -2,19 +2,30 @@ package bloat
|
||||||
|
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
||||||
func (b *Bloat[T]) Write(body T, recip Bloat[T]) ([]byte, error) {
|
func (b *Bloat[T]) WritePlain(body T, recip Bloat[T]) ([]byte, error) {
|
||||||
start, err := b.marshal(body)
|
start, err := b.marshal(body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
fmt.Println("marshal failed")
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
signed, err := b.sign(start) // our key
|
signed, err := b.sign(start) // our key
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
fmt.Println("sign failed")
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
return signed, err
|
||||||
|
}
|
||||||
|
func (b *Bloat[T]) WriteEnc(body T, recip Bloat[T]) ([]byte, error) {
|
||||||
|
signed, err := b.WritePlain(body, recip)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("plain write failed")
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
final, err := recip.encrypt(signed) // their key
|
final, err := recip.encrypt(signed) // their key
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
fmt.Println("encrypt failed")
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
}
|
}
|
||||||
return final, err
|
return final, err
|
||||||
|
|
Loading…
Add table
Reference in a new issue