feature: Implements basic key generation.

This commit is contained in:
imterah 2024-11-22 07:25:17 -05:00
parent 768e17f840
commit a317342aa6
Signed by: imterah
GPG key ID: 8FA7DD57BA6CEA37
6 changed files with 308 additions and 2 deletions

33
bofs/fs.go Normal file
View file

@ -0,0 +1,33 @@
package bofs
import (
"context"
"syscall"
"github.com/hanwen/go-fuse/v2/fs"
"github.com/hanwen/go-fuse/v2/fuse"
)
type BoronInode struct {
fs.Inode
}
func (r *BoronInode) OnAdd(ctx context.Context) {
ch := r.NewPersistentInode(
ctx, &fs.MemRegularFile{
Data: []byte("file.txt"),
Attr: fuse.Attr{
Mode: 0644,
},
}, fs.StableAttr{Ino: 2})
r.AddChild("file.txt", ch, false)
}
func (r *BoronInode) Getattr(ctx context.Context, fh fs.FileHandle, out *fuse.AttrOut) syscall.Errno {
out.Mode = 0755
return 0
}
var _ = (fs.NodeGetattrer)((*BoronInode)(nil))
var _ = (fs.NodeOnAdder)((*BoronInode)(nil))

10
go.mod
View file

@ -1,3 +1,13 @@
module git.greysoh.dev/imterah/boron module git.greysoh.dev/imterah/boron
go 1.23.2 go 1.23.2
require (
github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect
github.com/hanwen/go-fuse v1.0.0 // indirect
github.com/hanwen/go-fuse/v2 v2.7.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/urfave/cli/v2 v2.27.5 // indirect
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect
golang.org/x/sys v0.27.0 // indirect
)

15
go.sum Normal file
View file

@ -0,0 +1,15 @@
github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc=
github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/hanwen/go-fuse v1.0.0 h1:GxS9Zrn6c35/BnfiVsZVWmsG803xwE7eVRDvcf/BEVc=
github.com/hanwen/go-fuse v1.0.0/go.mod h1:unqXarDXqzAk0rt98O2tVndEPIpUgLD9+rwFisZH3Ok=
github.com/hanwen/go-fuse/v2 v2.7.0 h1:b3khst81C011GCwv9BF7PUa4lbbzIdRFPgAxRlgGUvw=
github.com/hanwen/go-fuse/v2 v2.7.0/go.mod h1:ugNaD/iv5JYyS1Rcvi57Wz7/vrLQJo10mmketmoef48=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/urfave/cli/v2 v2.27.5 h1:WoHEJLdsXr6dDWoJgMq/CboDmyY/8HMMH1fTECbih+w=
github.com/urfave/cli/v2 v2.27.5/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ=
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4=
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=

188
main.go
View file

