From b788e5d82eeb94f1a257d413d0b0ddf7a3e86075a36b8b683a669091436c98a3 Mon Sep 17 00:00:00 2001 From: Sergey Matveev Date: Wed, 12 Feb 2025 15:55:58 +0300 Subject: [PATCH] Great pki->cm renaming --- go/cm/algo.go | 44 +++++ go/{pki => cm}/av.go | 12 +- go/{pki => cm}/cmd/enctool/chapoly.go | 2 +- go/{pki => cm}/cmd/enctool/main.go | 60 +++---- go/{pki => cm}/cmd/enctool/usage.go | 11 +- go/{pki => cm}/cmd/hshtool/main.go | 38 ++--- go/cm/cmd/keytool/basic.t | 55 +++++++ .../cmd/certool => cm/cmd/keytool}/main.go | 106 ++++++------ .../cmd/certool => cm/cmd/keytool}/usage.go | 10 +- go/{pki => cm}/cmd/sigtool/basic.t | 24 +-- go/{pki => cm}/cmd/sigtool/main.go | 46 +++--- go/{pki => cm}/cmd/sigtool/usage.go | 10 +- go/cm/doc.go | 2 + go/{pki => cm}/ed25519-blake2b/.gitignore | 0 go/{pki => cm}/ed25519-blake2b/algo.go | 0 go/{pki => cm}/ed25519-blake2b/clean | 0 .../ed25519-blake2b/ed25519-to-blake2b.patch | 2 +- go/{pki => cm}/ed25519-blake2b/hasher.go | 4 +- go/{pki => cm}/ed25519-blake2b/kp.go | 4 +- go/{pki => cm}/ed25519-blake2b/mk-from-go | 2 +- go/{pki => cm}/ed25519-blake2b/signer.go | 8 +- go/{pki => cm}/ed25519-blake2b/verify.go | 4 +- go/{pki => cm}/go.mod | 4 +- go/cm/go.sum | 6 + go/{pki => cm}/gost/gost.go | 2 +- go/{pki => cm}/gost/hasher.go | 4 +- go/{pki => cm}/gost/kp.go | 2 +- go/{pki => cm}/gost/signer.go | 6 +- go/{pki => cm}/gost/verify.go | 4 +- go/{pki => cm}/hash/algo.go | 8 +- go/{pki => cm}/hash/merkle/hash.go | 2 +- go/{pki => cm}/hash/merkle/hash_test.go | 2 +- go/{pki => cm}/hash/merkle/prefixed.go | 2 +- go/{pki => cm}/hash/shake.go | 4 +- go/{pki => cm}/mceliece6960119-x25519/SOURCE | 0 go/{pki => cm}/mceliece6960119-x25519/algo.go | 0 go/{pki => cm}/mceliece6960119-x25519/kp.go | 2 +- go/{pki => cm}/prv.go | 12 +- go/{pki/cer.go => cm/pub.go} | 154 +++++++++--------- go/{pki => cm}/sign/iface.go | 0 go/{pki => cm}/sign/mode.go | 0 go/{pki => cm}/signed.go | 36 ++-- go/{pki => cm}/sntrup4591761-x25519/algo.go | 0 go/{pki => cm}/sntrup4591761-x25519/go.mod | 2 +- go/{pki => cm}/sntrup4591761-x25519/go.sum | 0 go/{pki => cm}/sntrup4591761-x25519/kp.go | 2 +- go/{pki => cm}/utils/utils.go | 2 +- go/pki/algo.go | 29 ---- go/pki/cmd/certool/basic.t | 55 ------- go/pki/doc.go | 2 - go/pki/go.sum | 5 - spec/encoding/float.texi | 1 + spec/encoding/list.texi | 1 + spec/encoding/magic.texi | 6 +- spec/format/encrypted.cddl | 2 +- spec/format/encrypted.texi | 68 ++++---- spec/format/hashed.cddl | 2 +- spec/format/hashed.texi | 63 ++++--- spec/format/index.texi | 4 +- spec/format/{private-key.cddl => prv.cddl} | 2 +- spec/format/{private-key.texi => prv.texi} | 32 ++-- spec/format/{cer-load.cddl => pub-load.cddl} | 2 +- .../{cer-sig-tbs.cddl => pub-sig-tbs.cddl} | 4 +- spec/format/{cer.texi => pub.texi} | 88 +++++----- spec/format/registry.texi | 68 ++++---- spec/format/signed-prehash.cddl | 2 +- spec/format/signed.cddl | 6 +- spec/format/signed.texi | 50 +++--- 68 files changed, 622 insertions(+), 570 deletions(-) create mode 100644 go/cm/algo.go rename go/{pki => cm}/av.go (84%) rename go/{pki => cm}/cmd/enctool/chapoly.go (98%) rename go/{pki => cm}/cmd/enctool/main.go (90%) rename go/{pki => cm}/cmd/enctool/usage.go (75%) rename go/{pki => cm}/cmd/hshtool/main.go (58%) create mode 100755 go/cm/cmd/keytool/basic.t rename go/{pki/cmd/certool => cm/cmd/keytool}/main.go (60%) rename go/{pki/cmd/certool => cm/cmd/keytool}/usage.go (77%) rename go/{pki => cm}/cmd/sigtool/basic.t (64%) rename go/{pki => cm}/cmd/sigtool/main.go (82%) rename go/{pki => cm}/cmd/sigtool/usage.go (75%) create mode 100644 go/cm/doc.go rename go/{pki => cm}/ed25519-blake2b/.gitignore (100%) rename go/{pki => cm}/ed25519-blake2b/algo.go (100%) rename go/{pki => cm}/ed25519-blake2b/clean (100%) rename go/{pki => cm}/ed25519-blake2b/ed25519-to-blake2b.patch (98%) rename go/{pki => cm}/ed25519-blake2b/hasher.go (91%) rename go/{pki => cm}/ed25519-blake2b/kp.go (89%) rename go/{pki => cm}/ed25519-blake2b/mk-from-go (93%) rename go/{pki => cm}/ed25519-blake2b/signer.go (92%) rename go/{pki => cm}/ed25519-blake2b/verify.go (91%) rename go/{pki => cm}/go.mod (69%) create mode 100644 go/cm/go.sum rename go/{pki => cm}/gost/gost.go (93%) rename go/{pki => cm}/gost/hasher.go (89%) rename go/{pki => cm}/gost/kp.go (94%) rename go/{pki => cm}/gost/signer.go (95%) rename go/{pki => cm}/gost/verify.go (94%) rename go/{pki => cm}/hash/algo.go (92%) rename go/{pki => cm}/hash/merkle/hash.go (98%) rename go/{pki => cm}/hash/merkle/hash_test.go (98%) rename go/{pki => cm}/hash/merkle/prefixed.go (94%) rename go/{pki => cm}/hash/shake.go (95%) rename go/{pki => cm}/mceliece6960119-x25519/SOURCE (100%) rename go/{pki => cm}/mceliece6960119-x25519/algo.go (100%) rename go/{pki => cm}/mceliece6960119-x25519/kp.go (95%) rename go/{pki => cm}/prv.go (84%) rename go/{pki/cer.go => cm/pub.go} (60%) rename go/{pki => cm}/sign/iface.go (100%) rename go/{pki => cm}/sign/mode.go (100%) rename go/{pki => cm}/signed.go (79%) rename go/{pki => cm}/sntrup4591761-x25519/algo.go (100%) rename go/{pki => cm}/sntrup4591761-x25519/go.mod (62%) rename go/{pki => cm}/sntrup4591761-x25519/go.sum (100%) rename go/{pki => cm}/sntrup4591761-x25519/kp.go (94%) rename go/{pki => cm}/utils/utils.go (93%) delete mode 100644 go/pki/algo.go delete mode 100755 go/pki/cmd/certool/basic.t delete mode 100644 go/pki/doc.go delete mode 100644 go/pki/go.sum rename spec/format/{private-key.cddl => prv.cddl} (77%) rename spec/format/{private-key.texi => prv.texi} (55%) rename spec/format/{cer-load.cddl => pub-load.cddl} (94%) rename spec/format/{cer-sig-tbs.cddl => pub-sig-tbs.cddl} (69%) rename spec/format/{cer.texi => pub.texi} (53%) diff --git a/go/cm/algo.go b/go/cm/algo.go new file mode 100644 index 0000000..94b0da7 --- /dev/null +++ b/go/cm/algo.go @@ -0,0 +1,44 @@ +// GoKEKS/CM -- KEKS-encoded cryptographic messages +// Copyright (C) 2024-2025 Sergey Matveev +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation, version 3 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this program. If not, see . + +package cm + +import ( + "go.cypherpunks.su/keks" + ed25519blake2b "go.cypherpunks.su/keks/cm/ed25519-blake2b" + "go.cypherpunks.su/keks/cm/gost" + mceliece6960119x25519 "go.cypherpunks.su/keks/cm/mceliece6960119-x25519" + sntrup4591761x25519 "go.cypherpunks.su/keks/cm/sntrup4591761-x25519" +) + +const ( + BalloonBLAKE2bHKDF = "balloon-blake2b-hkdf" + ChaCha20Poly1305 = "chacha20poly1305" + ClassicMcEliece6960119X25519 = mceliece6960119x25519.ClassicMcEliece6960119X25519 + ClassicMcEliece6960119X25519HKDFSHAKE256 = mceliece6960119x25519.ClassicMcEliece6960119X25519HKDFSHAKE256 + Ed25519BLAKE2b = ed25519blake2b.Ed25519BLAKE2b + Ed25519PhBLAKE2b = ed25519blake2b.Ed25519PhBLAKE2b + Ed25519PhBLAKE2bMerkle = ed25519blake2b.Ed25519PhBLAKE2bMerkle + GOST3410256A = gost.GOST3410256A + GOST3410256AMerkle = gost.GOST3410256AMerkle + GOST3410512C = gost.GOST3410512C + GOST3410512CMerkle = gost.GOST3410512CMerkle + SNTRUP4591761X25519 = sntrup4591761x25519.SNTRUP4591761X25519 + SNTRUP4591761X25519HKDFBLAKE2b = sntrup4591761x25519.SNTRUP4591761X25519HKDFBLAKE2b + + EncryptedMagic = keks.Magic("cm/encrypted") + HashedMagic = keks.Magic("cm/hashed") + PrvMagic = keks.Magic("cm/prv") +) diff --git a/go/pki/av.go b/go/cm/av.go similarity index 84% rename from go/pki/av.go rename to go/cm/av.go index b267941..fa920cb 100644 --- a/go/pki/av.go +++ b/go/cm/av.go @@ -1,4 +1,4 @@ -// GoKEKS/PKI -- PKI-related capabilities based on KEKS encoded formats +// GoKEKS/CM -- KEKS-encoded cryptographic messages // Copyright (C) 2024-2025 Sergey Matveev // // This program is free software: you can redistribute it and/or modify @@ -13,7 +13,7 @@ // You should have received a copy of the GNU Lesser General Public // License along with this program. If not, see . -package pki +package cm import ( "bytes" @@ -22,7 +22,7 @@ import ( "github.com/google/uuid" "go.cypherpunks.su/keks" - pkihash "go.cypherpunks.su/keks/pki/hash" + cmhash "go.cypherpunks.su/keks/cm/hash" ) // Algorithm-value often used structure. @@ -38,11 +38,11 @@ func (av *AV) Id() (id uuid.UUID) { var hasher hash.Hash switch av.A { case Ed25519BLAKE2b, SNTRUP4591761X25519: - hasher = pkihash.ByName(pkihash.BLAKE2b256) + hasher = cmhash.ByName(cmhash.BLAKE2b256) case GOST3410256A, GOST3410512C: - hasher = pkihash.ByName(pkihash.Streebog256) + hasher = cmhash.ByName(cmhash.Streebog256) case ClassicMcEliece6960119X25519: - hasher = pkihash.ByName(pkihash.SHAKE128) + hasher = cmhash.ByName(cmhash.SHAKE128) default: id = uuid.Nil return diff --git a/go/pki/cmd/enctool/chapoly.go b/go/cm/cmd/enctool/chapoly.go similarity index 98% rename from go/pki/cmd/enctool/chapoly.go rename to go/cm/cmd/enctool/chapoly.go index a8aa955..67fecc7 100644 --- a/go/pki/cmd/enctool/chapoly.go +++ b/go/cm/cmd/enctool/chapoly.go @@ -1,4 +1,4 @@ -// enctool -- dealing with KEKS-encoded pki-encrypted utility +// enctool -- dealing with KEKS-encoded cm-encrypted utility // Copyright (C) 2024-2025 Sergey Matveev // // This program is free software: you can redistribute it and/or modify diff --git a/go/pki/cmd/enctool/main.go b/go/cm/cmd/enctool/main.go similarity index 90% rename from go/pki/cmd/enctool/main.go rename to go/cm/cmd/enctool/main.go index 5533ac0..df1b304 100644 --- a/go/pki/cmd/enctool/main.go +++ b/go/cm/cmd/enctool/main.go @@ -1,4 +1,4 @@ -// enctool -- dealing with KEKS-encoded pki-encrypted utility +// enctool -- dealing with KEKS-encoded cm-encrypted utility // Copyright (C) 2024-2025 Sergey Matveev // // This program is free software: you can redistribute it and/or modify @@ -38,17 +38,17 @@ import ( "golang.org/x/term" "go.cypherpunks.su/keks" - "go.cypherpunks.su/keks/pki" - pkihash "go.cypherpunks.su/keks/pki/hash" - "go.cypherpunks.su/keks/pki/utils" + "go.cypherpunks.su/keks/cm" + cmhash "go.cypherpunks.su/keks/cm/hash" + "go.cypherpunks.su/keks/cm/utils" "go.cypherpunks.su/keks/types" ) const ( BalloonSaltLen = 8 - BalloonHKDFSalt = "keks/pki/encrypted/balloon-blake2b-hkdf" - SNTRUP4591761X25519Salt = "keks/pki/encrypted/sntrup4591761-x25519-hkdf-blake2b" - ClassicMcEliece6960119X25519Salt = "keks/pki/encrypted/mceliece6960119-x25519-hkdf-shake256" + BalloonHKDFSalt = "keks/cm/encrypted/balloon-blake2b-hkdf" + SNTRUP4591761X25519Salt = "keks/cm/encrypted/sntrup4591761-x25519-hkdf-blake2b" + ClassicMcEliece6960119X25519Salt = "keks/cm/encrypted/mceliece6960119-x25519-hkdf-shake256" BindFdNum = 3 + 1 ) @@ -122,18 +122,18 @@ func main() { balloonT := flag.Int("balloon-t", 3, "Balloon's time cost") balloonP := flag.Int("balloon-p", 2, "Balloon's number of threads") doDecrypt := flag.Bool("d", false, "Decrypt") - var pubs []*pki.Pub - flag.Func("cer", "Path to certificate to encrypt to", func(v string) error { - signed, err := pki.CerParse(utils.MustReadFile(v)) + var pubs []*cm.Pub + flag.Func("pub", "Path to public key to encrypt to", func(v string) error { + signed, err := cm.PubParse(utils.MustReadFile(v)) if err != nil { return err } - load := signed.CerLoad() + load := signed.PubLoad() if load.KU == nil { log.Println(v, "does not have key usages") } else { - if _, ok := (*load.KU)[pki.KUKEM]; !ok { - log.Println(v, "does not have", pki.KUKEM, "key usage") + if _, ok := (*load.KU)[cm.KUKEM]; !ok { + log.Println(v, "does not have", cm.KUKEM, "key usage") } } if len(load.Pub) != 1 { @@ -142,13 +142,13 @@ func main() { pubs = append(pubs, &load.Pub[0]) return err }) - var prvs []*pki.AV + var prvs []*cm.AV flag.Func("prv", "Our private keys for decryption", func(v string) (err error) { magic, data := keks.StripMagic(utils.MustReadFile(v)) - if magic == "" || magic != pki.PrvKeyMagic { + if magic == "" || magic != cm.PrvMagic { return errors.New("wrong magic") } - var av pki.AV + var av cm.AV d := keks.NewDecoderFromBytes(data, &keks.DecodeOpts{MaxStrLen: 1 << 16}) if err = d.DecodeStruct(&av); err != nil { return err @@ -171,7 +171,7 @@ func main() { if t != types.Magic { log.Fatal("no magic met") } - if d.Iter().Magic() != pki.EncryptedMagic { + if d.Iter().Magic() != cm.EncryptedMagic { log.Fatal("wrong magic") } } @@ -190,7 +190,7 @@ func main() { bindFd.WriteString(encrypted.Bind.String() + "\n") bindFd.Close() } - if encrypted.DEM.A != pki.ChaCha20Poly1305 { + if encrypted.DEM.A != cm.ChaCha20Poly1305 { log.Fatalln("unsupported DEM:", encrypted.DEM.A) } if len(encrypted.KEM) == 0 { @@ -198,7 +198,7 @@ func main() { } for kemIdx, kem := range encrypted.KEM { switch kem.A { - case pki.BalloonBLAKE2bHKDF: + case cm.BalloonBLAKE2bHKDF: if !*passphrase { log.Println(kemIdx, kem.A, "skipping because no -passwd") continue @@ -228,7 +228,7 @@ func main() { } cek = cekp } - case pki.SNTRUP4591761X25519HKDFBLAKE2b: + case cm.SNTRUP4591761X25519HKDFBLAKE2b: if len(prvs) == 0 { log.Println(kemIdx, kem.A, "skipping because no -prv") continue @@ -297,7 +297,7 @@ func main() { cek = cekp } } - case pki.ClassicMcEliece6960119X25519HKDFSHAKE256: + case cm.ClassicMcEliece6960119X25519HKDFSHAKE256: if len(prvs) == 0 { log.Println(kemIdx, kem.A, "skipping because no -prv") continue @@ -362,7 +362,7 @@ func main() { keyMcEliece, keyX25519, }, []byte{}) var kek []byte - kek, err = hkdf.Extract(pkihash.NewSHAKE256, + kek, err = hkdf.Extract(cmhash.NewSHAKE256, ikm, []byte(ClassicMcEliece6960119X25519Salt)) if err != nil { log.Fatal(err) @@ -428,7 +428,7 @@ func main() { log.Fatal(err) } kem := KEM{ - A: pki.BalloonBLAKE2bHKDF, + A: cm.BalloonBLAKE2bHKDF, Salt: &salt, Cost: &BalloonCost{ S: uint64(*balloonS), @@ -455,7 +455,7 @@ func main() { } for _, pub := range pubs { switch pub.A { - case pki.SNTRUP4591761X25519: + case cm.SNTRUP4591761X25519: if len(pub.V) != sntrup4591761.PublicKeySize+32 { log.Fatalln("invalid public keys len") } @@ -488,7 +488,7 @@ func main() { if err != nil { log.Fatal(err) } - kem := KEM{A: pki.SNTRUP4591761X25519HKDFBLAKE2b} + kem := KEM{A: cm.SNTRUP4591761X25519HKDFBLAKE2b} encap := append(ciphertext[:], ourPubX25519.Bytes()...) kem.Encap = &encap { @@ -512,7 +512,7 @@ func main() { kem.To = &pub.Id } kems = append(kems, kem) - case pki.ClassicMcEliece6960119X25519: + case cm.ClassicMcEliece6960119X25519: scheme := mceliece6960119.Scheme() if len(pub.V) != scheme.PublicKeySize()+32 { log.Fatalln("invalid public keys len") @@ -547,7 +547,7 @@ func main() { if err != nil { log.Fatal(err) } - kem := KEM{A: pki.ClassicMcEliece6960119X25519HKDFSHAKE256} + kem := KEM{A: cm.ClassicMcEliece6960119X25519HKDFSHAKE256} encap := append(ciphertext[:], ourPubX25519.Bytes()...) kem.Encap = &encap { @@ -557,7 +557,7 @@ func main() { keyMcEliece[:], keyX25519, }, []byte{}) var kek []byte - kek, err = hkdf.Extract(pkihash.NewSHAKE256, + kek, err = hkdf.Extract(cmhash.NewSHAKE256, ikm, []byte(ClassicMcEliece6960119X25519Salt)) if err != nil { log.Fatal(err) @@ -580,13 +580,13 @@ func main() { } { var hdr bytes.Buffer - if _, err = keks.Encode(&hdr, pki.EncryptedMagic, nil); err != nil { + if _, err = keks.Encode(&hdr, cm.EncryptedMagic, nil); err != nil { log.Fatal(err) } if _, err = keks.Encode(&hdr, &Encrypted{ Bind: binding, KEM: kems, - DEM: DEM{A: pki.ChaCha20Poly1305}, + DEM: DEM{A: cm.ChaCha20Poly1305}, }, nil); err != nil { log.Fatal(err) } diff --git a/go/pki/cmd/enctool/usage.go b/go/cm/cmd/enctool/usage.go similarity index 75% rename from go/pki/cmd/enctool/usage.go rename to go/cm/cmd/enctool/usage.go index 520d899..58fccfc 100644 --- a/go/pki/cmd/enctool/usage.go +++ b/go/cm/cmd/enctool/usage.go @@ -1,4 +1,4 @@ -// enctool -- dealing with KEKS-encoded pki-encrypted utility +// enctool -- dealing with KEKS-encoded cm-encrypted utility // Copyright (C) 2024-2025 Sergey Matveev // // This program is free software: you can redistribute it and/or modify @@ -23,11 +23,12 @@ import ( func usage() { fmt.Fprintf(os.Stderr, `Usage: - Encrypt to recipient: - enctool -cer CER [-include-to] [-bind UUID] DATA.encrypted [4>bind.value] + Encrypt to recipient(s): + enctool -pub PUB [-pub ...] [-include-to] [-bind UUID] + DATA.encrypted [4>bind.value] Encrypt on passphrase: - enctool -p [-bind UUID] DATA.encrypted [4>bind.value] - [-balloon-s X] [-balloon-t X] [-balloon-p X] + enctool -p [-bind UUID] [-balloon-s X] [-balloon-t X] [-balloon-p X] + DATA.encrypted [4>bind.value] Decrypt by providing possible KEMs: enctool -d [-p] [-prv PRV ...] DATA [4>bind.value] diff --git a/go/pki/cmd/hshtool/main.go b/go/cm/cmd/hshtool/main.go similarity index 58% rename from go/pki/cmd/hshtool/main.go rename to go/cm/cmd/hshtool/main.go index d62136f..eab2399 100644 --- a/go/pki/cmd/hshtool/main.go +++ b/go/cm/cmd/hshtool/main.go @@ -11,42 +11,42 @@ import ( "go.cypherpunks.su/gogost/v6/gost34112012256" "go.cypherpunks.su/gogost/v6/gost34112012512" - ed25519blake2b "go.cypherpunks.su/keks/pki/ed25519-blake2b" - "go.cypherpunks.su/keks/pki/gost" - pkihash "go.cypherpunks.su/keks/pki/hash" - "go.cypherpunks.su/keks/pki/hash/merkle" + ed25519blake2b "go.cypherpunks.su/keks/cm/ed25519-blake2b" + "go.cypherpunks.su/keks/cm/gost" + cmhash "go.cypherpunks.su/keks/cm/hash" + "go.cypherpunks.su/keks/cm/hash/merkle" ) func main() { workers := flag.Int("p", runtime.NumCPU(), "Parallel workers") chunkLenK := flag.Int("c", merkle.DefaultChunkLen/1024, "Chunk size, KiB") - algo := flag.String("a", pkihash.BLAKE2b, "Algorithm to use") + algo := flag.String("a", cmhash.BLAKE2b, "Algorithm to use") list := flag.Bool("list", false, "List available algorithms") mmap := flag.String("mmap", "", "Use that mmap-ed file instead of stdin") flag.Parse() if *list { - fmt.Println(pkihash.BLAKE2bMerkle) - fmt.Println(pkihash.SHA2512 + "-merkle") - fmt.Println(pkihash.SHAKE128Merkle) - fmt.Println(pkihash.SHAKE256Merkle) - fmt.Println(pkihash.Streebog256Merkle) - fmt.Println(pkihash.Streebog512Merkle) + fmt.Println(cmhash.BLAKE2bMerkle) + fmt.Println(cmhash.SHA2512 + "-merkle") + fmt.Println(cmhash.SHAKE128Merkle) + fmt.Println(cmhash.SHAKE256Merkle) + fmt.Println(cmhash.Streebog256Merkle) + fmt.Println(cmhash.Streebog512Merkle) return } chunkLen := 1024 * *chunkLenK var hasher *merkle.Hasher switch *algo { - case pkihash.BLAKE2bMerkle: + case cmhash.BLAKE2bMerkle: hasher = ed25519blake2b.NewMerkleHasher(chunkLen, *workers).(*merkle.Hasher) - case pkihash.SHA2512 + "-merkle": + case cmhash.SHA2512 + "-merkle": hasher = merkle.NewHasherPrefixed(sha512.New, chunkLen, *workers) - case pkihash.SHAKE128Merkle: - hasher = pkihash.NewSHAKE128MerkleHasher(chunkLen, *workers).(*merkle.Hasher) - case pkihash.SHAKE256Merkle: - hasher = pkihash.NewSHAKE256MerkleHasher(chunkLen, *workers).(*merkle.Hasher) - case pkihash.Streebog256Merkle: + case cmhash.SHAKE128Merkle: + hasher = cmhash.NewSHAKE128MerkleHasher(chunkLen, *workers).(*merkle.Hasher) + case cmhash.SHAKE256Merkle: + hasher = cmhash.NewSHAKE256MerkleHasher(chunkLen, *workers).(*merkle.Hasher) + case cmhash.Streebog256Merkle: hasher = gost.NewMerkleHasher(gost34112012256.New, chunkLen, *workers).(*merkle.Hasher) - case pkihash.Streebog512Merkle: + case cmhash.Streebog512Merkle: hasher = gost.NewMerkleHasher(gost34112012512.New, chunkLen, *workers).(*merkle.Hasher) default: log.Fatal("unknown -a") diff --git a/go/cm/cmd/keytool/basic.t b/go/cm/cmd/keytool/basic.t new file mode 100755 index 0000000..913ff63 --- /dev/null +++ b/go/cm/cmd/keytool/basic.t @@ -0,0 +1,55 @@ +#!/bin/sh + +test_description="Check that basic GOST-related functionality works" +. $SHARNESS_TEST_SRCDIR/sharness.sh + +TMPDIR=${TMPDIR:-/tmp} + +echo "gost3410-512C gost3410-256A +ed25519-blake2b ed25519-blake2b" | while read caAlgo eeAlgo ; do + +subj="-subj CN=CA -subj C=RU" +test_expect_success "$caAlgo: CA load generation" "keytool \ + -algo $caAlgo \ + -ku sig $subj \ + -prv $TMPDIR/ca.prv -pub $TMPDIR/ca.pub" +test_expect_success "$caAlgo: CA generation" "keytool \ + -pub $TMPDIR/ca.pub \ + -ca-prv $TMPDIR/ca.prv -ca-pub $TMPDIR/ca.pub" +test_expect_success "$caAlgo: CA regeneration" "keytool \ + -pub $TMPDIR/ca.pub \ + -ca-prv $TMPDIR/ca.prv -ca-pub $TMPDIR/ca.pub" +test_expect_success "$caAlgo: CA self-signature" "keytool \ + -ca-pub $TMPDIR/ca.pub \ + -pub $TMPDIR/ca.pub \ + -verify" + +subj="-subj CN=SubCA -subj C=RU" +test_expect_success "$eeAlgo: SubCA load generation" "keytool \ + -algo $eeAlgo \ + -ku sig $subj \ + -prv $TMPDIR/subca.prv -pub $TMPDIR/subca.pub" +test_expect_success "$eeAlgo: SubCA generation" "keytool \ + -pub $TMPDIR/subca.pub \ + -ca-pub $TMPDIR/ca.pub -ca-prv $TMPDIR/ca.prv" +test_expect_success "$eeAlgo: SubCA signature" "keytool \ + -ca-pub $TMPDIR/ca.pub \ + -pub $TMPDIR/subca.pub \ + -verify" + +subj="-subj CN=EE -subj C=RU" +test_expect_success "$eeAlgo: EE load generation" "keytool \ + -algo $eeAlgo $subj \ + -prv $TMPDIR/ee.prv -pub $TMPDIR/ee.pub" +test_expect_success "$eeAlgo: EE generation" "keytool \ + -ca-prv $TMPDIR/subca.prv -ca-pub $TMPDIR/subca.pub \ + -pub $TMPDIR/ee.pub" +test_expect_success "$eeAlgo: EE chain" "keytool \ + -ca-pub $TMPDIR/ca.pub \ + -ca-pub $TMPDIR/subca.pub \ + -pub $TMPDIR/ee.pub \ + -verify" + +done + +test_done diff --git a/go/pki/cmd/certool/main.go b/go/cm/cmd/keytool/main.go similarity index 60% rename from go/pki/cmd/certool/main.go rename to go/cm/cmd/keytool/main.go index ccd11dd..5822ace 100644 --- a/go/pki/cmd/certool/main.go +++ b/go/cm/cmd/keytool/main.go @@ -1,4 +1,4 @@ -// certool -- dealing with KEKS-encoded certificates utility +// keytool -- dealing with KEKS-encoded keypairs utility // Copyright (C) 2024-2025 Sergey Matveev // // This program is free software: you can redistribute it and/or modify @@ -27,13 +27,13 @@ import ( "time" "go.cypherpunks.su/keks" - "go.cypherpunks.su/keks/pki" - ed25519blake2b "go.cypherpunks.su/keks/pki/ed25519-blake2b" - "go.cypherpunks.su/keks/pki/gost" - mceliece6960119x25519 "go.cypherpunks.su/keks/pki/mceliece6960119-x25519" - "go.cypherpunks.su/keks/pki/sign" - sntrup4591761x25519 "go.cypherpunks.su/keks/pki/sntrup4591761-x25519" - "go.cypherpunks.su/keks/pki/utils" + "go.cypherpunks.su/keks/cm" + ed25519blake2b "go.cypherpunks.su/keks/cm/ed25519-blake2b" + "go.cypherpunks.su/keks/cm/gost" + mceliece6960119x25519 "go.cypherpunks.su/keks/cm/mceliece6960119-x25519" + "go.cypherpunks.su/keks/cm/sign" + sntrup4591761x25519 "go.cypherpunks.su/keks/cm/sntrup4591761-x25519" + "go.cypherpunks.su/keks/cm/utils" ) func main() { @@ -60,25 +60,25 @@ func main() { return nil }, ) - var issuingCers []string + var issuingPubs []string flag.Func( - "ca-cer", - "Add CA certificate to the chain", + "ca-pub", + "Add certification public key to the chain", func(v string) error { - issuingCers = append(issuingCers, v) + 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 certificate, days") - algo := flag.String("algo", pki.Ed25519BLAKE2b, "Public key algorithm") + "Lifetime of the certification, days") + algo := flag.String("algo", cm.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") - cerPath := flag.String("cer", "", "Path to certificate file") - verify := flag.Bool("verify", false, "Verify provided -cer with -ca-cer") + 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") flag.Parse() @@ -86,11 +86,11 @@ func main() { if *doList { algos := []string{ - pki.Ed25519BLAKE2b, - pki.GOST3410256A, - pki.GOST3410512C, - pki.SNTRUP4591761X25519, - pki.ClassicMcEliece6960119X25519, + cm.Ed25519BLAKE2b, + cm.GOST3410256A, + cm.GOST3410512C, + cm.SNTRUP4591761X25519, + cm.ClassicMcEliece6960119X25519, } sort.Strings(algos) for _, s := range algos { @@ -99,8 +99,8 @@ func main() { return } - if *cerPath == "" { - log.Fatal("no -cer is set") + if *pubPath == "" { + log.Fatal("no -pub is set") } var err error @@ -116,32 +116,32 @@ func main() { till := since.Add(time.Duration(*lifetime) * 24 * time.Hour) var caPrv sign.Iface - var caCers []*pki.Signed - for _, issuingCer := range issuingCers { - var signed *pki.Signed - signed, err = pki.CerParse(utils.MustReadFile(issuingCer)) + var caPubs []*cm.Signed + for _, issuingPub := range issuingPubs { + var signed *cm.Signed + signed, err = cm.PubParse(utils.MustReadFile(issuingPub)) if err != nil { log.Fatal(err) } - caCers = append(caCers, signed) + caPubs = append(caPubs, signed) } - if len(caCers) > 0 && !*verify { + if len(caPubs) > 0 && !*verify { if *issuingPrv == "" { log.Fatal("no -ca-prv is set") } - caPrv, _, err = pki.PrvParse(utils.MustReadFile(*issuingPrv)) + caPrv, _, err = cm.PrvParse(utils.MustReadFile(*issuingPrv)) if err != nil { log.Fatal(err) } } if *verify { - var signed *pki.Signed - signed, err = pki.CerParse(utils.MustReadFile(*cerPath)) + var signed *cm.Signed + signed, err = cm.PubParse(utils.MustReadFile(*pubPath)) if err != nil { log.Fatal(err) } - err = signed.CerVerify(caCers, time.Now().UTC()) + err = signed.CertificationVerify(caPubs, time.Now().UTC()) if err != nil { log.Fatal(err) } @@ -149,14 +149,14 @@ func main() { } var prvRaw []byte - var cerLoad *pki.CerLoad - var signed *pki.Signed + var pubLoad *cm.PubLoad + var signed *cm.Signed if caPrv != nil { - signed, err = pki.CerParse(utils.MustReadFile(*cerPath)) + signed, err = cm.PubParse(utils.MustReadFile(*pubPath)) if err != nil { log.Fatal(err) } - cerLoad = signed.CerLoad() + pubLoad = signed.PubLoad() } else { if len(subj) == 0 { log.Fatal("no -subj is set") @@ -166,13 +166,13 @@ func main() { log.Fatal("no -prv is set") } switch *algo { - case pki.Ed25519BLAKE2b: + case cm.Ed25519BLAKE2b: _, prvRaw, pub, err = ed25519blake2b.NewKeypair() - case pki.GOST3410256A, pki.GOST3410512C: + case cm.GOST3410256A, cm.GOST3410512C: _, prvRaw, pub, err = gost.NewKeypair(*algo) - case pki.SNTRUP4591761X25519: + case cm.SNTRUP4591761X25519: prvRaw, pub, err = sntrup4591761x25519.NewKeypair() - case pki.ClassicMcEliece6960119X25519: + case cm.ClassicMcEliece6960119X25519: prvRaw, pub, err = mceliece6960119x25519.NewKeypair() default: err = errors.New("unknown -algo specified") @@ -182,10 +182,10 @@ func main() { } { var buf bytes.Buffer - if _, err = keks.Encode(&buf, pki.PrvKeyMagic, nil); err != nil { + if _, err = keks.Encode(&buf, cm.PrvMagic, nil); err != nil { log.Fatal(err) } - if _, err = keks.Encode(&buf, pki.AV{A: *algo, V: prvRaw}, nil); err != nil { + if _, err = keks.Encode(&buf, cm.AV{A: *algo, V: prvRaw}, nil); err != nil { log.Fatal(err) } err = os.WriteFile(*prvPath, buf.Bytes(), 0o600) @@ -194,26 +194,26 @@ func main() { } } { - pubMap := pki.Pub{A: *algo, V: pub} + pubMap := cm.Pub{A: *algo, V: pub} { - av := pki.AV{A: *algo, V: pub} + av := cm.AV{A: *algo, V: pub} pubMap.Id = av.Id() } - cerLoad = &pki.CerLoad{Subj: subj, Pub: []pki.Pub{pubMap}} + pubLoad = &cm.PubLoad{Subj: subj, Pub: []cm.Pub{pubMap}} } if len(ku) > 0 { - cerLoad.KU = &ku + pubLoad.KU = &ku } } { - cerLoadAny := any(cerLoad) - signed = &pki.Signed{Load: pki.SignedLoad{T: "cer", V: &cerLoadAny}} + pubLoadAny := any(pubLoad) + signed = &cm.Signed{Load: cm.SignedLoad{T: "pub", V: &pubLoadAny}} } if caPrv != nil { - if err = signed.CerIssueWith( - caCers[0].CerLoad(), caPrv, since, till, + if err = signed.CertifyWith( + caPubs[0].PubLoad(), caPrv, since, till, ); err != nil { log.Fatal(err) } @@ -221,13 +221,13 @@ func main() { { var buf bytes.Buffer - if _, err = keks.Encode(&buf, pki.CerMagic, nil); err != nil { + if _, err = keks.Encode(&buf, cm.PubMagic, nil); err != nil { log.Fatal(err) } if _, err = keks.Encode(&buf, signed, nil); err != nil { log.Fatal(err) } - if err = os.WriteFile(*cerPath, buf.Bytes(), 0o666); err != nil { + if err = os.WriteFile(*pubPath, buf.Bytes(), 0o666); err != nil { log.Fatal(err) } } diff --git a/go/pki/cmd/certool/usage.go b/go/cm/cmd/keytool/usage.go similarity index 77% rename from go/pki/cmd/certool/usage.go rename to go/cm/cmd/keytool/usage.go index 344fbd3..fb72ddf 100644 --- a/go/pki/cmd/certool/usage.go +++ b/go/cm/cmd/keytool/usage.go @@ -1,4 +1,4 @@ -// certool -- dealing with KEKS-encoded certificates utility +// keytool -- dealing with KEKS-encoded keypairs utility // Copyright (C) 2024-2025 Sergey Matveev // // This program is free software: you can redistribute it and/or modify @@ -23,14 +23,14 @@ import ( func usage() { fmt.Fprintf(os.Stderr, `Usage: - Generate certificate load: - certool -prv PRV -cer CER [-algo ALGO] [-ku KU ...] \ + Generate public key load: + keytool -prv PRV -pub PUB [-algo ALGO] [-ku KU ...] \ -subj K=V [-subj K=V ...] Sign certificate: - certool -cer CER -ca-prv CA-PRV -ca-cer CA-CER \ + keytool -pub PUB -ca-prv CA-PRV -ca-pub CA-pub \ [-lifetime DAYS] [-since DATE] Verify certificate: - certool -verify -cer CER CA-PRV -ca-cer CA-CER0 [-ca-cer CA-CER1 ...] + keytool -verify -pub PUB CA-PRV -ca-pub CA-pub0 [-ca-pub CA-pub1 ...] `) flag.PrintDefaults() diff --git a/go/pki/cmd/sigtool/basic.t b/go/cm/cmd/sigtool/basic.t similarity index 64% rename from go/pki/cmd/sigtool/basic.t rename to go/cm/cmd/sigtool/basic.t index 399c049..e4931d6 100755 --- a/go/pki/cmd/sigtool/basic.t +++ b/go/cm/cmd/sigtool/basic.t @@ -11,40 +11,40 @@ ed25519-blake2b" | while read algo ; do subj="-subj what=ever" typ="some-different-type" -test_expect_success "$algo: cer generation" "certool \ +test_expect_success "$algo: pub generation" "keytool \ -algo $algo -ku sig $subj \ - -prv $TMPDIR/sign.prv -cer $TMPDIR/sign.cer" + -prv $TMPDIR/sign.prv -pub $TMPDIR/sign.pub" dd if=/dev/urandom of=$TMPDIR/sign.data bs=300K count=1 2>/dev/null bind="-encrypted-binding $(uuidgen)" badBind="-encrypted-binding $(uuidgen)" test_expect_success "$algo: signing" "sigtool \ - -prv $TMPDIR/sign.prv -cer $TMPDIR/sign.cer -type $typ \ + -prv $TMPDIR/sign.prv -pub $TMPDIR/sign.pub -type $typ \ $bind <$TMPDIR/sign.data >$TMPDIR/sign.sig" test_expect_success "$algo: verifying" "sigtool \ - -verify -cer $TMPDIR/sign.cer -type $typ \ + -verify -pub $TMPDIR/sign.pub -type $typ \ <$TMPDIR/sign.sig >$TMPDIR/sign.data.got" test_expect_success "$algo: comparing" \ "test_cmp $TMPDIR/sign.data $TMPDIR/sign.data.got" test_expect_success "$algo: differing type" "! sigtool \ - -verify -cer $TMPDIR/sign.cer <$TMPDIR/sign.sig >/dev/null" + -verify -pub $TMPDIR/sign.pub <$TMPDIR/sign.sig >/dev/null" test_expect_success "$algo: good bind" "! sigtool \ - -verify -cer $TMPDIR/sign.cer $bind <$TMPDIR/sign.sig >/dev/null" + -verify -pub $TMPDIR/sign.pub $bind <$TMPDIR/sign.sig >/dev/null" test_expect_success "$algo: bad bind" "! sigtool \ - -verify -cer $TMPDIR/sign.cer $badBind <$TMPDIR/sign.sig >/dev/null" + -verify -pub $TMPDIR/sign.pub $badBind <$TMPDIR/sign.sig >/dev/null" test_expect_success "$algo: detached signing" "sigtool -detached \ - -prv $TMPDIR/sign.prv -cer $TMPDIR/sign.cer -type $typ \ + -prv $TMPDIR/sign.prv -pub $TMPDIR/sign.pub -type $typ \ <$TMPDIR/sign.data >$TMPDIR/sign.sig" test_expect_success "$algo: detached verifying" \ "cat $TMPDIR/sign.sig $TMPDIR/sign.data | - sigtool -detached -verify -cer $TMPDIR/sign.cer -type $typ" + sigtool -detached -verify -pub $TMPDIR/sign.pub -type $typ" test_expect_success "$algo: differing type" "! sigtool -detached \ - -verify -cer $TMPDIR/sign.cer <$TMPDIR/sign.sig >/dev/null" + -verify -pub $TMPDIR/sign.pub <$TMPDIR/sign.sig >/dev/null" test_expect_success "$algo: good bind" "! sigtool -detached \ - -verify -cer $TMPDIR/sign.cer $bind <$TMPDIR/sign.sig >/dev/null" + -verify -pub $TMPDIR/sign.pub $bind <$TMPDIR/sign.sig >/dev/null" test_expect_success "$algo: bad bind" "! sigtool -detached \ - -verify -cer $TMPDIR/sign.cer $badBind <$TMPDIR/sign.sig >/dev/null" + -verify -pub $TMPDIR/sign.pub $badBind <$TMPDIR/sign.sig >/dev/null" done diff --git a/go/pki/cmd/sigtool/main.go b/go/cm/cmd/sigtool/main.go similarity index 82% rename from go/pki/cmd/sigtool/main.go rename to go/cm/cmd/sigtool/main.go index 592e1f0..1ed47f8 100644 --- a/go/pki/cmd/sigtool/main.go +++ b/go/cm/cmd/sigtool/main.go @@ -1,4 +1,4 @@ -// sigtool -- dealing with KEKS-encoded pki-signed utility +// sigtool -- dealing with KEKS-encoded cm-signed utility // Copyright (C) 2024-2025 Sergey Matveev // // This program is free software: you can redistribute it and/or modify @@ -28,10 +28,10 @@ import ( "github.com/google/uuid" "go.cypherpunks.su/keks" - "go.cypherpunks.su/keks/pki" - pkihash "go.cypherpunks.su/keks/pki/hash" - "go.cypherpunks.su/keks/pki/sign" - "go.cypherpunks.su/keks/pki/utils" + "go.cypherpunks.su/keks/cm" + cmhash "go.cypherpunks.su/keks/cm/hash" + "go.cypherpunks.su/keks/cm/sign" + "go.cypherpunks.su/keks/cm/utils" "go.cypherpunks.su/keks/types" ) @@ -40,7 +40,7 @@ const BlobChunkLen = 128 * 1024 func main() { flag.Usage = usage prvPath := flag.String("prv", "", "Path to private key file") - cerPath := flag.String("cer", "", "Path to certificate 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") encryptedBindingHex := flag.String("encrypted-binding", "", @@ -61,10 +61,10 @@ func main() { } } - if *cerPath == "" { - log.Fatal("no -cer is set") + if *pubPath == "" { + log.Fatal("no -pub is set") } - cer, err := pki.CerParse(utils.MustReadFile(*cerPath)) + pub, err := cm.PubParse(utils.MustReadFile(*pubPath)) if err != nil { log.Fatal(err) } @@ -77,15 +77,15 @@ func main() { if err != nil { log.Fatal(err) } - if t != types.Magic || decoder.Iter().Magic() != pki.SignedMagic { + if t != types.Magic || decoder.Iter().Magic() != cm.SignedMagic { log.Fatal("wrong magic") } decoder = keks.NewDecoderFromReader(stdin, nil) if _, err = decoder.Parse(); err != nil { log.Fatal(err) } - var prehash pki.SignedPrehash - var signed pki.Signed + var prehash cm.SignedPrehash + var signed cm.Signed err = decoder.UnmarshalStruct(&prehash) var hasher hash.Hash if err == nil && prehash.T == sign.PrehashT { @@ -96,7 +96,7 @@ func main() { log.Fatal("prehash: currently only single signature support") } for algo := range prehash.Sigs { - hasher = pkihash.ByName(algo) + hasher = cmhash.ByName(algo) } if hasher == nil { log.Fatal("prehash: unsupported algorithm") @@ -128,7 +128,7 @@ func main() { if err != nil { log.Fatal(err) } - if err = pki.SignedValidate(&signed); err != nil { + if err = cm.SignedValidate(&signed); err != nil { log.Fatal(err) } if len(signed.Sigs) == 0 { @@ -138,7 +138,7 @@ func main() { log.Fatal("prehash: currently only single signature support") } sig := signed.Sigs[0] - signer := cer.CerLoad() + signer := pub.PubLoad() if signed.Load.T != *typ { log.Fatalln("differing load type:", signed.Load.T) } @@ -151,12 +151,12 @@ func main() { } } if prehash.T == "" { - hasher = pkihash.ByName(sig.Sign.A) + hasher = cmhash.ByName(sig.Sign.A) if _, err = io.Copy(hasher, stdin); err != nil { log.Fatal(err) } } - if err = signed.CerCheckSignatureFrom(signer, &hasher); err != nil { + if err = signed.CertificationCheckSignatureFrom(signer, &hasher); err != nil { log.Fatal(err) } } else { @@ -164,7 +164,7 @@ func main() { log.Fatal("no -prv is set") } var signer sign.Iface - signer, _, err = pki.PrvParse(utils.MustReadFile(*prvPath)) + signer, _, err = cm.PrvParse(utils.MustReadFile(*prvPath)) if err != nil { log.Fatal(err) } @@ -177,7 +177,7 @@ func main() { log.Fatal(err) } - if _, err = keks.Encode(os.Stdout, pki.SignedMagic, nil); err != nil { + if _, err = keks.Encode(os.Stdout, cm.SignedMagic, nil); err != nil { log.Fatal(err) } if *detached { @@ -185,7 +185,7 @@ func main() { log.Fatal(err) } } else { - if _, err = keks.Encode(os.Stdout, pki.SignedPrehash{ + if _, err = keks.Encode(os.Stdout, cm.SignedPrehash{ T: sign.PrehashT, Sigs: map[string]*struct{}{signer.Algo(): nil}, }, nil); err != nil { @@ -207,9 +207,9 @@ func main() { log.Fatal(err) } } - var signed pki.Signed + var signed cm.Signed signed.Load.T = *typ - var sigTbs pki.SigTBS + var sigTbs cm.SigTBS if !*noWhen { when := time.Now().UTC().Truncate(time.Millisecond) sigTbs.When = &when @@ -217,7 +217,7 @@ func main() { if encryptedBinding != uuid.Nil { sigTbs.EncryptedBinding = &encryptedBinding } - if err = signed.SignWith(cer.CerLoad(), signer, sigTbs); err != nil { + if err = signed.SignWith(pub.PubLoad(), signer, sigTbs); err != nil { log.Fatal(err) } if _, err = keks.Encode(os.Stdout, signed, nil); err != nil { diff --git a/go/pki/cmd/sigtool/usage.go b/go/cm/cmd/sigtool/usage.go similarity index 75% rename from go/pki/cmd/sigtool/usage.go rename to go/cm/cmd/sigtool/usage.go index c3ad3d6..c38a039 100644 --- a/go/pki/cmd/sigtool/usage.go +++ b/go/cm/cmd/sigtool/usage.go @@ -1,4 +1,4 @@ -// sigtool -- dealing with KEKS-encoded pki-signed utility +// sigtool -- dealing with KEKS-encoded cm-signed utility // Copyright (C) 2024-2025 Sergey Matveev // // This program is free software: you can redistribute it and/or modify @@ -23,10 +23,10 @@ import ( func usage() { fmt.Fprintf(os.Stderr, `Usage: - sigtool -prv PRV -cer CER [-type TYPE] [bind] DATA.signed - sigtool -verify -cer CER [-type TYPE] [bind] DATA - sigtool -detached -prv PRV -cer CER [-type TYPE] [bind] DATA.signature - sigtool -detached -verify -cer CER [-type TYPE] [bind] <(cat DATA.signature DATA) + sigtool -prv PRV -pub PUB [-type TYPE] [bind] DATA.signed + sigtool -verify -pub PUB [-type TYPE] [bind] DATA + sigtool -detached -prv PRV -pub PUB [-type TYPE] [bind] DATA.signature + sigtool -detached -verify -pub PUB [-type TYPE] [bind] <(cat DATA.signature DATA) "bind" is optional -encrypted-binding flag. DATA.signed holds completely encapsulated DATA. diff --git a/go/cm/doc.go b/go/cm/doc.go new file mode 100644 index 0000000..4207e76 --- /dev/null +++ b/go/cm/doc.go @@ -0,0 +1,2 @@ +// GoKEKS/CM -- KEKS-encoded cryptographic messages +package cm diff --git a/go/pki/ed25519-blake2b/.gitignore b/go/cm/ed25519-blake2b/.gitignore similarity index 100% rename from go/pki/ed25519-blake2b/.gitignore rename to go/cm/ed25519-blake2b/.gitignore diff --git a/go/pki/ed25519-blake2b/algo.go b/go/cm/ed25519-blake2b/algo.go similarity index 100% rename from go/pki/ed25519-blake2b/algo.go rename to go/cm/ed25519-blake2b/algo.go diff --git a/go/pki/ed25519-blake2b/clean b/go/cm/ed25519-blake2b/clean similarity index 100% rename from go/pki/ed25519-blake2b/clean rename to go/cm/ed25519-blake2b/clean diff --git a/go/pki/ed25519-blake2b/ed25519-to-blake2b.patch b/go/cm/ed25519-blake2b/ed25519-to-blake2b.patch similarity index 98% rename from go/pki/ed25519-blake2b/ed25519-to-blake2b.patch rename to go/cm/ed25519-blake2b/ed25519-to-blake2b.patch index 69bafad..80d2a25 100644 --- a/go/pki/ed25519-blake2b/ed25519-to-blake2b.patch +++ b/go/cm/ed25519-blake2b/ed25519-to-blake2b.patch @@ -2,7 +2,7 @@ +++ ed25519/ed25519.go 2024-12-03 11:07:51.892841000 +0300 @@ -20,11 +20,12 @@ "crypto" - "go.cypherpunks.su/keks/pki/ed25519-blake2b/edwards25519" + "go.cypherpunks.su/keks/cm/ed25519-blake2b/edwards25519" cryptorand "crypto/rand" - "crypto/sha512" "crypto/subtle" diff --git a/go/pki/ed25519-blake2b/hasher.go b/go/cm/ed25519-blake2b/hasher.go similarity index 91% rename from go/pki/ed25519-blake2b/hasher.go rename to go/cm/ed25519-blake2b/hasher.go index 33762ba..4b7cc3e 100644 --- a/go/pki/ed25519-blake2b/hasher.go +++ b/go/cm/ed25519-blake2b/hasher.go @@ -1,4 +1,4 @@ -// GoKEKS/PKI -- PKI-related capabilities based on KEKS encoded formats +// GoKEKS/CM -- KEKS-encoded cryptographic messages // Copyright (C) 2024-2025 Sergey Matveev // // This program is free software: you can redistribute it and/or modify @@ -18,7 +18,7 @@ package ed25519blake2b import ( "hash" - "go.cypherpunks.su/keks/pki/hash/merkle" + "go.cypherpunks.su/keks/cm/hash/merkle" "golang.org/x/crypto/blake2b" ) diff --git a/go/pki/ed25519-blake2b/kp.go b/go/cm/ed25519-blake2b/kp.go similarity index 89% rename from go/pki/ed25519-blake2b/kp.go rename to go/cm/ed25519-blake2b/kp.go index 12a51fa..7ec5892 100644 --- a/go/pki/ed25519-blake2b/kp.go +++ b/go/cm/ed25519-blake2b/kp.go @@ -1,4 +1,4 @@ -// GoKEKS/PKI -- PKI-related capabilities based on KEKS encoded formats +// GoKEKS/CM -- KEKS-encoded cryptographic messages // Copyright (C) 2024-2025 Sergey Matveev // // This program is free software: you can redistribute it and/or modify @@ -18,7 +18,7 @@ package ed25519blake2b import ( "crypto/rand" - "go.cypherpunks.su/keks/pki/ed25519-blake2b/ed25519" + "go.cypherpunks.su/keks/cm/ed25519-blake2b/ed25519" ) func NewKeypair() (signer *Signer, prv, pub []byte, err error) { diff --git a/go/pki/ed25519-blake2b/mk-from-go b/go/cm/ed25519-blake2b/mk-from-go similarity index 93% rename from go/pki/ed25519-blake2b/mk-from-go rename to go/cm/ed25519-blake2b/mk-from-go index b53ae56..1c9408c 100755 --- a/go/pki/ed25519-blake2b/mk-from-go +++ b/go/cm/ed25519-blake2b/mk-from-go @@ -4,7 +4,7 @@ # That script copies the library (tested on 1.23.3) and patches it to # use BLAKE2b hash. -modname=go.cypherpunks.su/keks/pki/ed25519-blake2b +modname=go.cypherpunks.su/keks/cm/ed25519-blake2b go mod init $modname dst=$PWD cd $(go env GOROOT)/src diff --git a/go/pki/ed25519-blake2b/signer.go b/go/cm/ed25519-blake2b/signer.go similarity index 92% rename from go/pki/ed25519-blake2b/signer.go rename to go/cm/ed25519-blake2b/signer.go index 069cf20..28acbdf 100644 --- a/go/pki/ed25519-blake2b/signer.go +++ b/go/cm/ed25519-blake2b/signer.go @@ -1,4 +1,4 @@ -// GoKEKS/PKI -- PKI-related capabilities based on KEKS encoded formats +// GoKEKS/CM -- KEKS-encoded cryptographic messages // Copyright (C) 2024-2025 Sergey Matveev // // This program is free software: you can redistribute it and/or modify @@ -22,11 +22,11 @@ import ( "io" "runtime" - "go.cypherpunks.su/keks/pki/ed25519-blake2b/ed25519" - "go.cypherpunks.su/keks/pki/hash/merkle" + "go.cypherpunks.su/keks/cm/ed25519-blake2b/ed25519" + "go.cypherpunks.su/keks/cm/hash/merkle" "golang.org/x/crypto/blake2b" - "go.cypherpunks.su/keks/pki/sign" + "go.cypherpunks.su/keks/cm/sign" ) type Signer struct { diff --git a/go/pki/ed25519-blake2b/verify.go b/go/cm/ed25519-blake2b/verify.go similarity index 91% rename from go/pki/ed25519-blake2b/verify.go rename to go/cm/ed25519-blake2b/verify.go index e7d1ef5..f80d501 100644 --- a/go/pki/ed25519-blake2b/verify.go +++ b/go/cm/ed25519-blake2b/verify.go @@ -1,4 +1,4 @@ -// GoKEKS/PKI -- PKI-related capabilities based on KEKS encoded formats +// GoKEKS/CM -- KEKS-encoded cryptographic messages // Copyright (C) 2024-2025 Sergey Matveev // // This program is free software: you can redistribute it and/or modify @@ -19,7 +19,7 @@ import ( "crypto" "errors" - "go.cypherpunks.su/keks/pki/ed25519-blake2b/ed25519" + "go.cypherpunks.su/keks/cm/ed25519-blake2b/ed25519" ) func Verify(pub, signed, signature []byte) (valid bool, err error) { diff --git a/go/pki/go.mod b/go/cm/go.mod similarity index 69% rename from go/pki/go.mod rename to go/cm/go.mod index a6e8765..e296bd9 100644 --- a/go/pki/go.mod +++ b/go/cm/go.mod @@ -1,10 +1,10 @@ -module go.cypherpunks.su/keks/pki +module go.cypherpunks.su/keks/cm go 1.24 require ( github.com/google/uuid v1.6.0 - go.cypherpunks.su/gogost/v6 v6.0.1 + go.cypherpunks.su/gogost/v6 v6.1.0 ) require ( diff --git a/go/cm/go.sum b/go/cm/go.sum new file mode 100644 index 0000000..55a7d0f --- /dev/null +++ b/go/cm/go.sum @@ -0,0 +1,6 @@ +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +go.cypherpunks.su/balloon/v3 v3.0.0/go.mod h1:ftUPgriajbLsU16feNNHht6cuOwxCK6MGnDK3lLQhgM= +go.cypherpunks.su/gogost/v6 v6.1.0 h1:RJHFxDZ2j/TIfHXGn4AG0fTDg19GEX/oVFAgMvLCIPM= +go.cypherpunks.su/gogost/v6 v6.1.0/go.mod h1:cj9i0r80PN7jrwMqBAWhaY8JetCeg4x5jjnZsVRkaPI= +golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= diff --git a/go/pki/gost/gost.go b/go/cm/gost/gost.go similarity index 93% rename from go/pki/gost/gost.go rename to go/cm/gost/gost.go index dbd743d..71487d2 100644 --- a/go/pki/gost/gost.go +++ b/go/cm/gost/gost.go @@ -1,4 +1,4 @@ -// GoKEKS/PKI -- PKI-related capabilities based on KEKS encoded formats +// GoKEKS/CM -- KEKS-encoded cryptographic messages // Copyright (C) 2024-2025 Sergey Matveev // // This program is free software: you can redistribute it and/or modify diff --git a/go/pki/gost/hasher.go b/go/cm/gost/hasher.go similarity index 89% rename from go/pki/gost/hasher.go rename to go/cm/gost/hasher.go index 13af656..fcd729e 100644 --- a/go/pki/gost/hasher.go +++ b/go/cm/gost/hasher.go @@ -1,4 +1,4 @@ -// GoKEKS/PKI -- PKI-related capabilities based on KEKS encoded formats +// GoKEKS/CM -- KEKS-encoded cryptographic messages // Copyright (C) 2024-2025 Sergey Matveev // // This program is free software: you can redistribute it and/or modify @@ -18,7 +18,7 @@ package gost import ( "hash" - "go.cypherpunks.su/keks/pki/hash/merkle" + "go.cypherpunks.su/keks/cm/hash/merkle" ) const ( diff --git a/go/pki/gost/kp.go b/go/cm/gost/kp.go similarity index 94% rename from go/pki/gost/kp.go rename to go/cm/gost/kp.go index 59db966..2f9334b 100644 --- a/go/pki/gost/kp.go +++ b/go/cm/gost/kp.go @@ -1,4 +1,4 @@ -// GoKEKS/PKI -- PKI-related capabilities based on KEKS encoded formats +// GoKEKS/CM -- KEKS-encoded cryptographic messages // Copyright (C) 2024-2025 Sergey Matveev // // This program is free software: you can redistribute it and/or modify diff --git a/go/pki/gost/signer.go b/go/cm/gost/signer.go similarity index 95% rename from go/pki/gost/signer.go rename to go/cm/gost/signer.go index 3148b36..785e248 100644 --- a/go/pki/gost/signer.go +++ b/go/cm/gost/signer.go @@ -1,4 +1,4 @@ -// GoKEKS/PKI -- PKI-related capabilities based on KEKS encoded formats +// GoKEKS/CM -- KEKS-encoded cryptographic messages // Copyright (C) 2024-2025 Sergey Matveev // // This program is free software: you can redistribute it and/or modify @@ -26,8 +26,8 @@ import ( "go.cypherpunks.su/gogost/v6/gost34112012256" "go.cypherpunks.su/gogost/v6/gost34112012512" - "go.cypherpunks.su/keks/pki/hash/merkle" - "go.cypherpunks.su/keks/pki/sign" + "go.cypherpunks.su/keks/cm/hash/merkle" + "go.cypherpunks.su/keks/cm/sign" ) type Signer struct { diff --git a/go/pki/gost/verify.go b/go/cm/gost/verify.go similarity index 94% rename from go/pki/gost/verify.go rename to go/cm/gost/verify.go index f914899..f09ec74 100644 --- a/go/pki/gost/verify.go +++ b/go/cm/gost/verify.go @@ -1,4 +1,4 @@ -// GoKEKS/PKI -- PKI-related capabilities based on KEKS encoded formats +// GoKEKS/CM -- KEKS-encoded cryptographic messages // Copyright (C) 2024-2025 Sergey Matveev // // This program is free software: you can redistribute it and/or modify @@ -21,7 +21,7 @@ import ( "go.cypherpunks.su/gogost/v6/gost3410" "go.cypherpunks.su/gogost/v6/gost34112012256" "go.cypherpunks.su/gogost/v6/gost34112012512" - "go.cypherpunks.su/keks/pki/utils" + "go.cypherpunks.su/keks/cm/utils" ) func Verify(algo string, pub, signed, signature []byte) (valid bool, err error) { diff --git a/go/pki/hash/algo.go b/go/cm/hash/algo.go similarity index 92% rename from go/pki/hash/algo.go rename to go/cm/hash/algo.go index 6843839..7459fc3 100644 --- a/go/pki/hash/algo.go +++ b/go/cm/hash/algo.go @@ -1,4 +1,4 @@ -// GoKEKS/PKI -- PKI-related capabilities based on KEKS encoded formats +// GoKEKS/CM -- KEKS-encoded cryptographic messages // Copyright (C) 2024-2025 Sergey Matveev // // This program is free software: you can redistribute it and/or modify @@ -23,9 +23,9 @@ import ( "go.cypherpunks.su/gogost/v6/gost34112012512" "golang.org/x/crypto/blake2b" - ed25519blake2b "go.cypherpunks.su/keks/pki/ed25519-blake2b" - "go.cypherpunks.su/keks/pki/gost" - "go.cypherpunks.su/keks/pki/hash/merkle" + ed25519blake2b "go.cypherpunks.su/keks/cm/ed25519-blake2b" + "go.cypherpunks.su/keks/cm/gost" + "go.cypherpunks.su/keks/cm/hash/merkle" ) const ( diff --git a/go/pki/hash/merkle/hash.go b/go/cm/hash/merkle/hash.go similarity index 98% rename from go/pki/hash/merkle/hash.go rename to go/cm/hash/merkle/hash.go index d38dd49..aa7e8bc 100644 --- a/go/pki/hash/merkle/hash.go +++ b/go/cm/hash/merkle/hash.go @@ -1,4 +1,4 @@ -// GoKEKS/PKI -- PKI-related capabilities based on KEKS encoded formats +// GoKEKS/CM -- KEKS-encoded cryptographic messages // Copyright (C) 2024-2025 Sergey Matveev // // This program is free software: you can redistribute it and/or modify diff --git a/go/pki/hash/merkle/hash_test.go b/go/cm/hash/merkle/hash_test.go similarity index 98% rename from go/pki/hash/merkle/hash_test.go rename to go/cm/hash/merkle/hash_test.go index e59c715..0f152cf 100644 --- a/go/pki/hash/merkle/hash_test.go +++ b/go/cm/hash/merkle/hash_test.go @@ -1,4 +1,4 @@ -// GoKEKS/PKI -- PKI-related capabilities based on KEKS encoded formats +// GoKEKS/CM -- KEKS-encoded cryptographic messages // Copyright (C) 2024-2025 Sergey Matveev // // This program is free software: you can redistribute it and/or modify diff --git a/go/pki/hash/merkle/prefixed.go b/go/cm/hash/merkle/prefixed.go similarity index 94% rename from go/pki/hash/merkle/prefixed.go rename to go/cm/hash/merkle/prefixed.go index 133b6e2..ae6672e 100644 --- a/go/pki/hash/merkle/prefixed.go +++ b/go/cm/hash/merkle/prefixed.go @@ -1,4 +1,4 @@ -// GoKEKS/PKI -- PKI-related capabilities based on KEKS encoded formats +// GoKEKS/CM -- KEKS-encoded cryptographic messages // Copyright (C) 2024-2025 Sergey Matveev // // This program is free software: you can redistribute it and/or modify diff --git a/go/pki/hash/shake.go b/go/cm/hash/shake.go similarity index 95% rename from go/pki/hash/shake.go rename to go/cm/hash/shake.go index 84e05f5..78157b8 100644 --- a/go/pki/hash/shake.go +++ b/go/cm/hash/shake.go @@ -1,4 +1,4 @@ -// GoKEKS/PKI -- PKI-related capabilities based on KEKS encoded formats +// GoKEKS/CM -- KEKS-encoded cryptographic messages // Copyright (C) 2024-2025 Sergey Matveev // // This program is free software: you can redistribute it and/or modify @@ -20,7 +20,7 @@ import ( "hash" "io" - "go.cypherpunks.su/keks/pki/hash/merkle" + "go.cypherpunks.su/keks/cm/hash/merkle" ) type SHAKE struct { diff --git a/go/pki/mceliece6960119-x25519/SOURCE b/go/cm/mceliece6960119-x25519/SOURCE similarity index 100% rename from go/pki/mceliece6960119-x25519/SOURCE rename to go/cm/mceliece6960119-x25519/SOURCE diff --git a/go/pki/mceliece6960119-x25519/algo.go b/go/cm/mceliece6960119-x25519/algo.go similarity index 100% rename from go/pki/mceliece6960119-x25519/algo.go rename to go/cm/mceliece6960119-x25519/algo.go diff --git a/go/pki/mceliece6960119-x25519/kp.go b/go/cm/mceliece6960119-x25519/kp.go similarity index 95% rename from go/pki/mceliece6960119-x25519/kp.go rename to go/cm/mceliece6960119-x25519/kp.go index 9c311b3..35285ee 100644 --- a/go/pki/mceliece6960119-x25519/kp.go +++ b/go/cm/mceliece6960119-x25519/kp.go @@ -1,4 +1,4 @@ -// GoKEKS/PKI -- PKI-related capabilities based on KEKS encoded formats +// GoKEKS/CM -- KEKS-encoded cryptographic messages // Copyright (C) 2024-2025 Sergey Matveev // // This program is free software: you can redistribute it and/or modify diff --git a/go/pki/prv.go b/go/cm/prv.go similarity index 84% rename from go/pki/prv.go rename to go/cm/prv.go index fe9b9ba..64ca636 100644 --- a/go/pki/prv.go +++ b/go/cm/prv.go @@ -1,4 +1,4 @@ -// GoKEKS/PKI -- PKI-related capabilities based on KEKS encoded formats +// GoKEKS/CM -- KEKS-encoded cryptographic messages // Copyright (C) 2024-2025 Sergey Matveev // // This program is free software: you can redistribute it and/or modify @@ -13,16 +13,16 @@ // You should have received a copy of the GNU Lesser General Public // License along with this program. If not, see . -package pki +package cm import ( "errors" "fmt" "go.cypherpunks.su/keks" - ed25519blake2b "go.cypherpunks.su/keks/pki/ed25519-blake2b" - "go.cypherpunks.su/keks/pki/gost" - "go.cypherpunks.su/keks/pki/sign" + ed25519blake2b "go.cypherpunks.su/keks/cm/ed25519-blake2b" + "go.cypherpunks.su/keks/cm/gost" + "go.cypherpunks.su/keks/cm/sign" ) // Parse private key contained in AV KEKS-encoded structure. @@ -30,7 +30,7 @@ func PrvParse(data []byte) (prv sign.Iface, pub []byte, err error) { { var magic keks.Magic magic, data = keks.StripMagic(data) - if magic != "" && magic != PrvKeyMagic { + if magic != "" && magic != PrvMagic { err = errors.New("wrong magic") return } diff --git a/go/pki/cer.go b/go/cm/pub.go similarity index 60% rename from go/pki/cer.go rename to go/cm/pub.go index c07b468..f2e11af 100644 --- a/go/pki/cer.go +++ b/go/cm/pub.go @@ -1,4 +1,4 @@ -// GoKEKS/PKI -- PKI-related capabilities based on KEKS encoded formats +// GoKEKS/CM -- KEKS-encoded cryptographic messages // Copyright (C) 2024-2025 Sergey Matveev // // This program is free software: you can redistribute it and/or modify @@ -13,7 +13,7 @@ // You should have received a copy of the GNU Lesser General Public // License along with this program. If not, see . -package pki +package cm import ( "bytes" @@ -25,15 +25,15 @@ import ( "github.com/google/uuid" "go.cypherpunks.su/keks" - ed25519blake2b "go.cypherpunks.su/keks/pki/ed25519-blake2b" - "go.cypherpunks.su/keks/pki/gost" - "go.cypherpunks.su/keks/pki/sign" + ed25519blake2b "go.cypherpunks.su/keks/cm/ed25519-blake2b" + "go.cypherpunks.su/keks/cm/gost" + "go.cypherpunks.su/keks/cm/sign" ) const ( KUSig = "sig" // Signing-capable key usage KUKEM = "kem" // Key-encapsulation-mechanism key usage - CerMagic = keks.Magic("pki/cer") + PubMagic = keks.Magic("cm/pub") ) var ( @@ -48,38 +48,38 @@ type Pub struct { Id uuid.UUID `keks:"id"` } -// Certificate load (contents). -type CerLoad struct { +// Public key load. +type PubLoad struct { KU *map[string]*struct{} `keks:"ku,omitempty"` Subj map[string]string `keks:"sub"` Crit *[]map[string]any `keks:"crit,omitempty"` Pub []Pub `keks:"pub"` } -// Parse Signed contents as CerLoad (certificate) and check its -// signatures necessary structure. signed.Load.V will hold the CerLoad in -// case of success. -func (signed *Signed) CerParse() error { - if signed.Load.T != "cer" { - return errors.New("CerParse: wrong load type") +// Parse Signed contents as PubLoad (certificate) and check its +// signatures necessary structure. signed.Load.V will hold the +// PubLoad in case of success. +func (signed *Signed) PubParse() error { + if signed.Load.T != "pub" { + return errors.New("PubParse: wrong load type") } for _, sig := range signed.Sigs { if sig.TBS.CID == nil { - return errors.New("CerParse: missing cid") + return errors.New("PubParse: missing cid") } if sig.TBS.Exp == nil { - return errors.New("CerParse: missing exp") + return errors.New("PubParse: missing exp") } } if signed.Load.V == nil { - return errors.New("CerParse: missing /load/v") + return errors.New("PubParse: missing /load/v") } - var load CerLoad + var load PubLoad var err error if v, ok := (*signed.Load.V).(map[string]any); ok { err = keks.Map2Struct(&load, v) } else { - err = errors.New("CerParse: wrong /load/v") + err = errors.New("PubParse: wrong /load/v") } if err != nil { return err @@ -90,40 +90,40 @@ func (signed *Signed) CerParse() error { } if load.KU != nil { if len(*load.KU) == 0 { - return errors.New("CerParse: empty ku") + return errors.New("PubParse: empty ku") } for _, v := range *load.KU { if v != nil { - return errors.New("CerParse: non-nil ku value") + return errors.New("PubParse: non-nil ku value") } } } if len(load.Subj) == 0 { - return errors.New("CerParse: empty sub") + return errors.New("PubParse: empty sub") } if load.Crit != nil { if len(*load.Crit) == 0 { - return errors.New("CerParse: empty crit") + return errors.New("PubParse: empty crit") } - return errors.New("CerParse: currently no critical extensions are supported") + return errors.New("PubParse: currently no critical extensions are supported") } if len(load.Pub) == 0 { - return errors.New("CerParse: empty pub") + return errors.New("PubParse: empty pub") } for _, pub := range load.Pub { if len(pub.A) == 0 || len(pub.V) == 0 || pub.Id == uuid.Nil { - return errors.New("CerParse: non-filled pub") + return errors.New("PubParse: non-filled pub") } } return nil } -// Parse KEKS-encoded data as Signed with the CerLoad (certificate) contents. -func CerParse(data []byte) (signed *Signed, err error) { +// Parse KEKS-encoded data as Signed with the PubLoad (certificate) contents. +func PubParse(data []byte) (signed *Signed, err error) { { var magic keks.Magic magic, data = keks.StripMagic(data) - if magic != "" && magic != CerMagic { + if magic != "" && magic != PubMagic { err = errors.New("wrong magic") return } @@ -132,24 +132,24 @@ func CerParse(data []byte) (signed *Signed, err error) { if err != nil { return } - err = signed.CerParse() + err = signed.PubParse() return } -// Check if cer certificate has desired ku capability. -func (cer *CerLoad) Can(ku string) (yes bool) { - if cer.KU == nil { +// Check if public key has desired ku capability. +func (pub *PubLoad) Can(ku string) (yes bool) { + if pub.KU == nil { return false } - _, yes = (*cer.KU)[ku] + _, yes = (*pub.KU)[ku] return } -// Sign the current Signed, having CerLoad payload with the provided -// parent's CerLoad and prv key. Certificate's CID will be automatically +// Sign the provided Signed, having PubLoad payload with the provided +// parent's PubLoad and prv key. Certification CID will be automatically // generated UUIDv7. since and till times must not have nanoseconds part. -func (signed *Signed) CerIssueWith( - parent *CerLoad, +func (signed *Signed) CertifyWith( + parent *PubLoad, prv sign.Iface, since, till time.Time, ) error { @@ -163,27 +163,27 @@ func (signed *Signed) CerIssueWith( // Verify signature of signed data. ErrSigInvalid will be returned in // case of invalid signature. -func (cer *CerLoad) CheckSignature(algo string, signed, signature []byte) (err error) { - if !cer.Can(KUSig) || len(cer.Pub) != 1 { - err = errors.New("cer can not sign") +func (pub *PubLoad) CheckSignature(algo string, signed, signature []byte) (err error) { + if !pub.Can(KUSig) || len(pub.Pub) != 1 { + err = errors.New("pub can not sign") return } - pub := cer.Pub[0] + key := pub.Pub[0] var valid bool - switch pub.A { + switch key.A { case Ed25519BLAKE2b: if algo != Ed25519BLAKE2b { return ErrBadSigAlgo } - valid, err = ed25519blake2b.Verify(pub.V, signed, signature) + valid, err = ed25519blake2b.Verify(key.V, signed, signature) if !valid { err = ErrSigInvalid } case GOST3410256A, GOST3410512C: - if algo != pub.A { + if algo != key.A { return ErrBadSigAlgo } - valid, err = gost.Verify(pub.A, pub.V, signed, signature) + valid, err = gost.Verify(key.A, key.V, signed, signature) if !valid { err = ErrSigInvalid } @@ -195,17 +195,17 @@ func (cer *CerLoad) CheckSignature(algo string, signed, signature []byte) (err e // Verify signature of signed data, by providing prehashed data. // ErrSigInvalid will be returned in case of invalid signature. -func (cer *CerLoad) CheckSignaturePrehash( +func (pub *PubLoad) CheckSignaturePrehash( algo string, prehash, signature []byte, ) (err error) { - if !cer.Can(KUSig) || len(cer.Pub) != 1 { - err = errors.New("cer can not sign") + if !pub.Can(KUSig) || len(pub.Pub) != 1 { + err = errors.New("pub can not sign") return } - pub := cer.Pub[0] + key := pub.Pub[0] var valid bool - switch pub.A { + switch key.A { case Ed25519BLAKE2b: switch algo { case Ed25519PhBLAKE2b: @@ -213,7 +213,7 @@ func (cer *CerLoad) CheckSignaturePrehash( default: return ErrBadSigAlgo } - valid, err = ed25519blake2b.VerifyPrehash(pub.V, prehash, signature) + valid, err = ed25519blake2b.VerifyPrehash(key.V, prehash, signature) if !valid { err = ErrSigInvalid } @@ -226,7 +226,7 @@ func (cer *CerLoad) CheckSignaturePrehash( default: return ErrBadSigAlgo } - valid, err = gost.VerifyPrehash(pub.A, pub.V, prehash, signature) + valid, err = gost.VerifyPrehash(key.A, key.V, prehash, signature) if !valid { err = ErrSigInvalid } @@ -236,11 +236,11 @@ func (cer *CerLoad) CheckSignaturePrehash( return } -// Verify Signed CerLoad certificate's signature with provided parent. +// Verify Signed PubLoad certification signature with provided parent. // If prehasher is specified, then prehashed signature mode is used. // Currently only single signature can be verified. -func (signed *Signed) CerCheckSignatureFrom( - parent *CerLoad, +func (signed *Signed) CertificationCheckSignatureFrom( + parent *PubLoad, prehasher *hash.Hash, ) (err error) { if len(signed.Sigs) != 1 { @@ -276,54 +276,54 @@ func (signed *Signed) CerCheckSignatureFrom( } } -// Get CerLoad from Signed. +// Get PubLoad from Signed. // Returns nil if Signed does not hold it (or it is not yet parsed). -func (signed *Signed) CerLoad() *CerLoad { - if signed.Load.T != "cer" || signed.Load.V == nil { +func (signed *Signed) PubLoad() *PubLoad { + if signed.Load.T != "pub" || signed.Load.V == nil { return nil } - l, ok := (*signed.Load.V).(CerLoad) + l, ok := (*signed.Load.V).(PubLoad) if ok { return &l } return nil } -// Verify signed Signed CerLoad certificate against cers chain of -// certificate authority ones at specified point of time t. -func (signed *Signed) CerVerify(cers []*Signed, t time.Time) (err error) { +// 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) { { exp := *(signed.Sigs[0].TBS.Exp) if t.Before(exp[0]) || t.Equal(exp[0]) { - err = errors.New("cer is not active") + err = errors.New("pub is not active") return } if t.After(exp[1]) || t.Equal(exp[1]) { - err = errors.New("cer is expired") + err = errors.New("pub is expired") return } } sid := signed.Sigs[0].TBS.SID - if sid == signed.CerLoad().Pub[0].Id { - return signed.CerCheckSignatureFrom(signed.CerLoad(), nil) + if sid == signed.PubLoad().Pub[0].Id { + return signed.CertificationCheckSignatureFrom(signed.PubLoad(), nil) } - idToCer := make(map[uuid.UUID]*Signed, len(cers)) - for _, cer := range cers { - cerLoad := cer.CerLoad() - if !cerLoad.Can(KUSig) || len(cerLoad.Pub) != 1 { - err = errors.New("cer can not sign") + idToPub := make(map[uuid.UUID]*Signed, len(pubs)) + for _, cer := range pubs { + pubLoad := cer.PubLoad() + if !pubLoad.Can(KUSig) || len(pubLoad.Pub) != 1 { + err = errors.New("pub can not sign") return } - idToCer[cerLoad.Pub[0].Id] = cer + idToPub[pubLoad.Pub[0].Id] = cer } - signer := idToCer[sid] + signer := idToPub[sid] if signer == nil { - err = fmt.Errorf("no cer found for sid: %v", signed.Sigs[0].TBS.SID) + err = fmt.Errorf("no pub found for sid: %v", signed.Sigs[0].TBS.SID) return } - err = signed.CerCheckSignatureFrom(signer.CerLoad(), nil) + err = signed.CertificationCheckSignatureFrom(signer.PubLoad(), nil) if err != nil { return } - return signer.CerVerify(cers, t) + return signer.CertificationVerify(pubs, t) } diff --git a/go/pki/sign/iface.go b/go/cm/sign/iface.go similarity index 100% rename from go/pki/sign/iface.go rename to go/cm/sign/iface.go diff --git a/go/pki/sign/mode.go b/go/cm/sign/mode.go similarity index 100% rename from go/pki/sign/mode.go rename to go/cm/sign/mode.go diff --git a/go/pki/signed.go b/go/cm/signed.go similarity index 79% rename from go/pki/signed.go rename to go/cm/signed.go index 0ca3a10..ed821a0 100644 --- a/go/pki/signed.go +++ b/go/cm/signed.go @@ -1,4 +1,4 @@ -// GoKEKS/PKI -- PKI-related capabilities based on KEKS encoded formats +// GoKEKS/CM -- KEKS-encoded cryptographic messages // Copyright (C) 2024-2025 Sergey Matveev // // This program is free software: you can redistribute it and/or modify @@ -13,7 +13,7 @@ // You should have received a copy of the GNU Lesser General Public // License along with this program. If not, see . -package pki +package cm import ( "bytes" @@ -25,10 +25,10 @@ import ( "github.com/google/uuid" "go.cypherpunks.su/keks" - "go.cypherpunks.su/keks/pki/sign" + "go.cypherpunks.su/keks/cm/sign" ) -const SignedMagic = keks.Magic("pki/signed") +const SignedMagic = keks.Magic("cm/signed") type SignedPrehash struct { Sigs map[string]*struct{} `keks:"sigs"` @@ -50,33 +50,33 @@ type SigTBS struct { type Sig struct { TBS SigTBS `keks:"tbs,omitempty"` - CerLoc *[]string `keks:"cer-loc,omitempty"` + PubLoc *[]string `keks:"pub-loc,omitempty"` Sign AV `keks:"sign"` } type Signed struct { - Cers *[]*Signed `keks:"certs,omitempty"` Load SignedLoad `keks:"load"` + Pubs *[]*Signed `keks:"pubs,omitempty"` Sigs []*Sig `keks:"sigs"` } -// Validate parsed pki-signed structure. +// Validate parsed cm-signed structure. func SignedValidate(signed *Signed) (err error) { - if signed.Cers != nil { - if len(*signed.Cers) == 0 { - err = errors.New("SignedParse: empty /certs") + if signed.Pubs != nil { + if len(*signed.Pubs) == 0 { + err = errors.New("SignedParse: empty /pubs") return } - for _, cer := range *signed.Cers { - err = cer.CerParse() + for _, pub := range *signed.Pubs { + err = pub.PubParse() if err != nil { return } } } for _, sig := range signed.Sigs { - if sig.CerLoc != nil && len(*sig.CerLoc) == 0 { - err = errors.New("SignedParse: empty cer-loc") + if sig.PubLoc != nil && len(*sig.PubLoc) == 0 { + err = errors.New("SignedParse: empty pub-loc") return } if sig.TBS.Exp != nil { @@ -95,7 +95,7 @@ func SignedValidate(signed *Signed) (err error) { return } -// Parse pki-signed from KEKS-encoded data. This is just a wrapper over +// Parse cm-signed from KEKS-encoded data. This is just a wrapper over // SignedParseItem. func SignedParse(data []byte) (*Signed, error) { { @@ -116,9 +116,9 @@ func SignedParse(data []byte) (*Signed, error) { } // Sign Signed's contents and sigTBS corresponding data with the -// provided prv signer, having parent certificate. Signature is appended -// to the signed.Sigs. parent certificate must have "sig" key-usage. -func (signed *Signed) SignWith(parent *CerLoad, prv sign.Iface, sigTBS SigTBS) (err error) { +// provided prv signer, having parent certififer. Signature is appended +// to the signed.Sigs. parent must have "sig" key-usage. +func (signed *Signed) SignWith(parent *PubLoad, prv sign.Iface, sigTBS SigTBS) (err error) { if !parent.Can(KUSig) || len(parent.Pub) != 1 { return errors.New("parent can not sign") } diff --git a/go/pki/sntrup4591761-x25519/algo.go b/go/cm/sntrup4591761-x25519/algo.go similarity index 100% rename from go/pki/sntrup4591761-x25519/algo.go rename to go/cm/sntrup4591761-x25519/algo.go diff --git a/go/pki/sntrup4591761-x25519/go.mod b/go/cm/sntrup4591761-x25519/go.mod similarity index 62% rename from go/pki/sntrup4591761-x25519/go.mod rename to go/cm/sntrup4591761-x25519/go.mod index 6e563ce..4706ebb 100644 --- a/go/pki/sntrup4591761-x25519/go.mod +++ b/go/cm/sntrup4591761-x25519/go.mod @@ -1,4 +1,4 @@ -module go.cypherpunks.su/keks/pki/sntrup4591761-x25519 +module go.cypherpunks.su/keks/cm/sntrup4591761-x25519 go 1.24 diff --git a/go/pki/sntrup4591761-x25519/go.sum b/go/cm/sntrup4591761-x25519/go.sum similarity index 100% rename from go/pki/sntrup4591761-x25519/go.sum rename to go/cm/sntrup4591761-x25519/go.sum diff --git a/go/pki/sntrup4591761-x25519/kp.go b/go/cm/sntrup4591761-x25519/kp.go similarity index 94% rename from go/pki/sntrup4591761-x25519/kp.go rename to go/cm/sntrup4591761-x25519/kp.go index f692be1..0a60666 100644 --- a/go/pki/sntrup4591761-x25519/kp.go +++ b/go/cm/sntrup4591761-x25519/kp.go @@ -1,4 +1,4 @@ -// GoKEKS/PKI -- PKI-related capabilities based on KEKS encoded formats +// GoKEKS/CM -- KEKS-encoded cryptographic messages // Copyright (C) 2024-2025 Sergey Matveev // // This program is free software: you can redistribute it and/or modify diff --git a/go/pki/utils/utils.go b/go/cm/utils/utils.go similarity index 93% rename from go/pki/utils/utils.go rename to go/cm/utils/utils.go index 2b16054..c4bec88 100644 --- a/go/pki/utils/utils.go +++ b/go/cm/utils/utils.go @@ -1,4 +1,4 @@ -// GoKEKS/PKI -- PKI-related capabilities based on KEKS encoded formats +// GoKEKS/CM -- KEKS-encoded cryptographic messages // Copyright (C) 2024-2025 Sergey Matveev // // This program is free software: you can redistribute it and/or modify diff --git a/go/pki/algo.go b/go/pki/algo.go deleted file mode 100644 index 4b5f209..0000000 --- a/go/pki/algo.go +++ /dev/null @@ -1,29 +0,0 @@ -package pki - -import ( - "go.cypherpunks.su/keks" - ed25519blake2b "go.cypherpunks.su/keks/pki/ed25519-blake2b" - "go.cypherpunks.su/keks/pki/gost" - mceliece6960119x25519 "go.cypherpunks.su/keks/pki/mceliece6960119-x25519" - sntrup4591761x25519 "go.cypherpunks.su/keks/pki/sntrup4591761-x25519" -) - -const ( - BalloonBLAKE2bHKDF = "balloon-blake2b-hkdf" - ChaCha20Poly1305 = "chacha20poly1305" - ClassicMcEliece6960119X25519 = mceliece6960119x25519.ClassicMcEliece6960119X25519 - ClassicMcEliece6960119X25519HKDFSHAKE256 = mceliece6960119x25519.ClassicMcEliece6960119X25519HKDFSHAKE256 - Ed25519BLAKE2b = ed25519blake2b.Ed25519BLAKE2b - Ed25519PhBLAKE2b = ed25519blake2b.Ed25519PhBLAKE2b - Ed25519PhBLAKE2bMerkle = ed25519blake2b.Ed25519PhBLAKE2bMerkle - GOST3410256A = gost.GOST3410256A - GOST3410256AMerkle = gost.GOST3410256AMerkle - GOST3410512C = gost.GOST3410512C - GOST3410512CMerkle = gost.GOST3410512CMerkle - SNTRUP4591761X25519 = sntrup4591761x25519.SNTRUP4591761X25519 - SNTRUP4591761X25519HKDFBLAKE2b = sntrup4591761x25519.SNTRUP4591761X25519HKDFBLAKE2b - - EncryptedMagic = keks.Magic("pki/encryptd") - HashedMagic = keks.Magic("pki/hashed") - PrvKeyMagic = keks.Magic("pki/prvkey") -) diff --git a/go/pki/cmd/certool/basic.t b/go/pki/cmd/certool/basic.t deleted file mode 100755 index 705dd6e..0000000 --- a/go/pki/cmd/certool/basic.t +++ /dev/null @@ -1,55 +0,0 @@ -#!/bin/sh - -test_description="Check that basic GOST-related functionality works" -. $SHARNESS_TEST_SRCDIR/sharness.sh - -TMPDIR=${TMPDIR:-/tmp} - -echo "gost3410-512C gost3410-256A -ed25519-blake2b ed25519-blake2b" | while read caAlgo eeAlgo ; do - -subj="-subj CN=CA -subj C=RU" -test_expect_success "$caAlgo: CA load generation" "certool \ - -algo $caAlgo \ - -ku sig $subj \ - -prv $TMPDIR/ca.prv -cer $TMPDIR/ca.cer" -test_expect_success "$caAlgo: CA generation" "certool \ - -cer $TMPDIR/ca.cer \ - -ca-prv $TMPDIR/ca.prv -ca-cer $TMPDIR/ca.cer" -test_expect_success "$caAlgo: CA regeneration" "certool \ - -cer $TMPDIR/ca.cer \ - -ca-prv $TMPDIR/ca.prv -ca-cer $TMPDIR/ca.cer" -test_expect_success "$caAlgo: CA self-signature" "certool \ - -ca-cer $TMPDIR/ca.cer \ - -cer $TMPDIR/ca.cer \ - -verify" - -subj="-subj CN=SubCA -subj C=RU" -test_expect_success "$eeAlgo: SubCA load generation" "certool \ - -algo $eeAlgo \ - -ku sig $subj \ - -prv $TMPDIR/subca.prv -cer $TMPDIR/subca.cer" -test_expect_success "$eeAlgo: SubCA generation" "certool \ - -cer $TMPDIR/subca.cer \ - -ca-cer $TMPDIR/ca.cer -ca-prv $TMPDIR/ca.prv" -test_expect_success "$eeAlgo: SubCA signature" "certool \ - -ca-cer $TMPDIR/ca.cer \ - -cer $TMPDIR/subca.cer \ - -verify" - -subj="-subj CN=EE -subj C=RU" -test_expect_success "$eeAlgo: EE load generation" "certool \ - -algo $eeAlgo $subj \ - -prv $TMPDIR/ee.prv -cer $TMPDIR/ee.cer" -test_expect_success "$eeAlgo: EE generation" "certool \ - -ca-prv $TMPDIR/subca.prv -ca-cer $TMPDIR/subca.cer \ - -cer $TMPDIR/ee.cer" -test_expect_success "$eeAlgo: EE chain" "certool \ - -ca-cer $TMPDIR/ca.cer \ - -ca-cer $TMPDIR/subca.cer \ - -cer $TMPDIR/ee.cer \ - -verify" - -done - -test_done diff --git a/go/pki/doc.go b/go/pki/doc.go deleted file mode 100644 index 59945dd..0000000 --- a/go/pki/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// GoKEKS/PKI provides PKI-related capabilities based on KEKS encoded formats -package pki diff --git a/go/pki/go.sum b/go/pki/go.sum deleted file mode 100644 index f97535c..0000000 --- a/go/pki/go.sum +++ /dev/null @@ -1,5 +0,0 @@ -github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= -github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -go.cypherpunks.su/gogost/v6 v6.0.1 h1:PFjBnUmfdbx7L5R6hRt/+ZgGwWx45wTIWezFSgmknrs= -go.cypherpunks.su/gogost/v6 v6.0.1/go.mod h1:qJm0B7KJY4/OD5nYqL10kXY09dUwu2AfwSPu72Otngs= -golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= diff --git a/spec/encoding/float.texi b/spec/encoding/float.texi index 98fd3ef..4c02fff 100644 --- a/spec/encoding/float.texi +++ b/spec/encoding/float.texi @@ -1,4 +1,5 @@ @node Floats +@cindex floats @cindex FLOAT16 @cindex FLOAT32 @cindex FLOAT64 diff --git a/spec/encoding/list.texi b/spec/encoding/list.texi index 4582a38..432f8e2 100644 --- a/spec/encoding/list.texi +++ b/spec/encoding/list.texi @@ -1,4 +1,5 @@ @node LIST +@cindex LIST @cindex EOC @section LIST diff --git a/spec/encoding/magic.texi b/spec/encoding/magic.texi index 739b201..365bd4f 100644 --- a/spec/encoding/magic.texi +++ b/spec/encoding/magic.texi @@ -9,8 +9,8 @@ It is intended to be prepended to the KEKS-encoded data in files. @multitable @columnfractions .5 .5 -@item MAGIC(pki/cer) @tab @code{4B454B53 706B692F636572 0000000000} -@item MAGIC(pki/signed) @tab @code{4B454B53 706B692F7369676E6564 0000} -@item MAGIC(pki/encryptd) @tab @code{4B454B53 706B692F656E637279707464} +@item MAGIC(cm/pub) @tab @code{4B454B53 636D2F707562 000000000000} +@item MAGIC(cm/signed) @tab @code{4B454B53 636D2F7369676E6564 000000} +@item MAGIC(cm/encrypted) @tab @code{4B454B53 636D2F656E63727970746564} @end multitable diff --git a/spec/format/encrypted.cddl b/spec/format/encrypted.cddl index c575450..b6ddfd6 100644 --- a/spec/format/encrypted.cddl +++ b/spec/format/encrypted.cddl @@ -1,6 +1,6 @@ ai = text ; algorithm identifier -pki-encrypted = { +cm-encrypted = { dem: dem, kem: [+ kem], bind: uuid, diff --git a/spec/format/encrypted.texi b/spec/format/encrypted.texi index aca04bf..26980f2 100644 --- a/spec/format/encrypted.texi +++ b/spec/format/encrypted.texi @@ -1,8 +1,8 @@ -@node pki-encrypted -@cindex pki-encrypted -@section pki-encrypted format +@node cm-encrypted +@cindex cm-encrypted +@section cm-encrypted format -Stored in a file, it should begin with "pki/encryptd" @ref{Magic, magic}. +Stored in a file, it should begin with "cm/encrypted" @ref{Magic, magic}. @verbatiminclude format/encrypted.cddl @@ -14,24 +14,25 @@ initialisation vector. @code{/ciphertext} is a BLOB, which chunk's length depends on DEM algorithm. If it is absent, then ciphertext is provided by other means, -for example just following the @code{pki-encrypted} structure. +for example just following the @code{cm-encrypted} structure. CEK is encapsulated in @code{/kem/*} entries (key encapsulation mechanism), using @code{/kem/*/a} algorithm. @code{/kem/*/cek} field contains an encrypted CEK. -If KEM uses public-key based cryptography, then recipient's public -key(s) should be provided by @ref{cer, certificate}, which may lack the +If KEM uses public-key based cryptography, then recipient's +@ref{cm-pub, public key}(s) should be provided, which may lack the signatures at all. Optional @code{/kem/*/to}, public key's identifier, may provide a hint for quickly searching for the key on the recipient's side. @code{/bind} value can be used to bind the encrypted -@code{@ref{pki-signed, pki-signed}} to the envelope. +@code{@ref{cm-signed, cm-signed}} to the envelope. Either UUIDv4 or UUIDv7 are recommended. -@node pki-encrypted-chacha20poly1305 -@subsection pki-encrypted with ChaCha20-Poly1305 DEM +@node cm-encrypted-chacha20poly1305 +@cindex cm-encrypted-chacha20poly1305 +@subsection Encrypted data with ChaCha20-Poly1305 DEM @code{/dem/a} equals to "chacha20poly1305". Data is split on 64 KiB chunks which are encrypted the following way: @@ -49,8 +50,9 @@ ChaCha20-Poly1305( @code{/ciphertext}'s chunk length equals to 16+64KiB+16 bytes. -@node pki-encrypted-kuznechik-ctracpkm-hmac-hkdf -@subsection pki-encrypted-kuznechik-ctracpkm-hmac-hkdf +@node cm-encrypted-kuznechik-ctracpkm-hmac-hkdf +@cindex cm-encrypted-kuznechik-ctracpkm-hmac-hkdf +@subsection Encrypted data with Kuznechik-CTR-ACPKM-HMAC-HKDF DEM @code{/dem/a} equals to "kuznechik-ctracpkm-hmac-hkdf". @code{/dem/seed} contains 16 bytes for the HKDF invocation below. @@ -58,7 +60,7 @@ ChaCha20-Poly1305( @verbatim Kenc, Kauth = HKDF-Extract(Streebog-512, - salt="keks/pki/encrypted/kuznechik-ctracpkm-hmac-hkdf", + salt="keks/cm/encrypted/kuznechik-ctracpkm-hmac-hkdf", secret=seed || CEK) @end verbatim @@ -69,8 +71,9 @@ Kenc, Kauth = HKDF-Extract(Streebog-512, @code{/ciphertext}'s chunk length equals to 64KiB bytes. -@node pki-encrypted-balloon-blake2b-hkdf -@subsection pki-encrypted with Balloon-BLAKE2b+HKDF-BLAKE2b KEM +@node cm-encrypted-balloon-blake2b-hkdf +@cindex cm-encrypted-balloon-blake2b-hkdf +@subsection Encrypted data with Balloon-BLAKE2b+HKDF-BLAKE2b KEM @code{/kem/*/a} equals to "balloon-blake2b-hkdf". Recipient map must also contain additional fields: @@ -93,13 +96,14 @@ Kenc, Kauth = HKDF-Extract(Streebog-512, @verbatim KEK = HKDF-Extract(BLAKE2b-256, - salt="keks/pki/encrypted/balloon-blake2b-hkdf", + salt="keks/cm/encrypted/balloon-blake2b-hkdf", secret=balloon(BLAKE2b-256, password, bind || salt, s, t, p)) ChaCha20-Poly1305(data=16*0x00 || CEK, key=KEK, nonce=12*0x00, ad="") @end verbatim -@node pki-encrypted-gost3410-hkdf-kexp15 -@subsection pki-encrypted-gost3410-hkdf-kexp15 +@node cm-encrypted-gost3410-hkdf-kexp15 +@cindex cm-encrypted-gost3410-hkdf-kexp15 +@subsection Encrypted data with GOST R 34.10-HKDF-KExp15 KEM @code{/kem/*/a} equals to "gost3410-hkdf-kexp15". Recipient map must also contain additional fields: @@ -120,19 +124,20 @@ ChaCha20-Poly1305(data=16*0x00 || CEK, key=KEK, nonce=12*0x00, ad="") @verbatim KEKenv, KEKauth = HKDF-Extract(Streebog-512, - salt="keks/pki/encrypted/gost3410-hkdf-kexp15", + salt="keks/cm/encrypted/gost3410-hkdf-kexp15", secret=bind || VKO(...)) KExp15(KEKenc, KEKauth, IV, CEK): return CTR(Kenc, CEK+CMAC(Kauth, IV+CEK), IV=IV) @end verbatim -@node pki-encrypted-sntrup4591761-x25519-hkdf-blake2b -@subsection pki-encrypted with SNTRUP4591761+x25519+HKDF-BLAKE2b KEM +@node cm-encrypted-sntrup4591761-x25519-hkdf-blake2b +@cindex cm-encrypted-sntrup4591761-x25519-hkdf-blake2b +@subsection Encrypted data with SNTRUP4591761+x25519+HKDF-BLAKE2b KEM @code{/kem/*/a} equals to "sntrup4591761-x25519-hkdf-blake2b". - Recipient certificate with - @ref{cer-sntrup4591761-x25519, @code{sntrup4591761-x25519}} public key - must be used. It should have "kem" key usage set. + Recipient public key with + @ref{cm-pub-sntrup4591761-x25519, @code{sntrup4591761-x25519}} + algorithm must be used. It should have "kem" key usage set. Recipient map must also contain additional field: @code{/kem/*/encap: bytes} -- concatenation of 1047 bytes of Streamlined @@ -146,7 +151,7 @@ KExp15(KEKenc, KEKauth, IV, CEK): @verbatim KEK = HKDF-Extract(BLAKE2b-256, - salt="keks/pki/encrypted/sntrup4591761-x25519-hkdf-blake2b", + salt="keks/cm/encrypted/sntrup4591761-x25519-hkdf-blake2b", secret=bind || sntrup4591761-sender-ciphertext || x25519-sender-public-key || @@ -157,13 +162,14 @@ KEK = HKDF-Extract(BLAKE2b-256, ChaCha20-Poly1305(data=16*0x00 || CEK, key=KEK, nonce=12*0x00, ad="") @end verbatim -@node pki-encrypted-mceliece6960119-x25519-hkdf-shake256 -@subsection pki-encrypted with Classic McEliece 6960119+x25519+HKDF-SHAKE256 KEM +@node cm-encrypted-mceliece6960119-x25519-hkdf-shake256 +@cindex cm-encrypted-mceliece6960119-x25519-hkdf-shake256 +@subsection Encrypted data with Classic McEliece 6960119+x25519+HKDF-SHAKE256 KEM @code{/kem/*/a} equals to "mceliece6960119-x25519-hkdf-shake256". - Recipient certificate with - @ref{cer-mceliece6960119-x25519, @code{mceliece6960119-x25519}} public key - must be used. It should have "kem" key usage set. + Recipient public key with + @ref{cm-pub-mceliece6960119-x25519, @code{mceliece6960119-x25519}} + algorithm must be used. It should have "kem" key usage set. Recipient map must also contain additional field: @code{/kem/*/encap: bytes} -- concatenation of 194 bytes of @@ -177,7 +183,7 @@ ChaCha20-Poly1305(data=16*0x00 || CEK, key=KEK, nonce=12*0x00, ad="") @verbatim KEK = HKDF-Extract(SHAKE256, - salt="keks/pki/encrypted/mceliece6960119-x25519-hkdf-shake256", + salt="keks/cm/encrypted/mceliece6960119-x25519-hkdf-shake256", secret=bind || mceliece6960119-sender-ciphertext || x25519-sender-public-key || diff --git a/spec/format/hashed.cddl b/spec/format/hashed.cddl index 39465b0..8195590 100644 --- a/spec/format/hashed.cddl +++ b/spec/format/hashed.cddl @@ -1,6 +1,6 @@ ai = text ; algorithm identifier -pki-hashed = { +cm-hashed = { a: [+ ai], t: text, ; type of the content v: bytes / text / blob / map / list, ; content itself diff --git a/spec/format/hashed.texi b/spec/format/hashed.texi index 1a616d1..e5dcae5 100644 --- a/spec/format/hashed.texi +++ b/spec/format/hashed.texi @@ -1,9 +1,9 @@ -@node pki-hashed -@cindex pki-hashed -@section pki-hashed format +@node cm-hashed +@cindex cm-hashed +@section cm-hashed format Integrity protected container, CMS'es DigestedData analogue. -Stored in a file, it should begin with "pki/hashed" @ref{Magic, magic}. +Stored in a file, it should begin with "cm/hashed" @ref{Magic, magic}. @verbatiminclude format/hashed.cddl @@ -26,19 +26,22 @@ algorithms. Merkle trees are very convenient way to parallelise data hashing. @url{https://datatracker.ietf.org/doc/html/rfc9162, RFC 9162} is used as - a base for all Merkle-tree based hashers. By default 128KiB chunks are -used. + a base for all Merkle-tree based hashers. -@node pki-hashed-blake2b -@subsection pki-hashed with BLAKE2b + By default 128KiB chunks are used. + +@node cm-hashed-blake2b +@cindex cm-hashed-blake2b +@subsection Hashed data with BLAKE2b @url{https://www.blake2.net/, BLAKE2b} with 512-bit output has @code{blake2b} algorithm identifier. 256-bit output has @code{blake2b256} algorithm identifier. -@node pki-hashed-blake2b-merkle -@subsection pki-hashed with BLAKE2b in Merkle-tree mode +@node cm-hashed-blake2b-merkle +@cindex cm-hashed-blake2b-merkle +@subsection Hashed data with BLAKE2b in Merkle-tree mode BLAKE2b-512 is initialised with either "LEAF" or "NODE" keys, instead of using @code{0x00}/@code{0x01} constants prepending to the @@ -47,29 +50,33 @@ used. @code{blake2b-merkle} algorithm identifier is used. -@node pki-hashed-blake3 -@subsection pki-hashed with BLAKE3 +@node cm-hashed-blake3 +@cindex cm-hashed-blake3 +@subsection Hashed data with BLAKE3 @url{https://github.com/BLAKE3-team/BLAKE3/, BLAKE3} with fixed 256-bit output has @code{blake3} algorithm identifier. -@node pki-hashed-sha2 -@subsection pki-hashed with SHA2 +@node cm-hashed-sha2 +@cindex cm-hashed-sha2 +@subsection Hashed data with SHA2 SHA2-256 has @code{sha2-256} algorithm identifier. SHA2-512 has @code{sha2-512} algorithm identifier. -@node pki-hashed-shake -@subsection pki-hashed with SHAKE +@node cm-hashed-shake +@cindex cm-hashed-shake +@subsection Hashed data with SHAKE @url{https://keccak.team/, SHAKE} XOF function with fixed 256 (SHAKE128) or 512 (SHAKE256) bit output. @code{shake128}, @code{shake256} algorithm identifiers are used. -@node pki-hashed-shake-merkle -@subsection pki-hashed with SHAKE in Merkle-tree mode +@node cm-hashed-shake-merkle +@cindex cm-hashed-shake-merkle +@subsection Hashed data with SHAKE in Merkle-tree mode cSHAKE with either "LEAF" or "NODE" personalisation strings are used instead of @code{0x00}/@code{0x01} constants prepending to the @@ -78,28 +85,32 @@ used. @code{shake128-merkle}, @code{shake256-merkle} algorithm identifiers are used. -@node pki-hashed-skein512 -@subsection pki-hashed with Skein-512 +@node cm-hashed-skein512 +@cindex cm-hashed-skein512 +@subsection Hashed data with Skein-512 512-bit @url{https://www.schneier.com/academic/skein/, Skein-512} hash. @code{skein512} algorithm identifier is used. -@node pki-hashed-gost3411 -@subsection pki-hashed with GOST R 34.11-2012 +@node cm-hashed-gost3411 +@cindex cm-hashed-gost3411 +@subsection Hashed data with GOST R 34.11-2012 Streebog must be big-endian serialised. @code{streebog256}, @code{streebog512} algorithm identifiers are used. -@node pki-hashed-gost3411-merkle -@subsection pki-hashed with GOST R 34.11-2012 in Merkle tree mode +@node cm-hashed-gost3411-merkle +@cindex cm-hashed-gost3411-merkle +@subsection Hashed data with GOST R 34.11-2012 in Merkle tree mode @code{streebog256-merkle}, @code{streebog512-merkle} algorithm identifiers are used. -@node pki-hashed-xxh3-128 -@subsection pki-hashed with XXH3-128 +@node cm-hashed-xxh3-128 +@cindex cm-hashed-xxh3-128 +@subsection Hashed data with XXH3-128 128-bit @url{https://xxhash.com/, XXH3} hash must be big-endian encoded. diff --git a/spec/format/index.texi b/spec/format/index.texi index db281c9..f41ff74 100644 --- a/spec/format/index.texi +++ b/spec/format/index.texi @@ -5,9 +5,9 @@ Here are some suggested formats. They are written in @url{https://datatracker.ietf.org/doc/html/rfc8610, CDDL}-like format. -@include format/private-key.texi +@include format/prv.texi @include format/signed.texi -@include format/cer.texi +@include format/pub.texi @include format/hashed.texi @include format/encrypted.texi @include format/registry.texi diff --git a/spec/format/private-key.cddl b/spec/format/prv.cddl similarity index 77% rename from spec/format/private-key.cddl rename to spec/format/prv.cddl index e441adf..22b97e5 100644 --- a/spec/format/private-key.cddl +++ b/spec/format/prv.cddl @@ -1,4 +1,4 @@ ai = text ; algorithm identifier av = {a: ai, v: bytes} -private-key = av +cm-prv = av diff --git a/spec/format/private-key.texi b/spec/format/prv.texi similarity index 55% rename from spec/format/private-key.texi rename to spec/format/prv.texi index 80c6ddc..206acb6 100644 --- a/spec/format/private-key.texi +++ b/spec/format/prv.texi @@ -1,21 +1,25 @@ -@node private-key -@cindex private-key -@section private-key format +@node cm-prv +@cindex cm-prv +@section cm-prv format -@verbatiminclude format/private-key.cddl +Private key container. -Stored in a file, it should begin with "pki/prvkey" @ref{Magic, magic}. +@verbatiminclude format/prv.cddl -@node private-key-gost3410 -@subsection private-key with GOST R 34.10-2012 +Stored in a file, it should begin with "cm/prv" @ref{Magic, magic}. + +@node cm-prv-gost3410 +@cindex cm-prv-gost3410 +@subsection Private key with GOST R 34.10-2012 Big-endian private key representation must be used. Following algorithm identifiers are used: @code{gost3410-256A}, @code{gost3410-512C}. -@node private-key-ed25519-blake2b -@subsection private-key with Ed25519-BLAKE2b +@node cm-prv-ed25519-blake2b +@cindex cm-prv-ed25519-blake2b +@subsection Private key with Ed25519-BLAKE2b 32-byte Ed25519 private key is used, as described in @url{https://datatracker.ietf.org/doc/html/rfc8032, EdDSA} RFC. @@ -24,16 +28,18 @@ Stored in a file, it should begin with "pki/prvkey" @ref{Magic, magic}. @code{ed25519-blake2b} algorithm identifier is used, however actually no hash is involved in private key storage. -@node private-key-sntrup4591761-x25519 -@subsection private-key with SNTRUP4591761+X25519 +@node cm-prv-sntrup4591761-x25519 +@cindex cm-prv-sntrup4591761-x25519 +@subsection Private key with SNTRUP4591761+X25519 Concatenation of Streamlined NTRU Prime 4591^761's 1600-byte private key and Curve25519's 32-byte one. @code{sntrup4591761-x25519} algorithm identifier is used. -@node private-key-mceliece6960119-x25519 -@subsection private-key with Classic McEliece 6960119+X25519 +@node cm-prv-mceliece6960119-x25519 +@cindex cm-prv-mceliece6960119-x25519 +@subsection Private key with Classic McEliece 6960119+X25519 Concatenation of Classic McEliece 6960119 13948-byte private key and Curve25519's 32-byte one. diff --git a/spec/format/cer-load.cddl b/spec/format/pub-load.cddl similarity index 94% rename from spec/format/cer-load.cddl rename to spec/format/pub-load.cddl index ea64836..2c5edb6 100644 --- a/spec/format/cer-load.cddl +++ b/spec/format/pub-load.cddl @@ -1,7 +1,7 @@ ai = text ; algorithm identifier av = {a: ai, v: bytes} -cer-load = { +cm-pub-load = { ? ku: set, pub: [+ {av, id: uuid}], sub: {text => text}, ; subject diff --git a/spec/format/cer-sig-tbs.cddl b/spec/format/pub-sig-tbs.cddl similarity index 69% rename from spec/format/cer-sig-tbs.cddl rename to spec/format/pub-sig-tbs.cddl index 2034d50..115db0a 100644 --- a/spec/format/cer-sig-tbs.cddl +++ b/spec/format/pub-sig-tbs.cddl @@ -1,6 +1,6 @@ -cer-sig-tbs = { +cm-pub-sig-tbs = { sid: uuid, ; signer's public key id - cid: uuid, ; certificate's id + cid: uuid, ; certification id exp: validity, * text => any } diff --git a/spec/format/cer.texi b/spec/format/pub.texi similarity index 53% rename from spec/format/cer.texi rename to spec/format/pub.texi index 9061b61..830defb 100644 --- a/spec/format/cer.texi +++ b/spec/format/pub.texi @@ -1,18 +1,18 @@ -@node cer -@cindex cer -@section cer format +@node cm-pub +@cindex cm-pub +@section cm-pub format -Certificate is the @code{@ref{pki-signed}} structure. -Stored in a file, it should begin with "pki/cer" @ref{Magic, magic}. +Public key is the @code{@ref{cm-signed}} structure. +Stored in a file, it should begin with "cm/pub" @ref{Magic, magic}. -Its @code{/load/t} equals to @code{cer}. -@code{/load/v} contains @code{cer-load}: +Its @code{/load/t} equals to @code{pub}. +@code{/load/v} contains @code{cm-pub-load}: @verbatim -cer = pki-signed ; with /load/t = "cer", /load/v = cer-load +cm-pub = cm-signed ; with /load/t = "pub", /load/v = cm-pub-load @end verbatim -@verbatiminclude format/cer-load.cddl +@verbatiminclude format/pub-load.cddl @table @code @@ -23,13 +23,13 @@ his own. But you may mimic X.509's subject with keys like "CN", "C", "O" and similar ones. @item pub -Certificate may contain multiple public keys. +Public key container itself may contain multiple public keys. That is @strong{solely} intended for tasks requiring more than single key usage. For example @url{http://www.nncpgo.org, NNCP} uses one curve25519 for (DH) encryption, one curve25519 for online authentication and one ed25519 for signing purposes. All those three keys are used -together. That certificate's key usage field must contain something like +together. That public key's key usage field must contain something like "nncp". If your keypair is intended for general purposes like signing of @@ -47,14 +47,14 @@ above. It @strong{must} be absent if empty. @item crit Optional critical (in terms of X.509) extensions. Non-critical -ones may be placed outside that map, directly in @code{cer-load}. +ones may be placed outside that map, directly in @code{cm-pub-load}. It @strong{must} be absent if empty. Values are extension specific. @end table -@code{pki-signed}'s @code{sig-tbs} @strong{must} contain additional fields: +@code{cm-signed}'s @code{sig-tbs} @strong{must} contain additional fields: -@verbatiminclude format/cer-sig-tbs.cddl +@verbatiminclude format/pub-sig-tbs.cddl @table @code @@ -62,21 +62,21 @@ It @strong{must} be absent if empty. Values are extension specific. Signing public key identifier. @item cid -Certificate's unique identifier. UUIDv7 is a good choice. But it may be +Certification unique identifier. UUIDv7 is a good choice. But it may be UUIDv4, or any desired method of generation. @item exp -Expiration period of the certificate. It @strong{must} contain TAI64 +Certification expiration period. It @strong{must} contain TAI64 datetime (no nanoseconds). @end table -Example minimal certificate may look like: +Example minimal public key may look like: @verbatim { "load": { - "t": "cer", + "t": "pub", "v": { "pub": [{"a": "gost3410-256A", "v": 'pubkey', "id": UUID(hash(pub))}], "sub": {"CN": "Test", "O": "Testers"}, @@ -84,7 +84,7 @@ Example minimal certificate may look like: }, "sigs": [{ "tbs": { - "cid": UUID(certificate's id), + "cid": UUID(certification id), "sid": UUID(signer's pkid), "exp": [TAI64, TAI64], }, @@ -93,8 +93,9 @@ Example minimal certificate may look like: } @end verbatim -@node cer-gost3410 -@subsection cer with GOST R 34.10-2012 +@node cm-pub-gost3410 +@cindex cm-pub-gost3410 +@subsection Public key with GOST R 34.10-2012 GOST R 34.10-2012 must be used with Streebog (GOST R 34.11-2012) hash function. Its digest must be big-endian serialised. Public key must be @@ -103,40 +104,45 @@ in @code{BE(X)||BE(Y)} format. Algorithm identifiers for the public key: @code{gost3410-256A}, @code{gost3410-512C}. -Public key's identifier and @code{cid} should be calculated using -big-endian Streebog-256 hash. +Public key's identifier should be calculated using big-endian +Streebog-256 hash. -@node cer-ed25519-blake2b -@subsection cer with Ed25519-BLAKE2b +@node cm-pub-ed25519-blake2b +@cindex cm-pub-ed25519-blake2b +@subsection Public key with Ed25519-BLAKE2b Same calculation and serialisation rules must be used as with -@code{@ref{pki-signed-ed25519-blake2b}}. -Public key's identifier and @code{cid} should be calculated -using BLAKE2b hash with 128 or 256 bit output length specified. -Algorithm identifiers for the public key: @code{ed25519ph-blake2b}, +@code{@ref{cm-signed-ed25519-blake2b}}. -@node cer-sntrup4591761-x25519 -@subsection cer with SNTRUP4591761+X25519 +Public key's identifier should be calculated using BLAKE2b hash with 128 +or 256 bit output length specified. -Certificate with combined Streamlined NTRU Prime 4591^761 and Curve25519 -public keys is used for KEM purposes, so should have "kem" key usage set. +Algorithm identifier for the public key: @code{ed25519ph-blake2b}. + +@node cm-pub-sntrup4591761-x25519 +@cindex cm-pub-sntrup4591761-x25519 +@subsection Public key with SNTRUP4591761+X25519 + +Combined Streamlined NTRU Prime 4591^761 and Curve25519 public keys are +used for KEM purposes, so should have "kem" key usage set. Its algorithm identifier is @code{sntrup4591761-x25519}. Its public key value is a concatenation of 1218-byte SNTRUP4591761 public key and 32-byte Curve25519 one. -Public key's identifier and @code{cid} should be calculated -using BLAKE2b hash with 128 or 256 bit output length specified. +Public key's identifier should be calculated using BLAKE2b hash with 128 +or 256 bit output length specified. -@node cer-mceliece6960119-x25519 -@subsection cer with Classic McEliece 6960-119+x25519 +@node cm-pub-mceliece6960119-x25519 +@cindex cm-pub-mceliece6960119-x25519 +@subsection Public key with Classic McEliece 6960-119+x25519 -Certificate with combined Classic McEliece 6960-119 and Curve25519 -public keys is used for KEM purposes, so should have "kem" key usage set. +Combined Classic McEliece 6960-119 and Curve25519 public keys are used +for KEM purposes, so should have "kem" key usage set. Its algorithm identifier is @code{mceliece6960119-x25519}. Its public key value is a concatenation of 1047319-byte @code{mceliece6960119} public key and 32-byte Curve25519 one. -Public key's identifier and @code{cid} should be calculated -using either SHAKE128 or SHAKE256 hash. +Public key's identifier should be calculated using either SHAKE128 or +SHAKE256 hash. diff --git a/spec/format/registry.texi b/spec/format/registry.texi index 9b9d337..5b7b528 100644 --- a/spec/format/registry.texi +++ b/spec/format/registry.texi @@ -9,28 +9,28 @@ There is example registry of known algorithm identifiers. @table @code @item blake2b, blake2b256 - @code{@ref{cer-ed25519-blake2b}}, - @code{@ref{pki-hashed-blake2b}}, - @code{@ref{pki-signed-ed25519-blake2b}} + @code{@ref{cm-pub-ed25519-blake2b}}, + @code{@ref{cm-hashed-blake2b}}, + @code{@ref{cm-signed-ed25519-blake2b}} @item blake2b-merkle - @code{@ref{pki-hashed-blake2b-merkle}}, - @code{@ref{pki-signed-ed25519-blake2b-merkle}} + @code{@ref{cm-hashed-blake2b-merkle}}, + @code{@ref{cm-signed-ed25519-blake2b-merkle}} @item blake3 - @code{@ref{pki-hashed-blake3}} + @code{@ref{cm-hashed-blake3}} @item sha2-256, sha2-512 - @code{@ref{pki-hashed-sha2}} + @code{@ref{cm-hashed-sha2}} @item shake128, shake256 - @code{@ref{pki-hashed-shake}} + @code{@ref{cm-hashed-shake}} @item shake128-merkle, shake256-merkle - @code{@ref{pki-hashed-shake-merkle}} + @code{@ref{cm-hashed-shake-merkle}} @item skein512 - @code{@ref{pki-hashed-skein512}} + @code{@ref{cm-hashed-skein512}} @item streebog256, streebog512 - @code{@ref{pki-hashed-gost3411}} + @code{@ref{cm-hashed-gost3411}} @item streebog256-merkle, streebog512-merkle - @code{@ref{pki-hashed-gost3411-merkle}} + @code{@ref{cm-hashed-gost3411-merkle}} @item xxh3-128 - @code{@ref{pki-hashed-xxh3-128}} + @code{@ref{cm-hashed-xxh3-128}} @end table @node AI DH @@ -39,8 +39,8 @@ There is example registry of known algorithm identifiers. @table @code @item ecdsa-nist256p, ecdsa-nist521p @item gost3410-256A, gost3410-512C - @code{@ref{cer-gost3410}}, - @code{@ref{private-key-gost3410}} + @code{@ref{cm-pub-gost3410}}, + @code{@ref{cm-prv-gost3410}} @item x25519 @item x448 @end table @@ -50,9 +50,9 @@ There is example registry of known algorithm identifiers. @table @code @item chacha20poly1305 - @code{@ref{pki-encrypted-chacha20poly1305}} + @code{@ref{cm-encrypted-chacha20poly1305}} @item kuznechik-ctracpkm-hmac-hkdf - @code{@ref{pki-encrypted-kuznechik-ctracpkm-hmac-hkdf}} + @code{@ref{cm-encrypted-kuznechik-ctracpkm-hmac-hkdf}} @end table @node AI KEM @@ -61,18 +61,18 @@ There is example registry of known algorithm identifiers. @table @code @item argon2id-hkdf-blake2b @item balloon-blake2b-hkdf - @code{@ref{pki-encrypted-balloon-blake2b-hkdf}} + @code{@ref{cm-encrypted-balloon-blake2b-hkdf}} @item gost3410-hkdf-kexp15 - @code{@ref{pki-encrypted-gost3410-hkdf-kexp15}} + @code{@ref{cm-encrypted-gost3410-hkdf-kexp15}} @item mceliece6960119-x25519-hkdf-shake256 - @code{@ref{pki-encrypted-mceliece6960119-x25519-hkdf-shake256}} + @code{@ref{cm-encrypted-mceliece6960119-x25519-hkdf-shake256}} @item mlkem768-x25519 @item sntrup761-x25519 @item sntrup4591761-x25519 - @code{@ref{cer-sntrup4591761-x25519}}, - @code{@ref{private-key-sntrup4591761-x25519}} + @code{@ref{cm-pub-sntrup4591761-x25519}}, + @code{@ref{cm-prv-sntrup4591761-x25519}} @item sntrup4591761-x25519-hkdf-blake2b - @code{@ref{pki-encrypted-sntrup4591761-x25519-hkdf-blake2b}} + @code{@ref{cm-encrypted-sntrup4591761-x25519-hkdf-blake2b}} @item sntrup761-x25519-hkdf-blake2b @end table @@ -82,25 +82,25 @@ There is example registry of known algorithm identifiers. @table @code @item ecdsa-nist256p, ecdsa-nist521p @item ed25519-blake2b - @code{@ref{private-key-ed25519-blake2b}} - @code{@ref{pki-signed-ed25519-blake2b}}, - @code{@ref{cer-ed25519-blake2b}} + @code{@ref{cm-prv-ed25519-blake2b}} + @code{@ref{cm-signed-ed25519-blake2b}}, + @code{@ref{cm-pub-ed25519-blake2b}} @item ed25519-blake2b-merkle - @code{@ref{pki-signed-ed25519-blake2b-merkle}} + @code{@ref{cm-signed-ed25519-blake2b-merkle}} @item ed448 @item gost3410-256A, gost3410-512C - @code{@ref{cer-gost3410}}, - @code{@ref{private-key-gost3410}}, - @code{@ref{pki-signed-gost3410}} + @code{@ref{cm-pub-gost3410}}, + @code{@ref{cm-prv-gost3410}}, + @code{@ref{cm-signed-gost3410}} @item gost3410-256A-merkle, gost3410-512C-merkle - @code{@ref{pki-signed-gost3410-merkle}} + @code{@ref{cm-signed-gost3410-merkle}} @end table @node AI Content types @subsection Content types @itemize -@item @ref{cer, @code{cer}} -@item @ref{pki-signed, @code{data}} -@item @ref{private-key, @code{prv}} +@item @ref{cm-pub, @code{pub}} +@item @ref{cm-signed, @code{data}} +@item @ref{cm-prv, @code{prv}} @end itemize diff --git a/spec/format/signed-prehash.cddl b/spec/format/signed-prehash.cddl index 0d3c686..4f94c22 100644 --- a/spec/format/signed-prehash.cddl +++ b/spec/format/signed-prehash.cddl @@ -1,4 +1,4 @@ -pki-signed-prehash = { +cm-signed-prehash = { t: "prehash", sigs: set, ; set of signature algorithm identifiers (/sigs/*/sign/a) } diff --git a/spec/format/signed.cddl b/spec/format/signed.cddl index cb7077d..062f051 100644 --- a/spec/format/signed.cddl +++ b/spec/format/signed.cddl @@ -1,18 +1,18 @@ ai = text ; algorithm identifier -pki-signed = { +cm-signed = { load: { t: text, ? v: bytes / text / map / list, }, sigs: [+ sig], - ? certs: [+ cer], + ? pubs: [+ cm-pub], } sig = { tbs: sig-tbs, sign: {a: ai, v: bytes}, - ? cer-loc: [+ url], + ? pub-loc: [+ url], * text => any } diff --git a/spec/format/signed.texi b/spec/format/signed.texi index 76946f7..88fa8df 100644 --- a/spec/format/signed.texi +++ b/spec/format/signed.texi @@ -1,12 +1,12 @@ -@node pki-signed -@cindex pki-signed -@section pki-signed format +@node cm-signed +@cindex cm-signed +@section cm-signed format That resembles @url{https://datatracker.ietf.org/doc/html/rfc5652, CMS} (PKCS#7) ASN.1-based format. -Stored in a file, it should begin with "pki/signed" @ref{Magic, magic}, -unless it is a @ref{cer, certificate}. +Stored in a file, it should begin with "cm/signed" @ref{Magic, magic}, +unless it is a @ref{cm-pub, public key}. @verbatiminclude format/signed.cddl @@ -17,19 +17,19 @@ Signature is created by signing the: @end verbatim If no @code{/load/v} is provided, then the data is detached from the -@code{pki-signed} structure itself and it is fed into hasher before that +@code{cm-signed} structure itself and it is fed into hasher before that structure. You can provide it any way you wish, but for keeping that -detached data closely to the @code{pki-signed}, you should use the +detached data closely to the @code{cm-signed}, you should use the following approach: @verbatim -pki-signed-prehash || BLOB(detached-data) || pki-signed +cm-signed-prehash || BLOB(detached-data) || cm-signed @end verbatim @verbatiminclude format/signed-prehash.cddl -With @code{pki-signed-prehash} you initialise your hashers used during -signing process and fed BLOB's contents (not the encoded BLOB itself!) +With @code{cm-signed-prehash} you initialise your hashers used during +signing process and feed BLOB's contents (not the encoded BLOB itself!) into the them. @code{/sigs/*/tbs/when} is optional signing time. @@ -38,16 +38,17 @@ Additional values that must be protected (covered by signature) are placed in @code{/sigs/*/tbs} map. Non-protected (informational) fields are placed outside it. -@code{/certs} are optionally provided @ref{cer, certificates} to +@code{/pubs} are optionally provided @ref{cm-pub, public keys} to help creating the whole verification chain. They are placed outside @code{/sigs}, because some of them may be shared among signers. -If signed data is also intended to be @ref{pki-encrypted, encrypted}, +If signed data is also intended to be @ref{cm-encrypted, encrypted}, then @code{/sigs/*/tbs/encrypted-binding} should be set to -@ref{pki-encrypted, encrypted}'s @code{/bind} value. +@ref{cm-encrypted, encrypted}'s @code{/bind} value. -@node pki-signed-gost3410 -@subsection pki-signed with GOST R 34.10-2012 +@node cm-signed-gost3410 +@cindex cm-signed-gost3410 +@subsection Signed data with GOST R 34.10-2012 GOST R 34.10-2012 must be used with Streebog (GOST R 34.11-2012) hash function. Its digest must be big-endian serialised. Signature @@ -56,17 +57,19 @@ then @code{/sigs/*/tbs/encrypted-binding} should be set to Algorithm identifiers for the signature: @code{gost3410-256A}, @code{gost3410-512C}. -@node pki-signed-gost3410-merkle -@subsection pki-signed with GOST R 34.10-2012 with Merkle-tree hashing +@node cm-signed-gost3410-merkle +@cindex cm-signed-gost3410-merkle +@subsection Signed data with GOST R 34.10-2012 with Merkle-tree hashing - @ref{pki-hashed-gost3411-merkle} Merkle-tree hashing is used. + @ref{cm-hashed-gost3411-merkle} Merkle-tree hashing is used. Algorithm identifiers for the signature: @code{gost3410-256A-merkle}, @code{gost3410-512C-merkle}. -@node pki-signed-ed25519-blake2b -@subsection pki-signed with Ed25519-BLAKE2b +@node cm-signed-ed25519-blake2b +@cindex cm-signed-ed25519-blake2b +@subsection Signed data with Ed25519-BLAKE2b @url{https://datatracker.ietf.org/doc/html/rfc8032, EdDSA} with Edwards25519 is used similarly as in RFC 8032. But BLAKE2b is used @@ -82,9 +85,10 @@ then @code{/sigs/*/tbs/encrypted-binding} should be set to hash, using @code{ed25519ph-blake2b} algorithm identifier for signature. -@node pki-signed-ed25519-blake2b-merkle -@subsection pki-signed with Ed25519-BLAKE2b with Merkle-tree hashing +@node cm-signed-ed25519-blake2b-merkle +@cindex cm-signed-ed25519-blake2b-merkle +@subsection Signed data with Ed25519-BLAKE2b with Merkle-tree hashing - @ref{pki-hashed-blake2b-merkle} Merkle-tree hashing is used. + @ref{cm-hashed-blake2b-merkle} Merkle-tree hashing is used. HashEdDSA mode is used with @code{ed25519ph-blake2b-merkle} algorithm identifier for signature. -- 2.50.0