forked from gopacket/gopacket
/
ngwrite_dsb.go
109 lines (89 loc) · 4.55 KB
/
ngwrite_dsb.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
// Copyright 2018 The GoPacket Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file in the root of the source
// tree.
// author: CFC4N <cfc4n@cnxct.com>
package pcapgo
import (
"encoding/binary"
)
/*
Decryption Secrets Block (DSB) memory layout.
via https://github.com/pcapng/pcapng/blob/master/draft-tuexen-opsawg-pcapng.md
1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
0 | Block Type = 0x0000000A |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4 | Block Total Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
8 | Secrets Type |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
12 | Secrets Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16 / /
/ Secrets Data /
/ (variable length, padded to 32 bits) /
/ /
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
/ /
/ Options (variable) /
/ /
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
/ Block Total Length /
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Block Type: The block type of the Decryption Secrets Block is 10.
Block Total Length: total size of this block, as described in {{section_block}}.
Secrets Type (32 bits): an unsigned integer identifier that describes the format of the following Secrets field. Requests for new Secrets Type codes should be made by creating a pull request to update this document as described in {{section_block_code_registry}}.
Secrets Length (32 bits): an unsigned integer that indicates the size of the following Secrets field, without any padding octets.
Secrets Data: binary data containing secrets, padded to a 32 bit boundary.
Options: optionally, a list of options (formatted according to the rules defined in {{section_opt}}) can be present. No DSB-specific options are currently defined.
*/
const (
PcapngBlockHeadersize = 8 // block type + block total length
PcapngDecryptionSecretsBlockSize = 8 // Secrets type + Secrets length
)
// pcapngBlockHeader is the header of a pcapng block.
type pcapngBlockHeader struct {
blockType uint32
blockTotalLength uint32
}
// pcapngDecryptionSecretsBlock is the header of a section.
type pcapngDecryptionSecretsBlock struct {
secretsType uint32
secretsLength uint32
}
// WriteDecryptionSecretsBlock writes a Decryption Secrets Block to the writer.
func (w *NgWriter) WriteDecryptionSecretsBlock(secretType uint32, secretPayload []byte) error {
switch secretType {
case DSB_SECRETS_TYPE_SSH, DSB_SECRETS_TYPE_ZIGBEE_NWK_KEY, DSB_SECRETS_TYPE_WIREGUARD, DSB_SECRETS_TYPE_ZIGBEE_APS_KEY, DSB_SECRETS_TYPE_TLS:
default:
// unknown secrets type
return ErrUnknownSecretsType
}
secretPayloadLen := len(secretPayload)
padding := (4 - secretPayloadLen&3) & 3
// via https://github.com/wireshark/wireshark/blob/885d6b7f731760f4a76e0f257af57d03934986ed/wiretap/pcapng.c#L5233
// langth = MIN_DSB_SIZE + secretPayloadLen + padding
// MIN_DSB_SIZE = MIN_BLOCK_SIZE + PcapngDecryptionSecretsBlockSize
// MIN_BLOCK_SIZE = PcapngBlockHeadersize + 4
//
length := uint32(PcapngBlockHeadersize + 4 + PcapngDecryptionSecretsBlockSize + secretPayloadLen + padding)
// write block header
binary.LittleEndian.PutUint32(w.buf[:4], uint32(ngBlockTypeDecryptionSecrets))
binary.LittleEndian.PutUint32(w.buf[4:8], length)
// write decryption secrets block
binary.LittleEndian.PutUint32(w.buf[8:12], secretType)
binary.LittleEndian.PutUint32(w.buf[12:16], uint32(secretPayloadLen))
if _, err := w.w.Write(w.buf[:16]); err != nil {
return err
}
// write secrets data
if _, err := w.w.Write(secretPayload); err != nil {
return err
}
binary.LittleEndian.PutUint32(w.buf[:4], 0)
_, err := w.w.Write(w.buf[4-padding : 8]) // padding + length
return err
}