@ -1,7 +1,191 @@
package main package main
import "fmt" import (
"crypto"
"crypto/rand"
"crypto/rsa"
"crypto/sha1"
"crypto/x509"
"encoding/hex"
"encoding/pem"
"errors"
"fmt"
"log"
"os"
"os/signal"
"path"
"git.greysoh.dev/imterah/boron/bofs"
"github.com/hanwen/go-fuse/v2/fs"
"github.com/urfave/cli/v2"
)
func initializeFS(cCtx *cli.Context) error {
privKeyPath := cCtx.String("key")
allowKeyGeneration := cCtx.Bool("allow-keygeneration")
srcFolder := cCtx.String("source-folder")
destFolder := cCtx.String("dest-folder")
privKeyRaw, err := os.ReadFile(privKeyPath)
var privateKey *rsa.PrivateKey
if err != nil && errors.Is(err, os.ErrNotExist) && allowKeyGeneration {
log.Println("key not found. generating key...")
privateKey, err = rsa.GenerateKey(rand.Reader, 4096)
if err != nil {
return fmt.Errorf("could not generate private key: %s", err.Error())
}
log.Println("getting key signature...")
sha1Instance := sha1.New()
keySignature := sha1Instance.Sum(nil)
if _, err := rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA1, keySignature); err != nil {
return fmt.Errorf("could not get key fingerprint/signature: %s", err.Error())
}
log.Println("saving public key...")
if err := os.Mkdir(path.Join(srcFolder, "keys"), os.ModePerm); err != nil && !errors.Is(err, os.ErrExist) {
return fmt.Errorf("failed to create keys folder: %s", err.Error())
}
pubKeyFile, err := os.Create(path.Join(srcFolder, "keys", hex.EncodeToString(keySignature)+".pub"))
if err != nil {
return fmt.Errorf("failed to open public key file: %s", err.Error())
}
// We're doing PCKS1 (todo: look into maybe changing to PCKS8?)
err = pem.Encode(
pubKeyFile,
&pem.Block{
Type: "PUBLIC KEY",
Bytes: x509.MarshalPKCS1PublicKey(&privateKey.PublicKey),
},
)
if err != nil {
return fmt.Errorf("failed to encode public key: %s", err.Error())
}
pubKeyFile.Close()
privKeyFile, err := os.Create(privKeyPath)
if err != nil {
return fmt.Errorf("failed to open public key file: %s", err.Error())
}
log.Println("saving private key...")
err = pem.Encode(
privKeyFile,
&pem.Block{
Type: "PRIVATE KEY",
Bytes: x509.MarshalPKCS1PrivateKey(privateKey),
},
)
if err != nil {
return fmt.Errorf("failed to encode private key: %s", err.Error())
}
privKeyFile.Close()
log.Println("finished key generation steps.")
} else if err == nil {
privKeyPem, _ := pem.Decode(privKeyRaw)
if privKeyPem.Type != "RSA PRIVATE KEY" && privKeyPem.Type != "PRIVATE KEY" {
return fmt.Errorf("decoded private key's header does not match RSA private key signature")
}
var parsedKey interface{}
if parsedKey, err = x509.ParsePKCS1PrivateKey(privKeyPem.Bytes); err != nil {
log.Println("failed to decode private key using PCKS1 format. trying PCKS8 next")
if parsedKey, err = x509.ParsePKCS8PrivateKey(privKeyPem.Bytes); err != nil {
return fmt.Errorf("failed to decode private key using PCKS8 format")
}
}
var ok bool // Hack to make Go not complain
privateKey, ok = parsedKey.(*rsa.PrivateKey)
if !ok {
return fmt.Errorf("failed to set privateKey variable (failed typecast)")
}
} else {
return fmt.Errorf("could not read private key: %s", err.Error())
}
opts := &fs.Options{}
log.Println("mounting filesystem...")
server, err := fs.Mount(destFolder, &bofs.BoronInode{}, opts)
if err != nil {
return err
}
log.Println("successfully mounted filesystem.")
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt)
go func() {
for _ = range c {
log.Println("unmounting filesystem...")
err := server.Unmount()
if err != nil {
log.Println("failed to unmount filesystem.")
}
os.Exit(0)
}
}()
server.Wait()
return nil
}
func main() { func main() {
fmt.Println("Hello, world!") app := &cli.App{
Name: "boron",
Usage: "a collaborateive end-to-end-encrypted meta-filesystem",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "key",
Usage: "armored private key to use",
Required: true,
},
&cli.BoolFlag{
Name: "allow-keygeneration",
Usage: "if true, allows keys to be generated if the keys do not exist",
},
&cli.StringFlag{
Name: "source-folder",
Usage: "source folder to use",
Required: true,
},
&cli.StringFlag{
Name: "dest-folder",
Usage: "destination folder to use",
Required: true,
},
},
Action: initializeFS,
}
if err := app.Run(os.Args); err != nil {
log.Fatal(err)
}
} }

51
tmp/key Normal file
View file

@ -0,0 +1,51 @@
-----BEGIN PRIVATE KEY-----
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
-----END PRIVATE KEY-----

View file

@ -0,0 +1,13 @@
-----BEGIN PUBLIC KEY-----
MIICCgKCAgEAp7kY9Pa64fgcwaI38bboLarFjsS2P6V93Kwt98bjC1avPrclaIUM
phYYVT4hRnhhkP2LNwS+Qk/rWr8QuRdaSPSjlospgMQ20VfDIZBRYYU/sTC4hhuC
IMStnukCyVTrFgHsWMT7A+dd7OWxiZOQbO7FeFdds2vs/5T5ZOGoXAXxTHA0+Bft
PtvUjm/Edz7csam73ItGlaF8zFZqSUQa6Zgl1+LYvTrEyOymTGlipo7p86cGveLF
/i9v3NfPB7QbjZHPaS4DIz+zzaSP3glHXudI8aZJB1lKKQOGl3JHRiY0PhIPwZRB
KyXkYfomAaK++Wvr78a1mYMYRvPoEZbUI7fNAQrewVSsYSr5PgnhTrcWR/6URUB9
/ys3OJHHQnhLYRrJfpSroUZuVKYFUSSVwJe74thJJUbbCgzhMDpHuRM6YLNwXtOy
53iyYY/N61bUlESg/VoVRRmMmR4srE2jfTkOhaX7nzLWxIJ+wc9SLMItEJwqn/57
OPdBU7AefEy9CER35XJjy6wku3VhdHISYKunCW3uS/kA+xlTEgrdAyBKWi870q5G
Sj6uCBmJyNCMwj+bCC+sWEbOhVKHBjXdOervyP4/CWF9XrCrqndzgcupXMdCGQG9
H+BmXN1bOgIosd38hjdjLo+yiKo4MmhLWjBCVs9WFW5Tm8m7LZ50/lUCAwEAAQ==
-----END PUBLIC KEY-----