]> Cypherpunks repositories - keks.git/commitdiff
More djb-style keys passing
authorSergey Matveev <stargrave@stargrave.org>
Wed, 19 Feb 2025 14:49:17 +0000 (17:49 +0300)
committerSergey Matveev <stargrave@stargrave.org>
Wed, 19 Feb 2025 15:11:48 +0000 (18:11 +0300)
http://libpqcrypto.org/command.html

13 files changed:
go/cm/cmd/enctool/main.go
go/cm/cmd/enctool/passphrase.t
go/cm/cmd/enctool/prv-encrypted.t
go/cm/cmd/enctool/pub.t
go/cm/cmd/enctool/usage.go
go/cm/cmd/keytool/certification.t
go/cm/cmd/keytool/kem-generation.t
go/cm/cmd/keytool/main.go
go/cm/cmd/keytool/usage.go
go/cm/cmd/sigtool/basic.t
go/cm/cmd/sigtool/main.go
go/cm/cmd/sigtool/usage.go
go/cm/sign/pub.go

index 7b152acf4e94218e21fc7f9c2a5d6b186f8a563b127379f56ba1adf4fa398940..2eeceb57f1f63c291080db365527e38482f4c1d0f9e50747a4e1e7c4b50ca37a 100644 (file)
@@ -50,6 +50,11 @@ import (
        "go.cypherpunks.su/keks/types"
 )
 
