...

Source file src/golang.org/x/crypto/openpgp/packet/opaque.go

Documentation: golang.org/x/crypto/openpgp/packet

     1  // Copyright 2012 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package packet
     6  
     7  import (
     8  	"bytes"
     9  	"io"
    10  
    11  	"golang.org/x/crypto/openpgp/errors"
    12  )
    13  
    14  // OpaquePacket represents an OpenPGP packet as raw, unparsed data. This is
    15  // useful for splitting and storing the original packet contents separately,
    16  // handling unsupported packet types or accessing parts of the packet not yet
    17  // implemented by this package.
    18  type OpaquePacket struct {
    19  	// Packet type
    20  	Tag uint8
    21  	// Reason why the packet was parsed opaquely
    22  	Reason error
    23  	// Binary contents of the packet data
    24  	Contents []byte
    25  }
    26  
    27  func (op *OpaquePacket) parse(r io.Reader) (err error) {
    28  	op.Contents, err = io.ReadAll(r)
    29  	return
    30  }
    31  
    32  // Serialize marshals the packet to a writer in its original form, including
    33  // the packet header.
    34  func (op *OpaquePacket) Serialize(w io.Writer) (err error) {
    35  	err = serializeHeader(w, packetType(op.Tag), len(op.Contents))
    36  	if err == nil {
    37  		_, err = w.Write(op.Contents)
    38  	}
    39  	return
    40  }
    41  
    42  // Parse attempts to parse the opaque contents into a structure supported by
    43  // this package. If the packet is not known then the result will be another
    44  // OpaquePacket.
    45  func (op *OpaquePacket) Parse() (p Packet, err error) {
    46  	hdr := bytes.NewBuffer(nil)
    47  	err = serializeHeader(hdr, packetType(op.Tag), len(op.Contents))
    48  	if err != nil {
    49  		op.Reason = err
    50  		return op, err
    51  	}
    52  	p, err = Read(io.MultiReader(hdr, bytes.NewBuffer(op.Contents)))
    53  	if err != nil {
    54  		op.Reason = err
    55  		p = op
    56  	}
    57  	return
    58  }
    59  
    60  // OpaqueReader reads OpaquePackets from an io.Reader.
    61  type OpaqueReader struct {
    62  	r io.Reader
    63  }
    64  
    65  func NewOpaqueReader(r io.Reader) *OpaqueReader {
    66  	return &OpaqueReader{r: r}
    67  }
    68  
    69  // Read the next OpaquePacket.
    70  func (or *OpaqueReader) Next() (op *OpaquePacket, err error) {
    71  	tag, _, contents, err := readHeader(or.r)
    72  	if err != nil {
    73  		return
    74  	}
    75  	op = &OpaquePacket{Tag: uint8(tag), Reason: err}
    76  	err = op.parse(contents)
    77  	if err != nil {
    78  		consumeAll(contents)
    79  	}
    80  	return
    81  }
    82  
    83  // OpaqueSubpacket represents an unparsed OpenPGP subpacket,
    84  // as found in signature and user attribute packets.
    85  type OpaqueSubpacket struct {
    86  	SubType  uint8
    87  	Contents []byte
    88  }
    89  
    90  // OpaqueSubpackets extracts opaque, unparsed OpenPGP subpackets from
    91  // their byte representation.
    92  func OpaqueSubpackets(contents []byte) (result []*OpaqueSubpacket, err error) {
    93  	var (
    94  		subHeaderLen int
    95  		subPacket    *OpaqueSubpacket
    96  	)
    97  	for len(contents) > 0 {
    98  		subHeaderLen, subPacket, err = nextSubpacket(contents)
    99  		if err != nil {
   100  			break
   101  		}
   102  		result = append(result, subPacket)
   103  		contents = contents[subHeaderLen+len(subPacket.Contents):]
   104  	}
   105  	return
   106  }
   107  
   108  func nextSubpacket(contents []byte) (subHeaderLen int, subPacket *OpaqueSubpacket, err error) {
   109  	// RFC 4880, section 5.2.3.1
   110  	var subLen uint32
   111  	if len(contents) < 1 {
   112  		goto Truncated
   113  	}
   114  	subPacket = &OpaqueSubpacket{}
   115  	switch {
   116  	case contents[0] < 192:
   117  		subHeaderLen = 2 // 1 length byte, 1 subtype byte
   118  		if len(contents) < subHeaderLen {
   119  			goto Truncated
   120  		}
   121  		subLen = uint32(contents[0])
   122  		contents = contents[1:]
   123  	case contents[0] < 255:
   124  		subHeaderLen = 3 // 2 length bytes, 1 subtype
   125  		if len(contents) < subHeaderLen {
   126  			goto Truncated
   127  		}
   128  		subLen = uint32(contents[0]-192)<<8 + uint32(contents[1]) + 192
   129  		contents = contents[2:]
   130  	default:
   131  		subHeaderLen = 6 // 5 length bytes, 1 subtype
   132  		if len(contents) < subHeaderLen {
   133  			goto Truncated
   134  		}
   135  		subLen = uint32(contents[1])<<24 |
   136  			uint32(contents[2])<<16 |
   137  			uint32(contents[3])<<8 |
   138  			uint32(contents[4])
   139  		contents = contents[5:]
   140  	}
   141  	if subLen > uint32(len(contents)) || subLen == 0 {
   142  		goto Truncated
   143  	}
   144  	subPacket.SubType = contents[0]
   145  	subPacket.Contents = contents[1:subLen]
   146  	return
   147  Truncated:
   148  	err = errors.StructuralError("subpacket truncated")
   149  	return
   150  }
   151  
   152  func (osp *OpaqueSubpacket) Serialize(w io.Writer) (err error) {
   153  	buf := make([]byte, 6)
   154  	n := serializeSubpacketLength(buf, len(osp.Contents)+1)
   155  	buf[n] = osp.SubType
   156  	if _, err = w.Write(buf[:n+1]); err != nil {
   157  		return
   158  	}
   159  	_, err = w.Write(osp.Contents)
   160  	return
   161  }
   162  

View as plain text