diff --git a/.gitignore b/.gitignore index f3e294b..839b6ff 100755 --- a/.gitignore +++ b/.gitignore @@ -8,8 +8,12 @@ env/ .vscode test/mocks/evidence.json test/scripts/ss_out +test/scripts/bin/error.log *ss_out* # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] + +# Log file I use for test output. +all.txt \ No newline at end of file diff --git a/.gitmodules b/.gitmodules index 5e08d23..7d947ef 100755 --- a/.gitmodules +++ b/.gitmodules @@ -10,3 +10,6 @@ path = lib/openzeppelin-contracts url = https://github.com/openzeppelin/openzeppelin-contracts branch = v4.9.1 +[submodule "lib/ethereum-datetime"] + path = lib/ethereum-datetime + url = https://github.com/pipermerriam/ethereum-datetime.git diff --git a/lib/ethereum-datetime b/lib/ethereum-datetime new file mode 160000 index 0000000..7a08a9b --- /dev/null +++ b/lib/ethereum-datetime @@ -0,0 +1 @@ +Subproject commit 7a08a9bc10fdff2e0187d4cda7f6f0f7f72b62c0 diff --git a/out.key b/out.key new file mode 100644 index 0000000..163ee0c --- /dev/null +++ b/out.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDPimz4/B0p2TVY +Sxl7mc8Ju6M62gXfldZGr8PFcURI3ajcbYxBGwbzNHNP/sP/CwGZ4zkCZwiMPjDD +rKNpoSidnQkzmnHev5xuDSjz9Mk0/6tF4iMvd6Tc6yz1dOAElx+yGMlFcaNEPFqg +D2kEM/5FJwoxRxBkQiHpTsPfbMr7BQJTrGLz2c1JnLZl1uWqQuCL4+WP0QRNu06P +ljq7RVbj8ecOwZkQ7O68shxQvMtTlgBi80OSTg+o9Q8807kSATFUyvLh+a7dUERC +Si+qAslaSMqTudmXxj251KpFHq+lscBzVkxALhPeugWbYxG2Mxh1PN9GVugnW0pi +lJbcbFApAgMBAAECggEBAIHDyokPkeiFoD4ZjtBihjpOsSvuADghRr4hzeWZAZoR +xjA06roWfQz54ZPF9qR0LEcc9JtU8tpFVFY0jmRQWMXb11IFomclJVkGL3IBvwC9 +T0i9sURPqaxb+1tp/VvBZhcEOmyKNgxHNF7Z486196kjVNMk3NHjK7LmBcCgFHZI +Nia90NcSukpaLkOJnYt43sZ2Rjtfd8kuTzYjTyjchhnjz86qbOrm5IY/d2yJxS+M +znb71R/1XWGXLMiNUZF0dsrMFuCCCYnlUSxc+50W1N0M6Ioeaqe1MFLU9UATky3/ +cOy8FtEZvDoflAesM8qV+T0nxcgM3f1UHk4HYk41oIECgYEA7OkYs9dyaJ5IBzKG +PuCeN/qfvYi0HTIZYH3TWZHb+3BjDKblJr7HrSsbJBdyUGjlMyO2xN//gCqoN43Z +7ONxIfh9GIRSdt5V9ZoenrOiNvhAoy3vitdM5/ouwBJxICMlpS4s7gM3aq+7Shoj +CUc/RQBAFr0FPkfgVdqpQKygTnECgYEA4EN/43vRJaay0pzNovnod132U/ybTJ/O +7w9XGolxQqvtzZoOvaTRk2CsLn63l8Ppu/loPRM2rkl/9nQkr27Hld2YTi0xTgy9 +4CrSPBdHkFDXJULGGSkrQss6okPdnTHG5SXUrMEeIt1+GobArTj7iVF1VwdDPoqS +ND9QWVG26TkCgYEA2yHkeny+02wMfbPLHp/PWUIVvU+UIikz9d+MvZ2/13wl8g7x +iHwQ3+kuSpzxXNUZo8rWBJaYkylhvTkVKRtbiqt4slO6nz6aTfmHdw367lOEHiug +FVF+TlhII9srDinUaUwjvOf2u1TerPUuESf4qs9HeIDQN8JuC5uc0DicctECgYBI +CCY5sPlaeJKTZ139bPun63xFOavADsxuqKS3l1HTslltYoA9lYTjK3fibz0U+A5J +HDDI/TThAiahyGhIGPLuRgC3i3h8s0cBi39/YZLQ3cZc53eteTW1/ITWvame5fAW +hfIrktPVKwNoDcQxX04bqxhfXavRmLyhH3z1U3PGsQKBgFH2EEJ175cNHR4Fm21R +K6YTJQsIysBBuhnyUv8IJMqqjsJwY42IzD4Gp/MM+jUd+eUzFcQHYMoMJFIycqCK +2KDWJ2jIqdFjXDjZoG/aL5zls0uomCefuOHMklFN45iFSkWgOOCdNXAccCl0VlxU +18ij8ZttH5sZxogzQl1JXjyX +-----END PRIVATE KEY----- diff --git a/src/ASN1Decode.sol b/src/ASN1Decode.sol index da7da1c..bc74ad8 100755 --- a/src/ASN1Decode.sol +++ b/src/ASN1Decode.sol @@ -3,28 +3,55 @@ pragma solidity >=0.8.0 <0.9.0; import { BytesUtils } from "ens-contracts/dnssec-oracle/BytesUtils.sol"; +import { Math } from "openzeppelin-contracts/contracts/utils/math/Math.sol"; library NodePtr { + uint80 constant MAX_UNIT80 = 1208925819614629174706175; + uint256 constant ZERO_LEN = 0; + // Unpack first byte index - function ixs(uint256 self) internal pure returns (uint256) { + function type_index(uint256 self) internal pure returns (uint256) { return uint80(self); } - // Unpack first content byte index - function ixf(uint256 self) internal pure returns (uint256) { + // Unpack first content byte index + function content_index(uint256 self) internal pure returns (uint256) { return uint80(self >> 80); } - // Unpack last content byte index - function ixl(uint256 self) internal pure returns (uint256) { + // Points to the end of the DER segement. + // Not necessarily the end of the content segment as + // empty content segements are valid in DER. + function end_index(uint256 self) internal pure returns (uint256) { return uint80(self >> 160); } + + function content_len(uint256 self) public pure returns (uint256) { + if(content_index(self) == 0) { + return 0; + } + else { + return (end_index(self) - content_index(self)) + 1; + } + } + // Pack 3 uint80s into a uint256 + function getPtr(uint256 _type_index, uint256 _content_index, uint256 _end_index) internal pure returns (uint256) { + // This prevents overflowing the individual bit fields. + require(_type_index <= MAX_UNIT80); + require(_content_index <= MAX_UNIT80); + require(_end_index <= MAX_UNIT80); + + // Bit shift fields into correct segements. + _type_index |= _content_index << 80; + _type_index |= _end_index << 160; + return _type_index; + } - function getPtr(uint256 _ixs, uint256 _ixf, uint256 _ixl) internal pure returns (uint256) { - _ixs |= _ixf << 80; - _ixs |= _ixl << 160; - return _ixs; + function overflowCheck(uint256 self, uint256 len) internal pure { + require(type_index(self) < uint256(len)); + require(content_index(self) < uint256(len)); + require(end_index(self) < uint256(len)); } } @@ -38,6 +65,13 @@ library Asn1Decode { * @return A pointer to the outermost node */ function root(bytes memory der) internal pure returns (uint256) { + // seq byte (30) + // len pt 1 (x) + // len pt 2 (optional) + // ... contentbytes (1 or more) ... + // minimum sanity check + // Not the only length check. + require(der.length >= 3); return readNodeLength(der, 0); } @@ -47,8 +81,14 @@ library Asn1Decode { * @return A pointer to the outermost node */ function rootOfBitStringAt(bytes memory der, uint256 ptr) internal pure returns (uint256) { - require(der[ptr.ixs()] == 0x03, "Not type BIT STRING"); - return readNodeLength(der, ptr.ixf() + 1); + ptr.overflowCheck(der.length); + require(der[ptr.type_index()] == 0x03, "Not type BIT STRING"); + + // Not sure if the '+1' is right but overflow is checked for. + uint256 len = ptr.content_index() + 1; + require(len < der.length); + + return readNodeLength(der, len); } /* @@ -57,8 +97,9 @@ library Asn1Decode { * @return A pointer to the outermost node */ function rootOfOctetStringAt(bytes memory der, uint256 ptr) internal pure returns (uint256) { - require(der[ptr.ixs()] == 0x04, "Not type OCTET STRING"); - return readNodeLength(der, ptr.ixf()); + ptr.overflowCheck(der.length); + require(der[ptr.type_index()] == 0x04, "Not type OCTET STRING"); + return readNodeLength(der, ptr.content_index() + 1); } /* @@ -68,7 +109,10 @@ library Asn1Decode { * @return A pointer to the next sibling node */ function nextSiblingOf(bytes memory der, uint256 ptr) internal pure returns (uint256) { - return readNodeLength(der, ptr.ixl() + 1); + ptr.overflowCheck(der.length); + uint256 index = (ptr.end_index() + 1); + require(index < der.length); + return readNodeLength(der, index); } /* @@ -78,8 +122,16 @@ library Asn1Decode { * @return A pointer to the first child node */ function firstChildOf(bytes memory der, uint256 ptr) internal pure returns (uint256) { - require(der[ptr.ixs()] & 0x20 == 0x20, "Not a constructed type"); - return readNodeLength(der, ptr.ixf()); + ptr.overflowCheck(der.length); + require(der[ptr.type_index()] & 0x20 == 0x20, "Not a constructed type"); + if(ptr.content_len() == 0) + { + revert(); + } + else + { + return readNodeLength(der, ptr.content_index()); + } } /* @@ -89,7 +141,16 @@ library Asn1Decode { * @return True iff j is child of i or i is child of j. */ function isChildOf(uint256 i, uint256 j) internal pure returns (bool) { - return (((i.ixf() <= j.ixs()) && (j.ixl() <= i.ixl())) || ((j.ixf() <= i.ixs()) && (i.ixl() <= j.ixl()))); + return ( + ( + (i.content_index() <= j.type_index()) && + (j.end_index() <= i.end_index()) + ) || + ( + (j.content_index() <= i.type_index()) && + (i.end_index() <= j.end_index()) + ) + ); } /* @@ -99,7 +160,14 @@ library Asn1Decode { * @return Value bytes of node */ function bytesAt(bytes memory der, uint256 ptr) internal pure returns (bytes memory) { - return der.substring(ptr.ixf(), ptr.ixl() + 1 - ptr.ixf()); + ptr.overflowCheck(der.length); + if(ptr.content_len() >= 1) { + return der.substring( + ptr.content_index(), + ptr.content_len() + ); + } + revert(); } /* @@ -109,7 +177,13 @@ library Asn1Decode { * @return All bytes of node */ function allBytesAt(bytes memory der, uint256 ptr) internal pure returns (bytes memory) { - return der.substring(ptr.ixs(), ptr.ixl() + 1 - ptr.ixs()); + ptr.overflowCheck(der.length); + if(ptr.content_len() >= 1) { + uint256 len = (ptr.end_index() - ptr.type_index()) + 1; + require(ptr.type_index() + len <= der.length); + return der.substring(ptr.type_index(), len); + } + revert(); } /* @@ -119,7 +193,13 @@ library Asn1Decode { * @return Value bytes of node as bytes32 */ function bytes32At(bytes memory der, uint256 ptr) internal pure returns (bytes32) { - return der.readBytesN(ptr.ixf(), ptr.ixl() + 1 - ptr.ixf()); + ptr.overflowCheck(der.length); + require(ptr.content_len() <= 32); + + if(ptr.content_len() >= 1) { + return der.readBytesN(ptr.content_index(), ptr.content_len()); + } + revert(); } /* @@ -129,10 +209,26 @@ library Asn1Decode { * @return Uint value of node */ function uintAt(bytes memory der, uint256 ptr) internal pure returns (uint256) { - require(der[ptr.ixs()] == 0x02, "Not type INTEGER"); - require(der[ptr.ixf()] & 0x80 == 0, "Not positive"); - uint256 len = ptr.ixl() + 1 - ptr.ixf(); - return uint256(der.readBytesN(ptr.ixf(), len) >> (32 - len) * 8); + // Sanity checks for pointer fields. + ptr.overflowCheck(der.length); + + // Check field types and value. + require(der[ptr.type_index()] == 0x02, "Not type INTEGER"); + if(ptr.content_len() >= 1) { + // Ensure unsigned int. + require(der[ptr.content_index()] & 0x80 == 0, "Not positive"); + + // Specify bytes to read. + uint256 len = ptr.content_len(); + require(len <= 32); + + // Read N bytes into uint field. + return uint256( + der.readBytesN(ptr.content_index(), len) >> + ((32 - len) * 8) + ); + } + revert(); } /* @@ -142,22 +238,47 @@ library Asn1Decode { * @return Value bytes of a positive integer node */ function uintBytesAt(bytes memory der, uint256 ptr) internal pure returns (bytes memory) { - require(der[ptr.ixs()] == 0x02, "Not type INTEGER"); - require(der[ptr.ixf()] & 0x80 == 0, "Not positive"); - uint256 valueLength = ptr.ixl() + 1 - ptr.ixf(); - if (der[ptr.ixf()] == 0) { - return der.substring(ptr.ixf() + 1, valueLength - 1); + // Sanity check on pointer. + ptr.overflowCheck(der.length); + + // Only if content segment present. + if(ptr.content_len() >= 1) { + // Number must be a positive number. + require(der[ptr.type_index()] == 0x02, "Not type INTEGER"); + require(der[ptr.content_index()] & 0x80 == 0, "Not positive"); + + // Read bytes at offset. + return der.substring(ptr.content_index(), ptr.content_len()); + } + revert(); + + // This seems invalid. + /* + uint256 valueLength = ptr.content_len(); + if (der[ptr.content_index()] == 0) { + return der.substring(ptr.content_index() + 1, valueLength - 1); } else { - return der.substring(ptr.ixf(), valueLength); + return der.substring(ptr.content_index(), valueLength); } + */ } function keccakOfBytesAt(bytes memory der, uint256 ptr) internal pure returns (bytes32) { - return der.keccak(ptr.ixf(), ptr.ixl() + 1 - ptr.ixf()); + ptr.overflowCheck(der.length); + if(ptr.content_len() >= 1) { + return der.keccak(ptr.content_index(), ptr.content_len()); + } + revert(); } function keccakOfAllBytesAt(bytes memory der, uint256 ptr) internal pure returns (bytes32) { - return der.keccak(ptr.ixs(), ptr.ixl() + 1 - ptr.ixs()); + ptr.overflowCheck(der.length); + if(ptr.content_len() >= 1) { + uint256 len = (ptr.end_index() - ptr.type_index()) + 1; + require(ptr.type_index() + len <= der.length); + return der.keccak(ptr.type_index(), len); + } + revert(); } /* @@ -167,33 +288,112 @@ library Asn1Decode { * @return Value of bitstring converted to bytes */ function bitstringAt(bytes memory der, uint256 ptr) internal pure returns (bytes memory) { - require(der[ptr.ixs()] == 0x03, "Not type BIT STRING"); - // Only 00 padded bitstr can be converted to bytestr! - require(der[ptr.ixf()] == 0x00); - uint256 valueLength = ptr.ixl() + 1 - ptr.ixf(); - return der.substring(ptr.ixf() + 1, valueLength - 1); + ptr.overflowCheck(der.length); + + // Check type is bitstring. + require(der[ptr.type_index()] == 0x03, "Not type BIT STRING"); + + // Only attempt to read if content set. + if(ptr.content_len() >= 1) { + // Only 00 padded bitstr can be converted to bytestr! + require(der[ptr.content_index()] == 0x00); + + // Return the segment and avoid overflows. + uint256 start_index = ptr.content_index() + 1; + uint256 valueLength = (ptr.end_index() - ptr.content_index()); + require(start_index < der.length); + require(start_index + valueLength <= der.length); + return der.substring(start_index, valueLength); + } + revert(); } + /* + A DER field looks like: + +type, (opt type) (len or len flag) (opt len ... N) (opt buf .. N) + +- Possibility for: one or two-byte type field. +- Possible: + - one byte len field. + - two byte len field. + - len info field followed by: + - variable length len field. +- Possible: + - variable length buffer + - or nothing + + This function returns a NodePtr indexing these fields. + If the buffer (or content) section is empty then + ptr.content_len() == 0 and ptr.content_index() == 0. + + The ptr.end_index() always points to the last byte of + the segment which may be a length field (if there's no + content portion) or the last content byte (if there's + a content / buffer portion set for it.) + + */ function readNodeLength(bytes memory der, uint256 ix) private pure returns (uint256) { - uint256 length; - uint80 ixFirstContentByte; - uint80 ixLastContentByte; + // Avoid overflow for first len byte. + require((ix + 1) < der.length); + + // Reject multi-byte identifiers. + require((der[ix] & 0x1F) != 0x1F); + + // Read length of a DER segment. + uint256 length = 0; + uint80 ixFirstContentByte = 0; + uint80 ixLastContentByte = uint80(ix + 1); if ((der[ix + 1] & 0x80) == 0) { length = uint8(der[ix + 1]); - ixFirstContentByte = uint80(ix + 2); - ixLastContentByte = uint80(ixFirstContentByte + length - 1); + if(length >= 1) + { + ixFirstContentByte = uint80(ix + 2); + ixLastContentByte += uint80(length); + } } else { + // How large is the length field? uint8 lengthbytesLength = uint8(der[ix + 1] & 0x7F); + + // Avoid overflow. + require((ix + 2 + lengthbytesLength) < der.length); if (lengthbytesLength == 1) { length = der.readUint8(ix + 2); } else if (lengthbytesLength == 2) { + require(ix + 3 < der.length); length = der.readUint16(ix + 2); } else { + // Ensure enough bytes left for len no. + require(ix + 2 + lengthbytesLength <= der.length); + require(lengthbytesLength <= 32); + + // Read variable length len field. + // Shift out the bit length of the length. + // Max shift is limited to sizeof length. + // But zero is still checked for bellow. length = uint256(der.readBytesN(ix + 2, lengthbytesLength) >> (32 - lengthbytesLength) * 8); } - ixFirstContentByte = uint80(ix + 2 + lengthbytesLength); - ixLastContentByte = uint80(ixFirstContentByte + length - 1); + + // Content length field must be positive. + ixLastContentByte += uint80(lengthbytesLength); + if(length >= 1) + { + ixFirstContentByte = uint80(ix + 2 + lengthbytesLength); + ixLastContentByte += uint80(length); + } } + + // The expected content segment must not overflow. + require(ixFirstContentByte < der.length); + require(ixLastContentByte < der.length); + require(ixLastContentByte > 0); + + // If the end pointer value is less than start then + // it may lead to an underflow and this is + // particullarly bad with solidity's wrap-around math. + require(ixLastContentByte >= ixFirstContentByte); + + // Return the nodeptr structure. return NodePtr.getPtr(ix, ixFirstContentByte, ixLastContentByte); } } diff --git a/src/DateTime.sol b/src/DateTime.sol new file mode 100644 index 0000000..de1a724 --- /dev/null +++ b/src/DateTime.sol @@ -0,0 +1,216 @@ +pragma solidity >=0.8.0 <0.9.0; + +contract DateTime { + /* + * Date and Time utilities for ethereum contracts + * + */ + struct _DateTime { + uint16 year; + uint8 month; + uint8 day; + uint8 hour; + uint8 minute; + uint8 second; + uint8 weekday; + } + + uint constant DAY_IN_SECONDS = 86400; + uint constant YEAR_IN_SECONDS = 31536000; + uint constant LEAP_YEAR_IN_SECONDS = 31622400; + + uint constant HOUR_IN_SECONDS = 3600; + uint constant MINUTE_IN_SECONDS = 60; + + uint16 constant ORIGIN_YEAR = 1970; + + function isLeapYear(uint16 year) public pure returns (bool) { + if (year % 4 != 0) { + return false; + } + if (year % 100 != 0) { + return true; + } + if (year % 400 != 0) { + return false; + } + return true; + } + + function leapYearsBefore(uint year) public pure returns (uint) { + year -= 1; + return year / 4 - year / 100 + year / 400; + } + + function getDaysInMonth(uint8 month, uint16 year) public pure returns (uint8) { + if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) { + return 31; + } + else if (month == 4 || month == 6 || month == 9 || month == 11) { + return 30; + } + else if (isLeapYear(year)) { + return 29; + } + else { + return 28; + } + } + + function parseTimestamp(uint timestamp) internal pure returns (_DateTime memory dt) { + uint secondsAccountedFor = 0; + uint buf; + uint8 i; + + // Year + dt.year = getYear(timestamp); + buf = leapYearsBefore(dt.year) - leapYearsBefore(ORIGIN_YEAR); + + secondsAccountedFor += LEAP_YEAR_IN_SECONDS * buf; + secondsAccountedFor += YEAR_IN_SECONDS * (dt.year - ORIGIN_YEAR - buf); + + // Month + uint secondsInMonth; + for (i = 1; i <= 12; i++) { + secondsInMonth = DAY_IN_SECONDS * getDaysInMonth(i, dt.year); + if (secondsInMonth + secondsAccountedFor > timestamp) { + dt.month = i; + break; + } + secondsAccountedFor += secondsInMonth; + } + + // Day + for (i = 1; i <= getDaysInMonth(dt.month, dt.year); i++) { + if (DAY_IN_SECONDS + secondsAccountedFor > timestamp) { + dt.day = i; + break; + } + secondsAccountedFor += DAY_IN_SECONDS; + } + + // Hour + dt.hour = getHour(timestamp); + + // Minute + dt.minute = getMinute(timestamp); + + // Second + dt.second = getSecond(timestamp); + + // Day of week. + dt.weekday = getWeekday(timestamp); + } + + function getYear(uint timestamp) public pure returns (uint16) { + uint secondsAccountedFor = 0; + uint16 year; + uint numLeapYears; + + // Year + year = uint16(ORIGIN_YEAR + timestamp / YEAR_IN_SECONDS); + numLeapYears = leapYearsBefore(year) - leapYearsBefore(ORIGIN_YEAR); + + secondsAccountedFor += LEAP_YEAR_IN_SECONDS * numLeapYears; + secondsAccountedFor += YEAR_IN_SECONDS * (year - ORIGIN_YEAR - numLeapYears); + + while (secondsAccountedFor > timestamp) { + if (isLeapYear(uint16(year - 1))) { + secondsAccountedFor -= LEAP_YEAR_IN_SECONDS; + } + else { + secondsAccountedFor -= YEAR_IN_SECONDS; + } + year -= 1; + } + return year; + } + + function getMonth(uint timestamp) public pure returns (uint8) { + return parseTimestamp(timestamp).month; + } + + function getDay(uint timestamp) public pure returns (uint8) { + return parseTimestamp(timestamp).day; + } + + function getHour(uint timestamp) public pure returns (uint8) { + return uint8((timestamp / 60 / 60) % 24); + } + + function getMinute(uint timestamp) public pure returns (uint8) { + return uint8((timestamp / 60) % 60); + } + + function getSecond(uint timestamp) public pure returns (uint8) { + return uint8(timestamp % 60); + } + + function getWeekday(uint timestamp) public pure returns (uint8) { + return uint8((timestamp / DAY_IN_SECONDS + 4) % 7); + } + + function toTimestamp(uint16 year, uint8 month, uint8 day) public pure returns (uint timestamp) { + return toTimestamp(year, month, day, 0, 0, 0); + } + + function toTimestamp(uint16 year, uint8 month, uint8 day, uint8 hour) public pure returns (uint timestamp) { + return toTimestamp(year, month, day, hour, 0, 0); + } + + function toTimestamp(uint16 year, uint8 month, uint8 day, uint8 hour, uint8 minute) public pure returns (uint timestamp) { + return toTimestamp(year, month, day, hour, minute, 0); + } + + function toTimestamp(uint16 year, uint8 month, uint8 day, uint8 hour, uint8 minute, uint8 second) public pure returns (uint timestamp) { + uint16 i; + + // Year + for (i = ORIGIN_YEAR; i < year; i++) { + if (isLeapYear(i)) { + timestamp += LEAP_YEAR_IN_SECONDS; + } + else { + timestamp += YEAR_IN_SECONDS; + } + } + + // Month + uint8[12] memory monthDayCounts; + monthDayCounts[0] = 31; + if (isLeapYear(year)) { + monthDayCounts[1] = 29; + } + else { + monthDayCounts[1] = 28; + } + monthDayCounts[2] = 31; + monthDayCounts[3] = 30; + monthDayCounts[4] = 31; + monthDayCounts[5] = 30; + monthDayCounts[6] = 31; + monthDayCounts[7] = 31; + monthDayCounts[8] = 30; + monthDayCounts[9] = 31; + monthDayCounts[10] = 30; + monthDayCounts[11] = 31; + + for (i = 1; i < month; i++) { + timestamp += DAY_IN_SECONDS * monthDayCounts[i - 1]; + } + + // Day + timestamp += DAY_IN_SECONDS * (day - 1); + + // Hour + timestamp += HOUR_IN_SECONDS * (hour); + + // Minute + timestamp += MINUTE_IN_SECONDS * (minute); + + // Second + timestamp += second; + + return timestamp; + } +} diff --git a/src/IRave.sol b/src/IRave.sol index 0628f75..9f3a860 100755 --- a/src/IRave.sol +++ b/src/IRave.sol @@ -32,8 +32,8 @@ interface IRave { bytes memory leafX509Cert, bytes memory signingMod, bytes memory signingExp, - bytes32 mrenclave, - bytes32 mrsigner + bytes memory mrenclave, + bytes memory mrsigner ) external view returns (bytes memory payload); /* @@ -51,7 +51,7 @@ interface IRave { bytes memory sig, bytes memory signingMod, bytes memory signingExp, - bytes32 mrenclave, - bytes32 mrsigner + bytes memory mrenclave, + bytes memory mrsigner ) external view returns (bytes memory payload); } diff --git a/src/RAVE.sol b/src/RAVE.sol index 537cb39..4c228c7 100755 --- a/src/RAVE.sol +++ b/src/RAVE.sol @@ -1,6 +1,55 @@ +/* +The most significant function in this module is rave(). +The purpose of RAVE is to validate the integrity of an +'attestation report' vouched for by Intel and return the +reports payload body on success. + +The process involves: + (1) Re-constructing a JSON attestation report that + byte-for-byte matches the original report returned by + the appropriate Intel attestation APIs. + (2) Confirming that the report was signed by an X509 + 'leaf' certificate issued by a CA. + (3) Confirming that this CA was in fact Intel + (also known as the 'report attestation signer CA -- this + cert can be found in the certs directory in both + DER form and PEM form for convenience.) + +The result is an API that can verify attestation reports +on-chain issued by Intel. Unfortunately, the process to +call the rave() function is quite involved. One has to: + (1) Pack a special list of report fields as bytes. + (2) Extract the right enclave hash values. + (3) And pass in the right leaf certificate values. + +All of this is easier said than done. But I've created some +scripts to make this a little easier. + (1) There is a script that takes the output of the + secure signer binary (ss_out) and converts it into a + list of hex data for calling rave(). It can be found in + /test/scripts/bin/ss_to_abi. The bin directory also + contains other useful commands for working with certs + and doing operations needed for RAVE. You will need to cd + to this dir to use them though. + (2) There is also a script demonstrating full deployment + of the RAVE contract and calling rave() from scratch + using the above function. It can be found in my fork + here: https://github.com/matthew-puffer-finance-forks/rave-foundry/blob/master/deploy.sh + +Working with signed data is inherently painful because if +anything is off by so much as a single bit it will fail. +While testing this software I had the issue of a single +new line being added to the report due to the echo command. +Nothing was wrong with the code but the addition caused all +checks to fail. There are tools to assess whether much of +the values are correct in the /test/scripts/bin directory. +*/ + + // SPDX-License-Identifier: Apache-2.0 pragma solidity >=0.8.0 <0.9.0; +import { RAVEConsts } from "./RAVEConsts.sol"; import { X509Verifier } from "./X509Verifier.sol"; import { JSONBuilder } from "./JSONBuilder.sol"; import { BytesUtils } from "ens-contracts/dnssec-oracle/BytesUtils.sol"; @@ -28,43 +77,87 @@ contract RAVE is Test, RAVEBase, JSONBuilder, X509Verifier { bytes memory sig, bytes memory signingMod, bytes memory signingExp, - bytes32 mrenclave, - bytes32 mrsigner + bytes memory mrenclave, + bytes memory mrsigner ) public view override returns (bytes memory payload) { // Decode the encoded report JSON values to a Values struct and reconstruct the original JSON string (Values memory reportValues, bytes memory reportBytes) = _buildReportBytes(reportFieldsABI); console.log(string(reportBytes)); + // Verify the report's contents match the expected + payload = _verifyReportContents(reportValues, mrenclave, mrsigner); + + // Verify the report was signed by the SigningPK if (!verifyRSA(reportBytes, sig, signingMod, signingExp)) { + console.logBytes(sig); revert BadReportSignature(); } - // Verify the report's contents match the expected - payload = _verifyReportContents(reportValues, mrenclave, mrsigner); + return payload; } + + /** * @inheritdoc RAVEBase */ function rave( // ABI encoded list of report fields as bytes. - // current incorrectly passing json. bytes calldata report, + + /* + RSA encryption of the report from the leaf cert. + The exact algorithm is: sha256WithRSA (PKCS#1 padding.) + The signature can be verified with the signing + public key found inside the leaf X509 cert. + */ bytes memory sig, - // root ca or report cert? + /* + This can be a leaf certificate issued by Intel's + 'report signing CA' or it can be a self-signed cert. + Refer to the field bellow for more details. + */ bytes memory leafX509Cert, - // root ca or report cert? - // usage seems to indicate intel root ca + /* + The fields here allow passing in the parameters + for the CA who issued the leaf certificate. + Set the bytes to empty for both to force it to use + the Intel root CA. Otherwise, you can pass in your + own values to test the function with self-signed certs. + */ bytes memory signingMod, bytes memory signingExp, - bytes32 mrenclave, - bytes32 mrsigner + /* + These are special values that belong to the enclave binary + and hardware that did the attestation report. + You can gather them using: + occlum print mrenclave + occlum print mrsigner + In the enclave directory. + */ + bytes memory mrenclave, + bytes memory mrsigner ) public view override returns (bytes memory payload) { + /* + The root CA params are hard-coded in the contract. + If blank data is passed to the function use these values. + Otherwise use the passed values so self-signed certs + can be used as input test data. + */ + if( + (signingMod.compare(NULL) == 0) + && + (signingExp.compare(NULL) == 0) + ) { + signingMod = _INTEL_ROOT_MOD; + signingExp = _INTEL_ROOT_EXP; + } + // Verify the leafX509Cert was signed with signingMod and signingExp (bytes memory leafCertModulus, bytes memory leafCertExponent) = verifySignedX509(leafX509Cert, signingMod, signingExp); @@ -78,6 +171,8 @@ contract RAVE is Test, RAVEBase, JSONBuilder, X509Verifier { console.logBytes(truncMod); console.log(truncMod.length); + console.log("leaf cert modulus"); + console.log(leafCertModulus.length); payload = verifyRemoteAttestation(report, sig, truncMod, leafCertExponent, mrenclave, mrsigner); return payload; } @@ -153,7 +248,7 @@ contract RAVE is Test, RAVEBase, JSONBuilder, X509Verifier { * @param mrsigner The expected enclave signer. * @return The 64 byte payload if the mrenclave and mrsigner values were correctly set. */ - function _verifyReportContents(Values memory reportValues, bytes32 mrenclave, bytes32 mrsigner) + function _verifyReportContents(Values memory reportValues, bytes memory mrenclave, bytes memory mrsigner) internal pure returns (bytes memory payload) @@ -168,11 +263,13 @@ contract RAVE is Test, RAVEBase, JSONBuilder, X509Verifier { // Verify report's MRENCLAVE matches the expected bytes32 mre = quoteBody.readBytes32(MRENCLAVE_OFFSET); - require(mre == mrenclave); + bytes32 mre2 = mrenclave.readBytes32(0); + require(mre2 == mre); // Verify report's MRSIGNER matches the expected bytes32 mrs = quoteBody.readBytes32(MRSIGNER_OFFSET); - require(mrs == mrsigner); + bytes32 mrs2 = mrsigner.readBytes32(0); + require(mrs == mrs2); // Verify report's <= 64B payload matches the expected payload = quoteBody.substring(PAYLOAD_OFFSET, PAYLOAD_SIZE); diff --git a/src/RAVEBase.sol b/src/RAVEBase.sol index 09b0c12..65d6612 100755 --- a/src/RAVEBase.sol +++ b/src/RAVEBase.sol @@ -18,8 +18,8 @@ abstract contract RAVEBase is IRave { bytes memory sig, bytes memory signingMod, bytes memory signingExp, - bytes32 mrenclave, - bytes32 mrsigner + bytes memory mrenclave, + bytes memory mrsigner ) public view virtual returns (bytes memory payload) { } /** @@ -31,7 +31,7 @@ abstract contract RAVEBase is IRave { bytes memory leafX509Cert, bytes memory signingMod, bytes memory signingExp, - bytes32 mrenclave, - bytes32 mrsigner + bytes memory mrenclave, + bytes memory mrsigner ) external view virtual returns (bytes memory payload) { } } diff --git a/src/RAVEConsts.sol b/src/RAVEConsts.sol index 9c146d6..70da5b4 100755 --- a/src/RAVEConsts.sol +++ b/src/RAVEConsts.sol @@ -11,4 +11,5 @@ abstract contract RAVEConsts { bytes32 constant OK_STATUS = keccak256("OK"); bytes32 constant HARDENING_STATUS = keccak256("SW_HARDENING_NEEDED"); + bytes constant NULL = hex""; } diff --git a/src/X509Verifier.sol b/src/X509Verifier.sol index 17eac34..02b2089 100755 --- a/src/X509Verifier.sol +++ b/src/X509Verifier.sol @@ -7,9 +7,10 @@ import { BytesUtils } from "ens-contracts/dnssec-oracle/BytesUtils.sol"; import { SafeMath } from "openzeppelin-contracts/contracts/utils/math/SafeMath.sol"; import { Math } from "openzeppelin-contracts/contracts/utils/math/Math.sol"; import { Utils } from "./Utils.sol"; +import "./DateTime.sol"; import { Test, console } from "forge-std/Test.sol"; -contract X509Verifier is Test { +contract X509Verifier is Test, DateTime { using Asn1Decode for bytes; using BytesUtils for bytes; using Utils for bytes; @@ -17,6 +18,21 @@ contract X509Verifier is Test { bytes constant _SHA256_PAD_ID_WITH_NULL = hex"3031300d060960864801650304020105000420"; bytes constant _SHA256_PAD_ID_WITHOUT_NULL = hex"302f300b06096086480165030402010420"; + bytes constant _CERT_PUB_ALG = hex"2A864886F70D010101"; + bytes constant _CERT_SIG_ALG = hex"2a864886f70d01010b"; + + bytes constant _INTEL_ROOT_MOD = hex"9F3C647EB5773CBB512D2732C0D7415EBB55A0FA9EDE2E649199E6821DB910D53177370977466A6A5E4786CCD2DDEBD4149D6A2F6325529DD10CC98737B0779C1A07E29C47A1AE004948476C489F45A5A15D7AC8ECC6ACC645ADB43D87679DF59C093BC5A2E9696C5478541B979E754B573914BE55D32FF4C09DDF27219934CD990527B3F92ED78FBF29246ABECB71240EF39C2D7107B447545A7FFB10EB060A68A98580219E36910952683892D6A5E2A80803193E407531404E36B315623799AA825074409754A2DFE8F5AFD5FE631E1FC2AF3808906F28A790D9DD9FE060939B125790C5805D037DF56A99531B96DE69DE33ED226CC1207D1042B5C9AB7F404FC711C0FE4769FB9578B1DC0EC469EA1A25E0FF9914886EF2699B235BB4847DD6FF40B606E6170793C2FB98B314587F9CFD257362DFEAB10B3BD2D97673A1A4BD44C453AAF47FC1F2D3D0F384F74A06F89C089F0DA6CDB7FCEEE8C9821A8E54F25C0416D18C46839A5F8012FBDD3DC74D256279ADC2C0D55AFF6F0622425D1B"; + bytes constant _INTEL_ROOT_EXP = hex"010001"; + + // Intel SGX Attestation Report Signing [subject] (issuer blank) + bytes constant _SGX_REPORT_SIGNING_SUBJECT = hex"310b3009060355040613025553310b300906035504080c0243413114301206035504070c0b53616e746120436c617261311a3018060355040a0c11496e74656c20436f72706f726174696f6e3130302e06035504030c27496e74656c20534758204174746573746174696f6e205265706f7274205369676e696e67204341"; + + bytes constant _SGX_REPORT_SIGNING_ISSUER = hex"310b3009060355040613025553310b300906035504080c0243413114301206035504070c0b53616e746120436c617261311a3018060355040a0c11496e74656c20436f72706f726174696f6e312d302b06035504030c24496e74656c20534758204174746573746174696f6e205265706f7274205369676e696e67"; + + // Intel SGX Attestation Report Root CA Signing [subject and issuer] + bytes constant _SGX_ROOT_SA_SUBJECT = hex"310b3009060355040613025553310b300906035504080c0243413114301206035504070c0b53616e746120436c617261311a3018060355040a0c11496e74656c20436f72706f726174696f6e3130302e06035504030c27496e74656c20534758204174746573746174696f6e205265706f7274205369676e696e67204341"; + + // 06092a864886f70d01010b0500 constructor() { } @@ -153,6 +169,30 @@ contract X509Verifier is Test { return success && (keccak256(res) == keccak256(encodedMsg)); } + function toX509Time(bytes memory x509Time) public pure returns (uint) { + uint16 yrs; uint8 mnths; + uint8 dys; uint8 hrs; + uint8 mins; uint8 secs; + uint8 offset; + + if (x509Time.length == 13) { + if (uint8(x509Time[0])-48 < 5) yrs += 2000; + else yrs += 1900; + } + else { + yrs += (uint8(x509Time[0])-48) * 1000 + (uint8(x509Time[1])-48) * 100; + offset = 2; + } + yrs += (uint8(x509Time[offset+0])-48)*10 + uint8(x509Time[offset+1])-48; + mnths = (uint8(x509Time[offset+2])-48)*10 + uint8(x509Time[offset+3])-48; + dys += (uint8(x509Time[offset+4])-48)*10 + uint8(x509Time[offset+5])-48; + hrs += (uint8(x509Time[offset+6])-48)*10 + uint8(x509Time[offset+7])-48; + mins += (uint8(x509Time[offset+8])-48)*10 + uint8(x509Time[offset+9])-48; + secs += (uint8(x509Time[offset+10])-48)*10 + uint8(x509Time[offset+11])-48; + + return toTimestamp(yrs, mnths, dys, hrs, mins, secs); + } + /* * @dev specs: https://www.ietf.org/rfc/rfc5280.txt * @dev Certificate ::= SEQUENCE { @@ -187,17 +227,38 @@ contract X509Verifier is Test { view returns (bytes memory, bytes memory) { - // Pointer to top level asn1 object: Sequence{tbsCertificate, signatureAlgorithm, signatureValue} - uint256 root = cert.root(); + /* + Test code calls this function directly + using self-signed certs. Consequently, they + will have different mods and exps to Intel. + Extended checks for issuer and subject will + be disabled in this case. + */ + bool extended_checks = false; + if( + (parentMod.compare(_INTEL_ROOT_MOD) == 0) + && + (parentExp.compare(_INTEL_ROOT_EXP) == 0) + ) { + extended_checks = true; + } + console.log(extended_checks); // Traverse to first in sequence (the tbsCertificate) - uint256 tbsPtr = cert.firstChildOf(root); + uint256 tbsPtr = cert.firstChildOf(cert.root()); // Extracts the TBSCerificate (what is used as input to RSA-SHA256) - bytes memory certBody = cert.allBytesAt(tbsPtr); + //bytes memory certBody = cert.allBytesAt(tbsPtr); // Top level traverse to signatureAlgorithm uint256 sigAlgPtr = cert.nextSiblingOf(tbsPtr); + require( + _CERT_SIG_ALG.compare( + cert.bytesAt( + cert.firstChildOf(sigAlgPtr) + ) + ) == 0 + ); // Top level traverse to signatureValue uint256 sigPtr = cert.nextSiblingOf(sigAlgPtr); @@ -206,7 +267,7 @@ contract X509Verifier is Test { bytes memory signature = cert.bytesAt(sigPtr); // Verify the parent signed the certBody - require(verifyChildCert(certBody, signature, parentMod, parentExp), "verifyChildCert fail"); + require(verifyChildCert(cert.allBytesAt(tbsPtr), signature, parentMod, parentExp), "verifyChildCert fail"); //require(verifyRSA(certBody, signature, parentMod, parentExp), "verifyChildCert fail"); // ---------------- @@ -217,7 +278,7 @@ contract X509Verifier is Test { uint256 ptr = cert.firstChildOf(tbsPtr); // Account for v1 vs v3 - if (cert[NodePtr.ixs(ptr)] == 0xa0) { + if (cert[NodePtr.type_index(ptr)] == 0xa0) { ptr = cert.nextSiblingOf(ptr); } @@ -227,27 +288,65 @@ contract X509Verifier is Test { // Skip the next 3 fields (signature, issuer, validity, subject) ptr = cert.nextSiblingOf(ptr); // point to signature ptr = cert.nextSiblingOf(ptr); // point to issuer + console.log("issuer..."); + if(extended_checks) { + require( + _SGX_REPORT_SIGNING_SUBJECT.compare( + cert.bytesAt(ptr) + ) == 0 + ); + } + + ptr = cert.nextSiblingOf(ptr); // point to validity + //ptr = cert.firstChildOf(ptr); // Arrive at the validity field // todo verifiy validity timestamps - // uint256 validityPtr = ptr; - // bytes memory validNotBefore = cert.bytesAt(validityPtr); - // console.logBytes(validNotBefore); - // uint40 validNotBefore = uint40(toTimestamp(cert.bytesAt(validityPtr))); - // console.log("validNotBefore: %s", validNotBefore); - // validityPtr = cert.nextSiblingOf(validityPtr); - // bytes memory validNotAfter = cert.bytesAt(validityPtr); - // console.logBytes(validNotAfter); - // uint40 validNotAfter = uint40(toTimestamp(cert.bytesAt(validityPtr))); - // console.log("validNotAfter: %s", validNotAfter); - - // Traverse until the subjectPublicKeyInfo field + console.log("Valid before unix = "); + + console.logBytes(cert.bytesAt(ptr)); + console.logBytes(cert.bytesAt(cert.firstChildOf(ptr))); + + // Valid before. + ptr = cert.firstChildOf(ptr); + uint x = toX509Time(cert.bytesAt(ptr)); + console.log(x); + + // Valid after. + ptr = cert.nextSiblingOf(ptr); + x = toX509Time(cert.bytesAt(ptr)); + console.log(x); + + + + ptr = cert.nextSiblingOf(ptr); // point to subject + console.log("subject"); + console.logBytes(cert.bytesAt(ptr)); + if(extended_checks) { + require( + _SGX_REPORT_SIGNING_ISSUER.compare( + cert.bytesAt(ptr) + ) == 0 + ); + } + + ptr = cert.nextSiblingOf(ptr); // point to subjectPublicKeyInfo // Enter subjectPublicKeyInfo ptr = cert.firstChildOf(ptr); // point to subjectPublicKeyInfo.algorithm + + // Require the pubkey algorithm to be RSA. + require( + _CERT_PUB_ALG.compare( + cert.bytesAt( + cert.firstChildOf(ptr) + ) + ) == 0 + ); + ptr = cert.nextSiblingOf(ptr); // point to subjectPublicKeyInfo.subjectPublicKey // Extract DER-encoded RSA public key diff --git a/test/ASN1Decode.t.sol b/test/ASN1Decode.t.sol new file mode 100644 index 0000000..637d6a7 --- /dev/null +++ b/test/ASN1Decode.t.sol @@ -0,0 +1,387 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity >=0.8.0 <0.9.0; + +import { Test, console } from "forge-std/Test.sol"; +import { BytesUtils } from "ens-contracts/dnssec-oracle/BytesUtils.sol"; +import { Utils } from "rave/Utils.sol"; +import { NodePtr, Asn1Decode } from "rave/ASN1Decode.sol"; +import { X509Verifier } from "rave/X509Verifier.sol"; + +contract TestASN1 is Test { + + using Asn1Decode for bytes; + using BytesUtils for bytes; + using Utils for bytes; + using NodePtr for uint256; + X509Verifier Certs = new X509Verifier(); + + + // Intel's root CA modulus + bytes intelRootModulus = + hex"9F3C647EB5773CBB512D2732C0D7415EBB55A0FA9EDE2E649199E6821DB910D53177370977466A6A5E4786CCD2DDEBD4149D6A2F6325529DD10CC98737B0779C1A07E29C47A1AE004948476C489F45A5A15D7AC8ECC6ACC645ADB43D87679DF59C093BC5A2E9696C5478541B979E754B573914BE55D32FF4C09DDF27219934CD990527B3F92ED78FBF29246ABECB71240EF39C2D7107B447545A7FFB10EB060A68A98580219E36910952683892D6A5E2A80803193E407531404E36B315623799AA825074409754A2DFE8F5AFD5FE631E1FC2AF3808906F28A790D9DD9FE060939B125790C5805D037DF56A99531B96DE69DE33ED226CC1207D1042B5C9AB7F404FC711C0FE4769FB9578B1DC0EC469EA1A25E0FF9914886EF2699B235BB4847DD6FF40B606E6170793C2FB98B314587F9CFD257362DFEAB10B3BD2D97673A1A4BD44C453AAF47FC1F2D3D0F384F74A06F89C089F0DA6CDB7FCEEE8C9821A8E54F25C0416D18C46839A5F8012FBDD3DC74D256279ADC2C0D55AFF6F0622425D1B"; + + bytes intelRootExponent = hex"010001"; + + bytes cert = hex"308204a130820309a003020102020900d107765d32a3b096300d06092a864886f70d01010b0500307e310b3009060355040613025553310b300906035504080c0243413114301206035504070c0b53616e746120436c617261311a3018060355040a0c11496e74656c20436f72706f726174696f6e3130302e06035504030c27496e74656c20534758204174746573746174696f6e205265706f7274205369676e696e67204341301e170d3136313132323039333635385a170d3236313132303039333635385a307b310b3009060355040613025553310b300906035504080c0243413114301206035504070c0b53616e746120436c617261311a3018060355040a0c11496e74656c20436f72706f726174696f6e312d302b06035504030c24496e74656c20534758204174746573746174696f6e205265706f7274205369676e696e6730820122300d06092a864886f70d01010105000382010f003082010a0282010100a97a2de0e66ea6147c9ee745ac0162686c7192099afc4b3f040fad6de093511d74e802f510d716038157dcaf84f4104bd3fed7e6b8f99c8817fd1ff5b9b864296c3d81fa8f1b729e02d21d72ffee4ced725efe74bea68fbc4d4244286fcdd4bf64406a439a15bcb4cf67754489c423972b4a80df5c2e7c5bc2dbaf2d42bb7b244f7c95bf92c75d3b33fc5410678a89589d1083da3acc459f2704cd99598c275e7c1878e00757e5bdb4e840226c11c0a17ff79c80b15c1ddb5af21cc2417061fbd2a2da819ed3b72b7efaa3bfebe2805c9b8ac19aa346512d484cfc81941e15f55881cc127e8f7aa12300cd5afb5742fa1d20cb467a5beb1c666cf76a368978b50203010001a381a43081a1301f0603551d2304183016801478437b76a67ebcd0af7e4237eb357c3b8701513c300e0603551d0f0101ff0404030206c0300c0603551d130101ff0402300030600603551d1f045930573055a053a051864f687474703a2f2f7472757374656473657276696365732e696e74656c2e636f6d2f636f6e74656e742f43524c2f5347582f4174746573746174696f6e5265706f72745369676e696e6743412e63726c300d06092a864886f70d01010b050003820181006708b61b5c2bd215473e2b46af99284fbb939d3f3b152c996f1a6af3b329bd220b1d3b610f6bce2e6753bded304db21912f385256216cfcba456bd96940be892f5690c260d1ef84f1606040222e5fe08e5326808212a447cfdd64a46e94bf29f6b4b9a721d25b3c4e2f62f58baed5d77c505248f0f801f9fbfb7fd752080095cee80938b339f6dbb4e165600e20e4a718812d49d9901e310a9b51d66c79909c6996599fae6d76a79ef145d9943bf1d3e35d3b42d1fb9a45cbe8ee334c166eee7d32fcdc9935db8ec8bb1d8eb3779dd8ab92b6e387f0147450f1e381d08581fb83df33b15e000a59be57ea94a3a52dc64bdaec959b3464c91e725bbdaea3d99e857e380a23c9d9fb1ef58e9e42d71f12130f9261d7234d6c37e2b03dba40dfdfb13ac4ad8e13fd3756356b6b50015a3ec9580b815d87c2cef715cd28df00bbf2a3c403ebf6691b3f05edd9143803ca085cff57e053eec2f8fea46ea778a68c9be885bc28225bc5f309be4a2b74d3a03945319dd3c7122fed6ff53bb8b8cb3a03c"; + + constructor() { } + + function testASN1CertTraversial() public { + // Pointer to top level asn1 object: Sequence{tbsCertificate, signatureAlgorithm, signatureValue} + uint256 root = cert.root(); + + // Traverse to first in sequence (the tbsCertificate) + uint256 tbsPtr = cert.firstChildOf(root); + + // Extracts the TBSCerificate (what is used as input to RSA-SHA256) + bytes memory certBody = cert.allBytesAt(tbsPtr); + //console.log(tbsPtr.content_len()); + + // Top level traverse to signatureAlgorithm + uint256 sigAlgPtr = cert.nextSiblingOf(tbsPtr); + + // Top level traverse to signatureValue + uint256 sigPtr = cert.nextSiblingOf(sigAlgPtr); + + // Extracts the signed certificate body + bytes memory signature = cert.bytesAt(sigPtr); + + require(Certs.verifyChildCert(certBody, signature, intelRootModulus, intelRootExponent), "verifyChildCert fail"); + } + + /* + function testASN1RootOverflow() public { + bytes memory bugCert = bytes(cert); + + // Max certificate length portion. + bugCert[1] = hex"02"; + bugCert[2] = hex"99"; + bugCert[3] = hex"99"; + + // [1] len bytes length? + + // Attempt to load the 'root node' of the cert. + uint256 rootPtr = bugCert.root(); + bugCert.firstChildOf(rootPtr); + + test read uint, u16, readn overflow. + } + */ + + function testANS1NextSiblingOfOverflow() public { + vm.expectRevert(); + + bytes memory buf = hex"030400112233030400112233"; + uint256 ptr = NodePtr.getPtr(0, 2, 200); + buf.nextSiblingOf(ptr); + } + + function testANS1NextSiblingOfSuccess() public { + bytes memory buf = hex"030400112233020400112233"; + uint256 ptr = NodePtr.getPtr(0, 2, 5); + ptr = buf.nextSiblingOf(ptr); + uint256 out = buf.uintAt(ptr); + uint256 expect = 1122867; + assert(out == expect); + } + + function testANS1FirstChildOfOverflow() public { + vm.expectRevert(); + + bytes memory buf = hex"00000000200402020133"; + uint256 ptr = NodePtr.getPtr(4, 200, 5); + buf.firstChildOf(ptr); + } + + function testANS1FirstChildOfSuccess() public { + bytes memory buf = hex"00000000200402020133"; + uint256 ptr = NodePtr.getPtr(4, 6, 7); + ptr = buf.firstChildOf(ptr); + uint256 out = buf.uintAt(ptr); + uint256 expect = 307; + assert(out == expect); + } + + function testANS1RootOctetStringAtOverflow() public { + vm.expectRevert(); + + bytes memory buf = hex"040002990133"; + uint256 ptr = NodePtr.getPtr(0, 200, 5); + buf.rootOfOctetStringAt(ptr); + } + + function testANS1RootOctetStringAtSuccess() public { + bytes memory buf = hex"040402020133"; + uint256 ptr = NodePtr.getPtr(0, 2, 5); + ptr = buf.rootOfOctetStringAt(ptr); + uint256 out = buf.uintAt(ptr); + assert(out == 51); + } + + function testANS1RootOfBitStringAtOverflow() public { + vm.expectRevert(); + + // len -> 3 -> +1 = len -> 4 + bytes memory buf = hex"039900009933"; + uint256 ptr = NodePtr.getPtr(0, 2, 5); + buf.rootOfBitStringAt(ptr); + } + + function testANS1RootOfBitStringAtSuccess() public { + bytes memory buf = hex"030402020133"; + uint256 ptr = NodePtr.getPtr(0, 2, 5); + ptr = buf.rootOfBitStringAt(ptr); + uint256 out = buf.uintAt(ptr); + assert(out == 51); + } + + function testANS1BytesAtOverflow() public { + vm.expectRevert(); + + bytes memory buf = hex"020400112233"; + uint256 ptr = NodePtr.getPtr(0, 200, 200); + buf.bytesAt(ptr); + } + + function testANS1BytesAtSuccess() public { + bytes memory buf = hex"020400112233"; + uint256 ptr = NodePtr.getPtr(0, 2, 5); + bytes memory out = buf.bytesAt(ptr); + bytes memory expect = hex"00112233"; + assert(keccak256(out) == keccak256(expect)); + } + + function testANS1AllBytesAtOverflow() public { + vm.expectRevert(); + + bytes memory buf = hex"020400112233"; + uint256 ptr = NodePtr.getPtr(0, 200, 200); + buf.allBytesAt(ptr); + } + + function testANS1AllBytesAtSuccess() public { + bytes memory buf = hex"020400112233"; + uint256 ptr = NodePtr.getPtr(0, 2, 5); + bytes memory out = buf.allBytesAt(ptr); + assert(keccak256(out) == keccak256(buf)); + } + + function testANS1Bytes32AtOverflow() public { + vm.expectRevert(); + + bytes memory buf = hex"020400112233"; + uint256 ptr = NodePtr.getPtr(0, 200, 200); + buf.bytes32At(ptr); + } + + function testANS1Bytes32AtSuccess() public { + bytes memory buf = hex"020400112233"; + uint256 ptr = NodePtr.getPtr(0, 2, 5); + bytes32 out = buf.bytes32At(ptr); + bytes32 expect = hex"00112233"; + assert(out == expect); + } + + function testANS1UintAtOverflow() public { + vm.expectRevert(); + + bytes memory buf = hex"020400112233"; + uint256 ptr = NodePtr.getPtr(0, 200, 200); + buf.uintAt(ptr); + } + + function testANS1UintAtSuccess() public { + bytes memory buf = hex"020400112233"; + uint256 ptr = NodePtr.getPtr(0, 2, 5); + uint256 out = buf.uintAt(ptr); + uint256 expect = 1122867; + assert(out == expect); + } + + function testANS1UintBytesAtOverflow() public { + vm.expectRevert(); + + bytes memory buf = hex"020400112233"; + uint256 ptr = NodePtr.getPtr(0, 200, 200); + buf.uintBytesAt(ptr); + } + + function testANS1UintBytesAtSuccess() public { + bytes memory buf = hex"020400112233"; + uint256 ptr = NodePtr.getPtr(0, 2, 5); + bytes memory out = buf.uintBytesAt(ptr); + bytes memory expect = hex"00112233"; + assert(keccak256(out) == keccak256(expect)); + } + + function testANS1KeccakBytesAtOverflow() public { + vm.expectRevert(); + + bytes memory buf = hex"030400112233"; + uint256 ptr = NodePtr.getPtr(0, 200, 200); + buf.keccakOfBytesAt(ptr); + } + + function testANS1KeccakBytesAtSuccess() public { + bytes memory buf = hex"030400112233"; + uint256 ptr = NodePtr.getPtr(0, 2, 5); + bytes32 out = buf.keccakOfBytesAt(ptr); + bytes memory expect = hex"00112233"; + assert(out == keccak256(expect)); + } + + function testANS1KeccakAllAtOverflow() public { + vm.expectRevert(); + + bytes memory buf = hex"030400112233"; + uint256 ptr = NodePtr.getPtr(0, 200, 200); + buf.keccakOfAllBytesAt(ptr); + } + + function testANS1KeccakAllAtSuccess() public { + bytes memory buf = hex"030400112233"; + uint256 ptr = NodePtr.getPtr(0, 2, 5); + bytes32 out = buf.keccakOfAllBytesAt(ptr); + assert(out == keccak256(buf)); + } + + function testANS1BitStrAtOverflow() public { + vm.expectRevert(); + + // High order len bit is set + // which triggers else in readNodeLen + bytes memory buf = hex"030400112233"; + uint256 ptr = NodePtr.getPtr(0, 200, 200); + buf.bitstringAt(ptr); + } + + function testANS1BitStrAtSuccess() public { + // High order len bit is set + // which triggers else in readNodeLen + bytes memory buf = hex"030400112233"; + uint256 ptr = NodePtr.getPtr(0, 2, 5); + + // It does the weird padded bitstrings. + bytes memory out = buf.bitstringAt(ptr); + bytes memory expect = hex"112233"; + assert(keccak256(out) == keccak256(expect)); + } + + function testASN1RootOverflowIf() public { + vm.expectRevert(); + + // High order len bit is set + // which triggers else in readNodeLen + bytes memory buf = hex"0281"; + buf.root(); + } + + function testASN1RootOverflowElseIf() public { + vm.expectRevert(); + + // High order len bit is not set + // which triggers else, if in readNodeLen + bytes memory buf = hex"0201"; + buf.root(); + } + + function testASN1RootOverflowElseElIf() public { + vm.expectRevert(); + + // High order len bit is not set + // which triggers else, if in readNodeLen + bytes memory buf = hex"0202"; + buf.root(); + } + + function testASN1RootOverflowElseElse() public { + vm.expectRevert(); + + // High order len bit is not set + // which triggers else, if in readNodeLen + bytes memory buf = hex"0203"; + buf.root(); + } + + function testASN1Uint8Overflow() public { + vm.expectRevert(); + bytes memory buf = hex"029901"; + + uint256 rootPtr = buf.root(); + buf.uintAt(rootPtr); + } + + function testASN1IntegerOverflow() public { + vm.expectRevert(); + + // 02 (type = INTEGER) + // 99 (len = OVERFLOW) + // ... actual buffer to traverse + bytes memory x = hex"0299010010"; + + uint256 rootPtr = x.root(); + uint256 out = x.uintAt(rootPtr); + console.log(out); + } + + function testASN1RootSuccessChances() public { + // if, len = 1, buf 1 + uint256 out = 0; uint256 ptr = 0; + bytes memory a = hex"02010201"; + ptr = a.root(); + out = a.uintAt(ptr); + assert(out == 2); + + // if:if, len 1, buf 1 + bytes memory b = hex"02810101"; + b.root(); + out = a.uintAt(ptr); + assert(out == 2); + + // if:elseif, len 1 (2 bytes), buf 1 + bytes memory c = hex"0282000102"; + c.root(); + out = a.uintAt(ptr); + assert(out == 2); + + // if:..else var len 1 (3 bytes), buf 1 + bytes memory d = hex"028300000102"; + d.root(); + out = a.uintAt(ptr); + assert(out == 2); + } + + function testASN1RejectMultibyteTags() public { + vm.expectRevert(); + + bytes memory a = hex"1F020102"; + //uint256 ptr = NodePtr.getPtr(0, 2, 3); + a.root(); + } + + function testASN1ZeroLenContentFieldsSuccess() public { + // field 1: 0200 (len zero) + // field 2: 0202 0001 (len 02) + bytes memory buf = hex"200002020001"; + uint256 root = buf.root(); + uint256 ptr = buf.nextSiblingOf(root); + uint256 out = buf.uintAt(ptr); + assert(out == 1); + } +} + +/* + +TODO: check for x509 hdr byte sequence + +https://letsencrypt.org/docs/a-warm-welcome-to-asn1-and-der/ + +3082 +30 SEQUENCE +82 extended byte for tag data? +len + +The length of any DER field can be expressed as a series of up to 126 bytes. So the biggest INTEGER you can represent in DER is 256(2**1008)-1. For a truly unbounded INTEGER you’d have to encode in BER, which allows indefinitely-long fields. + + +*/ diff --git a/test/RAVE.t.sol b/test/RAVE.t.sol index 771324b..556ac5b 100755 --- a/test/RAVE.t.sol +++ b/test/RAVE.t.sol @@ -6,8 +6,9 @@ import { RAVE } from "rave/RAVE.sol"; import { BytesUtils } from "ens-contracts/dnssec-oracle/BytesUtils.sol"; import { MockEvidence, ValidBLSEvidence } from "test/mocks/MockEvidence.sol"; -import { X509GenHelper, BytesFFIFuzzer } from "test/utils/helper.sol"; +import { X509GenHelper, BytesFFIFuzzer, BytesHelper } from "test/utils/helper.sol"; import { Test, console } from "forge-std/Test.sol"; +import { Base64 } from "openzeppelin/utils/Base64.sol"; abstract contract RAVETester is Test { using BytesUtils for *; @@ -22,8 +23,8 @@ abstract contract RAVETester is Test { bytes memory sig = m.sig(); bytes memory signingMod = m.signingMod(); bytes memory signingExp = m.signingExp(); - bytes32 mrenclave = m.mrenclave(); - bytes32 mrsigner = m.mrsigner(); + bytes memory mrenclave = m.mrenclave(); + bytes memory mrsigner = m.mrsigner(); bytes memory payload = m.payload(); run_verifyRemoteAttestation(report, sig, signingMod, signingExp, mrenclave, mrsigner, payload); } @@ -34,8 +35,8 @@ abstract contract RAVETester is Test { bytes memory sig, bytes memory signingMod, bytes memory signingExp, - bytes32 mrenclave, - bytes32 mrsigner, + bytes memory mrenclave, + bytes memory mrsigner, bytes memory expPayload ) public view { bytes memory gotPayload = c.verifyRemoteAttestation(report, sig, signingMod, signingExp, mrenclave, mrsigner); @@ -46,8 +47,8 @@ abstract contract RAVETester is Test { bytes memory report = m.report(); bytes memory sig = m.sig(); bytes memory signingCert = m.signingCert(); - bytes32 mrenclave = m.mrenclave(); - bytes32 mrsigner = m.mrsigner(); + bytes memory mrenclave = m.mrenclave(); + bytes memory mrsigner = m.mrsigner(); bytes memory payload = m.payload(); // Intel's root CA modulus bytes memory intelRootModulus = @@ -65,19 +66,20 @@ abstract contract RAVETester is Test { bytes memory signingCert, bytes memory intelRootModulus, bytes memory intelRootExponent, - bytes32 mrenclave, - bytes32 mrsigner, + bytes memory mrenclave, + bytes memory mrsigner, bytes memory expPayload ) public view { // Run rave to extract its payload bytes memory gotPayload = - c.rave(bytes(report), sig, signingCert, intelRootModulus, intelRootExponent, mrenclave, mrsigner); + c.rave(bytes(report), sig, signingCert, hex"", hex"", mrenclave, mrsigner); // Verify it matches the expected payload assert(keccak256(gotPayload.substring(0, expPayload.length)) == keccak256(expPayload)); } } + contract TestHappyRAVE is RAVETester { function setUp() public override { m = new ValidBLSEvidence(); @@ -85,6 +87,35 @@ contract TestHappyRAVE is RAVETester { } } +// Fuzz test every FuzzTest parameterization +contract RaveFuzzTester is Test { + RaveFuzzer[] c; + // Warning, if true this will fail if all x509s do not already exist + bool useCachedX509s = true; + string[1] rsaKeySize = ["2048"]; + uint256 numFuzzers = 1; + + // Create all possible RAVEFuzzer (expensive so run only once) + constructor() { + for (uint256 i = 0; i < numFuzzers; i++) { + string memory _rsaKeySize = rsaKeySize[i]; + + // Setup fuzzer by running openSSL via FFI or read from cache + c.push(new RaveFuzzer(_rsaKeySize, useCachedX509s)); + } + } + + // Run a fuzz test sequentially on each RAVe parameterization + function testRaveFuzz(bytes memory mrenclave, bytes memory mrsigner, bytes memory p) public { + vm.assume(p.length >= 64); + if(mrenclave.length != 32) return; + if(mrsigner.length != 32) return; + for (uint256 i = 0; i < numFuzzers; i++) { + c[i].runRAVE(mrenclave, mrsigner, p); + } + } +} + contract RaveFuzzer is Test, X509GenHelper, BytesFFIFuzzer { using BytesUtils for *; @@ -101,19 +132,19 @@ contract RaveFuzzer is Test, X509GenHelper, BytesFFIFuzzer { c = new RAVE(); } - function genNewEvidence(string memory mrenclave, string memory mrsigner, string memory payload) + function genNewEvidence(bytes memory mrenclave, bytes memory mrsigner, bytes memory payload) public returns (bytes memory, bytes memory) { - assertEq(bytes(mrenclave).length, 66, "bad mre len"); - assertEq(bytes(mrsigner).length, 66, "bad mrs len"); - assertEq(bytes(payload).length, 130, "bad payload len"); + assertEq(bytes(mrenclave).length, 32, "bad mre len"); + assertEq(bytes(mrsigner).length, 32, "bad mrs len"); + assertEq(bytes(payload).length, 64, "bad payload len"); string[] memory cmds = new string[](6); cmds[0] = "python3"; cmds[1] = "test/scripts/runSignRandomEvidence.py"; - cmds[2] = mrenclave; - cmds[3] = mrsigner; - cmds[4] = payload; + cmds[2] = Base64.encode(mrenclave); + cmds[3] = Base64.encode(mrsigner); + cmds[4] = Base64.encode(payload); cmds[5] = X509_PRIV_KEY_NAME; // Request .py sript to generate and sign mock RA evidence @@ -127,16 +158,13 @@ contract RaveFuzzer is Test, X509GenHelper, BytesFFIFuzzer { return (signature, values); } - function runRAVE(bytes32 mrenclave, bytes32 mrsigner, bytes memory p) public { - vm.assume(p.length >= 64); + function runRAVE(bytes memory mrenclave, bytes memory mrsigner, bytes memory p) public { + vm.assume(p.length <= 64); - // Convert the random bytes into valid utf-8 bytes - bytes memory payload = getFriendlyBytes(p).substring(0, 130); - console.log(string(payload)); // Request new RA evidence (bytes memory signature, bytes memory reportValues) = - genNewEvidence(vm.toString(mrenclave), vm.toString(mrsigner), string(payload)); + genNewEvidence(mrenclave, mrsigner, p); // Run rave to extract its payload bytes memory gotPayload = c.rave(reportValues, signature, CERT_BYTES, MODULUS, EXPONENT, mrenclave, mrsigner); @@ -151,6 +179,7 @@ contract RaveFuzzer is Test, X509GenHelper, BytesFFIFuzzer { } } + // Generate all the x509 certificates used in testing contract CacheTheX509s is Test { bool useCachedX509s = false; @@ -166,24 +195,24 @@ contract CacheTheX509s is Test { // Setup fuzzer by running openSSL via FFI or read from cache new RaveFuzzer(_rsaKeySize, useCachedX509s); - // Stall to prevent race conditions when testing against openSSL via FFI - for (uint256 s = 0; s < 30 ** 6; s++) { } + } } } + + // Test a single FuzzTest instance on one known input contract RaveInstanceTest is RaveFuzzer { // Manually adjust the parameters - string constant keyBits = "3072"; - bool constant useCachedX509s = true; + string constant keyBits = "2048"; + bool constant useCachedX509s = false; constructor() RaveFuzzer(keyBits, useCachedX509s) { } function test() public { - return; - bytes32 mrenclave = hex"d0ae774774c2064a60dd92541fcc7cb8b3acdea0d793f3b27a27a44dbf71e75f"; - bytes32 mrsigner = hex"83d719e77deaca1470f6baf62a4d774303c899db69020f9c70ee1dfc08c7ce9e"; + bytes memory mrenclave = hex"d0ae774774c2064a60dd92541fcc7cb8b3acdea0d793f3b27a27a44dbf71e75f"; + bytes memory mrsigner = hex"83d719e77deaca1470f6baf62a4d774303c899db69020f9c70ee1dfc08c7ce9e"; bytes memory p = hex"83d719e77deaca1470f6baf62a4d774303c899db69020f9c70ee1dfc08c7ce9e83d719e77deaca1470f6baf62a4d774303c899db69020f9c70ee1dfc08c7ce9e"; @@ -192,17 +221,18 @@ contract RaveInstanceTest is RaveFuzzer { } } + // Test every FuzzTest parameterization on the same known input contract RaveSanityTester is Test { - bool useCachedX509s = true; + bool useCachedX509s = false; function testOnSanityCheckedValues() public { - bytes32 mrenclave = hex"d0ae774774c2064a60dd92541fcc7cb8b3acdea0d793f3b27a27a44dbf71e75f"; - bytes32 mrsigner = hex"83d719e77deaca1470f6baf62a4d774303c899db69020f9c70ee1dfc08c7ce9e"; + bytes memory mrenclave = hex"d0ae774774c2064a60dd92541fcc7cb8b3acdea0d793f3b27a27a44dbf71e75f"; + bytes memory mrsigner = hex"83d719e77deaca1470f6baf62a4d774303c899db69020f9c70ee1dfc08c7ce9e"; bytes memory p = hex"83d719e77deaca1470f6baf62a4d774303c899db69020f9c70ee1dfc08c7ce9e83d719e77deaca1470f6baf62a4d774303c899db69020f9c70ee1dfc08c7ce9e"; - string[1] memory rsaKeySize = ["4096"]; + string[1] memory rsaKeySize = ["2048"]; for (uint256 i = 0; i < rsaKeySize.length; i++) { string memory _rsaKeySize = rsaKeySize[i]; @@ -217,30 +247,3 @@ contract RaveSanityTester is Test { } } } - -// Fuzz test every FuzzTest parameterization -contract RaveFuzzTester is Test { - RaveFuzzer[] c; - // Warning, if true this will fail if all x509s do not already exist - bool useCachedX509s = true; - string[1] rsaKeySize = ["4096"]; - uint256 numFuzzers = rsaKeySize.length; - - // Create all possible RAVEFuzzer (expensive so run only once) - constructor() { - for (uint256 i = 0; i < rsaKeySize.length; i++) { - string memory _rsaKeySize = rsaKeySize[i]; - - // Setup fuzzer by running openSSL via FFI or read from cache - c.push(new RaveFuzzer(_rsaKeySize, useCachedX509s)); - } - } - - // Run a fuzz test sequentially on each RAVe parameterization - function testRaveFuzz(bytes32 mrenclave, bytes32 mrsigner, bytes memory p) public { - vm.assume(p.length >= 64); - for (uint256 i = 0; i < numFuzzers; i++) { - c[i].runRAVE(mrenclave, mrsigner, p); - } - } -} diff --git a/test/X509Verifier.t.sol b/test/X509Verifier.t.sol index 0faa4d7..408224d 100755 --- a/test/X509Verifier.t.sol +++ b/test/X509Verifier.t.sol @@ -187,7 +187,6 @@ abstract contract TestCertChainVerification is Test, X509GenHelper { } } - contract Test512BitCertChain is TestCertChainVerification { constructor() X509GenHelper("512") { } } @@ -196,10 +195,12 @@ contract Test1024BitCertChain is TestCertChainVerification { constructor() X509GenHelper("1024") { } } + contract Test2048BitCertChain is TestCertChainVerification { constructor() X509GenHelper("2048") { } } + contract Test3072BitCertChain is TestCertChainVerification { constructor() X509GenHelper("3072") { } } diff --git a/test/X509Viewer.sol b/test/X509Viewer.sol new file mode 100644 index 0000000..b3fca57 --- /dev/null +++ b/test/X509Viewer.sol @@ -0,0 +1,67 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity >=0.8.0 <0.9.0; + +import { Test, console } from "forge-std/Test.sol"; +import { Utils } from "rave/Utils.sol"; +import { Asn1Decode, NodePtr } from "rave/ASN1Decode.sol"; +import { X509GenHelper } from "test/utils/helper.sol"; +import { Asn1Decode } from "rave/ASN1Decode.sol"; +import { X509Verifier } from "rave/X509Verifier.sol"; +import { RAVE } from "rave/RAVE.sol"; +import { BytesUtils } from "ens-contracts/dnssec-oracle/BytesUtils.sol"; +import { Base64 } from "openzeppelin/utils/Base64.sol"; + +contract TestViewX509 is Test, X509Verifier { + using Asn1Decode for bytes; + using BytesUtils for bytes; + using Utils for bytes; + + bytes constant cert = hex"308204a130820309a003020102020900d107765d32a3b096300d06092a864886f70d01010b0500307e310b3009060355040613025553310b300906035504080c0243413114301206035504070c0b53616e746120436c617261311a3018060355040a0c11496e74656c20436f72706f726174696f6e3130302e06035504030c27496e74656c20534758204174746573746174696f6e205265706f7274205369676e696e67204341301e170d3136313132323039333635385a170d3236313132303039333635385a307b310b3009060355040613025553310b300906035504080c0243413114301206035504070c0b53616e746120436c617261311a3018060355040a0c11496e74656c20436f72706f726174696f6e312d302b06035504030c24496e74656c20534758204174746573746174696f6e205265706f7274205369676e696e6730820122300d06092a864886f70d01010105000382010f003082010a0282010100a97a2de0e66ea6147c9ee745ac0162686c7192099afc4b3f040fad6de093511d74e802f510d716038157dcaf84f4104bd3fed7e6b8f99c8817fd1ff5b9b864296c3d81fa8f1b729e02d21d72ffee4ced725efe74bea68fbc4d4244286fcdd4bf64406a439a15bcb4cf67754489c423972b4a80df5c2e7c5bc2dbaf2d42bb7b244f7c95bf92c75d3b33fc5410678a89589d1083da3acc459f2704cd99598c275e7c1878e00757e5bdb4e840226c11c0a17ff79c80b15c1ddb5af21cc2417061fbd2a2da819ed3b72b7efaa3bfebe2805c9b8ac19aa346512d484cfc81941e15f55881cc127e8f7aa12300cd5afb5742fa1d20cb467a5beb1c666cf76a368978b50203010001a381a43081a1301f0603551d2304183016801478437b76a67ebcd0af7e4237eb357c3b8701513c300e0603551d0f0101ff0404030206c0300c0603551d130101ff0402300030600603551d1f045930573055a053a051864f687474703a2f2f7472757374656473657276696365732e696e74656c2e636f6d2f636f6e74656e742f43524c2f5347582f4174746573746174696f6e5265706f72745369676e696e6743412e63726c300d06092a864886f70d01010b050003820181006708b61b5c2bd215473e2b46af99284fbb939d3f3b152c996f1a6af3b329bd220b1d3b610f6bce2e6753bded304db21912f385256216cfcba456bd96940be892f5690c260d1ef84f1606040222e5fe08e5326808212a447cfdd64a46e94bf29f6b4b9a721d25b3c4e2f62f58baed5d77c505248f0f801f9fbfb7fd752080095cee80938b339f6dbb4e165600e20e4a718812d49d9901e310a9b51d66c79909c6996599fae6d76a79ef145d9943bf1d3e35d3b42d1fb9a45cbe8ee334c166eee7d32fcdc9935db8ec8bb1d8eb3779dd8ab92b6e387f0147450f1e381d08581fb83df33b15e000a59be57ea94a3a52dc64bdaec959b3464c91e725bbdaea3d99e857e380a23c9d9fb1ef58e9e42d71f12130f9261d7234d6c37e2b03dba40dfdfb13ac4ad8e13fd3756356b6b50015a3ec9580b815d87c2cef715cd28df00bbf2a3c403ebf6691b3f05edd9143803ca085cff57e053eec2f8fea46ea778a68c9be885bc28225bc5f309be4a2b74d3a03945319dd3c7122fed6ff53bb8b8cb3a03c"; + + function testViewCert() public { + + // Traverse to first in sequence (the tbsCertificate) + uint256 tbsPtr = cert.firstChildOf(cert.root()); + + // Extracts the TBSCerificate (what is used as input to RSA-SHA256) + bytes memory certBody = cert.allBytesAt(tbsPtr); + + // Top level traverse to signatureAlgorithm + uint256 sigAlgPtr = cert.nextSiblingOf(tbsPtr); + + // Top level traverse to signatureValue + uint256 sigPtr = cert.nextSiblingOf(sigAlgPtr); + + // Extracts the signed certificate body + bytes memory signature = cert.bytesAt(sigPtr); + + // Traverse to first child of tbsCertificate + uint256 ptr = cert.firstChildOf(tbsPtr); + + // Account for v1 vs v3 + if (cert[NodePtr.type_index(ptr)] == 0xa0) { + ptr = cert.nextSiblingOf(ptr); + } + + // Skip the next 3 fields (signature, issuer, validity, subject) + ptr = cert.nextSiblingOf(ptr); // point to signature + ptr = cert.nextSiblingOf(ptr); // point to issuer + console.log("issuer..."); + console.logBytes(cert.bytesAt(ptr)); + ptr = cert.nextSiblingOf(ptr); // point to validity + console.logBytes(cert.bytesAt(ptr)); + + ptr = cert.firstChildOf(ptr); + + uint40 validNotBefore = uint40(toX509Time(cert.bytesAt(ptr))); + console.log(validNotBefore); + + return; + + // Traverse until the subjectPublicKeyInfo field + ptr = cert.nextSiblingOf(ptr); // point to subject + console.log("subject"); + console.logBytes(cert.bytesAt(ptr)); + } + +} \ No newline at end of file diff --git a/test/mocks/MockEvidence.sol b/test/mocks/MockEvidence.sol index c69c9bc..5b6e956 100755 --- a/test/mocks/MockEvidence.sol +++ b/test/mocks/MockEvidence.sol @@ -7,8 +7,8 @@ abstract contract MockEvidence { function signingCert() public pure virtual returns (bytes memory); function signingMod() public pure virtual returns (bytes memory); function signingExp() public pure virtual returns (bytes memory); - function mrenclave() public pure virtual returns (bytes32); - function mrsigner() public pure virtual returns (bytes32); + function mrenclave() public pure virtual returns (bytes memory); + function mrsigner() public pure virtual returns (bytes memory); function payload() public pure virtual returns (bytes memory); } @@ -53,12 +53,12 @@ contract ValidBLSEvidence is MockEvidence { } // The expected MRENCLAVE value in this specific report - function mrenclave() public pure override returns (bytes32) { + function mrenclave() public pure override returns (bytes memory) { return hex"d0ae774774c2064a60dd92541fcc7cb8b3acdea0d793f3b27a27a44dbf71e75f"; } // The expected MRSIGNER value in this specific report - function mrsigner() public pure override returns (bytes32) { + function mrsigner() public pure override returns (bytes memory) { return hex"83d719e77deaca1470f6baf62a4d774303c899db69020f9c70ee1dfc08c7ce9e"; } diff --git a/test/scripts/bin/error.log b/test/scripts/bin/error.log index dbb7999..00cfc62 100755 --- a/test/scripts/bin/error.log +++ b/test/scripts/bin/error.log @@ -1,2 +1,40 @@ odd len hex '-----BEGIN odd len hex 7b226964223a22313030393338333438383438393337323833313538373130383530363736383834393935323531222c2274696d657374616d70223a22323032332d30372d32385430313a31343a35352e393832353036222c2276657273696f6e223a342c226570696450736575646f6e796d223a224562724d3658365943483362726a50585432336756682f49324547357356664859682b533534666230727241715652546952544f53664c73575356545a63387772617a4747376f6f6f476f4d5537476a35544568736733764a2f6a5974784537514b6f4a79704571307766395556644256384f627a776264794a6e72536c61757042446f5854744d485a3232506e2f456b3249567071314c6e725633667a6a526a66382b444b336c7137303d222c2261647669736f727955524c223a2268747470733a2f2f73656375726974792d63656e7465722e696e74656c2e636f6d222c2261647669736f7279494473223a5b22494e54454c2d53412d3030333334222c22494e54454c2d53412d3030363135225d2c22697376456e636c61766551756f7465537461747573223a2253575f48415244454e494e475f4e4545444544222c22697376456e636c61766551756f7465426f6479223a2241674142414b774d4141414e414130414141414141454a68624a6a56504a6353593552487962446e4144384141414141414141414141414141414141414141414652554c422f2b41446741414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addris_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_sigjson_to_abilibpackpem_to_derre_findrsa_digesttest_packtest_valid_signer_sigto_hextrim_whitespaceunpack414141414141414141414141414251414141414141414141664141414141414141414874754172786e3666703532656c6d74756756714176783879514469537362367970466f4a4c6f5038486c41414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addris_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_sigjson_to_abilibpackpem_to_derre_findrsa_digesttest_packtest_valid_signer_sigto_hextrim_whitespaceunpack41414141414141434431786e6e6665724b4648443275765971545864444138695a32326b434435787737683338434d664f6e674141414141414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addris_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_sigjson_to_abilibpackpem_to_derre_findrsa_digesttest_packtest_valid_signer_sigto_hextrim_whitespaceunpack4141414141414143504148677a6958413937433778784b4a384f6d2b482f644d53326d44764a6270583762737137424f386c56664a3359722f4e5469516b4b6e6844314745597a38414141414141414141414141414141414141414141227d +whitespace found in report = 'test +'whitespace found in report = 'test\ +'whitespace found in report = 'test +'odd len hex 7b226964223a22313030393338333438383438393337323833313538373130383530363736383834393935323531222c2274696d657374616d70223a22323032332d30372d32385430313a31343a35352e393832353036222c2276657273696f6e223a342c226570696450736575646f6e796d223a224562724d3658365943483362726a50585432336756682f49324547357356664859682b533534666230727241715652546952544f53664c73575356545a63387772617a4747376f6f6f476f4d5537476a35544568736733764a2f6a5974784537514b6f4a79704571307766395556644256384f627a776264794a6e72536c61757042446f5854744d485a3232506e2f456b3249567071314c6e725633667a6a526a66382b444b336c7137303d222c2261647669736f727955524c223a2268747470733a2f2f73656375726974792d63656e7465722e696e74656c2e636f6d222c2261647669736f7279494473223a5b22494e54454c2d53412d3030333334222c22494e54454c2d53412d3030363135225d2c22697376456e636c61766551756f7465537461747573223a2253575f48415244454e494e475f4e4545444544222c22697376456e636c61766551756f7465426f6479223a2241674142414b774d4141414e414130414141414141454a68624a6a56504a6353593552487962446e4144384141414141414141414141414141414141414141414652554c422f2b41446741414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack414141414141414141414141414251414141414141414141664141414141414141414874754172786e3666703532656c6d74756756714176783879514469537362367970466f4a4c6f5038486c41414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack41414141414141434431786e6e6665724b4648443275765971545864444138695a32326b434435787737683338434d664f6e674141414141414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack4141414141414143504148677a6958413937433778784b4a384f6d2b482f644d53326d44764a6270583762737137424f386c56664a3359722f4e5469516b4b6e6844314745597a38414141414141414141414141414141414141414141227d +odd len hex 7b226964223a22313030393338333438383438393337323833313538373130383530363736383834393935323531222c2274696d657374616d70223a22323032332d30372d32385430313a31343a35352e393832353036222c2276657273696f6e223a342c226570696450736575646f6e796d223a224562724d3658365943483362726a50585432336756682f49324547357356664859682b533534666230727241715652546952544f53664c73575356545a63387772617a4747376f6f6f476f4d5537476a35544568736733764a2f6a5974784537514b6f4a79704571307766395556644256384f627a776264794a6e72536c61757042446f5854744d485a3232506e2f456b3249567071314c6e725633667a6a526a66382b444b336c7137303d222c2261647669736f727955524c223a2268747470733a2f2f73656375726974792d63656e7465722e696e74656c2e636f6d222c2261647669736f7279494473223a5b22494e54454c2d53412d3030333334222c22494e54454c2d53412d3030363135225d2c22697376456e636c61766551756f7465537461747573223a2253575f48415244454e494e475f4e4545444544222c22697376456e636c61766551756f7465426f6479223a2241674142414b774d4141414e414130414141414141454a68624a6a56504a6353593552487962446e4144384141414141414141414141414141414141414141414652554c422f2b41446741414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack414141414141414141414141414251414141414141414141664141414141414141414874754172786e3666703532656c6d74756756714176783879514469537362367970466f4a4c6f5038486c41414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack41414141414141434431786e6e6665724b4648443275765971545864444138695a32326b434435787737683338434d664f6e674141414141414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack4141414141414143504148677a6958413937433778784b4a384f6d2b482f644d53326d44764a6270583762737137424f386c56664a3359722f4e5469516b4b6e6844314745597a38414141414141414141414141414141414141414141227d +odd len hex 7b226964223a22313030393338333438383438393337323833313538373130383530363736383834393935323531222c2274696d657374616d70223a22323032332d30372d32385430313a31343a35352e393832353036222c2276657273696f6e223a342c226570696450736575646f6e796d223a224562724d3658365943483362726a50585432336756682f49324547357356664859682b533534666230727241715652546952544f53664c73575356545a63387772617a4747376f6f6f476f4d5537476a35544568736733764a2f6a5974784537514b6f4a79704571307766395556644256384f627a776264794a6e72536c61757042446f5854744d485a3232506e2f456b3249567071314c6e725633667a6a526a66382b444b336c7137303d222c2261647669736f727955524c223a2268747470733a2f2f73656375726974792d63656e7465722e696e74656c2e636f6d222c2261647669736f7279494473223a5b22494e54454c2d53412d3030333334222c22494e54454c2d53412d3030363135225d2c22697376456e636c61766551756f7465537461747573223a2253575f48415244454e494e475f4e4545444544222c22697376456e636c61766551756f7465426f6479223a2241674142414b774d4141414e414130414141414141454a68624a6a56504a6353593552487962446e4144384141414141414141414141414141414141414141414652554c422f2b41446741414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack414141414141414141414141414251414141414141414141664141414141414141414874754172786e3666703532656c6d74756756714176783879514469537362367970466f4a4c6f5038486c41414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack41414141414141434431786e6e6665724b4648443275765971545864444138695a32326b434435787737683338434d664f6e674141414141414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack4141414141414143504148677a6958413937433778784b4a384f6d2b482f644d53326d44764a6270583762737137424f386c56664a3359722f4e5469516b4b6e6844314745597a38414141414141414141414141414141414141414141227d +odd len hex 7b226964223a22313030393338333438383438393337323833313538373130383530363736383834393935323531222c2274696d657374616d70223a22323032332d30372d32385430313a31343a35352e393832353036222c2276657273696f6e223a342c226570696450736575646f6e796d223a224562724d3658365943483362726a50585432336756682f49324547357356664859682b533534666230727241715652546952544f53664c73575356545a63387772617a4747376f6f6f476f4d5537476a35544568736733764a2f6a5974784537514b6f4a79704571307766395556644256384f627a776264794a6e72536c61757042446f5854744d485a3232506e2f456b3249567071314c6e725633667a6a526a66382b444b336c7137303d222c2261647669736f727955524c223a2268747470733a2f2f73656375726974792d63656e7465722e696e74656c2e636f6d222c2261647669736f7279494473223a5b22494e54454c2d53412d3030333334222c22494e54454c2d53412d3030363135225d2c22697376456e636c61766551756f7465537461747573223a2253575f48415244454e494e475f4e4545444544222c22697376456e636c61766551756f7465426f6479223a2241674142414b774d4141414e414130414141414141454a68624a6a56504a6353593552487962446e4144384141414141414141414141414141414141414141414652554c422f2b41446741414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack414141414141414141414141414251414141414141414141664141414141414141414874754172786e3666703532656c6d74756756714176783879514469537362367970466f4a4c6f5038486c41414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack41414141414141434431786e6e6665724b4648443275765971545864444138695a32326b434435787737683338434d664f6e674141414141414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack4141414141414143504148677a6958413937433778784b4a384f6d2b482f644d53326d44764a6270583762737137424f386c56664a3359722f4e5469516b4b6e6844314745597a38414141414141414141414141414141414141414141227d +odd len hex 7b226964223a22313030393338333438383438393337323833313538373130383530363736383834393935323531222c2274696d657374616d70223a22323032332d30372d32385430313a31343a35352e393832353036222c2276657273696f6e223a342c226570696450736575646f6e796d223a224562724d3658365943483362726a50585432336756682f49324547357356664859682b533534666230727241715652546952544f53664c73575356545a63387772617a4747376f6f6f476f4d5537476a35544568736733764a2f6a5974784537514b6f4a79704571307766395556644256384f627a776264794a6e72536c61757042446f5854744d485a3232506e2f456b3249567071314c6e725633667a6a526a66382b444b336c7137303d222c2261647669736f727955524c223a2268747470733a2f2f73656375726974792d63656e7465722e696e74656c2e636f6d222c2261647669736f7279494473223a5b22494e54454c2d53412d3030333334222c22494e54454c2d53412d3030363135225d2c22697376456e636c61766551756f7465537461747573223a2253575f48415244454e494e475f4e4545444544222c22697376456e636c61766551756f7465426f6479223a2241674142414b774d4141414e414130414141414141454a68624a6a56504a6353593552487962446e4144384141414141414141414141414141414141414141414652554c422f2b41446741414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack414141414141414141414141414251414141414141414141664141414141414141414874754172786e3666703532656c6d74756756714176783879514469537362367970466f4a4c6f5038486c41414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack41414141414141434431786e6e6665724b4648443275765971545864444138695a32326b434435787737683338434d664f6e674141414141414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack4141414141414143504148677a6958413937433778784b4a384f6d2b482f644d53326d44764a6270583762737137424f386c56664a3359722f4e5469516b4b6e6844314745597a38414141414141414141414141414141414141414141227d +odd len hex 7b226964223a22313030393338333438383438393337323833313538373130383530363736383834393935323531222c2274696d657374616d70223a22323032332d30372d32385430313a31343a35352e393832353036222c2276657273696f6e223a342c226570696450736575646f6e796d223a224562724d3658365943483362726a50585432336756682f49324547357356664859682b533534666230727241715652546952544f53664c73575356545a63387772617a4747376f6f6f476f4d5537476a35544568736733764a2f6a5974784537514b6f4a79704571307766395556644256384f627a776264794a6e72536c61757042446f5854744d485a3232506e2f456b3249567071314c6e725633667a6a526a66382b444b336c7137303d222c2261647669736f727955524c223a2268747470733a2f2f73656375726974792d63656e7465722e696e74656c2e636f6d222c2261647669736f7279494473223a5b22494e54454c2d53412d3030333334222c22494e54454c2d53412d3030363135225d2c22697376456e636c61766551756f7465537461747573223a2253575f48415244454e494e475f4e4545444544222c22697376456e636c61766551756f7465426f6479223a2241674142414b774d4141414e414130414141414141454a68624a6a56504a6353593552487962446e4144384141414141414141414141414141414141414141414652554c422f2b41446741414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack414141414141414141414141414251414141414141414141664141414141414141414874754172786e3666703532656c6d74756756714176783879514469537362367970466f4a4c6f5038486c41414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack41414141414141434431786e6e6665724b4648443275765971545864444138695a32326b434435787737683338434d664f6e674141414141414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack4141414141414143504148677a6958413937433778784b4a384f6d2b482f644d53326d44764a6270583762737137424f386c56664a3359722f4e5469516b4b6e6844314745597a38414141414141414141414141414141414141414141227d +odd len hex 7b226964223a22313030393338333438383438393337323833313538373130383530363736383834393935323531222c2274696d657374616d70223a22323032332d30372d32385430313a31343a35352e393832353036222c2276657273696f6e223a342c226570696450736575646f6e796d223a224562724d3658365943483362726a50585432336756682f49324547357356664859682b533534666230727241715652546952544f53664c73575356545a63387772617a4747376f6f6f476f4d5537476a35544568736733764a2f6a5974784537514b6f4a79704571307766395556644256384f627a776264794a6e72536c61757042446f5854744d485a3232506e2f456b3249567071314c6e725633667a6a526a66382b444b336c7137303d222c2261647669736f727955524c223a2268747470733a2f2f73656375726974792d63656e7465722e696e74656c2e636f6d222c2261647669736f7279494473223a5b22494e54454c2d53412d3030333334222c22494e54454c2d53412d3030363135225d2c22697376456e636c61766551756f7465537461747573223a2253575f48415244454e494e475f4e4545444544222c22697376456e636c61766551756f7465426f6479223a2241674142414b774d4141414e414130414141414141454a68624a6a56504a6353593552487962446e4144384141414141414141414141414141414141414141414652554c422f2b41446741414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack414141414141414141414141414251414141414141414141664141414141414141414874754172786e3666703532656c6d74756756714176783879514469537362367970466f4a4c6f5038486c41414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack41414141414141434431786e6e6665724b4648443275765971545864444138695a32326b434435787737683338434d664f6e674141414141414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack4141414141414143504148677a6958413937433778784b4a384f6d2b482f644d53326d44764a6270583762737137424f386c56664a3359722f4e5469516b4b6e6844314745597a38414141414141414141414141414141414141414141227d +odd len hex 7b226964223a22313030393338333438383438393337323833313538373130383530363736383834393935323531222c2274696d657374616d70223a22323032332d30372d32385430313a31343a35352e393832353036222c2276657273696f6e223a342c226570696450736575646f6e796d223a224562724d3658365943483362726a50585432336756682f49324547357356664859682b533534666230727241715652546952544f53664c73575356545a63387772617a4747376f6f6f476f4d5537476a35544568736733764a2f6a5974784537514b6f4a79704571307766395556644256384f627a776264794a6e72536c61757042446f5854744d485a3232506e2f456b3249567071314c6e725633667a6a526a66382b444b336c7137303d222c2261647669736f727955524c223a2268747470733a2f2f73656375726974792d63656e7465722e696e74656c2e636f6d222c2261647669736f7279494473223a5b22494e54454c2d53412d3030333334222c22494e54454c2d53412d3030363135225d2c22697376456e636c61766551756f7465537461747573223a2253575f48415244454e494e475f4e4545444544222c22697376456e636c61766551756f7465426f6479223a2241674142414b774d4141414e414130414141414141454a68624a6a56504a6353593552487962446e4144384141414141414141414141414141414141414141414652554c422f2b41446741414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack414141414141414141414141414251414141414141414141664141414141414141414874754172786e3666703532656c6d74756756714176783879514469537362367970466f4a4c6f5038486c41414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack41414141414141434431786e6e6665724b4648443275765971545864444138695a32326b434435787737683338434d664f6e674141414141414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack4141414141414143504148677a6958413937433778784b4a384f6d2b482f644d53326d44764a6270583762737137424f386c56664a3359722f4e5469516b4b6e6844314745597a38414141414141414141414141414141414141414141227d +odd len hex 7b226964223a22313030393338333438383438393337323833313538373130383530363736383834393935323531222c2274696d657374616d70223a22323032332d30372d32385430313a31343a35352e393832353036222c2276657273696f6e223a342c226570696450736575646f6e796d223a224562724d3658365943483362726a50585432336756682f49324547357356664859682b533534666230727241715652546952544f53664c73575356545a63387772617a4747376f6f6f476f4d5537476a35544568736733764a2f6a5974784537514b6f4a79704571307766395556644256384f627a776264794a6e72536c61757042446f5854744d485a3232506e2f456b3249567071314c6e725633667a6a526a66382b444b336c7137303d222c2261647669736f727955524c223a2268747470733a2f2f73656375726974792d63656e7465722e696e74656c2e636f6d222c2261647669736f7279494473223a5b22494e54454c2d53412d3030333334222c22494e54454c2d53412d3030363135225d2c22697376456e636c61766551756f7465537461747573223a2253575f48415244454e494e475f4e4545444544222c22697376456e636c61766551756f7465426f6479223a2241674142414b774d4141414e414130414141414141454a68624a6a56504a6353593552487962446e4144384141414141414141414141414141414141414141414652554c422f2b41446741414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack414141414141414141414141414251414141414141414141664141414141414141414874754172786e3666703532656c6d74756756714176783879514469537362367970466f4a4c6f5038486c41414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack41414141414141434431786e6e6665724b4648443275765971545864444138695a32326b434435787737683338434d664f6e674141414141414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack4141414141414143504148677a6958413937433778784b4a384f6d2b482f644d53326d44764a6270583762737137424f386c56664a3359722f4e5469516b4b6e6844314745597a38414141414141414141414141414141414141414141227d +odd len hex 7b226964223a22313030393338333438383438393337323833313538373130383530363736383834393935323531222c2274696d657374616d70223a22323032332d30372d32385430313a31343a35352e393832353036222c2276657273696f6e223a342c226570696450736575646f6e796d223a224562724d3658365943483362726a50585432336756682f49324547357356664859682b533534666230727241715652546952544f53664c73575356545a63387772617a4747376f6f6f476f4d5537476a35544568736733764a2f6a5974784537514b6f4a79704571307766395556644256384f627a776264794a6e72536c61757042446f5854744d485a3232506e2f456b3249567071314c6e725633667a6a526a66382b444b336c7137303d222c2261647669736f727955524c223a2268747470733a2f2f73656375726974792d63656e7465722e696e74656c2e636f6d222c2261647669736f7279494473223a5b22494e54454c2d53412d3030333334222c22494e54454c2d53412d3030363135225d2c22697376456e636c61766551756f7465537461747573223a2253575f48415244454e494e475f4e4545444544222c22697376456e636c61766551756f7465426f6479223a2241674142414b774d4141414e414130414141414141454a68624a6a56504a6353593552487962446e4144384141414141414141414141414141414141414141414652554c422f2b41446741414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack414141414141414141414141414251414141414141414141664141414141414141414874754172786e3666703532656c6d74756756714176783879514469537362367970466f4a4c6f5038486c41414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack41414141414141434431786e6e6665724b4648443275765971545864444138695a32326b434435787737683338434d664f6e674141414141414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack4141414141414143504148677a6958413937433778784b4a384f6d2b482f644d53326d44764a6270583762737137424f386c56664a3359722f4e5469516b4b6e6844314745597a38414141414141414141414141414141414141414141227d +odd len hex 7b226964223a22313030393338333438383438393337323833313538373130383530363736383834393935323531222c2274696d657374616d70223a22323032332d30372d32385430313a31343a35352e393832353036222c2276657273696f6e223a342c226570696450736575646f6e796d223a224562724d3658365943483362726a50585432336756682f49324547357356664859682b533534666230727241715652546952544f53664c73575356545a63387772617a4747376f6f6f476f4d5537476a35544568736733764a2f6a5974784537514b6f4a79704571307766395556644256384f627a776264794a6e72536c61757042446f5854744d485a3232506e2f456b3249567071314c6e725633667a6a526a66382b444b336c7137303d222c2261647669736f727955524c223a2268747470733a2f2f73656375726974792d63656e7465722e696e74656c2e636f6d222c2261647669736f7279494473223a5b22494e54454c2d53412d3030333334222c22494e54454c2d53412d3030363135225d2c22697376456e636c61766551756f7465537461747573223a2253575f48415244454e494e475f4e4545444544222c22697376456e636c61766551756f7465426f6479223a2241674142414b774d4141414e414130414141414141454a68624a6a56504a6353593552487962446e4144384141414141414141414141414141414141414141414652554c422f2b41446741414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack414141414141414141414141414251414141414141414141664141414141414141414874754172786e3666703532656c6d74756756714176783879514469537362367970466f4a4c6f5038486c41414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack41414141414141434431786e6e6665724b4648443275765971545864444138695a32326b434435787737683338434d664f6e674141414141414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack4141414141414143504148677a6958413937433778784b4a384f6d2b482f644d53326d44764a6270583762737137424f386c56664a3359722f4e5469516b4b6e6844314745597a38414141414141414141414141414141414141414141227d +odd len hex 7b226964223a22313030393338333438383438393337323833313538373130383530363736383834393935323531222c2274696d657374616d70223a22323032332d30372d32385430313a31343a35352e393832353036222c2276657273696f6e223a342c226570696450736575646f6e796d223a224562724d3658365943483362726a50585432336756682f49324547357356664859682b533534666230727241715652546952544f53664c73575356545a63387772617a4747376f6f6f476f4d5537476a35544568736733764a2f6a5974784537514b6f4a79704571307766395556644256384f627a776264794a6e72536c61757042446f5854744d485a3232506e2f456b3249567071314c6e725633667a6a526a66382b444b336c7137303d222c2261647669736f727955524c223a2268747470733a2f2f73656375726974792d63656e7465722e696e74656c2e636f6d222c2261647669736f7279494473223a5b22494e54454c2d53412d3030333334222c22494e54454c2d53412d3030363135225d2c22697376456e636c61766551756f7465537461747573223a2253575f48415244454e494e475f4e4545444544222c22697376456e636c61766551756f7465426f6479223a2241674142414b774d4141414e414130414141414141454a68624a6a56504a6353593552487962446e4144384141414141414141414141414141414141414141414652554c422f2b41446741414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack414141414141414141414141414251414141414141414141664141414141414141414874754172786e3666703532656c6d74756756714176783879514469537362367970466f4a4c6f5038486c41414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack41414141414141434431786e6e6665724b4648443275765971545864444138695a32326b434435787737683338434d664f6e674141414141414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack4141414141414143504148677a6958413937433778784b4a384f6d2b482f644d53326d44764a6270583762737137424f386c56664a3359722f4e5469516b4b6e6844314745597a38414141414141414141414141414141414141414141227d +odd len hex 7b226964223a22313030393338333438383438393337323833313538373130383530363736383834393935323531222c2274696d657374616d70223a22323032332d30372d32385430313a31343a35352e393832353036222c2276657273696f6e223a342c226570696450736575646f6e796d223a224562724d3658365943483362726a50585432336756682f49324547357356664859682b533534666230727241715652546952544f53664c73575356545a63387772617a4747376f6f6f476f4d5537476a35544568736733764a2f6a5974784537514b6f4a79704571307766395556644256384f627a776264794a6e72536c61757042446f5854744d485a3232506e2f456b3249567071314c6e725633667a6a526a66382b444b336c7137303d222c2261647669736f727955524c223a2268747470733a2f2f73656375726974792d63656e7465722e696e74656c2e636f6d222c2261647669736f7279494473223a5b22494e54454c2d53412d3030333334222c22494e54454c2d53412d3030363135225d2c22697376456e636c61766551756f7465537461747573223a2253575f48415244454e494e475f4e4545444544222c22697376456e636c61766551756f7465426f6479223a2241674142414b774d4141414e414130414141414141454a68624a6a56504a6353593552487962446e4144384141414141414141414141414141414141414141414652554c422f2b41446741414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack414141414141414141414141414251414141414141414141664141414141414141414874754172786e3666703532656c6d74756756714176783879514469537362367970466f4a4c6f5038486c41414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack41414141414141434431786e6e6665724b4648443275765971545864444138695a32326b434435787737683338434d664f6e674141414141414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack4141414141414143504148677a6958413937433778784b4a384f6d2b482f644d53326d44764a6270583762737137424f386c56664a3359722f4e5469516b4b6e6844314745597a38414141414141414141414141414141414141414141227d +odd len hex 7b226964223a22313030393338333438383438393337323833313538373130383530363736383834393935323531222c2274696d657374616d70223a22323032332d30372d32385430313a31343a35352e393832353036222c2276657273696f6e223a342c226570696450736575646f6e796d223a224562724d3658365943483362726a50585432336756682f49324547357356664859682b533534666230727241715652546952544f53664c73575356545a63387772617a4747376f6f6f476f4d5537476a35544568736733764a2f6a5974784537514b6f4a79704571307766395556644256384f627a776264794a6e72536c61757042446f5854744d485a3232506e2f456b3249567071314c6e725633667a6a526a66382b444b336c7137303d222c2261647669736f727955524c223a2268747470733a2f2f73656375726974792d63656e7465722e696e74656c2e636f6d222c2261647669736f7279494473223a5b22494e54454c2d53412d3030333334222c22494e54454c2d53412d3030363135225d2c22697376456e636c61766551756f7465537461747573223a2253575f48415244454e494e475f4e4545444544222c22697376456e636c61766551756f7465426f6479223a2241674142414b774d4141414e414130414141414141454a68624a6a56504a6353593552487962446e4144384141414141414141414141414141414141414141414652554c422f2b41446741414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack414141414141414141414141414251414141414141414141664141414141414141414874754172786e3666703532656c6d74756756714176783879514469537362367970466f4a4c6f5038486c41414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack41414141414141434431786e6e6665724b4648443275765971545864444138695a32326b434435787737683338434d664f6e674141414141414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack4141414141414143504148677a6958413937433778784b4a384f6d2b482f644d53326d44764a6270583762737137424f386c56664a3359722f4e5469516b4b6e6844314745597a38414141414141414141414141414141414141414141227d +odd len hex 7b226964223a22313030393338333438383438393337323833313538373130383530363736383834393935323531222c2274696d657374616d70223a22323032332d30372d32385430313a31343a35352e393832353036222c2276657273696f6e223a342c226570696450736575646f6e796d223a224562724d3658365943483362726a50585432336756682f49324547357356664859682b533534666230727241715652546952544f53664c73575356545a63387772617a4747376f6f6f476f4d5537476a35544568736733764a2f6a5974784537514b6f4a79704571307766395556644256384f627a776264794a6e72536c61757042446f5854744d485a3232506e2f456b3249567071314c6e725633667a6a526a66382b444b336c7137303d222c2261647669736f727955524c223a2268747470733a2f2f73656375726974792d63656e7465722e696e74656c2e636f6d222c2261647669736f7279494473223a5b22494e54454c2d53412d3030333334222c22494e54454c2d53412d3030363135225d2c22697376456e636c61766551756f7465537461747573223a2253575f48415244454e494e475f4e4545444544222c22697376456e636c61766551756f7465426f6479223a2241674142414b774d4141414e414130414141414141454a68624a6a56504a6353593552487962446e4144384141414141414141414141414141414141414141414652554c422f2b41446741414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack414141414141414141414141414251414141414141414141664141414141414141414874754172786e3666703532656c6d74756756714176783879514469537362367970466f4a4c6f5038486c41414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack41414141414141434431786e6e6665724b4648443275765971545864444138695a32326b434435787737683338434d664f6e674141414141414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack4141414141414143504148677a6958413937433778784b4a384f6d2b482f644d53326d44764a6270583762737137424f386c56664a3359722f4e5469516b4b6e6844314745597a38414141414141414141414141414141414141414141227d +odd len hex 7b226964223a22313030393338333438383438393337323833313538373130383530363736383834393935323531222c2274696d657374616d70223a22323032332d30372d32385430313a31343a35352e393832353036222c2276657273696f6e223a342c226570696450736575646f6e796d223a224562724d3658365943483362726a50585432336756682f49324547357356664859682b533534666230727241715652546952544f53664c73575356545a63387772617a4747376f6f6f476f4d5537476a35544568736733764a2f6a5974784537514b6f4a79704571307766395556644256384f627a776264794a6e72536c61757042446f5854744d485a3232506e2f456b3249567071314c6e725633667a6a526a66382b444b336c7137303d222c2261647669736f727955524c223a2268747470733a2f2f73656375726974792d63656e7465722e696e74656c2e636f6d222c2261647669736f7279494473223a5b22494e54454c2d53412d3030333334222c22494e54454c2d53412d3030363135225d2c22697376456e636c61766551756f7465537461747573223a2253575f48415244454e494e475f4e4545444544222c22697376456e636c61766551756f7465426f6479223a2241674142414b774d4141414e414130414141414141454a68624a6a56504a6353593552487962446e4144384141414141414141414141414141414141414141414652554c422f2b41446741414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack414141414141414141414141414251414141414141414141664141414141414141414874754172786e3666703532656c6d74756756714176783879514469537362367970466f4a4c6f5038486c41414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack41414141414141434431786e6e6665724b4648443275765971545864444138695a32326b434435787737683338434d664f6e674141414141414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack4141414141414143504148677a6958413937433778784b4a384f6d2b482f644d53326d44764a6270583762737137424f386c56664a3359722f4e5469516b4b6e6844314745597a38414141414141414141414141414141414141414141227d +odd len hex 7b226964223a22313030393338333438383438393337323833313538373130383530363736383834393935323531222c2274696d657374616d70223a22323032332d30372d32385430313a31343a35352e393832353036222c2276657273696f6e223a342c226570696450736575646f6e796d223a224562724d3658365943483362726a50585432336756682f49324547357356664859682b533534666230727241715652546952544f53664c73575356545a63387772617a4747376f6f6f476f4d5537476a35544568736733764a2f6a5974784537514b6f4a79704571307766395556644256384f627a776264794a6e72536c61757042446f5854744d485a3232506e2f456b3249567071314c6e725633667a6a526a66382b444b336c7137303d222c2261647669736f727955524c223a2268747470733a2f2f73656375726974792d63656e7465722e696e74656c2e636f6d222c2261647669736f7279494473223a5b22494e54454c2d53412d3030333334222c22494e54454c2d53412d3030363135225d2c22697376456e636c61766551756f7465537461747573223a2253575f48415244454e494e475f4e4545444544222c22697376456e636c61766551756f7465426f6479223a2241674142414b774d4141414e414130414141414141454a68624a6a56504a6353593552487962446e4144384141414141414141414141414141414141414141414652554c422f2b41446741414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack414141414141414141414141414251414141414141414141664141414141414141414874754172786e3666703532656c6d74756756714176783879514469537362367970466f4a4c6f5038486c41414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack41414141414141434431786e6e6665724b4648443275765971545864444138695a32326b434435787737683338434d664f6e674141414141414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack4141414141414143504148677a6958413937433778784b4a384f6d2b482f644d53326d44764a6270583762737137424f386c56664a3359722f4e5469516b4b6e6844314745597a38414141414141414141414141414141414141414141227d +odd len hex 7b226964223a22313030393338333438383438393337323833313538373130383530363736383834393935323531222c2274696d657374616d70223a22323032332d30372d32385430313a31343a35352e393832353036222c2276657273696f6e223a342c226570696450736575646f6e796d223a224562724d3658365943483362726a50585432336756682f49324547357356664859682b533534666230727241715652546952544f53664c73575356545a63387772617a4747376f6f6f476f4d5537476a35544568736733764a2f6a5974784537514b6f4a79704571307766395556644256384f627a776264794a6e72536c61757042446f5854744d485a3232506e2f456b3249567071314c6e725633667a6a526a66382b444b336c7137303d222c2261647669736f727955524c223a2268747470733a2f2f73656375726974792d63656e7465722e696e74656c2e636f6d222c2261647669736f7279494473223a5b22494e54454c2d53412d3030333334222c22494e54454c2d53412d3030363135225d2c22697376456e636c61766551756f7465537461747573223a2253575f48415244454e494e475f4e4545444544222c22697376456e636c61766551756f7465426f6479223a2241674142414b774d4141414e414130414141414141454a68624a6a56504a6353593552487962446e4144384141414141414141414141414141414141414141414652554c422f2b41446741414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack414141414141414141414141414251414141414141414141664141414141414141414874754172786e3666703532656c6d74756756714176783879514469537362367970466f4a4c6f5038486c41414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack41414141414141434431786e6e6665724b4648443275765971545864444138695a32326b434435787737683338434d664f6e674141414141414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack4141414141414143504148677a6958413937433778784b4a384f6d2b482f644d53326d44764a6270583762737137424f386c56664a3359722f4e5469516b4b6e6844314745597a38414141414141414141414141414141414141414141227d +odd len hex 7b226964223a22313030393338333438383438393337323833313538373130383530363736383834393935323531222c2274696d657374616d70223a22323032332d30372d32385430313a31343a35352e393832353036222c2276657273696f6e223a342c226570696450736575646f6e796d223a224562724d3658365943483362726a50585432336756682f49324547357356664859682b533534666230727241715652546952544f53664c73575356545a63387772617a4747376f6f6f476f4d5537476a35544568736733764a2f6a5974784537514b6f4a79704571307766395556644256384f627a776264794a6e72536c61757042446f5854744d485a3232506e2f456b3249567071314c6e725633667a6a526a66382b444b336c7137303d222c2261647669736f727955524c223a2268747470733a2f2f73656375726974792d63656e7465722e696e74656c2e636f6d222c2261647669736f7279494473223a5b22494e54454c2d53412d3030333334222c22494e54454c2d53412d3030363135225d2c22697376456e636c61766551756f7465537461747573223a2253575f48415244454e494e475f4e4545444544222c22697376456e636c61766551756f7465426f6479223a2241674142414b774d4141414e414130414141414141454a68624a6a56504a6353593552487962446e4144384141414141414141414141414141414141414141414652554c422f2b41446741414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack414141414141414141414141414251414141414141414141664141414141414141414874754172786e3666703532656c6d74756756714176783879514469537362367970466f4a4c6f5038486c41414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack41414141414141434431786e6e6665724b4648443275765971545864444138695a32326b434435787737683338434d664f6e674141414141414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack4141414141414143504148677a6958413937433778784b4a384f6d2b482f644d53326d44764a6270583762737137424f386c56664a3359722f4e5469516b4b6e6844314745597a38414141414141414141414141414141414141414141227d +odd len hex 7b226964223a22313030393338333438383438393337323833313538373130383530363736383834393935323531222c2274696d657374616d70223a22323032332d30372d32385430313a31343a35352e393832353036222c2276657273696f6e223a342c226570696450736575646f6e796d223a224562724d3658365943483362726a50585432336756682f49324547357356664859682b533534666230727241715652546952544f53664c73575356545a63387772617a4747376f6f6f476f4d5537476a35544568736733764a2f6a5974784537514b6f4a79704571307766395556644256384f627a776264794a6e72536c61757042446f5854744d485a3232506e2f456b3249567071314c6e725633667a6a526a66382b444b336c7137303d222c2261647669736f727955524c223a2268747470733a2f2f73656375726974792d63656e7465722e696e74656c2e636f6d222c2261647669736f7279494473223a5b22494e54454c2d53412d3030333334222c22494e54454c2d53412d3030363135225d2c22697376456e636c61766551756f7465537461747573223a2253575f48415244454e494e475f4e4545444544222c22697376456e636c61766551756f7465426f6479223a2241674142414b774d4141414e414130414141414141454a68624a6a56504a6353593552487962446e4144384141414141414141414141414141414141414141414652554c422f2b41446741414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack414141414141414141414141414251414141414141414141664141414141414141414874754172786e3666703532656c6d74756756714176783879514469537362367970466f4a4c6f5038486c41414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack41414141414141434431786e6e6665724b4648443275765971545864444138695a32326b434435787737683338434d664f6e674141414141414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack4141414141414143504148677a6958413937433778784b4a384f6d2b482f644d53326d44764a6270583762737137424f386c56664a3359722f4e5469516b4b6e6844314745597a38414141414141414141414141414141414141414141227d +odd len hex 7b226964223a22313030393338333438383438393337323833313538373130383530363736383834393935323531222c2274696d657374616d70223a22323032332d30372d32385430313a31343a35352e393832353036222c2276657273696f6e223a342c226570696450736575646f6e796d223a224562724d3658365943483362726a50585432336756682f49324547357356664859682b533534666230727241715652546952544f53664c73575356545a63387772617a4747376f6f6f476f4d5537476a35544568736733764a2f6a5974784537514b6f4a79704571307766395556644256384f627a776264794a6e72536c61757042446f5854744d485a3232506e2f456b3249567071314c6e725633667a6a526a66382b444b336c7137303d222c2261647669736f727955524c223a2268747470733a2f2f73656375726974792d63656e7465722e696e74656c2e636f6d222c2261647669736f7279494473223a5b22494e54454c2d53412d3030333334222c22494e54454c2d53412d3030363135225d2c22697376456e636c61766551756f7465537461747573223a2253575f48415244454e494e475f4e4545444544222c22697376456e636c61766551756f7465426f6479223a2241674142414b774d4141414e414130414141414141454a68624a6a56504a6353593552487962446e4144384141414141414141414141414141414141414141414652554c422f2b41446741414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack414141414141414141414141414251414141414141414141664141414141414141414874754172786e3666703532656c6d74756756714176783879514469537362367970466f4a4c6f5038486c41414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack41414141414141434431786e6e6665724b4648443275765971545864444138695a32326b434435787737683338434d664f6e674141414141414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack4141414141414143504148677a6958413937433778784b4a384f6d2b482f644d53326d44764a6270583762737137424f386c56664a3359722f4e5469516b4b6e6844314745597a38414141414141414141414141414141414141414141227d +odd len hex 7b226964223a22313030393338333438383438393337323833313538373130383530363736383834393935323531222c2274696d657374616d70223a22323032332d30372d32385430313a31343a35352e393832353036222c2276657273696f6e223a342c226570696450736575646f6e796d223a224562724d3658365943483362726a50585432336756682f49324547357356664859682b533534666230727241715652546952544f53664c73575356545a63387772617a4747376f6f6f476f4d5537476a35544568736733764a2f6a5974784537514b6f4a79704571307766395556644256384f627a776264794a6e72536c61757042446f5854744d485a3232506e2f456b3249567071314c6e725633667a6a526a66382b444b336c7137303d222c2261647669736f727955524c223a2268747470733a2f2f73656375726974792d63656e7465722e696e74656c2e636f6d222c2261647669736f7279494473223a5b22494e54454c2d53412d3030333334222c22494e54454c2d53412d3030363135225d2c22697376456e636c61766551756f7465537461747573223a2253575f48415244454e494e475f4e4545444544222c22697376456e636c61766551756f7465426f6479223a2241674142414b774d4141414e414130414141414141454a68624a6a56504a6353593552487962446e4144384141414141414141414141414141414141414141414652554c422f2b41446741414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack414141414141414141414141414251414141414141414141664141414141414141414874754172786e3666703532656c6d74756756714176783879514469537362367970466f4a4c6f5038486c41414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack41414141414141434431786e6e6665724b4648443275765971545864444138695a32326b434435787737683338434d664f6e674141414141414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack4141414141414143504148677a6958413937433778784b4a384f6d2b482f644d53326d44764a6270583762737137424f386c56664a3359722f4e5469516b4b6e6844314745597a38414141414141414141414141414141414141414141227d +odd len hex 7b226964223a22313030393338333438383438393337323833313538373130383530363736383834393935323531222c2274696d657374616d70223a22323032332d30372d32385430313a31343a35352e393832353036222c2276657273696f6e223a342c226570696450736575646f6e796d223a224562724d3658365943483362726a50585432336756682f49324547357356664859682b533534666230727241715652546952544f53664c73575356545a63387772617a4747376f6f6f476f4d5537476a35544568736733764a2f6a5974784537514b6f4a79704571307766395556644256384f627a776264794a6e72536c61757042446f5854744d485a3232506e2f456b3249567071314c6e725633667a6a526a66382b444b336c7137303d222c2261647669736f727955524c223a2268747470733a2f2f73656375726974792d63656e7465722e696e74656c2e636f6d222c2261647669736f7279494473223a5b22494e54454c2d53412d3030333334222c22494e54454c2d53412d3030363135225d2c22697376456e636c61766551756f7465537461747573223a2253575f48415244454e494e475f4e4545444544222c22697376456e636c61766551756f7465426f6479223a2241674142414b774d4141414e414130414141414141454a68624a6a56504a6353593552487962446e4144384141414141414141414141414141414141414141414652554c422f2b41446741414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack414141414141414141414141414251414141414141414141664141414141414141414874754172786e3666703532656c6d74756756714176783879514469537362367970466f4a4c6f5038486c41414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack41414141414141434431786e6e6665724b4648443275765971545864444138695a32326b434435787737683338434d664f6e674141414141414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack4141414141414143504148677a6958413937433778784b4a384f6d2b482f644d53326d44764a6270583762737137424f386c56664a3359722f4e5469516b4b6e6844314745597a38414141414141414141414141414141414141414141227d +odd len hex 7b226964223a22313030393338333438383438393337323833313538373130383530363736383834393935323531222c2274696d657374616d70223a22323032332d30372d32385430313a31343a35352e393832353036222c2276657273696f6e223a342c226570696450736575646f6e796d223a224562724d3658365943483362726a50585432336756682f49324547357356664859682b533534666230727241715652546952544f53664c73575356545a63387772617a4747376f6f6f476f4d5537476a35544568736733764a2f6a5974784537514b6f4a79704571307766395556644256384f627a776264794a6e72536c61757042446f5854744d485a3232506e2f456b3249567071314c6e725633667a6a526a66382b444b336c7137303d222c2261647669736f727955524c223a2268747470733a2f2f73656375726974792d63656e7465722e696e74656c2e636f6d222c2261647669736f7279494473223a5b22494e54454c2d53412d3030333334222c22494e54454c2d53412d3030363135225d2c22697376456e636c61766551756f7465537461747573223a2253575f48415244454e494e475f4e4545444544222c22697376456e636c61766551756f7465426f6479223a2241674142414b774d4141414e414130414141414141454a68624a6a56504a6353593552487962446e4144384141414141414141414141414141414141414141414652554c422f2b41446741414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack414141414141414141414141414251414141414141414141664141414141414141414874754172786e3666703532656c6d74756756714176783879514469537362367970466f4a4c6f5038486c41414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack41414141414141434431786e6e6665724b4648443275765971545864444138695a32326b434435787737683338434d664f6e674141414141414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack4141414141414143504148677a6958413937433778784b4a384f6d2b482f644d53326d44764a6270583762737137424f386c56664a3359722f4e5469516b4b6e6844314745597a38414141414141414141414141414141414141414141227d +odd len hex 7b226964223a22313030393338333438383438393337323833313538373130383530363736383834393935323531222c2274696d657374616d70223a22323032332d30372d32385430313a31343a35352e393832353036222c2276657273696f6e223a342c226570696450736575646f6e796d223a224562724d3658365943483362726a50585432336756682f49324547357356664859682b533534666230727241715652546952544f53664c73575356545a63387772617a4747376f6f6f476f4d5537476a35544568736733764a2f6a5974784537514b6f4a79704571307766395556644256384f627a776264794a6e72536c61757042446f5854744d485a3232506e2f456b3249567071314c6e725633667a6a526a66382b444b336c7137303d222c2261647669736f727955524c223a2268747470733a2f2f73656375726974792d63656e7465722e696e74656c2e636f6d222c2261647669736f7279494473223a5b22494e54454c2d53412d3030333334222c22494e54454c2d53412d3030363135225d2c22697376456e636c61766551756f7465537461747573223a2253575f48415244454e494e475f4e4545444544222c22697376456e636c61766551756f7465426f6479223a2241674142414b774d4141414e414130414141414141454a68624a6a56504a6353593552487962446e4144384141414141414141414141414141414141414141414652554c422f2b41446741414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack414141414141414141414141414251414141414141414141664141414141414141414874754172786e3666703532656c6d74756756714176783879514469537362367970466f4a4c6f5038486c41414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack41414141414141434431786e6e6665724b4648443275765971545864444138695a32326b434435787737683338434d664f6e674141414141414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack4141414141414143504148677a6958413937433778784b4a384f6d2b482f644d53326d44764a6270583762737137424f386c56664a3359722f4e5469516b4b6e6844314745597a38414141414141414141414141414141414141414141227d +odd len hex 7b226964223a22313030393338333438383438393337323833313538373130383530363736383834393935323531222c2274696d657374616d70223a22323032332d30372d32385430313a31343a35352e393832353036222c2276657273696f6e223a342c226570696450736575646f6e796d223a224562724d3658365943483362726a50585432336756682f49324547357356664859682b533534666230727241715652546952544f53664c73575356545a63387772617a4747376f6f6f476f4d5537476a35544568736733764a2f6a5974784537514b6f4a79704571307766395556644256384f627a776264794a6e72536c61757042446f5854744d485a3232506e2f456b3249567071314c6e725633667a6a526a66382b444b336c7137303d222c2261647669736f727955524c223a2268747470733a2f2f73656375726974792d63656e7465722e696e74656c2e636f6d222c2261647669736f7279494473223a5b22494e54454c2d53412d3030333334222c22494e54454c2d53412d3030363135225d2c22697376456e636c61766551756f7465537461747573223a2253575f48415244454e494e475f4e4545444544222c22697376456e636c61766551756f7465426f6479223a2241674142414b774d4141414e414130414141414141454a68624a6a56504a6353593552487962446e4144384141414141414141414141414141414141414141414652554c422f2b41446741414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack414141414141414141414141414251414141414141414141664141414141414141414874754172786e3666703532656c6d74756756714176783879514469537362367970466f4a4c6f5038486c41414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack41414141414141434431786e6e6665724b4648443275765971545864444138695a32326b434435787737683338434d664f6e674141414141414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack4141414141414143504148677a6958413937433778784b4a384f6d2b482f644d53326d44764a6270583762737137424f386c56664a3359722f4e5469516b4b6e6844314745597a38414141414141414141414141414141414141414141227d +odd len hex 7b226964223a22313030393338333438383438393337323833313538373130383530363736383834393935323531222c2274696d657374616d70223a22323032332d30372d32385430313a31343a35352e393832353036222c2276657273696f6e223a342c226570696450736575646f6e796d223a224562724d3658365943483362726a50585432336756682f49324547357356664859682b533534666230727241715652546952544f53664c73575356545a63387772617a4747376f6f6f476f4d5537476a35544568736733764a2f6a5974784537514b6f4a79704571307766395556644256384f627a776264794a6e72536c61757042446f5854744d485a3232506e2f456b3249567071314c6e725633667a6a526a66382b444b336c7137303d222c2261647669736f727955524c223a2268747470733a2f2f73656375726974792d63656e7465722e696e74656c2e636f6d222c2261647669736f7279494473223a5b22494e54454c2d53412d3030333334222c22494e54454c2d53412d3030363135225d2c22697376456e636c61766551756f7465537461747573223a2253575f48415244454e494e475f4e4545444544222c22697376456e636c61766551756f7465426f6479223a2241674142414b774d4141414e414130414141414141454a68624a6a56504a6353593552487962446e4144384141414141414141414141414141414141414141414652554c422f2b41446741414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack414141414141414141414141414251414141414141414141664141414141414141414874754172786e3666703532656c6d74756756714176783879514469537362367970466f4a4c6f5038486c41414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack41414141414141434431786e6e6665724b4648443275765971545864444138695a32326b434435787737683338434d664f6e674141414141414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack4141414141414143504148677a6958413937433778784b4a384f6d2b482f644d53326d44764a6270583762737137424f386c56664a3359722f4e5469516b4b6e6844314745597a38414141414141414141414141414141414141414141227d +odd len hex 7b226964223a22313030393338333438383438393337323833313538373130383530363736383834393935323531222c2274696d657374616d70223a22323032332d30372d32385430313a31343a35352e393832353036222c2276657273696f6e223a342c226570696450736575646f6e796d223a224562724d3658365943483362726a50585432336756682f49324547357356664859682b533534666230727241715652546952544f53664c73575356545a63387772617a4747376f6f6f476f4d5537476a35544568736733764a2f6a5974784537514b6f4a79704571307766395556644256384f627a776264794a6e72536c61757042446f5854744d485a3232506e2f456b3249567071314c6e725633667a6a526a66382b444b336c7137303d222c2261647669736f727955524c223a2268747470733a2f2f73656375726974792d63656e7465722e696e74656c2e636f6d222c2261647669736f7279494473223a5b22494e54454c2d53412d3030333334222c22494e54454c2d53412d3030363135225d2c22697376456e636c61766551756f7465537461747573223a2253575f48415244454e494e475f4e4545444544222c22697376456e636c61766551756f7465426f6479223a2241674142414b774d4141414e414130414141414141454a68624a6a56504a6353593552487962446e4144384141414141414141414141414141414141414141414652554c422f2b41446741414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack414141414141414141414141414251414141414141414141664141414141414141414874754172786e3666703532656c6d74756756714176783879514469537362367970466f4a4c6f5038486c41414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack41414141414141434431786e6e6665724b4648443275765971545864444138695a32326b434435787737683338434d664f6e674141414141414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack4141414141414143504148677a6958413937433778784b4a384f6d2b482f644d53326d44764a6270583762737137424f386c56664a3359722f4e5469516b4b6e6844314745597a38414141414141414141414141414141414141414141227d +odd len hex 7b226964223a22313030393338333438383438393337323833313538373130383530363736383834393935323531222c2274696d657374616d70223a22323032332d30372d32385430313a31343a35352e393832353036222c2276657273696f6e223a342c226570696450736575646f6e796d223a224562724d3658365943483362726a50585432336756682f49324547357356664859682b533534666230727241715652546952544f53664c73575356545a63387772617a4747376f6f6f476f4d5537476a35544568736733764a2f6a5974784537514b6f4a79704571307766395556644256384f627a776264794a6e72536c61757042446f5854744d485a3232506e2f456b3249567071314c6e725633667a6a526a66382b444b336c7137303d222c2261647669736f727955524c223a2268747470733a2f2f73656375726974792d63656e7465722e696e74656c2e636f6d222c2261647669736f7279494473223a5b22494e54454c2d53412d3030333334222c22494e54454c2d53412d3030363135225d2c22697376456e636c61766551756f7465537461747573223a2253575f48415244454e494e475f4e4545444544222c22697376456e636c61766551756f7465426f6479223a2241674142414b774d4141414e414130414141414141454a68624a6a56504a6353593552487962446e4144384141414141414141414141414141414141414141414652554c422f2b41446741414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack414141414141414141414141414251414141414141414141664141414141414141414874754172786e3666703532656c6d74756756714176783879514469537362367970466f4a4c6f5038486c41414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack41414141414141434431786e6e6665724b4648443275765971545864444138695a32326b434435787737683338434d664f6e674141414141414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack4141414141414143504148677a6958413937433778784b4a384f6d2b482f644d53326d44764a6270583762737137424f386c56664a3359722f4e5469516b4b6e6844314745597a38414141414141414141414141414141414141414141227d +odd len hex 7b226964223a22313030393338333438383438393337323833313538373130383530363736383834393935323531222c2274696d657374616d70223a22323032332d30372d32385430313a31343a35352e393832353036222c2276657273696f6e223a342c226570696450736575646f6e796d223a224562724d3658365943483362726a50585432336756682f49324547357356664859682b533534666230727241715652546952544f53664c73575356545a63387772617a4747376f6f6f476f4d5537476a35544568736733764a2f6a5974784537514b6f4a79704571307766395556644256384f627a776264794a6e72536c61757042446f5854744d485a3232506e2f456b3249567071314c6e725633667a6a526a66382b444b336c7137303d222c2261647669736f727955524c223a2268747470733a2f2f73656375726974792d63656e7465722e696e74656c2e636f6d222c2261647669736f7279494473223a5b22494e54454c2d53412d3030333334222c22494e54454c2d53412d3030363135225d2c22697376456e636c61766551756f7465537461747573223a2253575f48415244454e494e475f4e4545444544222c22697376456e636c61766551756f7465426f6479223a2241674142414b774d4141414e414130414141414141454a68624a6a56504a6353593552487962446e4144384141414141414141414141414141414141414141414652554c422f2b41446741414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack414141414141414141414141414251414141414141414141664141414141414141414874754172786e3666703532656c6d74756756714176783879514469537362367970466f4a4c6f5038486c41414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack41414141414141434431786e6e6665724b4648443275765971545864444138695a32326b434435787737683338434d664f6e674141414141414141414141414141414141414141414141414141414141certsder_to_pemechoerror.logfields_to_abiforge_deployfrom_hexget_cert_keybitsget_forge_deploy_addrget_report_certis_cert_crlis_cert_deris_cert_pemis_mock_mrenclaveis_mock_mrsigneris_mock_payloadis_mock_reportis_mock_signer_certis_mock_signer_expis_mock_signer_modis_mock_signer_sigis_valid_certis_valid_hex_lenis_valid_reportis_valid_signer_certis_valid_signer_expis_valid_signer_modis_valid_signer_siglibpackpem_to_derprepend_func_sigre_findreport_to_calldatarsa_digestss_to_abitest_cert.pemtest_packtest_valid_signer_sigto_hextrim_whitespaceunpack4141414141414143504148677a6958413937433778784b4a384f6d2b482f644d53326d44764a6270583762737137424f386c56664a3359722f4e5469516b4b6e6844314745597a38414141414141414141414141414141414141414141227d +whitespace found in report = '{"id":"142090828149453720542199954221331392599","timestamp":"2023-02-15T01:24:57.989456","version":4,"epidPseudonym":"EbrM6X6YCH3brjPXT23gVh/I2EG5sVfHYh+S54fb0rrAqVRTiRTOSfLsWSVTZc8wrazGG7oooGoMU7Gj5TEhsvsDIV4aYpvkSk/E3Tsb7CaGd+Iy1cEhLO4GPwdmwt/PXNQQ3htLdy3aNb7iQMrNbiFcdkVdV/tepdezMsSB8Go=","isvEnclaveQuoteStatus":"OK","isvEnclaveQuoteBody":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANCud0d0wgZKYN2SVB/MfLizrN6g15PzsnonpE2/cedfAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACD1xnnferKFHD2uvYqTXdDA8iZ22kCD5xw7h38CMfOngAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACD1xnnferKFHD2uvYqTXdDA8iZ22kCD5xw7h38CMfOnoPXGed96soUcPa69ipNd0MDyJnbaQIPnHDuHfwIx86e"} +'whitespace found in report = '{"id":"142090828149453720542199954221331392599","timestamp":"2023-02-15T01:24:57.989456","version":4,"epidPseudonym":"EbrM6X6YCH3brjPXT23gVh/I2EG5sVfHYh+S54fb0rrAqVRTiRTOSfLsWSVTZc8wrazGG7oooGoMU7Gj5TEhsvsDIV4aYpvkSk/E3Tsb7CaGd+Iy1cEhLO4GPwdmwt/PXNQQ3htLdy3aNb7iQMrNbiFcdkVdV/tepdezMsSB8Go=","isvEnclaveQuoteStatus":"OK","isvEnclaveQuoteBody":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANCud0d0wgZKYN2SVB/MfLizrN6g15PzsnonpE2/cedfAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACD1xnnferKFHD2uvYqTXdDA8iZ22kCD5xw7h38CMfOngAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACD1xnnferKFHD2uvYqTXdDA8iZ22kCD5xw7h38CMfOnoPXGed96soUcPa69ipNd0MDyJnbaQIPnHDuHfwIx86e"} +'whitespace found in report = '{"id":"142090828149453720542199954221331392599","timestamp":"2023-02-15T01:24:57.989456","version":4,"epidPseudonym":"EbrM6X6YCH3brjPXT23gVh/I2EG5sVfHYh+S54fb0rrAqVRTiRTOSfLsWSVTZc8wrazGG7oooGoMU7Gj5TEhsvsDIV4aYpvkSk/E3Tsb7CaGd+Iy1cEhLO4GPwdmwt/PXNQQ3htLdy3aNb7iQMrNbiFcdkVdV/tepdezMsSB8Go=","isvEnclaveQuoteStatus":"OK","isvEnclaveQuoteBody":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANCud0d0wgZKYN2SVB/MfLizrN6g15PzsnonpE2/cedfAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACD1xnnferKFHD2uvYqTXdDA8iZ22kCD5xw7h38CMfOngAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACD1xnnferKFHD2uvYqTXdDA8iZ22kCD5xw7h38CMfOnoPXGed96soUcPa69ipNd0MDyJnbaQIPnHDuHfwIx86e"} +'whitespace found in report = '{"id":"142090828149453720542199954221331392599","timestamp":"2023-02-15T01:24:57.989456","version":4,"epidPseudonym":"EbrM6X6YCH3brjPXT23gVh/I2EG5sVfHYh+S54fb0rrAqVRTiRTOSfLsWSVTZc8wrazGG7oooGoMU7Gj5TEhsvsDIV4aYpvkSk/E3Tsb7CaGd+Iy1cEhLO4GPwdmwt/PXNQQ3htLdy3aNb7iQMrNbiFcdkVdV/tepdezMsSB8Go=","isvEnclaveQuoteStatus":"OK","isvEnclaveQuoteBody":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANCud0d0wgZKYN2SVB/MfLizrN6g15PzsnonpE2/cedfAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACD1xnnferKFHD2uvYqTXdDA8iZ22kCD5xw7h38CMfOngAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACD1xnnferKFHD2uvYqTXdDA8iZ22kCD5xw7h38CMfOnoPXGed96soUcPa69ipNd0MDyJnbaQIPnHDuHfwIx86e"} +' \ No newline at end of file diff --git a/test/scripts/bin/fields_to_abi b/test/scripts/bin/fields_to_abi index e69de29..20d52ea 100755 --- a/test/scripts/bin/fields_to_abi +++ b/test/scripts/bin/fields_to_abi @@ -0,0 +1,11 @@ +#!/usr/bin/python3 + +import sys, eth_abi, binascii + +vals = [] +for hex_val in sys.argv[1:]: + val = binascii.unhexlify(hex_val.encode("ascii")) + vals.append(val) + +payload = eth_abi.encode(['bytes'] * len(vals), vals) +print(payload.hex(), end="") \ No newline at end of file diff --git a/test/scripts/bin/get_uuid b/test/scripts/bin/get_uuid new file mode 100644 index 0000000..3ed48a8 --- /dev/null +++ b/test/scripts/bin/get_uuid @@ -0,0 +1,5 @@ +#!/usr/bin/python3 + +import uuid + +print(str(uuid.uuid4()), end="") \ No newline at end of file diff --git a/test/scripts/bin/is_valid_report b/test/scripts/bin/is_valid_report index 6779183..0eff59b 100755 --- a/test/scripts/bin/is_valid_report +++ b/test/scripts/bin/is_valid_report @@ -1,7 +1,32 @@ #!/usr/bin/python3 -import re, sys +import re, sys, json +from jsonschema import validate +from lib import * data = sys.stdin.buffer.read() -data = data.encode("utf-8") -print(data) \ No newline at end of file +data = data.decode("utf-8") + +# Whitespace should not exist in the report. +ws = re.findall("\s+", data) +if len(ws): + log(F"whitespace found in report = '{data}'") + print("0", end="") + exit() + +# Should use double quotes. +if "'" in data: + log(f"Double quotes found in report = '{data}'") + print("0", end="") + exit() + +# Use JSON schema to validate the report structure. +try: + instance = json.loads(data) + validate(instance=instance, schema=REPORT_SCHEMA) + print("1", end="") + exit() +except Exception: + log(f"JSON schema validation error for report = '{data}' error = '{str(e)}'") + print("0", end="") + exit() diff --git a/test/scripts/bin/lib/__init__.py b/test/scripts/bin/lib/__init__.py new file mode 100644 index 0000000..734f163 --- /dev/null +++ b/test/scripts/bin/lib/__init__.py @@ -0,0 +1 @@ +from .shared import * \ No newline at end of file diff --git a/test/scripts/bin/lib/shared.py b/test/scripts/bin/lib/shared.py new file mode 100644 index 0000000..5e61900 --- /dev/null +++ b/test/scripts/bin/lib/shared.py @@ -0,0 +1,73 @@ +import sha3 + +REPORT_FIELDS = [ + "id", + "timestamp", + "version", + "epidPseudonym", + "advisoryURL", + "advisoryIDs", + "isvEnclaveQuoteStatus", + "isvEnclaveQuoteBody" +] + +REPORT_SCHEMA = { + "type": "object", + "properties": { + "id": { + "type": "string", + "pattern": "^[0-9]+$" + }, + "timestamp": { + "type": "string", + "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}[.][0-9]+$", + "format": "date-time" + }, + "version": { + "type": "integer", + "minimum": 1 + }, + "epidPseudonym": { + "type": "string", + "pattern": "^[0-9a-zA-Z\\/=+]+$" + }, + "isvEnclaveQuoteStatus": { + "type": "string", + "pattern": "^OK|SW_HARDENING_NEEDED$" + }, + "isvEnclaveQuoteBody": { + "type": "string", + "pattern": "^[0-9a-zA-Z\\/=+]+$" + }, + "advisoryIDs": { + "type": "array", + "items": { + "type": "string", + "pattern": 'INTEL[-]SA[-][0-9]{5}', + } + }, + "advisoryURL": { + "type": "string", + "pattern": "https://security[-]center[.]intel[.]com" + } + }, + "required": [ + "id", + "timestamp", + "version", + "epidPseudonym", + "isvEnclaveQuoteStatus", + "isvEnclaveQuoteBody" + ] +} + +def log(m): + # Writing to file + with open("error.log", "a") as fp: + # Writing data to a file + fp.write(m) + +def sha3_hex(x): + k = sha3.keccak_256() + k.update(x) + return k.hexdigest() \ No newline at end of file diff --git a/test/scripts/bin/prepend_func_sig b/test/scripts/bin/prepend_func_sig new file mode 100755 index 0000000..16b1483 --- /dev/null +++ b/test/scripts/bin/prepend_func_sig @@ -0,0 +1,15 @@ +#!/usr/bin/python3 + +import sys +from lib import * + +data = sys.stdin.buffer.read() +data = data.decode("utf-8") +func_sig = sys.argv[1].encode("ascii") + +# Add function name to out. +out = sha3_hex(func_sig)[:8] +out = out + data + +# Then dump everything as hex. +print(out, end="") \ No newline at end of file diff --git a/test/scripts/bin/report_to_calldata b/test/scripts/bin/report_to_calldata index 3441a36..7d6ea30 100755 --- a/test/scripts/bin/report_to_calldata +++ b/test/scripts/bin/report_to_calldata @@ -1,23 +1,14 @@ #!/usr/bin/python3 import base64, eth_abi, sys, json +from lib import * data = sys.stdin.buffer.read() data = data.decode("utf-8") j = json.loads(data) -names = [ - "id", - "timestamp", - "version", - "epidPseudonym", - "advisoryURL", - "advisoryIDs", - "isvEnclaveQuoteStatus", - "isvEnclaveQuoteBody" -] values = [] -for name in names: +for name in REPORT_FIELDS: value = j[name] # Script takes decoded body. diff --git a/test/scripts/bin/ss_to_abi b/test/scripts/bin/ss_to_abi new file mode 100755 index 0000000..b75332a --- /dev/null +++ b/test/scripts/bin/ss_to_abi @@ -0,0 +1,62 @@ +#!/bin/bash + +# Conf -- set paths to secure signer ############################################# +signer_root=$1 +SECURE_SIGNER_PORT=9001 +if [ "$signer_root" == "" ]; then + echo "./ss_to_abi '/home/matthew/projects/secure-signer'" + exit +fi + +############################################# + +# Constants used by the script. +ROOT_CA_MOD="9F3C647EB5773CBB512D2732C0D7415EBB55A0FA9EDE2E649199E6821DB910D53177370977466A6A5E4786CCD2DDEBD4149D6A2F6325529DD10CC98737B0779C1A07E29C47A1AE004948476C489F45A5A15D7AC8ECC6ACC645ADB43D87679DF59C093BC5A2E9696C5478541B979E754B573914BE55D32FF4C09DDF27219934CD990527B3F92ED78FBF29246ABECB71240EF39C2D7107B447545A7FFB10EB060A68A98580219E36910952683892D6A5E2A80803193E407531404E36B315623799AA825074409754A2DFE8F5AFD5FE631E1FC2AF3808906F28A790D9DD9FE060939B125790C5805D037DF56A99531B96DE69DE33ED226CC1207D1042B5C9AB7F404FC711C0FE4769FB9578B1DC0EC469EA1A25E0FF9914886EF2699B235BB4847DD6FF40B606E6170793C2FB98B314587F9CFD257362DFEAB10B3BD2D97673A1A4BD44C453AAF47FC1F2D3D0F384F74A06F89C089F0DA6CDB7FCEEE8C9821A8E54F25C0416D18C46839A5F8012FBDD3DC74D256279ADC2C0D55AFF6F0622425D1B" +ROOT_CA_EXP="010001" + +# Key variables used by the script. +ss_out_path=$signer_root/ss_out +signer_path=$signer_root/target/x86_64-unknown-linux-musl/release/secure-signer +client_path=$signer_root/target/debug/client +enclave_path=$signer_root/Secure-Signer + +# Get enclave hash values. +pushd ${enclave_path} > /dev/null +mrenclave=$(occlum print mrenclave) # hex +mrsigner=$(occlum print mrsigner) +popd > /dev/null + +# Extract required fields from the keygen response. +keygen_response=$(cat $ss_out_path/keygen_response) +sig=$(echo $keygen_response | jq -r '.evidence.signed_report') +report=$(echo $keygen_response | jq -r '.evidence.raw_report') +certs=$(echo $keygen_response | jq -r '.evidence.signing_cert') + +# Get the right cert from the certs list. +leaf_cert_pem=$(echo "$certs" | ./get_report_cert) + +# Convert it to DER format and store as hex. +leaf_cert_hex=$(echo "$leaf_cert_pem" | ./pem_to_der | ./to_hex) + +# Convert signature from b64 and store as hex. +sig_hex=$(echo "$sig" | base64 --decode | ./to_hex) + +# Convert report JSON to hex format (don't add extra new line!) +report_hex=$(echo -n "$report" | ./to_hex) + +# Extract fields from JSON report and store as ABI encoded hex. +report_calldata_hex=$(echo -n "$report" | ./report_to_calldata) + +# Inputs should all be hex. +abi_out=$( + ./fields_to_abi \ + "$report_calldata_hex" \ + "$sig_hex" \ + "$leaf_cert_hex" \ + "$ROOT_CA_MOD" \ + "$ROOT_CA_EXP" \ + "$mrenclave" \ + "$mrsigner" +) + +echo -n $abi_out diff --git a/test/scripts/bin/test_report b/test/scripts/bin/test_report new file mode 100644 index 0000000..b475c07 --- /dev/null +++ b/test/scripts/bin/test_report @@ -0,0 +1 @@ +{"id":"142090828149453720542199954221331392599","timestamp":"2023-02-15T01:24:57.989456","version":4,"epidPseudonym":"EbrM6X6YCH3brjPXT23gVh/I2EG5sVfHYh+S54fb0rrAqVRTiRTOSfLsWSVTZc8wrazGG7oooGoMU7Gj5TEhsvsDIV4aYpvkSk/E3Tsb7CaGd+Iy1cEhLO4GPwdmwt/PXNQQ3htLdy3aNb7iQMrNbiFcdkVdV/tepdezMsSB8Go=","isvEnclaveQuoteStatus":"OK","isvEnclaveQuoteBody":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANCud0d0wgZKYN2SVB/MfLizrN6g15PzsnonpE2/cedfAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACD1xnnferKFHD2uvYqTXdDA8iZ22kCD5xw7h38CMfOngAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACD1xnnferKFHD2uvYqTXdDA8iZ22kCD5xw7h38CMfOnoPXGed96soUcPa69ipNd0MDyJnbaQIPnHDuHfwIx86e"} \ No newline at end of file diff --git a/test/scripts/preprocess_rave_inputs.py b/test/scripts/preprocess_rave_inputs.py index e617f41..3494671 100755 --- a/test/scripts/preprocess_rave_inputs.py +++ b/test/scripts/preprocess_rave_inputs.py @@ -48,7 +48,6 @@ def cert_wrap(x): # Trucate 0x prefix from args. rm_0x(args) - # unhex_list = [ args["report"], @@ -75,14 +74,14 @@ def cert_wrap(x): "bytes", # Leaf cert "bytes", # Sig modulus "bytes", # Sig exponent - "bytes32", # Mrenclave digest - "bytes32", # Mrsigner digest + "bytes", # Mrenclave digest + "bytes", # Mrsigner digest ], bytes_list ) # Add function name to out. - out = sha3_hex(b"rave(bytes,bytes,bytes,bytes,bytes,bytes32,bytes32)")[:8] + out = sha3_hex(b"rave(bytes,bytes,bytes,bytes,bytes,bytes,bytes)")[:8] out = to_s(out) + ffi_payload.hex() #out = ffi_payload.hex() diff --git a/test/scripts/runRSAKeygen.sh b/test/scripts/runRSAKeygen.sh index 70b14af..3a7c51b 100755 --- a/test/scripts/runRSAKeygen.sh +++ b/test/scripts/runRSAKeygen.sh @@ -1,7 +1,7 @@ #!/bin/bash # Generates new RSA private key with number of bits passed as command line arg -openssl genrsa -out /tmp/private.pem "$1" +openssl genrsa -out /tmp/private.pem "$1" 2>/dev/null # Write the public key to file -openssl rsa -in /tmp/private.pem -outform der -pubout -out /tmp/public.der \ No newline at end of file +openssl rsa -in /tmp/private.pem -outform der -pubout -out /tmp/public.der 2>/dev/null \ No newline at end of file diff --git a/test/scripts/runReadCached.py b/test/scripts/runReadCached.py index 33c7d50..495a19d 100755 --- a/test/scripts/runReadCached.py +++ b/test/scripts/runReadCached.py @@ -4,6 +4,7 @@ import json import eth_abi +from utils import * def main(): @@ -19,7 +20,8 @@ def main(): for p in paths: with open(p) as f: - hex_data = f.read().strip('0x') + hex_data = f.read() + hex_data = strip_0x(hex_data) bytes_data = bytes.fromhex(hex_data) cached_data.append(bytes_data) diff --git a/test/scripts/runSignRandomEvidence.py b/test/scripts/runSignRandomEvidence.py index 2cc4062..f5e9a44 100755 --- a/test/scripts/runSignRandomEvidence.py +++ b/test/scripts/runSignRandomEvidence.py @@ -10,6 +10,8 @@ from cryptography.hazmat.backends import default_backend import eth_abi +from utils import * + MRENCLAVE_OFFSET = 112 MRSIGNER_OFFSET = 176 PAYLOAD_OFFSET = 368 @@ -22,7 +24,8 @@ def build_quote_body(mre, mrs, payload) -> bytes: body_bytes = bytes(MRENCLAVE_OFFSET) + mre body_bytes += bytes(MRSIGNER_OFFSET - len(body_bytes)) + mrs body_bytes += bytes(PAYLOAD_OFFSET - len(body_bytes)) + payload - body_bytes += bytes(64 - len(payload)) # pad extra bytes with 0s + if len(payload) < 64: + body_bytes += bytes(64 - len(payload)) # pad extra bytes with 0s assert len(body_bytes) == QUOTE_BODY_LENGTH return body_bytes @@ -40,7 +43,7 @@ def mock_evidence(mrenclave, mrsigner, payload): ('epidPseudonym', "EbrM6X6YCH3brjPXT23gVh/I2EG5sVfHYh+S54fb0rrAqVRTiRTOSfLsWSVTZc8wrazGG7oooGoMU7Gj5TEhsvsDIV4aYpvkSk/E3Tsb7CaGd+Iy1cEhLO4GPwdmwt/PXNQQ3htLdy3aNb7iQMrNbiFcdkVdV/tepdezMsSB8Go="), ("advisoryURL", "https://security-center.intel.com"), ("advisoryIDs", ["INTEL-SA-00334","INTEL-SA-00615"]), - ("isvEnclaveQuoteStatus", "OK"), + ("isvEnclaveQuoteStatus", "SW_HARDENING_NEEDED"), ("isvEnclaveQuoteBody", f"{enc_quote_body}"), ]) @@ -75,15 +78,9 @@ def sign(fname, message) -> bytes: def main(): # Prepare inputs - stripped_mre = sys.argv[1].lstrip('0x') - stripped_mrs = sys.argv[2].lstrip('0x') - stripped_payload = sys.argv[3].lstrip('0x') - mrenclave = '0' * (64 - len(stripped_mre)) + stripped_mre - mrsigner = '0' * (64 - len(stripped_mrs)) + stripped_mrs - payload = '0' * (128 - len(stripped_payload)) + stripped_payload - mrenclave = bytes.fromhex(mrenclave) - mrsigner = bytes.fromhex(mrsigner) - payload = bytes.fromhex(payload) + mrenclave = base64.b64decode(to_b(sys.argv[1])) + mrsigner = base64.b64decode(to_b(sys.argv[2])) + payload = base64.b64decode(to_b(sys.argv[3])) # mock json report evidence, dec_quote_body = mock_evidence(mrenclave, mrsigner, payload) diff --git a/test/scripts/runX509Gen.sh b/test/scripts/runX509Gen.sh index 0998d35..25d6846 100755 --- a/test/scripts/runX509Gen.sh +++ b/test/scripts/runX509Gen.sh @@ -5,4 +5,5 @@ CERT_NAME=$2 KEY_NAME=$3 # Create a private key named $KEY_NAME and then self-sign an x509 certificate -echo -e "US\nCA\nSan Francisco\nMy Organization\nMy PARENT Name\n\n\n" | openssl req -x509 -newkey rsa:$BITS -keyout $KEY_NAME -out $CERT_NAME -sha256 -days 365 -nodes \ No newline at end of file +# US\nCA\nSan Francisco\nMy Organization\nMy PARENT Name\n\n\n +out=$(echo -e "US\nCA\nSanta Clara\nIntel Corporation\nIntel SGX Attestation Report Signing\n\n\n" | openssl req -x509 -newkey rsa:$BITS -keyout $KEY_NAME -out $CERT_NAME -sha256 -days 365 -nodes 2>/dev/null) \ No newline at end of file diff --git a/test/scripts/utils.py b/test/scripts/utils.py index e480cd9..f90ab76 100755 --- a/test/scripts/utils.py +++ b/test/scripts/utils.py @@ -6,13 +6,14 @@ b64_encode = lambda x: to_s(base64.b64encode(to_b(x))) b64_decode = lambda x: to_s(base64.b64decode(to_b(x))) rm_0x = lambda x: [x.update({k: v[2:]}) for k,v in x.items() if x[k] and x[k][0:2] == "0x"] +strip_0x = lambda x: x if x[0:2] != "0x" else x[2:] def from_hex(x): # Make sure the hex string is even. if len(x) % 2: x = "0" + x - return to_s(binascii.unhexlify(to_b(x))) + return binascii.unhexlify(to_b(x)) def to_hex(x): return to_s(binascii.hexlify(to_b(x))) diff --git a/test/utils/helper.sol b/test/utils/helper.sol index 5c83bce..6e43a24 100755 --- a/test/utils/helper.sol +++ b/test/utils/helper.sol @@ -6,6 +6,7 @@ import { SafeMath } from "openzeppelin-contracts/contracts/utils/math/SafeMath.s + library BytesHelper { function notAllZeroes(bytes memory data) public pure returns (bool) { for (uint256 i = 0; i < data.length; i++) { @@ -15,6 +16,38 @@ library BytesHelper { } return false; } + + function to_hex(bytes memory buffer) public pure returns (bytes memory) { + + // Fixed buffer size for hexadecimal convertion + bytes memory converted = new bytes(buffer.length * 2); + + bytes memory _base = "0123456789ABCDEF"; + + for (uint256 i = 0; i < buffer.length; i++) { + converted[i * 2] = _base[uint8(buffer[i]) / 16]; + converted[(i * 2) + 1] = _base[uint8(buffer[i]) % 16]; + } + + return converted; + } +} + +contract ExtraUtils is Test { + function uuid() + public + returns (string memory) + { + string[] memory cmds = new string[](2); + cmds[0] = "python3"; + cmds[1] = "test/scripts/bin/get_uuid"; + + // Request .py sript to generate and sign mock RA evidence + bytes memory resp = vm.ffi(cmds); + console.logBytes(resp); + + return (string(resp)); + } } contract BytesFFIFuzzer is Test { @@ -27,6 +60,8 @@ contract BytesFFIFuzzer is Test { function getFriendlyBytes32(bytes32 _fuzzedBytes) public pure returns (bytes memory) { return bytes(vm.toString(_fuzzedBytes)); } + + } contract KeyGenHelper is Test { @@ -51,7 +86,7 @@ contract KeyGenHelper is Test { } // Helper functions to generate self-signed x509 and methods to extract relevant info -contract X509GenHelper is Test { +contract X509GenHelper is Test, ExtraUtils { bytes public CERT_BYTES; bytes public CERT_BODY_BYTES; bytes public CERT_SIG; @@ -66,7 +101,7 @@ contract X509GenHelper is Test { constructor(string memory keyBits) { KEY_BITS = keyBits; X509_NAME = string(abi.encodePacked("/tmp/", keyBits, "BitSelfSignedx509.pem")); - X509_PRIV_KEY_NAME = string(abi.encodePacked("/tmp/", keyBits, "Bitx509SigningKey.pem")); + X509_PRIV_KEY_NAME = string(abi.encodePacked("/tmp/", keyBits, ExtraUtils.uuid(), "Bitx509SigningKey.pem")); } function newSelfSignedX509() public {