package document import ( "bytes" "crypto/openpgp" "fmt" "testing" ) var signedData = []struct { text string ok bool hash string body string sig string }{ { `-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 body -----BEGIN PGP SIGNATURE----- sig `, true, "SHA1", "body", "-----BEGIN PGP SIGNATURE-----\nsig\n"}, { `-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hash: SHA256 - body -----BEGIN PGP SIGNATURE----- sig `, false, "", "body", "-----BEGIN PGP SIGNATURE-----\nsig\n"}, } func TestSigned(t *testing.T) { for _, x := range signedData { c, err := ParseSigned([]byte(x.text)) if err != nil { t.Errorf("parsing %q failed: %s\n", x.text, err) continue } if string(c.Body) != x.body { t.Errorf("expected: %q, got %q\n", x.body, c.Body) } if string(c.Signature) != x.sig { t.Errorf("expected: %q, got %q\n", x.sig, c.Signature) } } for _, x := range signedData { if !x.ok { continue } c := &Signed{x.hash, []byte(x.body), []byte(x.sig)} s, err := FormatSigned(c) if err != nil { t.Errorf("formating %#v failed: %s\n", c, err) continue } if string(s) != x.text { t.Errorf("expected: %q, got %q\n", x.text, s) } } } var docData = []struct { text string ok bool t string k []string v []string }{ { `Content-Type: text/vnd.epoint.draft; charset=utf-8 K1: v1 K2-Foo: v 2 K3: v 3 `, true, "Draft", []string{"K1", "K2-Foo", "K3"}, []string{"v1", "v 2", "v 3"}}, { `Content-Type: text/vnd.epoint.debit; charset=utf-8 K1: v1 K2-Foo: v 2 K3: v 3 `, true, "DebitCert", []string{"K1", "K2-Foo", "K3"}, []string{" v1", "v 2", "v 3"}}, { `Content-Type: text/vnd.epoint.credit; charset=utf-8 K1: v1 K2-Foo: v 2 K3: v 3 `, false, "CreditCert", []string{"K1", "K2-Foo", "K3"}, []string{"v1", "v 2", "v 3"}}, } func TestDocument(t *testing.T) { for _, x := range docData { doc, err := ParseDocument([]byte(x.text)) if err != nil { t.Errorf("parsing %q failed: %s\n", x.text, err) continue } if string(doc.Type) != x.t { t.Errorf("expected: %q, got %q\n", x.t, doc.Type) } if len(doc.Fields) != len(x.k) { t.Errorf("expected: %d fields, got %d\n", len(x.k), len(doc.Fields)) } for i, k := range x.k { if doc.Fields[k] != x.v[i] { t.Errorf("value of %s expected to be %s, got %s\n", k, x.v[i], doc.Fields[k]) } } } for _, x := range docData { if !x.ok { continue } doc := new(Document) doc.Type = x.t doc.Fields = make(map[string]string) doc.Order = x.k for i, k := range x.k { doc.Fields[k] = x.v[i] } s, err := FormatDocument(doc) if err != nil { t.Errorf("formating %#v failed: %s\n", doc, err) continue } if string(s) != x.text { t.Errorf("expected: %q, got %q\n", x.text, s) } } } const draftBody = `Content-Type: text/vnd.epoint.draft; charset=utf-8 Drawer: 000000000000000000000000000000000000000A Beneficiary: 000000000000000000000000000000000000000B Amount: 1 Denomination: half euro Issuer: 000000000000000000000000000000000000000D Authorized-By: 000000000000000000000000000000000000000C Maturity-Date: 2011-11-13T12:20:35Z Expiry-Date: 2011-12-27T09:18:46Z Nonce: 42 Notes: some notes ` func TestDraft(t *testing.T) { doc, err := ParseDocument([]byte(draftBody)) if err != nil { t.Errorf("ParseDocument failed: %s\n", err) return } iv, err := ParseStruct(doc) if err != nil { t.Errorf("ParseStruct %v failed: %s\n", doc, err) return } d, ok := iv.(*Draft) if !ok { t.Errorf("expected *Draft got %#v\n", iv) return } doc, err = FormatStruct(d) if err != nil { t.Errorf("format %v draft failed: %s\n", d, err) return } s, err := FormatDocument(doc) if err != nil { t.Errorf("format %v doc failed: %s\n", doc, err) return } if string(s) != draftBody { t.Errorf("parsed %#v\nexpected: %s\ngot: %s\n", d, draftBody, s) } } const debitBody = `Content-Type: text/vnd.epoint.debit; charset=utf-8 Holder: 0000000000000000000000000000000000000009 Serial: 13 Balance: 23 Denomination: half euro Issuer: 000000000000000000000000000000000000000B Date: 2011-11-13T12:20:35Z Authorized-By: 000000000000000000000000000000000000000A Notes: - Last-Debit-Serial: 0 Last-Credit-Serial: 12 Last-Cert: 000000000000000000000000000000000000000C References: 000000000000000000000000000000000000000C 000000000000000000000000000000000000000F Difference: 1 Draft: 000000000000000000000000000000000000000D Beneficiary: 000000000000000000000000000000000000000E ` func TestCert(t *testing.T) { doc, err := ParseDocument([]byte(debitBody)) if err != nil { t.Errorf("ParseDocument failed: %s\n", err) return } iv, err := ParseStruct(doc) if err != nil { t.Errorf("ParseStruct %v failed: %s\n", doc, err) return } d, ok := iv.(*DebitCert) if !ok { t.Errorf("expected *DebitCert got %#v\n", iv) return } doc, err = FormatStruct(d) if err != nil { t.Errorf("format %v draft failed: %s\n", d, err) return } s, err := FormatDocument(doc) if err != nil { t.Errorf("format %v doc failed: %s\n", doc, err) return } if string(s) != debitBody { t.Errorf("parsed %#v\nexpected: %s\ngot: %s\n", d, debitBody, s) } } func parsekey(key []byte) (*openpgp.Entity, error) { elist, err := openpgp.ReadArmoredKeyRing(bytes.NewBuffer(key)) if err != nil { return nil, err } if len(elist) != 1 { return nil, fmt.Errorf("expected one key, got %d", len(elist)) } return elist[0], nil } func TestSign(t *testing.T) { k1, err := parsekey(skey1) if err != nil { t.Errorf("parsing key1 failed: %s", err) return } k2, err := parsekey(pkey2) if err != nil { t.Errorf("parsing key2 failed: %s", err) return } signed, err := Sign([]byte(debitBody), k1) if err != nil { t.Errorf("Sign failed: %s", err) return } err = Verify(signed, openpgp.EntityList{k1}) if err != nil { t.Errorf("Verify failed: %s", err) } err = Verify(signed, openpgp.EntityList{k2}) if err == nil { t.Errorf("Verify succeeded with wrong key") } } func debitcert() (d *DebitCert, err error) { doc, err := ParseDocument([]byte(debitBody)) if err != nil { return } iv, err := ParseStruct(doc) if err != nil { return } d, ok := iv.(*DebitCert) if !ok { err = fmt.Errorf("expecetd *DebitCert, got %T", d) } return } func BenchmarkSign(b *testing.B) { d, err := debitcert() if err != nil { panic(err) } b.ResetTimer() for i := 0; i < b.N; i++ { k, err := parsekey(skey1) if err != nil { panic(err) } _, _, err = Format(d, k) if err != nil { panic(err) } } } func BenchmarkVerify(b *testing.B) { d, err := debitcert() if err != nil { panic(err) } k, err := parsekey(skey1) if err != nil { panic(err) } s, _, err := Format(d, k) if err != nil { panic(err) } b.ResetTimer() for i := 0; i < b.N; i++ { k, err := parsekey(skey1) if err != nil { panic(err) } _, signed, err := Parse(s) if err != nil { panic(err) } err = Verify(signed, openpgp.EntityList{k}) if err != nil { panic(err) } } } var skey1 = []byte(`-----BEGIN PGP PRIVATE KEY BLOCK----- xcD7BAAAAAARBACk0rlXXCXw5iK4aUOHEop5PhrSfRL/9LW6EaN879Mck1vLsKlE WBpubaEphvy6nWZmB9cdNlwoa5vLV/bZOL50mCt9dwzkOPA7CiCroC5WkUWMOdlu boauVkF27Rpt+6+27nZ0zF7c+f62FYRx+z+rU7oc4bpkxWJrnoWF/O9dMQCg//// /////////yVOr555FtYHqq8D/36lyJh3e+S7KdzcRyiecY9ydMnNflcNPVUvOz7k PD3ve6aOV3hpJlIMyscduhPzfEBkOV1a8zNKBKvYztXn/0dsZhlTk26K3elqOdjE rBCAor4/6GOiSwi9Q4J+VK+tpyQzcE6jwS5Q5b0IwTDGihQC/CDaec/g3pMcQUNI 0ysQBACIdEX3XRinq+oFm3+YFu5bC1Ewry7eVxukto18dtMJnU69oMjF3x7Uio5A kvYNWYPxdtLjEzk/HMo/3Mg6u/jK006CPqZRcx/m3B5R7gYb5D9PyF/tJsrht4nD eDuCAT00kHKYMElgwSzXg03cFcC5AEMf6U7MsrX1JLwY5Dq12gAAoOX6RPKzHB+1 U7YCHnNg0H1dkf9eCuzNBklzc3VlcsJMBBMRCAAWBQIAAAAACRCRl3ps/DHg6wIZ AQIbAwAAIroAoBn5gA6TmLKXU9ASu+ENhV0UxowzAKA9Y/4CiQzAeCDcKIcWCg7W 3r6Jow== =NVdT -----END PGP PRIVATE KEY BLOCK----- `) var pkey2 = []byte(`-----BEGIN PGP PUBLIC KEY BLOCK----- xsDiBAAAAAARBACk0rlXXCXw5iK4aUOHEop5PhrSfRL/9LW6EaN879Mck1vLsKlE WBpubaEphvy6nWZmB9cdNlwoa5vLV/bZOL50mCt9dwzkOPA7CiCroC5WkUWMOdlu boauVkF27Rpt+6+27nZ0zF7c+f62FYRx+z+rU7oc4bpkxWJrnoWF/O9dMQCg//// /////////yVOr555FtYHqq8D/36lyJh3e+S7KdzcRyiecY9ydMnNflcNPVUvOz7k PD3ve6aOV3hpJlIMyscduhPzfEBkOV1a8zNKBKvYztXn/0dsZhlTk26K3elqOdjE rBCAor4/6GOiSwi9Q4J+VK+tpyQzcE6jwS5Q5b0IwTDGihQC/CDaec/g3pMcQUNI 0ysQBACFl7Go0A5UqlnmwRmsLfvAEBM2+tsIoBlBDEwcgd+nJZzCQpAqO/OpSqHk Yx4imGcdknfPLkMmN+Kz9j4o0T+LZuYyblhuj2t1M9lf0Is/Go0Drf/7oc2KpHAo nfKu7fkM5nfZWFsgE9TxOz8SQa2RuuhpbkpB2k0Vg2TbqTpFeM0GSXNzdWVywkwE ExEIABYFAgAAAAAJEKqJF6U/VQ52AhkBAhsDAADIMwCgt/kmhRwmlzcnc1S3Qlfo BD0PBa8AoG5Vm9U4gzWQM/BzVxDToJPB1ZHf =MNqN -----END PGP PUBLIC KEY BLOCK----- `)