github.com/readium/readium-lcp-server@v0.0.0-20240509124024-799e77a0bbd6/xmlenc/encryption.go (about)

     1  // Copyright 2020 Readium Foundation. All rights reserved.
     2  // Use of this source code is governed by a BSD-style license
     3  // that can be found in the LICENSE file exposed on Github (readium) in the project repository.
     4  
     5  package xmlenc
     6  
     7  import (
     8  	"encoding/xml"
     9  	"io"
    10  	"net/url"
    11  	"strings"
    12  
    13  	"golang.org/x/net/html/charset"
    14  )
    15  
    16  type Manifest struct {
    17  	//Keys []Key
    18  	Data    []Data   `xml:"http://www.w3.org/2001/04/xmlenc# EncryptedData"`
    19  	XMLName struct{} `xml:"urn:oasis:names:tc:opendocument:xmlns:container encryption"`
    20  }
    21  
    22  // ResourcePathEscape encodes a path for a URL but keep slashes unescaped
    23  func ResourcePathEscape(path string) string {
    24  	segments := strings.Split(path, "/")
    25  
    26  	// Encode each segment individually
    27  	for i, segment := range segments {
    28  		segments[i] = url.PathEscape(segment)
    29  	}
    30  
    31  	// Join the encoded segments with slashes
    32  	return strings.Join(segments, "/")
    33  }
    34  
    35  // DataForFile returns the EncryptedData item corresponding to a given path
    36  func (m Manifest) DataForFile(path string) (Data, bool) {
    37  	uri := URI(ResourcePathEscape(path))
    38  
    39  	for _, datum := range m.Data {
    40  		if datum.CipherData.CipherReference.URI == uri {
    41  			return datum, true
    42  		}
    43  	}
    44  
    45  	return Data{}, false
    46  }
    47  
    48  // Write writes the encryption XML structure
    49  func (m Manifest) Write(w io.Writer) error {
    50  	w.Write([]byte(xml.Header))
    51  	enc := xml.NewEncoder(w)
    52  	enc.Indent("", "  ")
    53  	return enc.Encode(m)
    54  }
    55  
    56  // Read parses the encryption XML structure
    57  func Read(r io.Reader) (Manifest, error) {
    58  	var m Manifest
    59  	dec := xml.NewDecoder(r)
    60  	// deal with non utf-8 xml files
    61  	dec.CharsetReader = charset.NewReaderLabel
    62  	err := dec.Decode(&m)
    63  
    64  	return m, err
    65  }
    66  
    67  //<sequence>
    68  //<element name="EncryptionMethod" type="xenc:EncryptionMethodType"
    69  //minOccurs="0"/>
    70  //<element ref="ds:KeyInfo" minOccurs="0"/>
    71  //<element ref="xenc:CipherData"/>
    72  //<element ref="xenc:EncryptionProperties" minOccurs="0"/>
    73  //</sequence>
    74  //<attribute name="Id" type="ID" use="optional"/>
    75  //<attribute name="Type" type="anyURI" use="optional"/>
    76  //<attribute name="MimeType" type="string" use="optional"/>
    77  //<attribute name="Encoding" type="anyURI" use="optional"/>
    78  
    79  type URI string
    80  
    81  type Method struct {
    82  	KeySize int `xml:"KeySize,omitempty"`
    83  	//OAEPParams []byte `xml:"AOEParams,omitempty"`
    84  	Algorithm URI `xml:"Algorithm,attr,omitempty"`
    85  }
    86  
    87  type CipherReference struct {
    88  	URI URI `xml:"URI,attr"`
    89  }
    90  
    91  type CipherData struct {
    92  	CipherReference CipherReference `xml:"http://www.w3.org/2001/04/xmlenc# CipherReference"`
    93  	Value           []byte          `xml:"Value,omitempty"`
    94  }
    95  
    96  //type DSAKeyValue struct {
    97  //P []byte
    98  //Q []byte
    99  //G []byte
   100  //Y []byte
   101  //J []byte
   102  //Seed []byte
   103  //PgenCounter []byte
   104  //}
   105  
   106  //type RSAKeyValue struct {
   107  //Modulus []byte
   108  //Exponent []byte
   109  //}
   110  
   111  //type KeyValue struct {
   112  //DSAKeyValue
   113  //RSAKeyValue
   114  //}
   115  
   116  type RetrievalMethod struct {
   117  	URI  `xml:"URI,attr"`
   118  	Type string `xml:"Type,attr"`
   119  }
   120  
   121  type KeyInfo struct {
   122  	KeyName string `xml:"KeyName,attr,omitempty"`
   123  	//KeyValue
   124  	RetrievalMethod RetrievalMethod `xml:"http://www.w3.org/2000/09/xmldsig# RetrievalMethod"`
   125  	//X509Data
   126  	//PGPData
   127  	//SPKIData
   128  	//MgmtData
   129  }
   130  
   131  type encryptedType struct {
   132  	Method     Method     `xml:"http://www.w3.org/2001/04/xmlenc# EncryptionMethod"`
   133  	KeyInfo    *KeyInfo   `xml:"http://www.w3.org/2000/09/xmldsig# KeyInfo"`
   134  	CipherData CipherData `xml:"http://www.w3.org/2001/04/xmlenc# CipherData"`
   135  	ID         string     `xml:"Id,attr,omitempty"`
   136  	Type       URI        `xml:"Type,attr,omitempty"`
   137  	MimeType   string     `xml:"MimeType,omitempty"`
   138  	Encoding   URI        `xml:"Encoding,omitempty"`
   139  }
   140  
   141  type ReferenceList struct {
   142  	Key  []string
   143  	Data []string
   144  }
   145  
   146  type Key struct {
   147  	encryptedType
   148  	References     ReferenceList
   149  	CarriedKeyName string
   150  	Recipient      string
   151  }
   152  type Compression struct {
   153  	Method         int    `xml:"Method,attr"`
   154  	OriginalLength uint64 `xml:"OriginalLength,attr"`
   155  }
   156  
   157  type EncryptionProperty struct {
   158  	Compression Compression `xml:"http://www.idpf.org/2016/encryption#compression Compression"`
   159  }
   160  
   161  type EncryptionProperties struct {
   162  	Properties []EncryptionProperty `xml:"http://www.w3.org/2001/04/xmlenc# EncryptionProperty"`
   163  }
   164  
   165  type Data struct {
   166  	encryptedType
   167  	Properties *EncryptionProperties `xml:"http://www.w3.org/2001/04/xmlenc# EncryptionProperties,omitempty"`
   168  }