fdPubR := os.NewFile(FdPubR, "pub-in")
fdPrvR := os.NewFile(FdPrvR, "prv-in")
- pub, _, err := sign.PubParse(mustReadAll(fdPubR))
- if err != nil {
- log.Fatal(err)
+ var pubs []*sign.PubLoad
+ var err error
+ {
+ data := mustReadAll(fdPubR)
+ for len(data) > 0 {
+ var signed *sign.Signed
+ signed, data, err = sign.PubParse(data)
+ if err != nil {
+ log.Fatal(err)
+ }
+ pubs = append(pubs, signed.PubLoad())
+ }
+ fdPubR.Close()
}
- fdPubR.Close()
stdin := bufio.NewReaderSize(os.Stdin, BlobChunkLen)
if *verify {
err = decoder.UnmarshalStruct(&prehash)
}
var signed sign.Signed
- var hasher hash.Hash
+ hashers := make(map[string]hash.Hash)
if err == nil && prehash.T == mode.PrehashT {
- if len(prehash.Sigs) > 1 {
- log.Fatal("prehash: currently only single signature support")
- }
+ dsts := make([]io.Writer, 0, len(prehash.Sigs)+1)
+ dsts = append(dsts, os.Stdout)
for algo := range prehash.Sigs {
- hasher = cmhash.ByName(algo)
- }
- if hasher == nil {
- log.Fatal("prehash: unsupported algorithm")
+ hasher := cmhash.ByName(algo)
+ if hasher == nil {
+ log.Fatalln("prehash: unsupported algorithm:", algo)
+ }
+ hashers[algo] = hasher
+ dsts = append(dsts, hasher)
}
var blob *keks.BlobDecoder
blob, err = keks.NewBlobDecoder(stdin, 1<<32)
log.Fatal(err)
}
var chunk []byte
- mw := io.MultiWriter(hasher, os.Stdout)
+ mw := io.MultiWriter(dsts...)
for {
chunk, err = blob.Next()
if err != nil {
if err != nil {
log.Fatal(err)
}
- if len(signed.Sigs) == 0 {
- log.Fatal("no sigs")
- }
- if len(signed.Sigs) > 1 {
- log.Fatal("prehash: currently only single signature support")
- }
- signer := pub.PubLoad()
if signed.Load.T != *typ {
log.Fatalln("differing load type:", signed.Load.T)
}
- sig := signed.Sigs[0]
- var tbs *sign.TBS
- tbs, err = sig.TBSGet()
- if err != nil {
- log.Fatal(err)
- }
- if len(encryptedTo) > 0 {
- if len(tbs.EncryptedTo) == 0 {
- log.Fatal("missing encrypted-to")
- }
- found := false
- for _, their := range tbs.EncryptedTo {
- for _, our := range encryptedTo {
- if bytes.Equal(our, their) {
- found = true
- break
+ for _, sig := range signed.Sigs {
+ sid := sig.TBS["sid"].([]byte)
+ var signerFound bool
+ for _, pub := range pubs {
+ if !bytes.Equal(sid, pub.Id) {
+ continue
+ }
+ signerFound = true
+ var tbs *sign.TBS
+ tbs, err = sig.TBSGet()
+ if err != nil {
+ log.Fatal(err)
+ }
+ if len(encryptedTo) > 0 {
+ if len(tbs.EncryptedTo) == 0 {
+ log.Fatalln(hex.EncodeToString(sid), "missing encrypted-to")
+ }
+ found := false
+ for _, their := range tbs.EncryptedTo {
+ for _, our := range encryptedTo {
+ if bytes.Equal(our, their) {
+ found = true
+ break
+ }
+ }
+ }
+ if !found {
+ log.Fatalln(
+ hex.EncodeToString(sid),
+ "corresponding encrypted-to not found")
}
}
+ var hasher hash.Hash
+ if prehash.T == "" {
+ hasher = cmhash.ByName(sig.Sign.A)
+ if _, err = io.Copy(hasher, stdin); err != nil {
+ log.Fatal(hex.EncodeToString(sid), err)
+ }
+ } else {
+ var found bool
+ hasher, found = hashers[sig.Sign.A]
+ if !found {
+ log.Fatalln(hex.EncodeToString(sid), "no hasher in prehash")
+ }
+ }
+ if err = signed.CertificationCheckSignatureFrom(
+ pub, &hasher,
+ ); err != nil {
+ log.Fatalln(hex.EncodeToString(sid), err)
+ }
+ break
}
- if !found {
- log.Fatalln("corresponding encrypted-to not found")
- }
- }
- if prehash.T == "" {
- hasher = cmhash.ByName(sig.Sign.A)
- if _, err = io.Copy(hasher, stdin); err != nil {
- log.Fatal(err)
+ if !signerFound {
+ log.Fatalln(hex.EncodeToString(sid), "can not find signer")
}
}
- if err = signed.CertificationCheckSignatureFrom(signer, &hasher); err != nil {
- log.Fatal(err)
- }
} else {
var signer sign.Iface
signer, _, err = sign.PrvParse(mustReadAll(fdPrvR))
if len(encryptedTo) > 0 {
tbs["encrypted-to"] = encryptedTo
}
- if err = signed.SignWith(pub.PubLoad(), signer, tbs); err != nil {
+ if err = signed.SignWith(pubs[0], signer, tbs); err != nil {
log.Fatal(err)
}
if _, err = keks.Encode(os.Stdout, signed, nil); err != nil {
parent *PubLoad,
prehasher *hash.Hash,
) (err error) {
- if len(signed.Sigs) != 1 {
- err = errors.New("can verify only single signature")
- return
- }
if !parent.Can(KUSig) || len(parent.Pub) != 1 {
err = errors.New("parent can not sign")
return
}
- sig := signed.Sigs[0]
- if !bytes.Equal(sig.TBS["sid"].([]byte), parent.Id) {
- err = errors.New("sid != parent pub id")
- return
- }
- if prehasher == nil {
- var tbs bytes.Buffer
- if _, err = keks.Encode(&tbs, signed.Load, nil); err != nil {
- return
+ for _, sig := range signed.Sigs {
+ if !bytes.Equal(sig.TBS["sid"].([]byte), parent.Id) {
+ continue
}
- if _, err = keks.Encode(&tbs, sig.TBS, nil); err != nil {
- return
- }
- return parent.CheckSignature(sig.Sign.A, tbs.Bytes(), sig.Sign.V)
- } else {
- if _, err = keks.Encode(*prehasher, signed.Load, nil); err != nil {
- return
- }
- if _, err = keks.Encode(*prehasher, sig.TBS, nil); err != nil {
- return
+ if prehasher == nil {
+ var tbs bytes.Buffer
+ if _, err = keks.Encode(&tbs, signed.Load, nil); err != nil {
+ return
+ }
+ if _, err = keks.Encode(&tbs, sig.TBS, nil); err != nil {
+ return
+ }
+ return parent.CheckSignature(sig.Sign.A, tbs.Bytes(), sig.Sign.V)
+ } else {
+ if _, err = keks.Encode(*prehasher, signed.Load, nil); err != nil {
+ return
+ }
+ if _, err = keks.Encode(*prehasher, sig.TBS, nil); err != nil {
+ return
+ }
+ return parent.CheckSignaturePrehash(
+ sig.Sign.A, (*prehasher).Sum(nil), sig.Sign.V)
}
- return parent.CheckSignaturePrehash(sig.Sign.A, (*prehasher).Sum(nil), sig.Sign.V)
}
+ return errors.New("can not find necessary sid")
}
// Get PubLoad from Signed.