Skip to content

Commit 0cfbc40

Browse files
committed
add Protobuf Stream Decode operation
1 parent 037590f commit 0cfbc40

File tree

4 files changed

+101
-1
lines changed

4 files changed

+101
-1
lines changed

Diff for: src/core/config/Categories.json

+1
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@
207207
"URL Decode",
208208
"Protobuf Decode",
209209
"Protobuf Encode",
210+
"Protobuf Stream Decode",
210211
"VarInt Encode",
211212
"VarInt Decode",
212213
"JA3 Fingerprint",

Diff for: src/core/lib/Protobuf.mjs

+19-1
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,24 @@ class Protobuf {
116116
return this.mergeDecodes(input);
117117
}
118118

119+
static decodeStream(input, args) {
120+
this.updateProtoRoot(args[0]);
121+
this.showUnknownFields = args[1];
122+
this.showTypes = args[2];
123+
124+
let streams = new Protobuf(input);
125+
let output = [];
126+
let objLength = streams._varInt();
127+
while (!isNaN(objLength) && objLength > 0) {
128+
let subData = streams.data.slice(streams.offset, streams.offset + objLength);
129+
output.push(this.mergeDecodes(subData));
130+
streams.offset += objLength;
131+
objLength = streams._varInt();
132+
}
133+
134+
return output;
135+
}
136+
119137
/**
120138
* Update the parsedProto, throw parsing errors
121139
*
@@ -184,7 +202,7 @@ class Protobuf {
184202
bytes: String,
185203
longs: Number,
186204
enums: String,
187-
defualts: true
205+
defaults: true
188206
});
189207
const output = {};
190208

Diff for: src/core/operations/ProtobufStreamDecode.mjs

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/**
2+
* @author GCHQ Contributor [3]
3+
* @copyright Crown Copyright 2019
4+
* @license Apache-2.0
5+
*/
6+
7+
import Operation from "../Operation.mjs";
8+
import OperationError from "../errors/OperationError.mjs";
9+
import Protobuf from "../lib/Protobuf.mjs";
10+
11+
/**
12+
* Protobuf Stream Decode operation
13+
*/
14+
class ProtobufStreamDecode extends Operation {
15+
16+
/**
17+
* ProtobufStreamDecode constructor
18+
*/
19+
constructor() {
20+
super();
21+
22+
this.name = "Protobuf Stream Decode";
23+
this.module = "Protobuf";
24+
this.description = "Decodes Protobuf encoded data from streams to a JSON array representation of the data using the field number as the field key.<br><br>If a .proto schema is defined, the encoded data will be decoded with reference to the schema. Only one message instance will be decoded. <br><br><u>Show Unknown Fields</u><br>When a schema is used, this option shows fields that are present in the input data but not defined in the schema.<br><br><u>Show Types</u><br>Show the type of a field next to its name. For undefined fields, the wiretype and example types are shown instead.";
25+
this.infoURL = "https://developers.google.com/protocol-buffers/docs/techniques#streaming";
26+
this.inputType = "ArrayBuffer";
27+
this.outputType = "JSON";
28+
this.args = [
29+
{
30+
name: "Show Types",
31+
type: "boolean",
32+
value: false
33+
}
34+
];
35+
}
36+
37+
/**
38+
* @param {ArrayBuffer} input
39+
* @param {Object[]} args
40+
* @returns {JSON}
41+
*/
42+
run(input, args) {
43+
input = new Uint8Array(input);
44+
try {
45+
// provide standard values for currently removed arguments
46+
return Protobuf.decodeStream(input, ["", false, ...args]);
47+
} catch (err) {
48+
throw new OperationError(err);
49+
}
50+
}
51+
52+
}
53+
54+
export default ProtobufStreamDecode;

Diff for: tests/operations/tests/Protobuf.mjs

+27
Original file line numberDiff line numberDiff line change
@@ -303,4 +303,31 @@ TestRegister.addTests([
303303
}
304304
]
305305
},
306+
{
307+
name: "Protobuf Stream Decode: no schema",
308+
input: "0d081c1203596f751a024d65202b0c0a0a0a066162633132331200",
309+
expectedOutput: JSON.stringify([{
310+
"1": 28,
311+
"2": "You",
312+
"3": "Me",
313+
"4": 43
314+
},
315+
{
316+
"1": {
317+
"1": "abc123",
318+
"2": {}
319+
}
320+
}], null, 4),
321+
recipeConfig: [
322+
{
323+
"op": "From Hex",
324+
"args": ["Auto"]
325+
},
326+
{
327+
"op": "Protobuf Stream Decode",
328+
"args": ["", false, false]
329+
}
330+
]
331+
},
332+
306333
]);

0 commit comments

Comments
 (0)