build test funcs
This commit is contained in:
parent
f388fcf9ee
commit
51003e492b
14 changed files with 291 additions and 1 deletions
21
LICENSE
Normal file
21
LICENSE
Normal file
|
@ -0,0 +1,21 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright © 2024 NAME HERE <EMAIL ADDRESS>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
45
README.md
45
README.md
|
@ -1,3 +1,46 @@
|
|||
# bloat
|
||||
|
||||
> XML serialization version. for ActivityPub see dogberry
|
||||
> XML serialization version. for ActivityPub see dogberry
|
||||
|
||||
|
||||
|
||||
- [ ] Read
|
||||
- [ ] serialize
|
||||
- [ ] decrypt
|
||||
- [ ] verify
|
||||
- [ ] Write
|
||||
- [ ] sign
|
||||
- [ ] encrypt
|
||||
- [ ] deserialize
|
||||
|
||||
|
||||
|
||||
- notes on deletions:
|
||||
|
||||
- /host.xml
|
||||
- /group/
|
||||
- /index.xml <-
|
||||
- /indexes/
|
||||
- /{peer name}/
|
||||
- /passwords.xml <- encrypted to a peer
|
||||
- /posts.a.xml <-
|
||||
- /posts.b.xml <-
|
||||
|
||||
|
||||
- options:
|
||||
- encrypt each post to every group member
|
||||
- pros:
|
||||
- safe if they haven't downloaded something
|
||||
- cons:
|
||||
- removing a member means rewriting each post
|
||||
- adding a member means rewriting each post
|
||||
- encrypt a password file next to each post
|
||||
- pros:
|
||||
- don't need to upload the content twice
|
||||
- cons:
|
||||
- need a password file for each member (n x m storage)
|
||||
- encrypt an index file
|
||||
- pros:
|
||||
- need o(n) storage
|
||||
- cons:
|
||||
- if they've downloaded the index they have the passwords to the files
|
17
decrypt.go
17
decrypt.go
|
@ -1 +1,18 @@
|
|||
package bloat
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
|
||||
"filippo.io/age"
|
||||
)
|
||||
|
||||
func (b *Bloat[T]) Decrypt(src []byte) ([]byte, error) {
|
||||
input := bytes.NewReader(src)
|
||||
out, err := age.Decrypt(input, &b.encDec)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res, err := io.ReadAll(out)
|
||||
return res, err
|
||||
}
|
||||
|
|
18
encrypt.go
18
encrypt.go
|
@ -1 +1,19 @@
|
|||
package bloat
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
|
||||
"filippo.io/age"
|
||||
)
|
||||
|
||||
func (b *Bloat[T]) Encrypt(plain []byte) ([]byte, error) {
|
||||
buf := &bytes.Buffer{}
|
||||
w, err := age.Encrypt(buf, &b.EncPub) // my wrapper doesn't support multiple recipients yet
|
||||
if err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
var r string
|
||||
_, err = io.WriteString(w, r)
|
||||
return []byte(r), err
|
||||
}
|
||||
|
|
10
go.mod
10
go.mod
|
@ -1,3 +1,13 @@
|
|||
module git.bivouac.wiki/go/bloat
|
||||
|
||||
go 1.22.5
|
||||
|
||||
require (
|
||||
aead.dev/minisign v0.3.0
|
||||
filippo.io/age v1.2.1
|
||||
)
|
||||
|
||||
require (
|
||||
golang.org/x/crypto v0.24.0 // indirect
|
||||
golang.org/x/sys v0.21.0 // indirect
|
||||
)
|
||||
|
|
8
go.sum
Normal file
8
go.sum
Normal file
|
@ -0,0 +1,8 @@
|
|||
aead.dev/minisign v0.3.0 h1:8Xafzy5PEVZqYDNP60yJHARlW1eOQtsKNp/Ph2c0vRA=
|
||||
aead.dev/minisign v0.3.0/go.mod h1:NLvG3Uoq3skkRMDuc3YHpWUTMTrSExqm+Ij73W13F6Y=
|
||||
filippo.io/age v1.2.1 h1:X0TZjehAZylOIj4DubWYU1vWQxv9bJpo+Uu2/LGhi1o=
|
||||
filippo.io/age v1.2.1/go.mod h1:JL9ew2lTN+Pyft4RiNGguFfOpewKwSHm5ayKD/A4004=
|
||||
golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI=
|
||||
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
|
||||
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
|
||||
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
|
@ -1 +1,8 @@
|
|||
package bloat
|
||||
|
||||
import "encoding/xml"
|
||||
|
||||
func (b *Bloat[T]) Marshal(body T) ([]byte, error) {
|
||||
final, err := xml.Marshal(body)
|
||||
return final, err
|
||||
}
|
||||
|
|
47
module_test.go
Normal file
47
module_test.go
Normal file
|
@ -0,0 +1,47 @@
|
|||
package bloat
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestItem(t *testing.T) {
|
||||
type typ struct {
|
||||
A int
|
||||
B string
|
||||
}
|
||||
data := typ{
|
||||
A: 1,
|
||||
B: "hello",
|
||||
}
|
||||
trySender, err := NewBloat[typ]()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Errorf("error on newbloat")
|
||||
}
|
||||
trySender.Obj = typ{}
|
||||
tryReceiver, err := NewBloat[typ]()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Errorf("error on newbloat")
|
||||
}
|
||||
cyphertext, err := trySender.Write(data, tryReceiver)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Errorf("error on write")
|
||||
}
|
||||
plainobj, err := tryReceiver.Read(cyphertext, trySender)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Errorf("error on read")
|
||||
}
|
||||
if plainobj.A != 1 {
|
||||
fmt.Println(err)
|
||||
t.Errorf("int not equal")
|
||||
}
|
||||
if plainobj.B != "hello" {
|
||||
fmt.Println(err)
|
||||
t.Errorf("string not hello")
|
||||
}
|
||||
|
||||
}
|
37
obj.go
Normal file
37
obj.go
Normal file
|
@ -0,0 +1,37 @@
|
|||
package bloat
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
|
||||
"aead.dev/minisign"
|
||||
"filippo.io/age"
|
||||
)
|
||||
|
||||
type Bloat[T any] struct {
|
||||
SignPub minisign.PublicKey
|
||||
signPriv minisign.PrivateKey
|
||||
EncPub age.X25519Recipient
|
||||
encDec age.X25519Identity // Scrypt is the password one?
|
||||
Obj T
|
||||
}
|
||||
|
||||
func NewBloat[T any]() (Bloat[T], error) {
|
||||
|
||||
pub, sign, err := minisign.GenerateKey(rand.Reader)
|
||||
if err != nil {
|
||||
return Bloat[T]{}, err
|
||||
}
|
||||
enc, err := age.GenerateX25519Identity()
|
||||
if err != nil {
|
||||
return Bloat[T]{}, err
|
||||
}
|
||||
recip := enc.Recipient()
|
||||
|
||||
res := Bloat[T]{
|
||||
SignPub: pub,
|
||||
signPriv: sign,
|
||||
EncPub: *recip,
|
||||
encDec: *enc,
|
||||
}
|
||||
return res, nil
|
||||
}
|
19
read.go
19
read.go
|
@ -1 +1,20 @@
|
|||
package bloat
|
||||
|
||||
import "errors"
|
||||
|
||||
func (b *Bloat[T]) Read(packed []byte, author Bloat[T]) (T, error) {
|
||||
var final T
|
||||
decrypted, err := b.Decrypt(packed) // our own key
|
||||
if err != nil {
|
||||
return final, err
|
||||
}
|
||||
body, verified, err := author.Verify(decrypted) // author's key
|
||||
if err != nil {
|
||||
return final, err
|
||||
}
|
||||
if !verified {
|
||||
return final, errors.New("not verified")
|
||||
}
|
||||
final, err = b.Unmarshal(body)
|
||||
return final, err
|
||||
}
|
||||
|
|
15
sign.go
15
sign.go
|
@ -1 +1,16 @@
|
|||
package bloat
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
||||
"aead.dev/minisign"
|
||||
)
|
||||
|
||||
// sign the payload and append 4 lines
|
||||
func (b *Bloat[T]) Sign(plaintext []byte) ([]byte, error) {
|
||||
|
||||
signature := minisign.Sign(b.signPriv, plaintext)
|
||||
parts := [][]byte{plaintext, signature}
|
||||
final := bytes.Join(parts, []byte("\n"))
|
||||
return final, nil
|
||||
}
|
||||
|
|
17
unmarshal.go
17
unmarshal.go
|
@ -1 +1,18 @@
|
|||
package bloat
|
||||
|
||||
import "encoding/xml"
|
||||
|
||||
/*
|
||||
types to decode:
|
||||
.phish (identity)
|
||||
.bivouac (decisions)
|
||||
.cicada (indexes/feeds)
|
||||
.crew (groups)
|
||||
.mores (rules)
|
||||
|
||||
*/
|
||||
|
||||
func (b *Bloat[T]) Unmarshal(plain []byte) (T, error) {
|
||||
err := xml.Unmarshal(plain, b.Obj)
|
||||
return b.Obj, err
|
||||
}
|
||||
|
|
18
verify.go
18
verify.go
|
@ -1 +1,19 @@
|
|||
package bloat
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
||||
"aead.dev/minisign"
|
||||
)
|
||||
|
||||
// Verify checks the minisign signature and returns the body if valid.
|
||||
func (b *Bloat[T]) Verify(message []byte) ([]byte, bool, error) {
|
||||
// signature is last 4 lines:
|
||||
separated := bytes.Split(message, []byte("\n"))
|
||||
signature := bytes.Join(separated[len(separated)-4:len(separated)], []byte("\n"))
|
||||
body := bytes.Join(separated[:len(separated)-4], []byte("\n"))
|
||||
if !minisign.Verify(b.SignPub, body, signature) {
|
||||
return []byte(""), false, nil
|
||||
}
|
||||
return body, true, nil
|
||||
}
|
||||
|
|
13
write.go
13
write.go
|
@ -1 +1,14 @@
|
|||
package bloat
|
||||
|
||||
func (b *Bloat[T]) Write(body T, recip Bloat[T]) ([]byte, error) {
|
||||
start, err := b.Marshal(body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
signed, err := b.Sign(start) // our key
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
final, err := recip.Encrypt(signed) // their key
|
||||
return final, err
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue