|
| 1 | +#!/usr/bin/gawk -bf |
| 2 | +@load "readfile" |
| 3 | + |
| 4 | +function assert(condition, string) |
| 5 | +{ |
| 6 | + if (!condition) { |
| 7 | + print string |
| 8 | + exit 1 |
| 9 | + } |
| 10 | +} |
| 11 | + |
| 12 | +function ord_init() |
| 13 | +{ |
| 14 | + for (_i = 0; _i < 256; _i++) { |
| 15 | + ord[sprintf("%c", _i)] = _i |
| 16 | + } |
| 17 | +} |
| 18 | + |
| 19 | +function x2n(hex, width) |
| 20 | +{ |
| 21 | + mult = 1 |
| 22 | + num = 0 |
| 23 | + for (_i = 0; _i < width; _i++) { |
| 24 | + num += ord[substr(hex, _i+1, 1)] * mult |
| 25 | + mult *= 256 |
| 26 | + } |
| 27 | + return num |
| 28 | +} |
| 29 | + |
| 30 | +function hexdump(hex, len) |
| 31 | +{ |
| 32 | + for (_i = 0; _i < len; _i++) { |
| 33 | + printf("%02x", ord[substr(hex, _i+1, 1)]) |
| 34 | + } |
| 35 | +} |
| 36 | + |
| 37 | +function string_or_hex(str, len) |
| 38 | +{ |
| 39 | + _len = len |
| 40 | + if (_len > 128) |
| 41 | + _len = 128 |
| 42 | + # String must start with a series of printable characters ... |
| 43 | + if (match(str, "[[:graph:][:blank:]]*", a) != 1) { |
| 44 | + hexdump(str, _len) |
| 45 | + # ... long until the end, with "optional" (i.e. bad implementation) \0. |
| 46 | + } else if (len != a[0, "length"] && |
| 47 | + (len != a[0, "length"] + 1 || index(str, "\0") != len)) { |
| 48 | + hexdump(str, _len) |
| 49 | + } else |
| 50 | + printf("%.*s", _len, a[0]) |
| 51 | + if (_len != len) |
| 52 | + printf("... (event truncated to %d first bytes, was %d)", _len, len) |
| 53 | +} |
| 54 | + |
| 55 | +BEGIN { |
| 56 | + PROCINFO["readfile"] |
| 57 | + FIELDWIDTHS = "20 12 1 1 1 1 4 4 4 *" |
| 58 | + ord_init() |
| 59 | +} |
| 60 | +{ |
| 61 | + # Header sanity checks |
| 62 | + assert($1 == "TXT Event Container\0", "Bad TXT Event Container signature") |
| 63 | + assert(match($2, "\0{12}"), "Reserved field is not all 0") |
| 64 | + assert($3 == "\1", "Bad container major version") |
| 65 | + # Minor version is bumped if there are compatible changes like new |
| 66 | + # fields added to the end of structure. Header stores offset to PCR |
| 67 | + # events so those new fields can be skipped. |
| 68 | + #assert($4 == "\0", "Bad container minor version") |
| 69 | + assert($5 == "\1", "Bad event structure major version") |
| 70 | + # There is no field that would specify size of whole event structure, |
| 71 | + # any new fields added to it would break this parser. |
| 72 | + assert($6 == "\0", "Bad event structure minor version") |
| 73 | + assert(x2n($7, 4) == length(), "Bad container size") |
| 74 | + assert(x2n($8, 4) >= (20+12+1+1+1+1+4+4+4), "PCR Event offset too small") |
| 75 | + assert(x2n($9, 4) > x2n($8, 4), "Next Event offset too small") |
| 76 | + FIELDWIDTHS="4 4 20 4 *" |
| 77 | + $0 = substr($0, x2n($8, 4) + 1) |
| 78 | +} |
| 79 | +{ |
| 80 | + entry = 0 |
| 81 | + printf("\n") |
| 82 | + while (NF > 0) { |
| 83 | + if ($2 == "\0\0\0\0") break |
| 84 | + printf("Entry %d:\n", ++entry) |
| 85 | + printf(" PCR: %d\n", x2n($1, 4)) |
| 86 | + printf(" Event Type: %#x\n", x2n($2, 4)) |
| 87 | + printf(" Digests:\n") |
| 88 | + printf(" SHA1: ") |
| 89 | + hexdump($3, 20) |
| 90 | + printf("\n") |
| 91 | + printf(" Event: ") |
| 92 | + string_or_hex($5, x2n($4, 4)) |
| 93 | + printf("\n\n") |
| 94 | + $0 = substr($5, x2n($4, 4) + 1) |
| 95 | + } |
| 96 | +} |
0 commit comments