PUBKEY-CM.pub.asc | 9 +++++---- c/lib/cm/pub.c | 41 +++++++++++++++++++++++++++-------------- c/lib/cm/pub.h | 4 ++-- go/cm/cmd/cmenctool/main.go | 10 +++++----- go/cm/cmd/cmkeytool/main.go | 18 +++++++++--------- go/cm/cmd/cmsigtool/main.go | 18 +++++++++--------- go/cm/sign/pub.go | 72 +++++++++++++++++++++++++++++------------------------ go/cm/sign/signed.go | 36 +++++++++++++++++++++--------------- spec/cm/encrypted/authcrypt | 2 +- spec/cm/kem/mceliece6960119-x25519-hkdf-shake256 | 5 ++--- spec/cm/pub/index | 28 ++++++++++++++-------------- spec/cm/pub/mceliece6960119-x25519 | 4 ++-- spec/cm/signed/index | 6 +++--- spec/schema/tcl | 2 +- tcl/schemas/pub-load.tcl => tcl/schemas/pub-data.tcl | 2 +- tcl/schemas/pub.tcl | 10 +++++----- tcl/schemas/signed.tcl | 14 +++++++------- diff --git a/PUBKEY-CM.pub b/PUBKEY-CM.pub index 5e6bc0f10fb3397b40840454685fb1835bd809512f1bb5bac856757653ec75dc..015e8c7919c75d210f5bf9cf7b47c5dd67b048017d0ae17ae747e9388439944c 100644 Binary files a/PUBKEY-CM.pub and b/PUBKEY-CM.pub differ diff --git a/PUBKEY-CM.pub.asc b/PUBKEY-CM.pub.asc index 45e9c40ad9b17b33f90b06f0aa1bd10bdbc066d677fd7f3bed0dd4a2528a7257..5a3c3305d2bc36af1932debdd6230123e63a2e342981d168f3db5c89208fd1f4 100644 --- a/PUBKEY-CM.pub.asc +++ b/PUBKEY-CM.pub.asc @@ -1,7 +1,8 @@ -----BEGIN PGP SIGNATURE----- -iHUEABYKAB0WIQTbL/jtRAp+lJhvt3bSI36ECQhstwUCaGEDswAKCRDSI36ECQhs -twPcAPwLJuuTjhU3y6sSRNqr/69Q452vv1a2TWUNxTCyxCPd0wD/fWPvM/PxO8aW -lt/Yfko5vPVbnwFP/GczCzugHFGWZws= -=ydWw +iJEEABYKADkWIQTbL/jtRAp+lJhvt3bSI36ECQhstwUCaNf4oBsUgAAAAAAEAA5t +YW51MiwyLjUrMS4xMSwyLDMACgkQ0iN+hAkIbLcCQAEAzsCbtqjkxqxtKWuK5qYb +dDgrkPU2J7c4nq8OVnvLfXoBANcnFYroJtAKt3xQYO9I3My8vLBH68pkFHFj9WTR +sPIO +=HAQ6 -----END PGP SIGNATURE----- diff --git a/c/lib/cm/pub.c b/c/lib/cm/pub.c index 25b9601c0bef37f2603ab2cca2456cd5b3d61d9d4a14b73bf01294ba930a3791..678ff53c199acb2273a78ccdce1e384104697ca4b62e605a3235a76e5aba3ede 100644 --- a/c/lib/cm/pub.c +++ b/c/lib/cm/pub.c @@ -61,7 +61,7 @@ if (errSchema.code != KEKSSchemaErrNo) { (*failReason) = "schema failed"; return KEKSErrUnsatisfiedSchema; } - size_t idx = KEKSItemsGetByKey(items, KEKSItemsGetByKey(items, 0, "load"), "v"); + size_t idx = KEKSItemsGetByKey(items, 0, "data"); cer->pub = KEKSItemsGetByKey(items, idx, "pub"); cer->pub = items->list[cer->pub].atom.v.list.head; cer->sub = KEKSItemsGetByKey(items, idx, "sub"); @@ -74,7 +74,7 @@ if (idx == 0) { return KEKSErrNo; } if (items->list[idx].atom.v.list.len != 1) { - (*failReason) = "len(/load/sigs) != 1"; + (*failReason) = "len(/sigs) != 1"; return KEKSErrUnsatisfiedSchema; } cer->sig = items->list[idx].atom.v.list.head; @@ -154,24 +154,37 @@ unsigned char buf[(uint16_t)1 << (uint8_t)10] = {0}; size_t off = 0; if (!KEKSItemsEncode( &(cer->items), - KEKSItemsGetByKey(&(cer->items), 0, "load"), + KEKSItemsGetByKey(&(cer->items), 0, "data"), &off, buf, cap)) { - (*failReason) = "can not prepare tbs: load"; + (*failReason) = "can not prepare tbs: data"; return false; } - size_t off2 = 0; - if (!KEKSItemsEncode( - &(cer->items), - KEKSItemsGetByKey(&(cer->items), cer->sig, "tbs"), - &off2, - buf + off, - cap - off)) { - (*failReason) = "can not prepare tbs: tbs"; - return false; + { + size_t off2 = 0; + if (!KEKSItemsEncode( + &(cer->items), + KEKSItemsGetByKey(&(cer->items), 0, "tbs"), + &off2, + buf + off, + cap - off)) { + (*failReason) = "can not prepare tbs: tbs"; + return false; + } + off += off2; + off2 = 0; + if (!KEKSItemsEncode( + &(cer->items), + KEKSItemsGetByKey(&(cer->items), cer->sig, "tbs"), + &off2, + buf + off, + cap - off)) { + (*failReason) = "can not prepare tbs: sig-tbs"; + return false; + } + off += off2; } - off += off2; for (size_t i = 0; opts.sigVerifiers[i].algo != NULL; i++) { if (!KEKSStrEqual(&(pubA->atom), opts.sigVerifiers[i].algo)) { diff --git a/c/lib/cm/pub.h b/c/lib/cm/pub.h index ac831d010586e32f3cd228a82c9ab064c8781290f7c3dfcbb9b962f12bba7242..50cfc510a050d1d18832c240541265518edf125aa632e986f2cb0d16de7ab038 100644 --- a/c/lib/cm/pub.h +++ b/c/lib/cm/pub.h @@ -15,9 +15,9 @@ // @table @code // @item .items // Holds parsed @ref{KEKSItems} items. // @item .pub -// Items index of the first @code{/load/v/pub}, certificate's public key. +// Items index of the first @code{/data/pub}, certificate's public key. // @item .sub -// Items index of the @code{/load/v/sub}, certificate's subject. +// Items index of the @code{/data/sub}, certificate's subject. // @item .sig // Items index of the first @code{/sigs}, certificate's signature. // @item .cid diff --git a/go/cm/cmd/cmenctool/main.go b/go/cm/cmd/cmenctool/main.go index ed64e5381f95a5572c122f58b5b3cf3f712680d6a0146fed2c6950460176b0dc..e0e55761c5b30268e9a7d054bbe0bd58c67c0fe06576aa0b9cbc0a8cdbbbc921 100644 --- a/go/cm/cmd/cmenctool/main.go +++ b/go/cm/cmd/cmenctool/main.go @@ -122,18 +122,18 @@ signed, data, err = sign.PubParse(data) if err != nil { log.Fatalln("public key:", len(pubs), ":", err) } - load := signed.PubLoad() - if !load.Can(sign.KUKEM) { + pubData := signed.PubData() + if !pubData.Can(sign.KUKEM) { log.Println( "public key:", len(pubs), ": does not have", sign.KUKEM, "key usage", ) } - if len(load.Pub) != 1 { + if len(pubData.Pub) != 1 { log.Fatalln("public key:", len(pubs), ": expected single public key") } - pubs = append(pubs, load.Pub[0]) - pubIds = append(pubIds, load.Id) + pubs = append(pubs, pubData.Pub[0]) + pubIds = append(pubIds, pubData.Id) } } fdPubR.Close() diff --git a/go/cm/cmd/cmkeytool/main.go b/go/cm/cmd/cmkeytool/main.go index 545c39146fd6348398c0371405bef4d1671a780a83c7d54a05b52dd81fbfdebf..8481ce96cd6e7a1c977f753294d48dc1ea97aa62f778f61ce369a7c5bd990f5a 100644 --- a/go/cm/cmd/cmkeytool/main.go +++ b/go/cm/cmd/cmkeytool/main.go @@ -166,9 +166,9 @@ return } var prvRaw []byte - var pubLoad map[string]any + var pubData map[string]any if doCertify { - pubLoad = (*signed.Load.V).(map[string]any) + pubData = (*signed.Data).(map[string]any) } else { var pub []byte switch *algo { @@ -201,7 +201,7 @@ log.Fatal(err) } } { - pubLoad = map[string]any{ + pubData = map[string]any{ "sub": sub, "pub": []cm.AV{{A: *algo, V: pub}}, } @@ -216,28 +216,28 @@ hasher = cmhash.ByName(cmhash.SHAKE128) default: log.Fatal("unsupported algorithm") } - _, err = keks.Encode(hasher, pubLoad["pub"], nil) + _, err = keks.Encode(hasher, pubData["pub"], nil) if err != nil { log.Fatal(err) } - pubLoad["id"] = hasher.Sum(nil) + pubData["id"] = hasher.Sum(nil) if err != nil { log.Fatal(err) } } if len(ku) > 0 { - pubLoad["ku"] = ku + pubData["ku"] = ku } } { - pubLoadAny := any(pubLoad) - signed = &sign.Signed{Load: sign.Load{T: "pub", V: &pubLoadAny}} + pubLoadAny := any(pubData) + signed = &sign.Signed{TBS: sign.SDTBS{T: "pub"}, Data: &pubLoadAny} } if doCertify { if err = signed.CertifyWith( - caPubs[0].PubLoad(), caPrv, since, till, + caPubs[0].PubData(), caPrv, since, till, ); err != nil { log.Fatal(err) } diff --git a/go/cm/cmd/cmsigtool/main.go b/go/cm/cmd/cmsigtool/main.go index af99ab004b7e88be677a030e16102059499a570895ff6b211a2e4868dd1b7037..c0ef13dc012e4325c7af8646695df9a205204ad6a462e5b8485c5e5980288a75 100644 --- a/go/cm/cmd/cmsigtool/main.go +++ b/go/cm/cmd/cmsigtool/main.go @@ -72,7 +72,7 @@ fdPubR := os.NewFile(FdPubR, "pub-in") fdPrvR := os.NewFile(FdPrvR, "prv-in") - var pubs []*sign.PubLoad + var pubs []*sign.PubData var err error { data := mustReadAll(fdPubR) @@ -82,7 +82,7 @@ signed, data, err = sign.PubParse(data) if err != nil { log.Fatal(err) } - pubs = append(pubs, signed.PubLoad()) + pubs = append(pubs, signed.PubData()) } fdPubR.Close() } @@ -155,8 +155,8 @@ err = decoder.UnmarshalStruct(&signed) if err != nil { log.Fatal(err) } - if signed.Load.T != *typ { - log.Fatalln("differing load type:", signed.Load.T) + if signed.TBS.T != *typ { + log.Fatalln("differing load type:", signed.TBS.T) } for _, sig := range signed.Sigs { sid := sig.TBS["sid"].([]byte) @@ -166,17 +166,17 @@ if !bytes.Equal(sid, pub.Id) { continue } signerFound = true - var tbs *sign.TBS - tbs, err = sig.TBSGet() + var sigTBS *sign.SigTBS + sigTBS, err = sig.TBSGet() if err != nil { log.Fatal(err) } if len(encryptedTo) > 0 { - if len(tbs.EncryptedTo) == 0 { + if len(sigTBS.EncryptedTo) == 0 { log.Fatalln(hex.EncodeToString(sid), "missing encrypted-to") } found := false - for _, their := range tbs.EncryptedTo { + for _, their := range sigTBS.EncryptedTo { for _, our := range encryptedTo { if bytes.Equal(our, their) { found = true @@ -268,7 +268,7 @@ log.Fatal(err) } } var signed sign.Signed - signed.Load.T = *typ + signed.TBS.T = *typ tbs := make(map[string]any) if !*noWhen { tbs["when"] = time.Now().UTC().Truncate(time.Millisecond) diff --git a/go/cm/sign/pub.go b/go/cm/sign/pub.go index 898b6a515330ac7a91e33131dddaa60b0fd45b0be7c03297413fc41472261ce1..fedc13da4b53f24d234e13fdb9d9c8e46f948e41964056464d86cf5a6f27efe2 100644 --- a/go/cm/sign/pub.go +++ b/go/cm/sign/pub.go @@ -45,8 +45,8 @@ ErrSigInvalid = errors.New("signature is invalid") ErrBadSigAlgo = errors.New("bad signature algo") ) -// Public key load. -type PubLoad struct { +// Public key' contents. +type PubData struct { KU map[string]*struct{} `keks:"ku"` Sub map[string]string `keks:"sub"` Crit []map[string]any `keks:"crit"` @@ -54,7 +54,7 @@ Pub []cm.AV `keks:"pub"` Id []byte `keks:"id"` } -// Parse KEKS-encoded data as Signed with the PubLoad (certificate) contents. +// Parse KEKS-encoded data as Signed with the PubData (certificate) contents. func PubParse(data []byte) (signed *Signed, tail []byte, err error) { { var magic keks.Magic @@ -84,23 +84,23 @@ return } tail = d.B signed = &sd - if sd.Load.T != "pub" { + if sd.TBS.T != "pub" { err = errors.New("PubParse: wrong load type") } return } // Check if public key has desired ku capability. -func (pub *PubLoad) Can(ku string) (yes bool) { +func (pub *PubData) Can(ku string) (yes bool) { _, yes = pub.KU[ku] return } -// Sign the provided Signed, having PubLoad payload with the provided -// parent's PubLoad and prv key. Certification CID will be automatically +// Sign the provided Signed, having PubData payload with the provided +// parent's PubData and prv key. Certification CID will be automatically // generated UUIDv7. since and till times must not have nanoseconds part. func (signed *Signed) CertifyWith( - parent *PubLoad, + parent *PubData, prv Iface, since, till time.Time, ) error { @@ -116,7 +116,7 @@ } // Verify signature of signed data. ErrSigInvalid will be returned in // case of invalid signature. -func (pub *PubLoad) CheckSignature(algo string, signed, signature []byte) (err error) { +func (pub *PubData) CheckSignature(algo string, signed, signature []byte) (err error) { if !pub.Can(KUSig) || len(pub.Pub) != 1 { err = errors.New("pub can not sign") return @@ -156,7 +156,7 @@ } // Verify signature of signed data, by providing prehashed data. // ErrSigInvalid will be returned in case of invalid signature. -func (pub *PubLoad) CheckSignaturePrehash( +func (pub *PubData) CheckSignaturePrehash( algo string, prehash, signature []byte, ) (err error) { @@ -208,11 +208,11 @@ } return } -// Verify Signed PubLoad certification signature with provided parent. +// Verify Signed PubData 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) CertificationCheckSignatureFrom( - parent *PubLoad, + parent *PubData, prehasher *hash.Hash, ) (err error) { if !parent.Can(KUSig) || len(parent.Pub) != 1 { @@ -225,7 +225,10 @@ continue } if prehasher == nil { var tbs bytes.Buffer - if _, err = keks.Encode(&tbs, signed.Load, nil); err != nil { + if _, err = keks.Encode(&tbs, signed.Data, nil); err != nil { + return + } + if _, err = keks.Encode(&tbs, signed.TBS, nil); err != nil { return } if _, err = keks.Encode(&tbs, sig.TBS, nil); err != nil { @@ -233,7 +236,10 @@ return } return parent.CheckSignature(sig.Sign.A, tbs.Bytes(), sig.Sign.V) } else { - if _, err = keks.Encode(*prehasher, signed.Load, nil); err != nil { + if _, err = keks.Encode(*prehasher, signed.Data, nil); err != nil { + return + } + if _, err = keks.Encode(*prehasher, signed.TBS, nil); err != nil { return } if _, err = keks.Encode(*prehasher, sig.TBS, nil); err != nil { @@ -246,38 +252,38 @@ } return errors.New("can not find necessary sid") } -// Get PubLoad from Signed. +// Get PubData from Signed. // Returns nil if Signed does not hold it (or it is not yet parsed). -func (signed *Signed) PubLoad() *PubLoad { - if signed.Load.T != "pub" || signed.Load.V == nil { +func (signed *Signed) PubData() *PubData { + if signed.TBS.T != "pub" || signed.Data == nil { return nil } - v, ok := (*signed.Load.V).(map[string]any) + v, ok := (*signed.Data).(map[string]any) if !ok { return nil } - var pubLoad PubLoad - err := keks.Map2Struct(&pubLoad, v) + var pubData PubData + err := keks.Map2Struct(&pubData, v) if err != nil { return nil } - return &pubLoad + return &pubData } -// Verify signed Signed PubLoad certification against pubs chain of +// Verify signed Signed PubData certification against pubs chain of // public keys at specified point of time t. func (signed *Signed) CertificationVerify(pubs []*Signed, t time.Time) (err error) { if len(signed.Sigs) == 0 { return errors.New("no sigs") } - var tbs *TBS - tbs, err = signed.Sigs[0].TBSGet() + var sigTBS *SigTBS + sigTBS, err = signed.Sigs[0].TBSGet() if err != nil { return } { - exp := tbs.Exp + exp := sigTBS.Exp if t.Before(exp[0]) || t.Equal(exp[0]) { err = errors.New("pub is not active") return @@ -287,26 +293,26 @@ err = errors.New("pub is expired") return } } - sid := tbs.SID - if bytes.Equal(sid, signed.PubLoad().Id) { - return signed.CertificationCheckSignatureFrom(signed.PubLoad(), nil) + sid := sigTBS.SID + if bytes.Equal(sid, signed.PubData().Id) { + return signed.CertificationCheckSignatureFrom(signed.PubData(), nil) } type FPR [FPRLen]byte idToPub := make(map[FPR]*Signed, len(pubs)) for _, cer := range pubs { - pubLoad := cer.PubLoad() - if !pubLoad.Can(KUSig) || len(pubLoad.Pub) != 1 { + pubData := cer.PubData() + if !pubData.Can(KUSig) || len(pubData.Pub) != 1 { err = errors.New("pub can not sign") return } - idToPub[FPR(pubLoad.Id)] = cer + idToPub[FPR(pubData.Id)] = cer } signer := idToPub[FPR(sid)] if signer == nil { - err = fmt.Errorf("no pub found for sid: %v", tbs.SID) + err = fmt.Errorf("no pub found for sid: %v", sigTBS.SID) return } - err = signed.CertificationCheckSignatureFrom(signer.PubLoad(), nil) + err = signed.CertificationCheckSignatureFrom(signer.PubData(), nil) if err != nil { return } diff --git a/go/cm/sign/signed.go b/go/cm/sign/signed.go index 8a41b3a16c0090ae2a88bdc6a325e541d111dc0a057c4fbe605b986ce36f0a34..9997d843abcec97f6921355892e7fe7d64bf50a2b032d1ebf9d1d094689b69d7 100644 --- a/go/cm/sign/signed.go +++ b/go/cm/sign/signed.go @@ -32,20 +32,19 @@ ) const SignedMagic = keks.Magic("cm/signed") -type Load struct { - V *any `keks:"v,omitempty"` +type SDTBS struct { T string `keks:"t"` } -type TBS struct { +type SigTBS struct { EncryptedTo [][]byte `keks:"encrypted-to"` Exp []time.Time `keks:"exp"` SID []byte `keks:"sid"` CID uuid.UUID `keks:"cid"` } -func (sig *Sig) TBSGet() (*TBS, error) { - var tbs TBS +func (sig *Sig) TBSGet() (*SigTBS, error) { + var tbs SigTBS return &tbs, keks.Map2Struct(&tbs, sig.TBS) } @@ -55,7 +54,8 @@ Sign cm.AV `keks:"sign"` } type Signed struct { - Load Load `keks:"load"` + TBS SDTBS `keks:"tbs"` + Data *any `keks:"data,omitempty"` Pubs *[]*Signed `keks:"pubs,omitempty"` Sigs []*Sig `keks:"sigs,omitempty"` } @@ -93,38 +93,44 @@ signed = &sd return } -// Sign Signed's contents and tbs corresponding data with the +// Sign Signed's contents and sig-tbs corresponding data with the // 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, + parent *PubData, prv Iface, - tbs map[string]any, + sigTBS map[string]any, ) (err error) { if !parent.Can(KUSig) || len(parent.Pub) != 1 { return errors.New("parent can not sign") } - tbs["sid"] = parent.Id + sigTBS["sid"] = parent.Id var tbsRaw []byte if prv.Mode() == mode.Pure { var b bytes.Buffer - if _, err = keks.Encode(&b, signed.Load, nil); err != nil { + if _, err = keks.Encode(&b, signed.Data, nil); err != nil { + return + } + if _, err = keks.Encode(&b, signed.TBS, nil); err != nil { return } - if _, err = keks.Encode(&b, tbs, nil); err != nil { + if _, err = keks.Encode(&b, sigTBS, nil); err != nil { return } tbsRaw = b.Bytes() } else { - if _, err = keks.Encode(*prv.Prehasher(), signed.Load, nil); err != nil { + if _, err = keks.Encode(*prv.Prehasher(), signed.Data, nil); err != nil { + return + } + if _, err = keks.Encode(*prv.Prehasher(), signed.TBS, nil); err != nil { return } - if _, err = keks.Encode(*prv.Prehasher(), tbs, nil); err != nil { + if _, err = keks.Encode(*prv.Prehasher(), sigTBS, nil); err != nil { return } tbsRaw = (*prv.Prehasher()).Sum(nil) } - sig := Sig{TBS: tbs} + sig := Sig{TBS: sigTBS} sig.Sign.A = prv.Algo() sig.Sign.V, err = prv.Sign(rand.Reader, tbsRaw, crypto.Hash(0)) if err != nil { diff --git a/spec/cm/encrypted/authcrypt b/spec/cm/encrypted/authcrypt index 047fb0ffa33c7c8ecc596dbdfdabecce9be241520353e5005038b389c3ae63e8..67034d82fbbd413b5d3b1a73f39a23fbc91d24b14f4e2780f083027921b860e1 100644 --- a/spec/cm/encrypted/authcrypt +++ b/spec/cm/encrypted/authcrypt @@ -1,6 +1,6 @@ Public-key based [cm/kem/]s provides sender authentication *only* if "/kem/*/from" field is specified. It should contain public -key's "/load/v/id", but may be equal to 256-bit zeros, to explicitly +key's "/data/id", but may be equal to 256-bit zeros, to explicitly specify that sender's public key is used, but it is anonymous and hidden. It is not specified how recipient should find corresponding sender's key that way -- implementation/protocol specific. diff --git a/spec/cm/kem/mceliece6960119-x25519-hkdf-shake256 b/spec/cm/kem/mceliece6960119-x25519-hkdf-shake256 index 9436d2f9257fdb2fb27218143226bbb739d5cca22255a0794f4abe499e301095..c0a2e90e437a90dff6f7d11804b059ee61174af186ab677f70b9c94e24b24c2e 100644 --- a/spec/cm/kem/mceliece6960119-x25519-hkdf-shake256 +++ b/spec/cm/kem/mceliece6960119-x25519-hkdf-shake256 @@ -56,6 +56,5 @@ KEM combiner nearly fully resembles: => https://datatracker.ietf.org/doc/draft-josefsson-chempat/ Chempat -If sender/recipient's public key structure contains -"/load/v/prehash" field, then it could be used as already -calculated values of SHAKE256 calls of PRK. +If sender/recipient's public key structure contains "/data/prehash" field, +then it could be used as already calculated values of SHAKE256 calls of PRK. diff --git a/spec/cm/pub/index b/spec/cm/pub/index index ec16a972110c453fc5ccad8a840e0eeb28899d196c6c58e797596513ecc5e018..ea0e0cae86620f98d09bdd1708db46d55850a02e37337432a060a4b3672ffb43 100644 --- a/spec/cm/pub/index +++ b/spec/cm/pub/index @@ -2,9 +2,9 @@ do-backs Public key is the [cm/signed/] structure. Stored in a file, it should begin with "cm/pub" [encoding/MAGIC]. -Its "/load/t" equals to "pub". "/load/v" contains "cm/pub/load": +Its "/tbs/t" equals to "pub". "/data" contains: -<< [schemas/pub-load.tcl] +<< [schemas/pub-data.tcl] sub: Subject is a map of arbitrary strings. Currently no constraints on @@ -32,7 +32,7 @@ Application-specific example with multiple public keys is described above. It *must* be absent if empty. crit: Optional critical (in terms of X.509) extensions. Non-critical - ones may be placed outside that map, directly in cm/pub/load. + ones may be placed outside that map, directly in /data. It *must* be absent if empty. Values are extension specific. [cm/signed/]'s "tbs" *must* contain additional fields: @@ -48,19 +48,19 @@ Example minimal certified public key may look like: MAGIC cm/pub MAP { - load {MAP { + tbs {MAP { t {STR pub} - v {MAP { - id {BIN "6aee..."} - pub {LIST { - {MAP { - a {STR ed25519-blake2b} - v {BIN "c1bf..."} - }} - }} - sub {MAP { - N {STR test} + }} + data {MAP { + id {BIN "6aee..."} + pub {LIST { + {MAP { + a {STR ed25519-blake2b} + v {BIN "c1bf..."} }} + }} + sub {MAP { + N {STR test} }} }} sigs {LIST { diff --git a/spec/cm/pub/mceliece6960119-x25519 b/spec/cm/pub/mceliece6960119-x25519 index 68599cfa30c52be77a4edeba2d86a05458aeef642e74eec6def8902622624bb5..fd38517a1ccb8d6bc7ac88362c7dd2da0c7cae2848b98e00bd47dfc1dac85dbd 100644 --- a/spec/cm/pub/mceliece6960119-x25519 +++ b/spec/cm/pub/mceliece6960119-x25519 @@ -12,7 +12,7 @@ Public key's fingerprint should be calculated using SHAKE128. => https://keccak.team/ SHAKE XOF function -Optional "/load/v/prehash" field can contain the SHAKE256 hash -of the concatenated public keys in "/load/v/pub/0", that could +Optional "/data/prehash" field can contain the SHAKE256 hash +of the concatenated public keys in "/data/pub/0", that could save resources during [cm/kem/mceliece6960119-x25519-hkdf-shake256] KDF calculations. diff --git a/spec/cm/signed/index b/spec/cm/signed/index index 52ba03840423531cdc33c300729b7950bc14b64051eba5c8ea61f7a93fb40a84..a172be60c1fac3eaeebdc1ae4459e229ebb6030847ace3e42401d6941791f18a 100644 --- a/spec/cm/signed/index +++ b/spec/cm/signed/index @@ -20,15 +20,15 @@ << [schemas/fpr.tcl] Signature is created by signing the: - [detached-data] || /load || /sig/./tbs + data || /tbs || /sig/./tbs -If no "/load/v" is provided, then the data is detached from the +If no "/data" is provided, then the data is detached from the "cm/signed" structure itself and is fed into hasher before that structure. You can provide it any way you wish, but for keeping that detached data closely to the "cm/signed", you should use the following approach: - prehash || BLOB(detached-data) || cm/signed + prehash || BLOB(data) || cm/signed << [schemas/prehash.tcl] diff --git a/spec/schema/tcl b/spec/schema/tcl index 01d28bca94b59eae50522f245251b3a45439d0b08721050aa0ee49a38267ca12..a664a4cd001f734ec857c40bf2515eb493ac678ba5b2fbfad5052d8edaa6e1eb 100644 --- a/spec/schema/tcl +++ b/spec/schema/tcl @@ -30,7 +30,7 @@ And [cm/pub/] as: << [schemas/pub.tcl] << [schemas/fpr.tcl] -<< [schemas/pub-load.tcl] +<< [schemas/pub-data.tcl] << [schemas/pub-sig-tbs.tcl] schema.tcl calls "schemas {s0 cmds0 s1 cmds1 ...}" command to produce diff --git a/tcl/schemas/pub-load.tcl b/tcl/schemas/pub-data.tcl rename from tcl/schemas/pub-load.tcl rename to tcl/schemas/pub-data.tcl index dbc7d8f0a7b23ba6a4fa6f87257e515c0581f3fa8278eef38fc771006c5a8e28..3bdfcf1a11171d8d252e5c7f7c3d0b82c6a5894c827a0a19738af89e2bb14c18 100644 --- a/tcl/schemas/pub-load.tcl +++ b/tcl/schemas/pub-data.tcl @@ -1,4 +1,4 @@ -pub-load { +pub-data { {field . {map}} {field id {with fpr}} {field crit {} !exists} diff --git a/tcl/schemas/pub.tcl b/tcl/schemas/pub.tcl index 6e1c0ef47aad0ea0cd83ea181881f1a38bffa8f4e9c0219b1a330241f4903b99..f2ca6d9d92cb39ef0c2aa8ba14c454bbc528b1d54184573e9208d64f6dec3f2a 100644 --- a/tcl/schemas/pub.tcl +++ b/tcl/schemas/pub.tcl @@ -1,14 +1,14 @@ pub { {field . {map}} - {field load {with load}} - {field sigs {list} {of sig} >0 optional} + {field tbs {with tbs}} + {field data {with pub-data}} {field pubs {list} {of pub} >0 optional} + {field sigs {list} {of sig} >0 optional} } -load { +tbs { {field . {map}} {field t {str} =pub} - {field v {with pub-load}} } av { @@ -24,5 +24,5 @@ {field sign {with av}} } schema-include fpr.tcl -schema-include pub-load.tcl +schema-include pub-data.tcl schema-include pub-sig-tbs.tcl diff --git a/tcl/schemas/signed.tcl b/tcl/schemas/signed.tcl index 3ff6548b30fafd553900e34dcb49b0865ea318817cbf9de2c5eb937c3dc70f9d..0edbb4a81991452b60e9bb9f7488d6fb6ab8ae799f80e9b65a835661c3861553 100644 --- a/tcl/schemas/signed.tcl +++ b/tcl/schemas/signed.tcl @@ -3,24 +3,24 @@ schema-include fpr.tcl signed { {field . {map}} - {field load {with load}} + {field tbs {with tbs}} + {# field data is optional, arbitrary type} + {field pubs {list} {of type map} >0 optional} {field sigs {list} {of sig} >0 optional} - {field pubs {list} {of type map} >0 optional} } -load { +tbs { {field . {map}} - {field t {str} >0} - {# field v is optional, arbitrary type} + {field t {str} >0} {# type of the data we sign} } sig { {field . {map}} - {field tbs {with tbs}} + {field tbs {with sig-tbs}} {field sign {with av}} } -tbs { +sig-tbs { {field . {map}} {field sid {with fpr}} {field nonce {bin} >0 optional} {# random bytes}