diff options
Diffstat (limited to 'pkg')
-rw-r--r-- | pkg/client/submitter.go | 2 | ||||
-rw-r--r-- | pkg/signatures/ssh/ssh.go | 89 |
2 files changed, 88 insertions, 3 deletions
diff --git a/pkg/client/submitter.go b/pkg/client/submitter.go index 412890f..287bac3 100644 --- a/pkg/client/submitter.go +++ b/pkg/client/submitter.go @@ -75,7 +75,7 @@ func (sc *SubmitClient) AddLeaves(_ context.Context, leaves []requests.Leaf) ([] l := types.Leaf{ Statement: types.Statement{ ShardHint: leaf.ShardHint, - Checksum: leaf.Checksum, + Checksum: *types.HashFn(leaf.Preimage[:]), }, Signature: leaf.Signature, KeyHash: *types.HashFn(leaf.VerificationKey[:]), 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 } |