feature: Implements basic key generation.
This commit is contained in:
parent
768e17f840
commit
a317342aa6
6 changed files with 308 additions and 2 deletions
33
bofs/fs.go
Normal file
33
bofs/fs.go
Normal 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
10
go.mod
|
@ -1,3 +1,13 @@
|
|||
module git.greysoh.dev/imterah/boron
|
||||
|
||||
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
15
go.sum
Normal 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
188
main.go
|
@ -1,7 +1,191 @@
|
|||
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() {
|
||||
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
51
tmp/key
Normal file
|
@ -0,0 +1,51 @@
|
|||
-----BEGIN PRIVATE KEY-----
|
||||
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
|
||||
-----END PRIVATE KEY-----
|
13
tmp/src/keys/da39a3ee5e6b4b0d3255bfef95601890afd80709.pub
Normal file
13
tmp/src/keys/da39a3ee5e6b4b0d3255bfef95601890afd80709.pub
Normal 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-----
|
Loading…
Add table
Add a link
Reference in a new issue