From 743b7dd58e33914199a5de5ee405b9932d1368a07884571eb5b9259bfc0f2950 Mon Sep 17 00:00:00 2001 From: Sergey Matveev Date: Wed, 5 Mar 2025 13:11:04 +0300 Subject: [PATCH] =?utf8?q?struct=E2=86=92map=20to=20deal=20with=20arbitrar?= =?utf8?q?y=20signed=20fields?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- go/cm/cmd/enctool/main.go | 14 ++---- go/cm/cmd/enctool/multirecipient.t | 31 +++++++++++++ go/cm/cmd/keytool/main.go | 17 ++++--- go/cm/cmd/sigtool/basic.t | 28 ++++++------ go/cm/cmd/sigtool/main.go | 32 +++++++------ go/cm/cmd/sigtool/usage.go | 10 ++-- go/cm/sign/pub.go | 73 ++++++++++++++---------------- go/cm/sign/signed.go | 66 +++++++++++++++------------ 8 files changed, 155 insertions(+), 116 deletions(-) create mode 100755 go/cm/cmd/enctool/multirecipient.t diff --git a/go/cm/cmd/enctool/main.go b/go/cm/cmd/enctool/main.go index df4c7a5..0b55450 100644 --- a/go/cm/cmd/enctool/main.go +++ b/go/cm/cmd/enctool/main.go @@ -164,15 +164,11 @@ func main() { 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 !load.Can(sign.KUKEM) { + 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") diff --git a/go/cm/cmd/enctool/multirecipient.t b/go/cm/cmd/enctool/multirecipient.t new file mode 100755 index 0000000..09fa7e3 --- /dev/null +++ b/go/cm/cmd/enctool/multirecipient.t @@ -0,0 +1,31 @@ +#!/bin/sh + +test_description="Check multiple recipients" +. $SHARNESS_TEST_SRCDIR/sharness.sh + +TMPDIR=${TMPDIR:-/tmp} + +dd if=/dev/urandom of=$TMPDIR/enc.data bs=300K count=1 2>/dev/null + +test_expect_success "0: pub generation" "cmkeytool \ + -algo sntrup4591761-x25519 -ku kem -sub N=0 \ + 5>$TMPDIR/enc.0.pub 9>$TMPDIR/enc.0.prv" +test_expect_success "1: pub generation" "cmkeytool \ + -algo sntrup4591761-x25519 -ku kem -sub N=1 \ + 5>$TMPDIR/enc.1.pub 9>$TMPDIR/enc.1.prv" + +test_expect_success "encrypting" " + cat $TMPDIR/enc.0.pub $TMPDIR/enc.1.pub | + cmenctool 4<&0 <$TMPDIR/enc.data >$TMPDIR/enc.enc" + +test_expect_success "0: decrypting" " + cmenctool -d 8<$TMPDIR/enc.0.prv <$TMPDIR/enc.enc >$TMPDIR/enc.data.got" +test_expect_success "0: comparing" \ + "test_cmp $TMPDIR/enc.data $TMPDIR/enc.data.got" + +test_expect_success "1: decrypting" " + cmenctool -d 8<$TMPDIR/enc.1.prv <$TMPDIR/enc.enc >$TMPDIR/enc.data.got" +test_expect_success "1: comparing" \ + "test_cmp $TMPDIR/enc.data $TMPDIR/enc.data.got" + +test_done diff --git a/go/cm/cmd/keytool/main.go b/go/cm/cmd/keytool/main.go index 4e1ee1f..c2bc1a7 100644 --- a/go/cm/cmd/keytool/main.go +++ b/go/cm/cmd/keytool/main.go @@ -164,9 +164,9 @@ func main() { } var prvRaw []byte - var pubLoad *sign.PubLoad + var pubLoad map[string]any if doCertify { - pubLoad = signed.PubLoad() + pubLoad = (*signed.Load.V).(map[string]any) } else { var pub []byte switch *algo { @@ -197,7 +197,10 @@ func main() { } } { - pubLoad = &sign.PubLoad{Sub: sub, Pub: []cm.AV{{A: *algo, V: pub}}} + pubLoad = map[string]any{ + "sub": sub, + "pub": []cm.AV{{A: *algo, V: pub}}, + } var hasher hash.Hash switch *algo { case ed25519blake2b.Ed25519BLAKE2b, sntrup4591761x25519.SNTRUP4591761X25519: @@ -209,23 +212,23 @@ func main() { default: log.Fatal("unsupported algorithm") } - _, err = keks.Encode(hasher, pubLoad.Pub, nil) + _, err = keks.Encode(hasher, pubLoad["pub"], nil) if err != nil { log.Fatal(err) } - pubLoad.Id = hasher.Sum(nil) + pubLoad["id"] = hasher.Sum(nil) if err != nil { log.Fatal(err) } } if len(ku) > 0 { - pubLoad.KU = &ku + pubLoad["ku"] = ku } } { pubLoadAny := any(pubLoad) - signed = &sign.Signed{Load: sign.SignedLoad{T: "pub", V: &pubLoadAny}} + signed = &sign.Signed{Load: sign.Load{T: "pub", V: &pubLoadAny}} } if doCertify { diff --git a/go/cm/cmd/sigtool/basic.t b/go/cm/cmd/sigtool/basic.t index 5423395..8e3cb3b 100755 --- a/go/cm/cmd/sigtool/basic.t +++ b/go/cm/cmd/sigtool/basic.t @@ -24,33 +24,33 @@ for merkle in "" "-merkle" ; do algo=${keyalgo}${merkle} test_expect_success "$algo: signing" "cmsigtool $merkle \ - -type $typ $encTo \ + -t $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 -type $typ 4<$TMPDIR/sign.$keyalgo.pub \ + -v -t $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 4<$TMPDIR/sign.$keyalgo.pub <$TMPDIR/sign.$algo.sig >/dev/null" + -v 4<$TMPDIR/sign.$keyalgo.pub <$TMPDIR/sign.$algo.sig >/dev/null" test_expect_success "$algo: good encTo" "! cmsigtool \ - -verify $encTo 4<$TMPDIR/sign.$keyalgo.pub <$TMPDIR/sign.$algo.sig >/dev/null" + -v $encTo 4<$TMPDIR/sign.$keyalgo.pub <$TMPDIR/sign.$algo.sig >/dev/null" test_expect_success "$algo: bad encTo" "! cmsigtool \ - -verify $badEncTo 4<$TMPDIR/sign.$keyalgo.pub <$TMPDIR/sign.$algo.sig >/dev/null" + -v $badEncTo 4<$TMPDIR/sign.$keyalgo.pub <$TMPDIR/sign.$algo.sig >/dev/null" -test_expect_success "$algo: detached signing" "cmsigtool -detached $merkle \ - -type $typ 4<$TMPDIR/sign.$keyalgo.pub 8<$TMPDIR/sign.$keyalgo.prv \ +test_expect_success "$algo: detached signing" "cmsigtool -d $merkle \ + -t $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 -type $typ 4<$TMPDIR/sign.$keyalgo.pub" -test_expect_success "$algo: differing type" "! cmsigtool -detached \ - -verify 4<$TMPDIR/sign.$keyalgo.pub <$TMPDIR/sign.$algo.detached.sig >/dev/null" -test_expect_success "$algo: good encTo" "! cmsigtool -detached \ - -verify $encTo 4<$TMPDIR/sign.$keyalgo.pub <$TMPDIR/sign.$algo.detached.sig >/dev/null" -test_expect_success "$algo: bad encTo" "! cmsigtool -detached \ - -verify $badEncTo 4<$TMPDIR/sign.$keyalgo.pub <$TMPDIR/sign.$algo.detached.sig >/dev/null" + cmsigtool -d -v -t $typ 4<$TMPDIR/sign.$keyalgo.pub" +test_expect_success "$algo: differing type" "! cmsigtool -d \ + -v 4<$TMPDIR/sign.$keyalgo.pub <$TMPDIR/sign.$algo.detached.sig >/dev/null" +test_expect_success "$algo: good encTo" "! cmsigtool -d \ + -v $encTo 4<$TMPDIR/sign.$keyalgo.pub <$TMPDIR/sign.$algo.detached.sig >/dev/null" +test_expect_success "$algo: bad encTo" "! cmsigtool -d \ + -v $badEncTo 4<$TMPDIR/sign.$keyalgo.pub <$TMPDIR/sign.$algo.detached.sig >/dev/null" done diff --git a/go/cm/cmd/sigtool/main.go b/go/cm/cmd/sigtool/main.go index 8e82e34..4bcafa2 100644 --- a/go/cm/cmd/sigtool/main.go +++ b/go/cm/cmd/sigtool/main.go @@ -51,8 +51,8 @@ func mustReadAll(r io.Reader) []byte { func main() { log.SetFlags(log.Lshortfile) flag.Usage = usage - typ := flag.String("type", "data", "Set/check the load type") - verify := flag.Bool("verify", false, "Do verification") + typ := flag.String("t", "data", "Set/check the load type") + verify := flag.Bool("v", false, "Do verification") var encryptedTo [][]byte flag.Func("encrypted-to", "Set/check encrypted-to, hex", func(v string) error { to, err := hex.DecodeString(v) @@ -62,7 +62,7 @@ func main() { encryptedTo = append(encryptedTo, to) return nil }) - detached := flag.Bool("detached", false, "Detached data mode") + detached := flag.Bool("d", false, "Detached data mode") noWhen := flag.Bool("no-when", false, `Do not include "when"`) doMerkle := flag.Bool("merkle", false, "Use Merkle-tree based hasher") flag.Parse() @@ -91,7 +91,7 @@ func main() { if _, err = decoder.Parse(); err != nil { log.Fatal(err) } - var prehash sign.SignedPrehash + var prehash sign.Prehash var signed sign.Signed err = decoder.UnmarshalStruct(&prehash) var hasher hash.Hash @@ -144,17 +144,22 @@ func main() { if len(signed.Sigs) > 1 { log.Fatal("prehash: currently only single signature support") } - sig := signed.Sigs[0] signer := pub.PubLoad() if signed.Load.T != *typ { log.Fatalln("differing load type:", signed.Load.T) } + sig := signed.Sigs[0] + var tbs *sign.TBS + tbs, err = sig.TBSGet() + if err != nil { + log.Fatal(err) + } if len(encryptedTo) > 0 { - if sig.TBS.EncryptedTo == nil { + if len(tbs.EncryptedTo) == 0 { log.Fatal("missing encrypted-to") } found := false - for _, their := range sig.TBS.EncryptedTo { + for _, their := range tbs.EncryptedTo { for _, our := range encryptedTo { if bytes.Equal(our, their) { found = true @@ -199,7 +204,7 @@ func main() { log.Fatal(err) } } else { - if _, err = keks.Encode(os.Stdout, sign.SignedPrehash{ + if _, err = keks.Encode(os.Stdout, sign.Prehash{ T: mode.PrehashT, Sigs: map[string]*struct{}{signer.Algo(): nil}, }, nil); err != nil { @@ -223,13 +228,14 @@ func main() { } var signed sign.Signed signed.Load.T = *typ - var sigTbs sign.SigTBS + tbs := make(map[string]any) if !*noWhen { - when := time.Now().UTC().Truncate(time.Millisecond) - sigTbs.When = &when + tbs["when"] = time.Now().UTC().Truncate(time.Millisecond) + } + if len(encryptedTo) > 0 { + tbs["encrypted-to"] = encryptedTo } - sigTbs.EncryptedTo = encryptedTo - if err = signed.SignWith(pub.PubLoad(), signer, sigTbs); err != nil { + if err = signed.SignWith(pub.PubLoad(), signer, tbs); err != nil { log.Fatal(err) } if _, err = keks.Encode(os.Stdout, signed, nil); err != nil { diff --git a/go/cm/cmd/sigtool/usage.go b/go/cm/cmd/sigtool/usage.go index 7510370..c4c4f38 100644 --- a/go/cm/cmd/sigtool/usage.go +++ b/go/cm/cmd/sigtool/usage.go @@ -23,13 +23,13 @@ import ( func usage() { fmt.Fprintf(os.Stderr, `Usage: - cmsigtool [-type TYPE] 4DATA.signed - cmsigtool -verify [-type TYPE] 4DATA - cmsigtool -detached [-type TYPE] 4DATA.signature - cmsigtool -detached -verify [-type TYPE] 4DATA.signed + cmsigtool -v [-t TYPE] 4DATA + cmsigtool -d [-t TYPE] 4DATA.signature + cmsigtool -d -v [-t TYPE] 4