1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package vsix
18
19 import (
20 "crypto"
21 "encoding/xml"
22 "fmt"
23 "io/ioutil"
24 "path"
25
26 "github.com/sassoftware/relic/lib/certloader"
27 )
28
29 type oxfRelationships struct {
30 XMLName xml.Name `xml:"http://schemas.openxmlformats.org/package/2006/relationships Relationships"`
31 Relationship []oxfRelationship
32 }
33
34 type oxfRelationship struct {
35 Target string `xml:",attr"`
36 Id string `xml:",attr"`
37 Type string `xml:",attr"`
38 }
39
40 func readZip(files zipFiles, path string) ([]byte, error) {
41 zf := files[path]
42 if zf == nil {
43 return nil, fmt.Errorf("file missing from zip: %s", path)
44 }
45 f, err := zf.Open()
46 if err != nil {
47 return nil, fmt.Errorf("failed to read zip file %s: %s", path, err)
48 }
49 return ioutil.ReadAll(f)
50 }
51
52 func parseRels(files zipFiles, path string) (*oxfRelationships, error) {
53 blob, err := readZip(files, path)
54 if err != nil {
55 return nil, err
56 }
57 rels := new(oxfRelationships)
58 if err := xml.Unmarshal(blob, rels); err != nil {
59 return nil, fmt.Errorf("error parsing rels: %s", err)
60 }
61 return rels, nil
62 }
63
64 func (rels *oxfRelationships) Find(rType string) string {
65 for _, rel := range rels.Relationship {
66 if rel.Type == rType {
67 return path.Clean("./" + rel.Target)
68 }
69 }
70 return ""
71 }
72
73 func (rels *oxfRelationships) Append(zipPath, relType string) {
74 d := crypto.SHA1.New()
75 d.Write([]byte(zipPath))
76 d.Write([]byte(relType))
77 rel := oxfRelationship{Target: path.Clean("/" + zipPath), Type: relType}
78 for {
79 rel.Id = fmt.Sprintf("R%X", d.Sum(nil)[:4])
80 ok := true
81 for _, rel2 := range rels.Relationship {
82 if rel2.Id == rel.Id {
83 ok = false
84 }
85 }
86 if ok {
87 break
88 }
89 d.Write([]byte{0})
90 }
91 rels.Relationship = append(rels.Relationship, rel)
92 }
93
94 func (rels *oxfRelationships) Marshal() ([]byte, error) {
95 x, err := xml.Marshal(rels)
96 if err != nil {
97 return nil, err
98 }
99 ret := make([]byte, len(xml.Header), len(xml.Header)+len(x))
100 copy(ret, xml.Header)
101 ret = append(ret, x...)
102 return ret, nil
103 }
104
105 func relPath(fp string) string {
106 base := path.Base(fp)
107 if base == "." {
108 base = ""
109 }
110 return path.Join(path.Dir(fp), "_rels", base+".rels")
111 }
112
113 func (m *mangler) addFile(name string, contents []byte) error {
114 d := m.hash.New()
115 d.Write(contents)
116 m.digests[name] = d.Sum(nil)
117 return m.m.NewFile(name, contents)
118 }
119
120 func (m *mangler) newRels(parent, child, relType string) error {
121 var rels oxfRelationships
122 rels.Append(child, relType)
123 contents, err := rels.Marshal()
124 if err != nil {
125 return err
126 }
127 return m.addFile(relPath(parent), contents)
128 }
129
130 func (m *mangler) addOrigin() error {
131 return m.addFile(originPath, nil)
132 }
133
134 func (m *mangler) addCerts(cert *certloader.Certificate, sigName string) error {
135
136
137 var rels oxfRelationships
138 for _, chain := range cert.Chain() {
139 certpath := path.Join(xmlCertPath, calcFileName(chain)+".cer")
140 if err := m.m.NewFile(certpath, chain.Raw); err != nil {
141 return err
142 }
143 rels.Append(certpath, certType)
144 }
145 contents, err := rels.Marshal()
146 if err != nil {
147 return err
148 }
149 return m.m.NewFile(relPath(sigName), contents)
150 }
151
View as plain text