...

Source file src/github.com/sassoftware/relic/signers/vsix/rels.go

Documentation: github.com/sassoftware/relic/signers/vsix

     1  //
     2  // Copyright (c) SAS Institute Inc.
     3  //
     4  // Licensed under the Apache License, Version 2.0 (the "License");
     5  // you may not use this file except in compliance with the License.
     6  // You may obtain a copy of the License at
     7  //
     8  //     http://www.apache.org/licenses/LICENSE-2.0
     9  //
    10  // Unless required by applicable law or agreed to in writing, software
    11  // distributed under the License is distributed on an "AS IS" BASIS,
    12  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  // See the License for the specific language governing permissions and
    14  // limitations under the License.
    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  	// NB: neither the certs nor the rels file are part of the signature, so
   136  	// bypass m.digests and just call NewFile directly
   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