1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package vsix
18
19 import (
20 "archive/zip"
21 "errors"
22 "io"
23 "os"
24 "path"
25
26 "github.com/beevik/etree"
27 "github.com/sassoftware/relic/lib/certloader"
28 "github.com/sassoftware/relic/lib/magic"
29 "github.com/sassoftware/relic/lib/pkcs7"
30 "github.com/sassoftware/relic/lib/pkcs9"
31 "github.com/sassoftware/relic/lib/xmldsig"
32 "github.com/sassoftware/relic/signers"
33 "github.com/sassoftware/relic/signers/zipbased"
34 )
35
36 var Signer = &signers.Signer{
37 Name: "vsix",
38 Magic: magic.FileTypeVSIX,
39 CertTypes: signers.CertTypeX509,
40 Transform: zipbased.Transform,
41 Sign: sign,
42 Verify: verify,
43 }
44
45 type zipFiles map[string]*zip.File
46
47 func init() {
48 signers.Register(Signer)
49 Signer.Flags().Bool("detach-certs", false, "(VSIX) Package certificates separately in the archive")
50 }
51
52 func sign(r io.Reader, cert *certloader.Certificate, opts signers.SignOpts) ([]byte, error) {
53 detachCerts := opts.Flags.GetBool("detach-certs")
54 m, err := mangleZip(r, opts.Hash)
55 if err != nil {
56 return nil, err
57 }
58
59 sigName := path.Join(xmlSigPath, calcFileName(cert.Leaf)+".psdsxs")
60 if err := m.newRels("", originPath, sigOriginType); err != nil {
61 return nil, err
62 }
63 if err := m.newRels(originPath, sigName, sigType); err != nil {
64 return nil, err
65 }
66 if err := m.addOrigin(); err != nil {
67 return nil, err
68 }
69
70 if detachCerts {
71 if err := m.addCerts(cert, sigName); err != nil {
72 return nil, err
73 }
74 }
75
76 sigfile, err := m.makeSignature(cert, opts, detachCerts)
77 if err != nil {
78 return nil, err
79 }
80 if err := m.m.NewFile(sigName, sigfile); err != nil {
81 return nil, err
82 }
83 if err := m.newCtypes(detachCerts); err != nil {
84 return nil, err
85 }
86 patch, err := m.m.MakePatch(true)
87 if err != nil {
88 return nil, err
89 }
90 return opts.SetBinPatch(patch)
91 }
92
93 func verify(f *os.File, opts signers.VerifyOpts) ([]*signers.Signature, error) {
94
95 size, err := f.Seek(0, io.SeekEnd)
96 if err != nil {
97 return nil, err
98 }
99 inz, err := zip.NewReader(f, size)
100 if err != nil {
101 return nil, err
102 }
103 files := make(zipFiles, len(inz.File))
104 for _, f := range inz.File {
105 files[f.Name] = f
106 }
107
108 sig, certs, err := readSignature(files)
109 if err != nil {
110 return nil, err
111 }
112 doc := etree.NewDocument()
113 if err := doc.ReadFromString(string(sig)); err != nil {
114 return nil, err
115 }
116 root := doc.Root()
117
118 xs, err := xmldsig.Verify(root, ".", certs)
119 if err != nil {
120 return nil, err
121 }
122
123 if err := checkManifest(files, xs.Reference); err != nil {
124 return nil, err
125 }
126
127 cs, err := checkTimestamp(root, xs.EncryptedDigest)
128 if err != nil {
129 return nil, err
130 }
131 psig := pkcs7.Signature{Intermediates: xs.Certificates, Certificate: xs.Leaf()}
132 if psig.Certificate == nil {
133 return nil, errors.New("leaf x509 certificate not found")
134 }
135 return []*signers.Signature{&signers.Signature{
136 Hash: xs.Hash,
137 X509Signature: &pkcs9.TimestampedSignature{
138 Signature: psig,
139 CounterSignature: cs,
140 },
141 }}, nil
142 }
143
View as plain text