From 8da382069f42f6d88d3abf914dd38d7e40a845bc Mon Sep 17 00:00:00 2001 From: Rasmus Dahlberg Date: Wed, 2 Mar 2022 23:16:43 +0100 Subject: initial commit --- pkg/signatures/signify/signify.go | 91 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 pkg/signatures/signify/signify.go (limited to 'pkg/signatures/signify') diff --git a/pkg/signatures/signify/signify.go b/pkg/signatures/signify/signify.go new file mode 100644 index 0000000..6dbbf07 --- /dev/null +++ b/pkg/signatures/signify/signify.go @@ -0,0 +1,91 @@ +package signify + +import ( + "bytes" + "encoding/base64" + "fmt" + "io" + "io/ioutil" + + "git.sigsum.org/sigsum-lib-go/pkg/types" +) + +type Parser struct{} + +func (p *Parser) SignatureSuffix() string { + return ".sig" +} + +func (p *Parser) PublicKey(r io.Reader) (*types.PublicKey, error) { + b, err := ioutil.ReadAll(r) + if err != nil { + return nil, fmt.Errorf("signify: read failed: %v", err) + } + var pub types.PublicKey + if err := parse(pub[:], b); err != nil { + return nil, fmt.Errorf("signify: %v", err) + } + return &pub, nil +} + +func (p *Parser) Signature(r io.Reader) (*types.Signature, error) { + b, err := ioutil.ReadAll(r) + if err != nil { + return nil, fmt.Errorf("signify: read failed: %v", err) + } + var sig types.Signature + if err := parse(sig[:], b); err != nil { + return nil, fmt.Errorf("signify: %v", err) + } + return &sig, nil +} + +func parse(dst, lines []byte) error { + commentLine, dataLine, err := parseLines(lines) + if err != nil { + return fmt.Errorf("invalid: %v", err) + } + if err := parseCommentLine(commentLine); err != nil { + return fmt.Errorf("invalid: %v", err) + } + if err := parseDataLine(dst, dataLine); err != nil { + return fmt.Errorf("invalid: %v", err) + } + return nil +} + +func parseLines(lines []byte) ([]byte, []byte, error) { + split := bytes.Split(lines, []byte("\n")) + if len(split) != 3 { + return nil, nil, fmt.Errorf("number of lines") + } + return split[0], split[1], nil +} + +func parseCommentLine(line []byte) error { + if !bytes.HasPrefix(line, []byte("untrusted comment: ")) { + return fmt.Errorf("no untrusted comment") + } + return nil +} + +func parseDataLine(dst, line []byte) error { + data, err := base64.StdEncoding.DecodeString(string(line)) + if err != nil { + return fmt.Errorf("base64 encoding") + } + if len(data) < 2 || !bytes.Equal(data[:2], []byte("Ed")) { + return fmt.Errorf("algorithm") + } + data = data[2:] + if len(data) < 8 { + return fmt.Errorf("random fingerprint") + } + data = data[8:] + if len(data) != len(dst) { + return fmt.Errorf("data length") + } + + copy(dst[:], data) + return nil +} -- cgit v1.2.3