From f7d2c65559a5149e4923554695a99540abdcc56f Mon Sep 17 00:00:00 2001 From: Linus Nordberg Date: Wed, 23 Mar 2022 09:12:26 +0100 Subject: follow SSHSIG changes in lib --- cmd/sigsum/cmd.go | 19 +++++++++++-------- pkg/client/submitter.go | 4 ++-- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/cmd/sigsum/cmd.go b/cmd/sigsum/cmd.go index 70a1c51..417e68d 100644 --- a/cmd/sigsum/cmd.go +++ b/cmd/sigsum/cmd.go @@ -66,15 +66,18 @@ func cmdBundle(args []string, policy policy.Policy, optBundleType, optBundleKey, } req := requests.Leaf{ - Statement: types.Statement{ - ShardHint: policy.ShardHint(), - Checksum: *checksum, - }, + ShardHint: policy.ShardHint(), + Preimage: *checksum, Signature: *sig, VerificationKey: *pub, DomainHint: optBundleDomainHint, } - if !req.Statement.Verify(&req.VerificationKey, &req.Signature) { + + sd := types.SignedData{ + ShardHint: req.ShardHint, + Checksum: *types.HashFn(req.Preimage[:]), + } + if !sd.Verify(&req.VerificationKey, &req.Signature) { return fmt.Errorf("bundle: invalid signature for file %q", path) } reqs = append(reqs, req) @@ -103,12 +106,12 @@ func cmdFormat(args []string, policy policy.Policy) error { if err != nil { return fmt.Errorf("format: %v", err) } - stm := types.Statement{ + sd := types.SignedData{ ShardHint: policy.ShardHint(), - Checksum: *checksum, + Checksum: *types.HashFn(checksum[:]), } - fmt.Printf("%s", stm.ToBinary()) + fmt.Printf("%s", sd.ToBinary()) return nil } diff --git a/pkg/client/submitter.go b/pkg/client/submitter.go index f03e66a..21c9258 100644 --- a/pkg/client/submitter.go +++ b/pkg/client/submitter.go @@ -73,9 +73,9 @@ func (sc *SubmitClient) AddLeaves(_ context.Context, leaves []requests.Leaf) ([] bundles = nil for _, leaf := range leaves { l := types.Leaf{ - Statement: types.Statement{ + SignedData: types.SignedData{ ShardHint: leaf.ShardHint, - Checksum: leaf.Checksum, + Checksum: *types.HashFn(leaf.Preimage[:]), }, Signature: leaf.Signature, KeyHash: *types.HashFn(leaf.VerificationKey[:]), -- cgit v1.2.3 From cdc373563cb620068a6c436678bba3f276be015b Mon Sep 17 00:00:00 2001 From: Linus Nordberg Date: Wed, 23 Mar 2022 12:08:18 +0100 Subject: add support for signing with ssh-keygen TODO: add tests --- cmd/sigsum/test/keys/ssh | 7 ++++ cmd/sigsum/test/keys/ssh.pub | 1 + cmd/sigsum/test/ssh.sh | 53 ++++++++++++++++++++++++++ go.mod | 5 ++- go.sum | 11 ++++++ pkg/signatures/ssh/ssh.go | 89 +++++++++++++++++++++++++++++++++++++++++++- 6 files changed, 163 insertions(+), 3 deletions(-) create mode 100644 cmd/sigsum/test/keys/ssh create mode 100644 cmd/sigsum/test/keys/ssh.pub create mode 100755 cmd/sigsum/test/ssh.sh diff --git a/cmd/sigsum/test/keys/ssh b/cmd/sigsum/test/keys/ssh new file mode 100644 index 0000000..2bbd974 --- /dev/null +++ b/cmd/sigsum/test/keys/ssh @@ -0,0 +1,7 @@ +-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW +QyNTUxOQAAACC/0wdPezO/W1upVq2RduQ/ieEHn0r6LgwkXEINfJ52fQAAAJCRqZKpkamS +qQAAAAtzc2gtZWQyNTUxOQAAACC/0wdPezO/W1upVq2RduQ/ieEHn0r6LgwkXEINfJ52fQ +AAAEClIbTUqSPBTrfD9MCpwTF1Fwit4NXU2ci3R57uq4Aic7/TB097M79bW6lWrZF25D+J +4QefSvouDCRcQg18nnZ9AAAACmxpbnVzQGJlc2sBAgM= +-----END OPENSSH PRIVATE KEY----- diff --git a/cmd/sigsum/test/keys/ssh.pub b/cmd/sigsum/test/keys/ssh.pub new file mode 100644 index 0000000..14588ac --- /dev/null +++ b/cmd/sigsum/test/keys/ssh.pub @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL/TB097M79bW6lWrZF25D+J4QefSvouDCRcQg18nnZ9 linus@besk diff --git a/cmd/sigsum/test/ssh.sh b/cmd/sigsum/test/ssh.sh new file mode 100755 index 0000000..56cae70 --- /dev/null +++ b/cmd/sigsum/test/ssh.sh @@ -0,0 +1,53 @@ +#!/bin/bash + +set -eu +trap cleanup EXIT + +priv=keys/ssh +pub=keys/ssh.pub +domain_hint=_sigsum_v0.ssh.test.sigsum.org +msg=msg-$(date +%s) +num_msg=3 + +function cleanup() { + set +e + + rm -f sigsum + for i in $(seq 1 $num_msg); do + rm -f $msg-$i{,.trunnel,.sig} + done + + exit +} + +go build ../ + +files="" +for i in $(seq 1 $num_msg); do + echo $msg-$i > $msg-$i + if ! openssl dgst -binary $msg-$i | ssh-keygen \ + -Y sign \ + -O hashalg=sha256 \ + -f $priv \ + -n $(./sigsum namespace) > $msg-$i.sig ; then + echo "[FAIL] sign for $num_msg ssh message(s)" >&2 + exit 1 + fi + files=$(echo -n $files $msg-$i) +done + +echo "[PASS] sign for $num_msg ssh message(s)" >&2 + +if ! ./sigsum bundle -t ssh -k $pub -d $domain_hint $files; then + echo "[FAIL] bundle for $num_msg ssh message(s)" >&2 + exit 1 +fi + +echo "[PASS] bundle for $num_msg ssh message(s)" >&2 + +if ! ./sigsum verify -t ssh -k $pub $files; then + echo "[FAIL] verify for $num_msg ssh message(s)" >&2 + exit 1 +fi + +echo "[PASS] verify for $num_msg ssh message(s)" >&2 diff --git a/go.mod b/go.mod index a7699f5..4b09be4 100644 --- a/go.mod +++ b/go.mod @@ -2,4 +2,7 @@ module git.sigsum.org/sigsum-tool-go go 1.15 -require git.sigsum.org/sigsum-lib-go v0.0.2 +require ( + git.sigsum.org/sigsum-lib-go v0.0.2 + golang.org/x/crypto v0.0.0-20220321153916-2c7772ba3064 +) diff --git a/go.sum b/go.sum index 03ffc2d..c098457 100644 --- a/go.sum +++ b/go.sum @@ -1,2 +1,13 @@ git.sigsum.org/sigsum-lib-go v0.0.2 h1:1FwdnraPaasw1D1Lb+flRMJRGLTuZrp17AZ6tx+iT/0= git.sigsum.org/sigsum-lib-go v0.0.2/go.mod h1:DVmlcf0MBHy4IZdnZ5DcbsKkGEd0EkOAoLINhLgcndY= +golang.org/x/crypto v0.0.0-20220321153916-2c7772ba3064 h1:S25/rfnfsMVgORT4/J61MJ7rdyseOZOyvLIrZEZ7s6s= +golang.org/x/crypto v0.0.0-20220321153916-2c7772ba3064/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/pkg/signatures/ssh/ssh.go b/pkg/signatures/ssh/ssh.go index d5fb8f4..99b2a48 100644 --- a/pkg/signatures/ssh/ssh.go +++ b/pkg/signatures/ssh/ssh.go @@ -3,20 +3,105 @@ package ssh import ( "fmt" "io" + "io/ioutil" + "encoding/pem" + sshLib "golang.org/x/crypto/ssh" "git.sigsum.org/sigsum-lib-go/pkg/types" ) type Parser struct{} +const ( + BLOB_PREAMBLE = "SSHSIG" + SIG_VERSION = 0x01 + HASH_ALGO = "sha256" +) + +type sshBlob struct { + MagicPreamble [6]byte + SigVersion uint32 + PublicKey string + Namespace string + Reserved string + HashAlgorithm string + Signature string +} + +type sshKeypart struct { + Type string + Key string +} + func (p *Parser) SignatureSuffix() string { return ".sig" } func (p *Parser) PublicKey(r io.Reader) (*types.PublicKey, error) { - return nil, fmt.Errorf("TODO") + b, err := ioutil.ReadAll(r) + if err != nil { + return nil, fmt.Errorf("ssh: read failed: %v", err) + } + var pub types.PublicKey + if err := parsePub(pub[:], b); err != nil { + return nil, fmt.Errorf("ssh: %v", err) + } + return &pub, nil } func (p *Parser) Signature(r io.Reader) (*types.Signature, error) { - return nil, fmt.Errorf("TODO") + b, err := ioutil.ReadAll(r) + if err != nil { + return nil, fmt.Errorf("ssh: signature read failed: %v", err) + } + + block, rest := pem.Decode(b) + if len(rest) > 0 { + return nil, fmt.Errorf("ssh: invalid signature rest: %v", rest) + } + if block == nil { + return nil, fmt.Errorf("ssh: invalid signature PEM format") + } + if block.Type != "SSH SIGNATURE" { + return nil, fmt.Errorf("ssh: invalid signature PEM type: %v", block.Type) + } + + var blob sshBlob + if err := sshLib.Unmarshal(block.Bytes, &blob); err != nil { + return nil, fmt.Errorf("ssh: invalid signature format: %v", err) + } + if string(blob.MagicPreamble[:]) != BLOB_PREAMBLE { + return nil, fmt.Errorf("ssh: invalid signature magic: %s", string(blob.MagicPreamble[:])) + } + if blob.SigVersion != SIG_VERSION { + return nil, fmt.Errorf("ssh: invalid signature version: %d", blob.SigVersion) + } + if blob.HashAlgorithm != HASH_ALGO { + return nil, fmt.Errorf("ssh: invalid signature hash algorithm: %s", blob.HashAlgorithm) + } + + var sshSig sshLib.Signature + if err := sshLib.Unmarshal([]byte(blob.Signature), &sshSig); err != nil { + return nil, fmt.Errorf("ssh: invalid signature blob: %v", err) + } + + var sig types.Signature + copy(sig[:], sshSig.Blob) + + return &sig, nil +} + +func parsePub(dst, data []byte) error { + pubkey, _, _, _, err := sshLib.ParseAuthorizedKey(data) + if err != nil { + return fmt.Errorf("ssh.ParseAuthorizedKey: %s", err) + } + + var keyPart sshKeypart + if err := sshLib.Unmarshal(pubkey.Marshal(), &keyPart); err != nil { + return fmt.Errorf("ssh: invalid pubkey: %v", err) + } + + copy(dst[:], keyPart.Key) + return nil } -- cgit v1.2.3 From 150244638cd425313523f4c95a353fdeea9f593a Mon Sep 17 00:00:00 2001 From: Linus Nordberg Date: Thu, 24 Mar 2022 14:00:02 +0100 Subject: get rid of the last traces of "checksum" --- cmd/sigsum/cmd.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cmd/sigsum/cmd.go b/cmd/sigsum/cmd.go index 417e68d..fc2274e 100644 --- a/cmd/sigsum/cmd.go +++ b/cmd/sigsum/cmd.go @@ -50,7 +50,7 @@ func cmdBundle(args []string, policy policy.Policy, optBundleType, optBundleKey, var reqs []requests.Leaf for _, path := range args { - checksum, err := fileHash(path) + preimage, err := fileHash(path) if err != nil { return fmt.Errorf("bundle: %v", err) } @@ -67,7 +67,7 @@ func cmdBundle(args []string, policy policy.Policy, optBundleType, optBundleKey, req := requests.Leaf{ ShardHint: policy.ShardHint(), - Preimage: *checksum, + Preimage: *preimage, Signature: *sig, VerificationKey: *pub, DomainHint: optBundleDomainHint, @@ -102,13 +102,13 @@ func cmdFormat(args []string, policy policy.Policy) error { return fmt.Errorf("format: need exactly one file") } - checksum, err := fileHash(args[0]) + preimage, err := fileHash(args[0]) if err != nil { return fmt.Errorf("format: %v", err) } sd := types.SignedData{ ShardHint: policy.ShardHint(), - Checksum: *types.HashFn(checksum[:]), + Checksum: *types.HashFn(preimage[:]), } fmt.Printf("%s", sd.ToBinary()) -- cgit v1.2.3 From ee322c9e18b9675aab08f4c9f38f6be19b1d6890 Mon Sep 17 00:00:00 2001 From: Rasmus Dahlberg Date: Wed, 13 Apr 2022 15:04:44 +0200 Subject: minor edits to make sshsig stuff compile --- cmd/sigsum/cmd.go | 4 ++-- go.mod | 2 +- go.sum | 2 ++ pkg/client/submitter.go | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/cmd/sigsum/cmd.go b/cmd/sigsum/cmd.go index fc2274e..69598d5 100644 --- a/cmd/sigsum/cmd.go +++ b/cmd/sigsum/cmd.go @@ -73,7 +73,7 @@ func cmdBundle(args []string, policy policy.Policy, optBundleType, optBundleKey, DomainHint: optBundleDomainHint, } - sd := types.SignedData{ + sd := types.Statement{ ShardHint: req.ShardHint, Checksum: *types.HashFn(req.Preimage[:]), } @@ -106,7 +106,7 @@ func cmdFormat(args []string, policy policy.Policy) error { if err != nil { return fmt.Errorf("format: %v", err) } - sd := types.SignedData{ + sd := types.Statement{ ShardHint: policy.ShardHint(), Checksum: *types.HashFn(preimage[:]), } diff --git a/go.mod b/go.mod index 4b09be4..034a726 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,6 @@ module git.sigsum.org/sigsum-tool-go go 1.15 require ( - git.sigsum.org/sigsum-lib-go v0.0.2 + git.sigsum.org/sigsum-lib-go v0.0.3 golang.org/x/crypto v0.0.0-20220321153916-2c7772ba3064 ) diff --git a/go.sum b/go.sum index c098457..d21009f 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,7 @@ git.sigsum.org/sigsum-lib-go v0.0.2 h1:1FwdnraPaasw1D1Lb+flRMJRGLTuZrp17AZ6tx+iT/0= git.sigsum.org/sigsum-lib-go v0.0.2/go.mod h1:DVmlcf0MBHy4IZdnZ5DcbsKkGEd0EkOAoLINhLgcndY= +git.sigsum.org/sigsum-lib-go v0.0.3 h1:VXtUC/LOPVb990P8dFitQkYx8a1M54hKFcsK7MiZ514= +git.sigsum.org/sigsum-lib-go v0.0.3/go.mod h1:DVmlcf0MBHy4IZdnZ5DcbsKkGEd0EkOAoLINhLgcndY= golang.org/x/crypto v0.0.0-20220321153916-2c7772ba3064 h1:S25/rfnfsMVgORT4/J61MJ7rdyseOZOyvLIrZEZ7s6s= golang.org/x/crypto v0.0.0-20220321153916-2c7772ba3064/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= diff --git a/pkg/client/submitter.go b/pkg/client/submitter.go index 21c9258..a1345bc 100644 --- a/pkg/client/submitter.go +++ b/pkg/client/submitter.go @@ -73,7 +73,7 @@ func (sc *SubmitClient) AddLeaves(_ context.Context, leaves []requests.Leaf) ([] bundles = nil for _, leaf := range leaves { l := types.Leaf{ - SignedData: types.SignedData{ + Statement: types.Statement{ ShardHint: leaf.ShardHint, Checksum: *types.HashFn(leaf.Preimage[:]), }, -- cgit v1.2.3