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