+const (
+       FdPubR = 4
+       FdPrvR = 8
+)
+
 func blake2bHash() hash.Hash {
        h, err := blake2b.New512(nil)
        if err != nil {
@@ -58,16 +63,8 @@ func blake2bHash() hash.Hash {
        return h
 }
 
-func mustReadFile(p string) []byte {
-       data, err := os.ReadFile(p)
-       if err != nil {
-               log.Fatalln("read:", p, err)
-       }
-       return data
-}
-
 func readPasswd(prompt string) (passwd []byte) {
-       if raw := os.Getenv("ENCTOOL_PASSPHRASE"); raw != "" {
+       if raw := os.Getenv("CMENCTOOL_PASSPHRASE"); raw != "" {
                return []byte(raw)
        }
        tty, err := os.OpenFile("/dev/tty", os.O_RDWR, 0)
@@ -90,8 +87,7 @@ func readPasswd(prompt string) (passwd []byte) {
        return
 }
 
-func readPrv(pth string) (*cm.AV, error) {
-       data := mustReadFile(pth)
+func parsePrv(data []byte) (av cm.AV, tail []byte, err error) {
        var magic keks.Magic
        magic, data = keks.StripMagic(data)
        switch magic {
@@ -100,31 +96,35 @@ func readPrv(pth string) (*cm.AV, error) {
                var encrypted cmenc.Encrypted
                {
                        d := keks.NewDecoderFromBytes(data, nil)
-                       if err := d.DecodeStruct(&encrypted); err != nil {
-                               return nil, err
+                       err = d.DecodeStruct(&encrypted)
+                       if err != nil {
+                               return
                        }
                }
                if encrypted.DEM.A != cmenc.ChaCha20Poly1305 {
-                       return nil, errors.New("unsupported prv encryption DEM")
+                       err = errors.New("unsupported prv encryption DEM")
+                       return
                }
                if len(encrypted.KEM) != 1 ||
                        encrypted.KEM[0].A != cmballoon.BalloonBLAKE2bHKDF ||
                        len(encrypted.Payload) == 0 {
-                       return nil, errors.New("wrong prv encryption KEM")
+                       err = errors.New("wrong prv encryption KEM")
+                       return
                }
-               passwd := readPasswd("Passphrase for " + pth + ":")
-               cek, err := cmballoon.Decapsulate(
+               passwd := readPasswd("Passphrase for private key:")
+               var cek []byte
+               cek, err = cmballoon.Decapsulate(
                        encrypted.KEM[0],
                        encrypted.Salt[:],
                        passwd,
                )
                if err != nil {
-                       return nil, err
+                       return
                }
                var buf bytes.Buffer
                _, err = chaPoly.Open(&buf, bytes.NewReader(encrypted.Payload), cek, 1)
                if err != nil {
-                       return nil, err
+                       return
                }
                data = buf.Bytes()
                magic, data = keks.StripMagic(data)
@@ -133,11 +133,13 @@ func readPrv(pth string) (*cm.AV, error) {
                }
                fallthrough
        default:
-               return nil, errors.New("wrong magic")
+               err = errors.New("wrong magic")
+               return
        }
-       var av cm.AV
        d := keks.NewDecoderFromBytes(data, &keks.DecodeOpts{MaxStrLen: 1 << 16})
-       return &av, d.DecodeStruct(&av)
+       err = d.DecodeStruct(&av)
+       tail = d.B
+       return
 }
 
 func main() {
@@ -152,37 +154,51 @@ func main() {
        doDecrypt := flag.Bool("d", false, "Decrypt")
        parallel := flag.Int("parallel", runtime.NumCPU(), "Parallel cryptors")
        noblob := flag.Bool("no-stream", false, "Include payload into container")
+       flag.Parse()
+
+       fdPubR := os.NewFile(FdPubR, "pub-in")
        var pubs []cm.AV
        var pubIds []uuid.UUID
-       flag.Func("pub", "Path to public key to encrypt to", func(v string) error {
-               signed, _, err := sign.PubParse(mustReadFile(v))
-               if err != nil {
-                       return err
-               }
-               load := signed.PubLoad()
-               if load.KU == nil {
-                       log.Println(v, "does not have key usages")
-               } else {
-                       if _, ok := (*load.KU)[sign.KUKEM]; !ok {
-                               log.Println(v, "does not have", sign.KUKEM, "key usage")
+       if data, err := io.ReadAll(fdPubR); err == nil {
+               for len(data) > 0 {
+                       var signed *sign.Signed
+                       signed, data, err = sign.PubParse(data)
+                       if err != nil {
+                               log.Fatalln("public key:", len(pubs), ":", err)
                        }
+                       load := signed.PubLoad()
+                       if load.KU == nil {
+                               log.Println("public key:", len(pubs), ": does not have key usages")
+                       } else {
+                               if _, ok := (*load.KU)[sign.KUKEM]; !ok {
+                                       log.Println(
+                                               "public key:", len(pubs), ": does not have",
+                                               sign.KUKEM, "key usage",
+                                       )
+                               }
+                       }
+                       if len(load.Pub) != 1 {
+                               log.Fatalln("public key:", len(pubs), ": expected single public key")
+                       }
+                       pubs = append(pubs, load.Pub[0])
+                       pubIds = append(pubIds, load.Id)
                }
-               if len(load.Pub) != 1 {
-                       return errors.New("expected single public key")
-               }
-               pubs = append(pubs, load.Pub[0])
-               pubIds = append(pubIds, load.Id)
-               return err
-       })
+       }
+       fdPubR.Close()
+
+       fdPrvR := os.NewFile(FdPrvR, "prv-in")
        var prvs []*cm.AV
-       flag.Func("prv", "Our private keys for decryption", func(v string) error {
-               av, err := readPrv(v)
-               if err == nil {
-                       prvs = append(prvs, av)
+       if data, err := io.ReadAll(fdPrvR); err == nil {
+               for len(data) > 0 {
+                       var av cm.AV
+                       av, data, err = parsePrv(data)
+                       if err != nil {
+                               log.Fatalln("private key:", len(prvs), ":", err)
+                       }
+                       prvs = append(prvs, &av)
                }
-               return err
-       })
-       flag.Parse()
+       }
+       fdPrvR.Close()
 
        var err error
        var cek []byte
index 66506de3a755c8a829044c83390ea18cc3aac006e211decea7001689113ace1b..f738873faa88236b8aaa882eddbb7fbe9d74b711e056cc566f1ebe0ea2b6b69b 100755 (executable)
@@ -6,10 +6,11 @@ test_description="Check passphrase encryption"
 TMPDIR=${TMPDIR:-/tmp}
 
 dd if=/dev/urandom of=$TMPDIR/enc.data bs=300K count=1 2>/dev/null
-export ENCTOOL_PASSPHRASE=$(dd if=/dev/urandom bs=32 count=1 2>/dev/null | xxd -p)
-test_expect_success "encrypting" "cmenctool -p \
+export CMENCTOOL_PASSPHRASE=$(dd if=/dev/urandom bs=32 count=1 2>/dev/null | xxd -p)
+balloonparams="-balloon-s 123 -balloon-t 2"
+test_expect_success "encrypting" "cmenctool $balloonparams -p \
     <$TMPDIR/enc.data >$TMPDIR/enc.enc"
-test_expect_success "decrypting" "cmenctool -d -p \
+test_expect_success "decrypting" "cmenctool $balloonparams -d -p \
     <$TMPDIR/enc.enc >$TMPDIR/enc.data.got"
 test_expect_success "comparing" \
     "test_cmp $TMPDIR/enc.data $TMPDIR/enc.data.got"
index a621ec7a2da7b89785625b84b046756efd8216e325568989c5b8469d50fe51dc..f7912e8acabca180d49befee2beb29a2185d0663f3f326f0371267bb9367c47e 100755 (executable)
@@ -5,15 +5,15 @@ test_description="Check passphrase-encrypted key decryption"
 
 TMPDIR=${TMPDIR:-/tmp}
 
-cmkeytool -algo sntrup4591761-x25519 -ku kem -subj A=KEY \
-    -prv $TMPDIR/enc.prv -pub $TMPDIR/enc.pub
+cmkeytool -algo sntrup4591761-x25519 -ku kem -subj A=KEY 5>$TMPDIR/enc.pub 9>$TMPDIR/enc.prv
 dd if=/dev/urandom of=$TMPDIR/enc.data bs=12K count=1 2>/dev/null
-export ENCTOOL_PASSPHRASE=$(dd if=/dev/urandom bs=32 count=1 2>/dev/null | xxd -p)
-test_expect_success "key encrypting" "cmenctool -p -no-stream \
+export CMENCTOOL_PASSPHRASE=$(dd if=/dev/urandom bs=32 count=1 2>/dev/null | xxd -p)
+balloonparams="-balloon-s 123 -balloon-t 2"
+test_expect_success "key encrypting" "cmenctool -p -no-stream $balloonparams \
     <$TMPDIR/enc.prv >$TMPDIR/enc.prv.enc"
-test_expect_success "data encrypting" "cmenctool -pub $TMPDIR/enc.pub \
+test_expect_success "data encrypting" "cmenctool 4<$TMPDIR/enc.pub \
     <$TMPDIR/enc.data >$TMPDIR/enc.enc"
-test_expect_success "decrypting" "cmenctool -d -prv $TMPDIR/enc.prv.enc \
+test_expect_success "decrypting" "cmenctool -d 8<$TMPDIR/enc.prv.enc \
     <$TMPDIR/enc.enc >$TMPDIR/enc.data.got"
 test_expect_success "comparing" \
     "test_cmp $TMPDIR/enc.data $TMPDIR/enc.data.got"
index 5d7065d64f4c01ff381a6367fcf239b7baf00d8606c64b34fd3fbbd115d63d29..25560c2c0297429b6c8c644426990ed35dc9afc6bad6fcd541ba5e59972231dc 100755 (executable)
@@ -6,47 +6,46 @@ test_description="Check public-key encryption"
 TMPDIR=${TMPDIR:-/tmp}
 
 dd if=/dev/urandom of=$TMPDIR/enc.data bs=300K count=1 2>/dev/null
+balloonparams="-balloon-s 123 -balloon-t 2"
 
 algo=mceliece6960119-x25519
 algo0=$algo
 test_expect_success "$algo: pub generation" "cmkeytool \
     -algo $algo -ku kem -subj A=$algo \
-    -prv $TMPDIR/enc.$algo.prv -pub $TMPDIR/enc.$algo.pub"
+    5>$TMPDIR/enc.$algo.pub 9>$TMPDIR/enc.$algo.prv"
 algo=sntrup4591761-x25519
 algo1=$algo
 test_expect_success "$algo: pub generation" "cmkeytool \
     -algo $algo -ku kem -subj A=$algo \
-    -prv $TMPDIR/enc.$algo.prv -pub $TMPDIR/enc.$algo.pub"
+    5>$TMPDIR/enc.$algo.pub 9>$TMPDIR/enc.$algo.prv"
 
-test_expect_success "encrypting" "cmenctool \
-    -pub $TMPDIR/enc.$algo0.pub -pub $TMPDIR/enc.$algo1.pub \
-    <$TMPDIR/enc.data >$TMPDIR/enc.enc"
+test_expect_success "encrypting" "
+    cat $TMPDIR/enc.$algo0.pub $TMPDIR/enc.$algo1.pub |
+    cmenctool 4<&0 <$TMPDIR/enc.data >$TMPDIR/enc.enc"
 
-test_expect_success "any: decrypting" "cmenctool -d \
-    -prv $TMPDIR/enc.$algo0.prv -prv $TMPDIR/enc.$algo1.prv \
-    <$TMPDIR/enc.enc >$TMPDIR/enc.data.got"
+test_expect_success "any: decrypting" "
+    cat $TMPDIR/enc.$algo0.prv $TMPDIR/enc.$algo1.prv |
+    cmenctool -d 8<&0 <$TMPDIR/enc.enc >$TMPDIR/enc.data.got"
 test_expect_success "comparing" \
     "test_cmp $TMPDIR/enc.data $TMPDIR/enc.data.got"
 
 test_expect_success "$algo0: decrypting" "cmenctool -d \
-    -prv $TMPDIR/enc.$algo0.prv \
-    <$TMPDIR/enc.enc >$TMPDIR/enc.data.got"
+    8<$TMPDIR/enc.$algo0.prv <$TMPDIR/enc.enc >$TMPDIR/enc.data.got"
 test_expect_success "$algo0: comparing" \
     "test_cmp $TMPDIR/enc.data $TMPDIR/enc.data.got"
 
 test_expect_success "$algo1: decrypting" "cmenctool -d \
-    -prv $TMPDIR/enc.$algo1.prv \
-    <$TMPDIR/enc.enc >$TMPDIR/enc.data.got"
+    8<$TMPDIR/enc.$algo1.prv <$TMPDIR/enc.enc >$TMPDIR/enc.data.got"
 test_expect_success "$algo1: comparing" \
     "test_cmp $TMPDIR/enc.data $TMPDIR/enc.data.got"
 
-export ENCTOOL_PASSPHRASE=$(dd if=/dev/urandom bs=32 count=1 2>/dev/null | xxd -p)
-test_expect_success "encrypting also with passphrase" "cmenctool \
-    -pub $TMPDIR/enc.$algo0.pub -pub $TMPDIR/enc.$algo1.pub -p \
-    <$TMPDIR/enc.data >$TMPDIR/enc.enc"
-test_expect_success "any: decrypting" "cmenctool -d \
-    -prv $TMPDIR/enc.$algo0.prv -prv $TMPDIR/enc.$algo1.prv \
-    <$TMPDIR/enc.enc >$TMPDIR/enc.data.got"
+export CMENCTOOL_PASSPHRASE=$(dd if=/dev/urandom bs=32 count=1 2>/dev/null | xxd -p)
+test_expect_success "encrypting also with passphrase" "
+    cat $TMPDIR/enc.$algo0.pub $TMPDIR/enc.$algo1.pub |
+    cmenctool $balloonparams -p 4<&0 <$TMPDIR/enc.data >$TMPDIR/enc.enc"
+test_expect_success "any: decrypting" "
+    cat $TMPDIR/enc.$algo0.prv $TMPDIR/enc.$algo1.prv |
+    cmenctool -d 8<&0 <$TMPDIR/enc.enc >$TMPDIR/enc.data.got"
 test_expect_success "comparing" \
     "test_cmp $TMPDIR/enc.data $TMPDIR/enc.data.got"
 test_expect_success "passphrase: decrypting" "cmenctool -d -p \
index 655cf38fc5b06c90b7fdf3cd549b8919db74fc578e47a04cb2d6d38e17327002..91aaec46410223f6f1f362a5a7f6f639694c566d000a4c69b872695893e2af76 100644 (file)
@@ -24,11 +24,11 @@ import (
 func usage() {
        fmt.Fprintf(os.Stderr, `Usage:
   Encrypt to recipient(s):
-    enctool -pub PUB [-pub ...] [-include-to] <DATA >DATA.encrypted
+    cmenctool [-include-to] 4<PUB[,PUB1...] <DATA >DATA.encrypted
   Encrypt on passphrase:
-    enctool -p [-balloon-s X] [-balloon-t X] [-balloon-p X] <DATA >DATA.encrypted
-  Decrypt by providing possible KEMs:
-    enctool -d [-p] [-prv PRV ...] <DATA.encrypted >DATA
+    cmenctool -p [-balloon-s X] [-balloon-t X] [-balloon-p X] <DATA >DATA.encrypted
+  Decrypt by providing possible KEMs and/or passphrase(s):
+    cmenctool -d [-p] 8<PRV0[,PRV1...] <DATA.encrypted >DATA
 
 `)
        flag.PrintDefaults()
index 30f68e9e78237e529acee5832204da07e4739649fb8b4c9f3c70843dda453e5e..a97e8b3cb9fc8bddfac91dc289ad10bc9ecae956b8d1ff2fd609ae7a6a8eb149 100755 (executable)
@@ -10,45 +10,49 @@ ed25519-blake2b ed25519-blake2b" | while read caAlgo eeAlgo ; do
 
 subj="-subj CN=CA -subj C=RU"
 test_expect_success "$caAlgo: CA load generation" "cmkeytool \
-    -algo $caAlgo \
-    -ku sig $subj \
-    -prv $TMPDIR/ca.$caAlgo.prv -pub $TMPDIR/ca.$caAlgo.pub"
+    -algo $caAlgo -ku sig $subj \
+    5>$TMPDIR/ca.$caAlgo.pub 9>$TMPDIR/ca.$caAlgo.prv"
 test_expect_success "$caAlgo: CA generation" "cmkeytool \
-    -pub $TMPDIR/ca.$caAlgo.pub \
-    -ca-prv $TMPDIR/ca.$caAlgo.prv -ca-pub $TMPDIR/ca.$caAlgo.pub"
+    4<$TMPDIR/ca.$caAlgo.pub \
+    8<$TMPDIR/ca.$caAlgo.prv \
+    <$TMPDIR/ca.$caAlgo.pub \
+    5>$TMPDIR/ca.$caAlgo.pub.certified"
+mv $TMPDIR/ca.$caAlgo.pub.certified $TMPDIR/ca.$caAlgo.pub
 test_expect_success "$caAlgo: CA regeneration" "cmkeytool \
-    -pub $TMPDIR/ca.$caAlgo.pub \
-    -ca-prv $TMPDIR/ca.$caAlgo.prv -ca-pub $TMPDIR/ca.$caAlgo.pub"
-test_expect_success "$caAlgo: CA self-signature" "cmkeytool \
-    -ca-pub $TMPDIR/ca.$caAlgo.pub \
-    -pub $TMPDIR/ca.$caAlgo.pub \
-    -verify"
+    4<$TMPDIR/ca.$caAlgo.pub \
+    8<$TMPDIR/ca.$caAlgo.prv \
+    <$TMPDIR/ca.$caAlgo.pub \
+    5>$TMPDIR/ca.$caAlgo.pub.certified"
+mv $TMPDIR/ca.$caAlgo.pub.certified $TMPDIR/ca.$caAlgo.pub
+test_expect_success "$caAlgo: CA self-signature" "cmkeytool -verify \
+    4<$TMPDIR/ca.$caAlgo.pub <$TMPDIR/ca.$caAlgo.pub"
 
 subj="-subj CN=SubCA -subj C=RU"
 test_expect_success "$eeAlgo: SubCA load generation" "cmkeytool \
-    -algo $eeAlgo \
-    -ku sig $subj \
-    -prv $TMPDIR/subca.$eeAlgo.prv -pub $TMPDIR/subca.$eeAlgo.pub"
+    -algo $eeAlgo -ku sig $subj \
+    5>$TMPDIR/subca.$eeAlgo.pub 9>$TMPDIR/subca.$eeAlgo.prv"
 test_expect_success "$eeAlgo: SubCA generation" "cmkeytool \
-    -pub $TMPDIR/subca.$eeAlgo.pub \
-    -ca-pub $TMPDIR/ca.$caAlgo.pub -ca-prv $TMPDIR/ca.$caAlgo.prv"
-test_expect_success "$eeAlgo: SubCA signature" "cmkeytool \
-    -ca-pub $TMPDIR/ca.$caAlgo.pub \
-    -pub $TMPDIR/subca.$eeAlgo.pub \
-    -verify"
+    4<$TMPDIR/ca.$caAlgo.pub \
+    8<$TMPDIR/ca.$caAlgo.prv \
+    <$TMPDIR/subca.$eeAlgo.pub \
+    5>$TMPDIR/subca.$eeAlgo.pub.certified"
+mv $TMPDIR/subca.$eeAlgo.pub.certified $TMPDIR/subca.$eeAlgo.pub
+test_expect_success "$eeAlgo: SubCA signature" "cmkeytool -verify \
+    4<$TMPDIR/ca.$caAlgo.pub <$TMPDIR/subca.$eeAlgo.pub"
 
 subj="-subj CN=EE -subj C=RU"
 test_expect_success "$eeAlgo: EE load generation" "cmkeytool \
     -algo $eeAlgo $subj \
-    -prv $TMPDIR/ee.$eeAlgo.prv -pub $TMPDIR/ee.$eeAlgo.pub"
+    5>$TMPDIR/ee.$eeAlgo.pub 9>$TMPDIR/ee.$eeAlgo.prv"
 test_expect_success "$eeAlgo: EE generation" "cmkeytool \
-    -ca-prv $TMPDIR/subca.$eeAlgo.prv -ca-pub $TMPDIR/subca.$eeAlgo.pub \
-    -pub $TMPDIR/ee.$eeAlgo.pub"
-test_expect_success "$eeAlgo: EE chain" "cmkeytool \
-    -ca-pub $TMPDIR/ca.$caAlgo.pub \
-    -ca-pub $TMPDIR/subca.$eeAlgo.pub \
-    -pub $TMPDIR/ee.$eeAlgo.pub \
-    -verify"
+    4<$TMPDIR/subca.$eeAlgo.pub \
+    8<$TMPDIR/subca.$eeAlgo.prv \
+    <$TMPDIR/ee.$eeAlgo.pub \
+    5>$TMPDIR/ee.$eeAlgo.pub.certified"
+mv $TMPDIR/ee.$eeAlgo.pub.certified $TMPDIR/ee.$eeAlgo.pub
+test_expect_success "$eeAlgo: EE chain" "
+    cat $TMPDIR/ca.$caAlgo.pub $TMPDIR/subca.$eeAlgo.pub |
+    cmkeytool -verify 4<&0 <$TMPDIR/ee.$eeAlgo.pub"
 
 done
 
index 0b18e9cb482941b4aab62a8baeea8dd9a907de031d0595f275f63eeea8793e31..61c7b3f011d082df634bfc628b799ee1cd47cadc4ae79eb7b9bf4d26bc1b0a84 100755 (executable)
@@ -10,8 +10,7 @@ sntrup4591761-x25519" | while read algo ; do
 
 test_expect_success "$algo: generation" "cmkeytool \
     -algo $algo \
-    -ku kem -subj CN=DH \
-    -prv $TMPDIR/kem.$algo.prv -pub $TMPDIR/kem.$algo.pub"
+    -ku kem -subj CN=DH 5>$TMPDIR/kem.$algo.pub 9>$TMPDIR/kem.$algo.prv"
 
 done
 
index 45acf8c78340eb2d478e6a5a4da91375ef4ca053692c4e9c610c9734f75c2a6f..41a471a4f3e64580de9a1d6ef655450e675a8bf4418afe3ab60ae7ecbc24d900 100644 (file)
@@ -21,6 +21,7 @@ import (
        "flag"
        "fmt"
        "hash"
+       "io"
        "log"
        "os"
        "sort"
@@ -38,11 +39,19 @@ import (
        "go.cypherpunks.su/keks/cm/sign/gost"
 )
 
-func mustReadFile(p string) []byte {
-       data, err := os.ReadFile(p)
+const (
+       FdPubR = 4
+       FdPubW = 5
+       FdPrvR = 8
+       FdPrvW = 9
+)
+
+func mustReadAll(r io.ReadCloser) []byte {
+       data, err := io.ReadAll(r)
        if err != nil {
-               log.Fatalln("read:", p, err)
+               log.Fatal(err)
        }
+       r.Close()
        return data
 }
 
@@ -70,25 +79,12 @@ func main() {
                        return nil
                },
        )
-       var issuingPubs []string
-       flag.Func(
-               "ca-pub",
-               "Add certification public key to the chain",
-               func(v string) error {
-                       issuingPubs = append(issuingPubs, v)
-                       return nil
-               },
-       )
        sinceRaw := flag.String("since", "",
                "Optional notBefore, \"2006-01-02 15:04:05\" format")
        lifetime := flag.Uint("lifetime", 365,
                "Lifetime of the certification, days")
        algo := flag.String("algo", ed25519blake2b.Ed25519BLAKE2b,
                "Public key algorithm")
-       issuingPrv := flag.String("ca-prv", "",
-               "Path to private key file for issuing with")
-       prvPath := flag.String("prv", "", "Path to private key file")
-       pubPath := flag.String("pub", "", "Path to public key file")
        verify := flag.Bool("verify", false, "Verify provided -pub with -ca-pub")
        doList := flag.Bool("list-algo", false, "List available algorithms")
 
@@ -110,8 +106,14 @@ func main() {
                return
        }
 
-       if *pubPath == "" {
-               log.Fatal("no -pub is set")
+       fdPubR := os.NewFile(FdPubR, "pub-in")
+       fdPubW := os.NewFile(FdPubW, "pub-out")
+       fdPrvR := os.NewFile(FdPrvR, "prv-in")
+       fdPrvW := os.NewFile(FdPrvW, "prv-out")
+
+       var doCertify bool
+       if len(subj) == 0 && !*verify {
+               doCertify = true
        }
 
        var err error
@@ -128,30 +130,33 @@ func main() {
 
        var caPrv sign.Iface
        var caPubs []*sign.Signed
-       for _, issuingPub := range issuingPubs {
-               var signed *sign.Signed
-               signed, _, err = sign.PubParse(mustReadFile(issuingPub))
-               if err != nil {
-                       log.Fatal(err)
+       if doCertify || *verify {
+               data := mustReadAll(fdPubR)
+               for len(data) > 0 {
+                       var signed *sign.Signed
+                       signed, data, err = sign.PubParse(data)
+                       if err != nil {
+                               log.Fatal(err)
+                       }
+                       caPubs = append(caPubs, signed)
                }
-               caPubs = append(caPubs, signed)
        }
-       if len(caPubs) > 0 && !*verify {
-               if *issuingPrv == "" {
-                       log.Fatal("no -ca-prv is set")
-               }
-               caPrv, _, err = sign.PrvParse(mustReadFile(*issuingPrv))
+       if doCertify {
+               caPrv, _, err = sign.PrvParse(mustReadAll(fdPrvR))
                if err != nil {
                        log.Fatal(err)
                }
        }
 
-       if *verify {
-               var signed *sign.Signed
-               signed, _, err = sign.PubParse(mustReadFile(*pubPath))
+       var signed *sign.Signed
+       if doCertify || *verify {
+               signed, _, err = sign.PubParse(mustReadAll(os.Stdin))
                if err != nil {
                        log.Fatal(err)
                }
+       }
+
+       if *verify {
                err = signed.CertificationVerify(caPubs, time.Now().UTC())
                if err != nil {
                        log.Fatal(err)
@@ -161,21 +166,10 @@ func main() {
 
        var prvRaw []byte
        var pubLoad *sign.PubLoad
-       var signed *sign.Signed
-       if caPrv != nil {
-               signed, _, err = sign.PubParse(mustReadFile(*pubPath))
-               if err != nil {
-                       log.Fatal(err)
-               }
+       if doCertify {
                pubLoad = signed.PubLoad()
        } else {
-               if len(subj) == 0 {
-                       log.Fatal("no -subj is set")
-               }
                var pub []byte
-               if *prvPath == "" {
-                       log.Fatal("no -prv is set")
-               }
                switch *algo {
                case ed25519blake2b.Ed25519BLAKE2b:
                        _, prvRaw, pub, err = ed25519blake2b.NewKeypair()
@@ -199,8 +193,7 @@ func main() {
                        if _, err = keks.Encode(&buf, cm.AV{A: *algo, V: prvRaw}, nil); err != nil {
                                log.Fatal(err)
                        }
-                       err = os.WriteFile(*prvPath, buf.Bytes(), 0o600)
-                       if err != nil {
+                       if _, err = io.Copy(fdPrvW, &buf); err != nil {
                                log.Fatal(err)
                        }
                }
@@ -236,7 +229,7 @@ func main() {
                signed = &sign.Signed{Load: sign.SignedLoad{T: "pub", V: &pubLoadAny}}
        }
 
-       if caPrv != nil {
+       if doCertify {
                if err = signed.CertifyWith(
                        caPubs[0].PubLoad(), caPrv, since, till,
                ); err != nil {
@@ -252,7 +245,7 @@ func main() {
                if _, err = keks.Encode(&buf, signed, nil); err != nil {
                        log.Fatal(err)
                }
-               if err = os.WriteFile(*pubPath, buf.Bytes(), 0o666); err != nil {
+               if _, err = io.Copy(fdPubW, &buf); err != nil {
                        log.Fatal(err)
                }
        }
index fb72ddf67a4d34acfddec82e519bf73bd42098ec2c073acc25c4e9c39eb14293..d93be5a3b2ab2f5ab35706e8b4d58dfaac486cc96a3745b0876ff5a4e3679412 100644 (file)
@@ -24,13 +24,11 @@ import (
 func usage() {
        fmt.Fprintf(os.Stderr, `Usage:
   Generate public key load:
-    keytool -prv PRV -pub PUB [-algo ALGO] [-ku KU ...] \
-      -subj K=V [-subj K=V ...]
-  Sign certificate:
-    keytool -pub PUB -ca-prv CA-PRV -ca-pub CA-pub \
-      [-lifetime DAYS] [-since DATE]
-  Verify certificate:
-    keytool -verify -pub PUB CA-PRV -ca-pub CA-pub0 [-ca-pub CA-pub1 ...]
+    cmkeytool -subj K=V [-subj K=V ...] [-algo ALGO] [-ku KU ...] 5>PUB 9>PRV
+  Certify public key:
+    cmkeytool [-lifetime DAYS] [-since DATE] 4<CA-PUB 8<CA-PRV <PUB
+  Verify certification:
+    cmkeytool -verify 4<CA-PUB0[,CA-PUB1,...] <PUB
 
 `)
        flag.PrintDefaults()
index 14d61113c431179837d032d1c23d0ee7b83a424cc595ba64d8614f318ebaa61c..232a54eee4d96a9d04c22f5f5bedd297299b3c5367023680cd680ca2eb5faec6 100755 (executable)
@@ -13,7 +13,7 @@ subj="-subj what=ever"
 typ="some-different-type"
 test_expect_success "$keyalgo: pub generation" "cmkeytool \
     -algo $keyalgo -ku sig $subj \
-    -prv $TMPDIR/sign.$keyalgo.prv -pub $TMPDIR/sign.$keyalgo.pub"
+    5>$TMPDIR/sign.$keyalgo.pub 9>$TMPDIR/sign.$keyalgo.prv"
 dd if=/dev/urandom of=$TMPDIR/sign.$keyalgo.data bs=300K count=1 2>/dev/null
 encTo="-encrypted-to $(uuidgen)"
 badEncTo="-encrypted-to $(uuidgen)"
@@ -22,32 +22,33 @@ for merkle in "" "-merkle" ; do
 
 algo=${keyalgo}${merkle}
 test_expect_success "$algo: signing" "cmsigtool $merkle \
-    -prv $TMPDIR/sign.$keyalgo.prv -pub $TMPDIR/sign.$keyalgo.pub -type $typ \
-    $encTo <$TMPDIR/sign.$keyalgo.data >$TMPDIR/sign.$algo.sig"
+    -type $typ $encTo \
+    4<$TMPDIR/sign.$keyalgo.pub 8<$TMPDIR/sign.$keyalgo.prv \
+    <$TMPDIR/sign.$keyalgo.data >$TMPDIR/sign.$algo.sig"
 test_expect_success "$algo: verifying" "cmsigtool \
-    -verify -pub $TMPDIR/sign.$keyalgo.pub -type $typ \
-        <$TMPDIR/sign.$algo.sig >$TMPDIR/sign.data.got"
+    -verify -type $typ 4<$TMPDIR/sign.$keyalgo.pub \
+    <$TMPDIR/sign.$algo.sig >$TMPDIR/sign.data.got"
 test_expect_success "$algo: comparing" \
     "test_cmp $TMPDIR/sign.$keyalgo.data $TMPDIR/sign.data.got"
 test_expect_success "$algo: differing type" "! cmsigtool \
-    -verify -pub $TMPDIR/sign.$keyalgo.pub <$TMPDIR/sign.$algo.sig >/dev/null"
+    -verify 4<$TMPDIR/sign.$keyalgo.pub <$TMPDIR/sign.$algo.sig >/dev/null"
 test_expect_success "$algo: good encTo" "! cmsigtool \
-    -verify -pub $TMPDIR/sign.$keyalgo.pub $encTo <$TMPDIR/sign.$algo.sig >/dev/null"
+    -verify $encTo 4<$TMPDIR/sign.$keyalgo.pub <$TMPDIR/sign.$algo.sig >/dev/null"
 test_expect_success "$algo: bad encTo" "! cmsigtool \
-    -verify -pub $TMPDIR/sign.$keyalgo.pub $badEncTo <$TMPDIR/sign.$algo.sig >/dev/null"
+    -verify $badEncTo 4<$TMPDIR/sign.$keyalgo.pub <$TMPDIR/sign.$algo.sig >/dev/null"
 
 test_expect_success "$algo: detached signing" "cmsigtool -detached $merkle \
-    -prv $TMPDIR/sign.$keyalgo.prv -pub $TMPDIR/sign.$keyalgo.pub -type $typ \
-        <$TMPDIR/sign.$keyalgo.data >$TMPDIR/sign.$algo.detached.sig"
+    -type $typ 4<$TMPDIR/sign.$keyalgo.pub 8<$TMPDIR/sign.$keyalgo.prv \
+    <$TMPDIR/sign.$keyalgo.data >$TMPDIR/sign.$algo.detached.sig"
 test_expect_success "$algo: detached verifying" \
     "cat $TMPDIR/sign.$algo.detached.sig $TMPDIR/sign.$keyalgo.data |
-        cmsigtool -detached -verify -pub $TMPDIR/sign.$keyalgo.pub -type $typ"
+        cmsigtool -detached -verify -type $typ 4<$TMPDIR/sign.$keyalgo.pub"
 test_expect_success "$algo: differing type" "! cmsigtool -detached \
-    -verify -pub $TMPDIR/sign.$keyalgo.pub <$TMPDIR/sign.$algo.detached.sig >/dev/null"
+    -verify -pub 4<$TMPDIR/sign.$keyalgo.pub <$TMPDIR/sign.$algo.detached.sig >/dev/null"
 test_expect_success "$algo: good encTo" "! cmsigtool -detached \
-    -verify -pub $TMPDIR/sign.$keyalgo.pub $encTo <$TMPDIR/sign.$algo.detached.sig >/dev/null"
+    -verify -pub $encTo 4<$TMPDIR/sign.$keyalgo.pub <$TMPDIR/sign.$algo.detached.sig >/dev/null"
 test_expect_success "$algo: bad encTo" "! cmsigtool -detached \
-    -verify -pub $TMPDIR/sign.$keyalgo.pub $badEncTo <$TMPDIR/sign.$algo.detached.sig >/dev/null"
+    -verify -pub $badEncTo 4<$TMPDIR/sign.$keyalgo.pub <$TMPDIR/sign.$algo.detached.sig >/dev/null"
 
 done
 
index 585f3f04dc774aa585a5699bb51c47b87f33abca5720d52d7ab089730370decd..defdcb29201475b2a8dbc90ff28d27ae32eef06832ee6f9e081e559e4d60b6e0 100644 (file)
@@ -35,12 +35,17 @@ import (
        "go.cypherpunks.su/keks/types"
 )
 
+const (
+       FdPubR = 4
+       FdPrvR = 8
+)
+
 const BlobChunkLen = 128 * 1024
 
-func mustReadFile(p string) []byte {
-       data, err := os.ReadFile(p)
+func mustReadAll(r io.Reader) []byte {
+       data, err := io.ReadAll(r)
        if err != nil {
-               log.Fatalln("read:", p, err)
+               log.Fatal(err)
        }
        return data
 }
@@ -48,8 +53,6 @@ func mustReadFile(p string) []byte {
 func main() {
        log.SetFlags(log.Lshortfile)
        flag.Usage = usage
-       prvPath := flag.String("prv", "", "Path to private key file")
-       pubPath := flag.String("pub", "", "Path to public key file")
        typ := flag.String("type", "data", "Set/check the load type")
        verify := flag.Bool("verify", false, "Do verification")
        var encryptedTo []uuid.UUID
@@ -66,13 +69,14 @@ func main() {
        doMerkle := flag.Bool("merkle", false, "Use Merkle-tree based hasher")
        flag.Parse()
 
-       if *pubPath == "" {
-               log.Fatal("no -pub is set")
-       }
-       pub, _, err := sign.PubParse(mustReadFile(*pubPath))
+       fdPubR := os.NewFile(FdPubR, "pub-in")
+       fdPrvR := os.NewFile(FdPrvR, "prv-in")
+
+       pub, _, err := sign.PubParse(mustReadAll(fdPubR))
        if err != nil {
                log.Fatal(err)
        }
+       fdPubR.Close()
 
        stdin := bufio.NewReaderSize(os.Stdin, BlobChunkLen)
        if *verify {
@@ -172,11 +176,9 @@ func main() {
                        log.Fatal(err)
                }
        } else {
-               if *prvPath == "" {
-                       log.Fatal("no -prv is set")
-               }
                var signer sign.Iface
-               signer, _, err = sign.PrvParse(mustReadFile(*prvPath))
+               signer, _, err = sign.PrvParse(mustReadAll(fdPrvR))
+               fdPrvR.Close()
                if err != nil {
                        log.Fatal(err)
                }
index cad6ab1e4d25cf0d4e58d419a45b85280ff5575cea0581768e518f3d95e32dfe..751037077deeb6982930734dd2aef7e69ec2ecafcbe14833f796af7cb477ea11 100644 (file)
@@ -23,10 +23,10 @@ import (
 
 func usage() {
        fmt.Fprintf(os.Stderr, `Usage:
-  sigtool -prv PRV -pub PUB [-type TYPE] <DATA >DATA.signed
-  sigtool -verify -pub PUB [-type TYPE] <DATA.signed >DATA
-  sigtool -detached -prv PRV -pub PUB [-type TYPE] <DATA >DATA.signature
-  sigtool -detached -verify -pub PUB [-type TYPE] <(cat DATA.signature DATA)
+  cmsigtool [-type TYPE] 4<PUB 8<PRV <DATA >DATA.signed
+  cmsigtool -verify [-type TYPE] 4<PUB <DATA.signed >DATA
+  cmsigtool -detached [-type TYPE] 4<PUB 8<PRV <DATA >DATA.signature
+  cmsigtool -detached -verify [-type TYPE] 4<PUB <(cat DATA.signature DATA)
 
 DATA.signed holds completely encapsulated DATA.
 -detached mode keeps DATA completely separate.
index 23ece336610a468a0a69e38ce5325ee188a800168ac8c12ad034e28849ce7411..221e5f628d9e11a8ee79a098f297de38202176be9bd0cd034f1cf33472844072 100644 (file)
@@ -290,6 +290,9 @@ func (signed *Signed) PubLoad() *PubLoad {
 // Verify signed Signed PubLoad certification against pubs chain of
 // public keys at specified point of time t.
 func (signed *Signed) CertificationVerify(pubs []*Signed, t time.Time) (err error) {
+       if len(signed.Sigs) == 0 {
+               return errors.New("no sigs")
+       }
        {
                exp := *(signed.Sigs[0].TBS.Exp)
                if t.Before(exp[0]) || t.Equal(exp[0]) {