@super-protocol/sdk-js 2.2.0-beta.59 → 2.2.0-beta.60
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.d.ts +1 -1
- package/dist/cjs/index.js +5 -2
- package/dist/cjs/tee/QuoteParser.d.ts +59 -5
- package/dist/cjs/tee/QuoteParser.js +219 -27
- package/dist/cjs/tee/QuoteValidator.d.ts +1 -0
- package/dist/cjs/tee/QuoteValidator.js +53 -28
- package/dist/cjs/tee/types.d.ts +49 -9
- package/dist/cjs/tee/types.js +32 -1
- package/dist/mjs/index.d.ts +1 -1
- package/dist/mjs/index.js +2 -2
- package/dist/mjs/tee/QuoteParser.d.ts +59 -5
- package/dist/mjs/tee/QuoteParser.js +216 -26
- package/dist/mjs/tee/QuoteValidator.d.ts +1 -0
- package/dist/mjs/tee/QuoteValidator.js +54 -29
- package/dist/mjs/tee/types.d.ts +49 -9
- package/dist/mjs/tee/types.js +28 -2
- package/package.json +1 -1
package/dist/cjs/index.d.ts
CHANGED
|
@@ -71,7 +71,7 @@ export * as helpers from './utils/helpers/index.js';
|
|
|
71
71
|
export * as constants from './constants.js';
|
|
72
72
|
export { Web3TransactionRevertedByEvmError } from './utils/TxManager.js';
|
|
73
73
|
import './polyfills.js';
|
|
74
|
-
export { TeeSgxParser } from './tee/QuoteParser.js';
|
|
74
|
+
export { TeeSgxParser, TeeTdxParser, TeeParser } from './tee/QuoteParser.js';
|
|
75
75
|
export { QuoteValidator } from './tee/QuoteValidator.js';
|
|
76
76
|
export * from './tee/statuses.js';
|
|
77
77
|
export { TeeBlockVerifier } from './tee/TeeBlockVerifier.js';
|
package/dist/cjs/index.js
CHANGED
|
@@ -29,7 +29,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
29
29
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
30
30
|
};
|
|
31
31
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
32
|
-
exports.
|
|
32
|
+
exports.BrowserEventProvider = exports.NodeEventProvider = exports.Analytics = exports.TeeBlockVerifier = exports.QuoteValidator = exports.TeeParser = exports.TeeTdxParser = exports.TeeSgxParser = exports.Web3TransactionRevertedByEvmError = exports.constants = exports.helpers = exports.StorjCredentialsManager = exports.CredentialsPermissions = exports.parseStorageCredentials = exports.getStorageProvider = exports.ContentWriterType = exports.StorageContentWriter = exports.CacheEvents = exports.StorageAdapter = exports.StorageKeyValueAdapter = exports.StorageMetadataReader = exports.StorjAdapter = exports.ChunkedStorageProvider = exports.TCB = exports.Offer = exports.TeeOffer = exports.Provider = exports.Order = exports.SecretRequests = exports.OffersStorageRequests = exports.OffersStorageAllocated = exports.OfferResources = exports.LoaderSecretsPublicKeys = exports.LoaderSessions = exports.Deposits = exports.Marks = exports.Superpro = exports.SuperproToken = exports.ProviderRegistry = exports.TeeOffers = exports.Offers = exports.ActiveOffers = exports.ActiveOrders = exports.Orders = exports.Consensus = exports.RIGenerator = exports.TIIGenerator = exports.Crypto = exports.BlockchainEventsListener = exports.BlockchainConnector = void 0;
|
|
33
|
+
exports.FetchTransport = exports.AxiosTransport = void 0;
|
|
33
34
|
var BlockchainConnector_js_1 = require("./connectors/BlockchainConnector.js");
|
|
34
35
|
Object.defineProperty(exports, "BlockchainConnector", { enumerable: true, get: function () { return __importDefault(BlockchainConnector_js_1).default; } });
|
|
35
36
|
__exportStar(require("./connectors/BlockchainConnector.js"), exports);
|
|
@@ -139,6 +140,8 @@ Object.defineProperty(exports, "Web3TransactionRevertedByEvmError", { enumerable
|
|
|
139
140
|
require("./polyfills.js");
|
|
140
141
|
var QuoteParser_js_1 = require("./tee/QuoteParser.js");
|
|
141
142
|
Object.defineProperty(exports, "TeeSgxParser", { enumerable: true, get: function () { return QuoteParser_js_1.TeeSgxParser; } });
|
|
143
|
+
Object.defineProperty(exports, "TeeTdxParser", { enumerable: true, get: function () { return QuoteParser_js_1.TeeTdxParser; } });
|
|
144
|
+
Object.defineProperty(exports, "TeeParser", { enumerable: true, get: function () { return QuoteParser_js_1.TeeParser; } });
|
|
142
145
|
var QuoteValidator_js_1 = require("./tee/QuoteValidator.js");
|
|
143
146
|
Object.defineProperty(exports, "QuoteValidator", { enumerable: true, get: function () { return QuoteValidator_js_1.QuoteValidator; } });
|
|
144
147
|
__exportStar(require("./tee/statuses.js"), exports);
|
|
@@ -156,4 +159,4 @@ Object.defineProperty(exports, "AxiosTransport", { enumerable: true, get: functi
|
|
|
156
159
|
var FetchTransport_js_1 = require("./analytics/transports/FetchTransport.js");
|
|
157
160
|
Object.defineProperty(exports, "FetchTransport", { enumerable: true, get: function () { return __importDefault(FetchTransport_js_1).default; } });
|
|
158
161
|
__exportStar(require("./utils/cache/index.js"), exports);
|
|
159
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
162
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsOEVBQXFGO0FBQTVFLDhJQUFBLE9BQU8sT0FBdUI7QUFFdkMsc0VBQW9EO0FBSXBELHdGQUErRjtBQUF0Rix3SkFBQSxPQUFPLE9BQTRCO0FBRTVDLDhDQUFzRDtBQUE3QyxtSEFBQSxPQUFPLE9BQVU7QUFDMUIsb0RBQWtDO0FBRWxDLHFEQUE0RDtBQUFuRCxnSUFBQSxPQUFPLE9BQWdCO0FBQ2hDLG9EQUFrQztBQUVsQyxtREFBMEQ7QUFBakQsOEhBQUEsT0FBTyxPQUFlO0FBQy9CLG9EQUFrQztBQUVsQyw0REFBbUU7QUFBMUQsMEhBQUEsT0FBTyxPQUFhO0FBQzdCLDhEQUE0QztBQUU1QyxzREFBNkQ7QUFBcEQsb0hBQUEsT0FBTyxPQUFVO0FBQzFCLDJEQUF5QztBQUV6QyxrRUFBeUU7QUFBaEUsZ0lBQUEsT0FBTyxPQUFnQjtBQUNoQyxpRUFBK0M7QUFFL0Msa0VBQXlFO0FBQWhFLGdJQUFBLE9BQU8sT0FBZ0I7QUFDaEMsaUVBQStDO0FBRS9DLHNEQUE2RDtBQUFwRCxvSEFBQSxPQUFPLE9BQVU7QUFDMUIsMkRBQXlDO0FBRXpDLDREQUFtRTtBQUExRCwwSEFBQSxPQUFPLE9BQWE7QUFDN0IsOERBQTRDO0FBRTVDLDBFQUFpRjtBQUF4RSx3SUFBQSxPQUFPLE9BQW9CO0FBQ3BDLHFFQUFtRDtBQUVuRCxvRUFBMkU7QUFBbEUsa0lBQUEsT0FBTyxPQUFpQjtBQUNqQyxrRUFBZ0Q7QUFFaEQsMERBQWlFO0FBQXhELHdIQUFBLE9BQU8sT0FBWTtBQUM1Qiw2REFBMkM7QUFFM0Msb0RBQTJEO0FBQWxELGtIQUFBLE9BQU8sT0FBUztBQUN6QiwwREFBd0M7QUFFeEMsMERBQWlFO0FBQXhELHdIQUFBLE9BQU8sT0FBWTtBQUM1Qiw2REFBMkM7QUFFM0Msc0VBQTZFO0FBQXBFLG9JQUFBLE9BQU8sT0FBa0I7QUFDbEMsbUVBQWlEO0FBRWpELHdGQUErRjtBQUF0RixzSkFBQSxPQUFPLE9BQTJCO0FBQzNDLDRFQUEwRDtBQUUxRCxzRUFBNkU7QUFBcEUsb0lBQUEsT0FBTyxPQUFrQjtBQUNsQyxtRUFBaUQ7QUFFakQsc0ZBQTZGO0FBQXBGLG9KQUFBLE9BQU8sT0FBMEI7QUFDMUMsMkVBQXlEO0FBRXpELG9GQUEyRjtBQUFsRixrSkFBQSxPQUFPLE9BQXlCO0FBQ3pDLDBFQUF3RDtBQUV4RCxzRUFBNkU7QUFBcEUsb0lBQUEsT0FBTyxPQUFrQjtBQUNsQyxtRUFBaUQ7QUFFakQsOENBQXFEO0FBQTVDLGtIQUFBLE9BQU8sT0FBUztBQUN6QixvREFBa0M7QUFFbEMsb0RBQTJEO0FBQWxELHdIQUFBLE9BQU8sT0FBWTtBQUM1Qix1REFBcUM7QUFFckMsb0RBQTJEO0FBQWxELHdIQUFBLE9BQU8sT0FBWTtBQUM1Qix1REFBcUM7QUFFckMsOENBQXFEO0FBQTVDLGtIQUFBLE9BQU8sT0FBUztBQUN6QixvREFBa0M7QUFFbEMsMENBQWlEO0FBQXhDLDhHQUFBLE9BQU8sT0FBTztBQUN2QixrREFBZ0M7QUFFaEMsbURBQWlDO0FBRWpDLHlHQUF5RjtBQUN6Rix1RUFBMkY7QUFBbEYsZ0lBQUEsT0FBTyxPQUFnQjtBQUNoQyx5RkFHc0Q7QUFGcEQsa0pBQUEsT0FBTyxPQUF5QjtBQUdsQywyRkFBa0c7QUFBekYsb0pBQUEsT0FBTyxPQUEwQjtBQUMxQywyRUFJK0M7QUFIN0Msb0lBQUEsT0FBTyxPQUFrQjtBQUN6QixnSEFBQSxXQUFXLE9BQUE7QUFHYix1RkFJcUQ7QUFIbkQsZ0pBQUEsT0FBTyxPQUF3QjtBQUUvQiw0SEFBQSxpQkFBaUIsT0FBQTtBQU1uQixtRkFBMEY7QUFBakYsNElBQUEsT0FBTyxPQUFzQjtBQUV0Qyw2RkFBeUY7QUFBaEYscUlBQUEsdUJBQXVCLE9BQUE7QUFDaEMsNkZBR3dEO0FBRnRELG9JQUFBLHNCQUFzQixPQUFBO0FBQ3RCLHFJQUFBLHVCQUF1QixPQUFBO0FBR3pCLG1FQUFpRDtBQUNqRCxvRUFBb0Q7QUFDcEQsNERBQTRDO0FBRTVDLHFEQUF5RTtBQUFoRSxpSUFBQSxpQ0FBaUMsT0FBQTtBQUUxQywwQkFBd0I7QUFFeEIsdURBQTZFO0FBQXBFLDhHQUFBLFlBQVksT0FBQTtBQUFFLDhHQUFBLFlBQVksT0FBQTtBQUFFLDJHQUFBLFNBQVMsT0FBQTtBQUM5Qyw2REFBeUQ7QUFBaEQsbUhBQUEsY0FBYyxPQUFBO0FBQ3ZCLG9EQUFrQztBQUNsQyxpRUFBNkQ7QUFBcEQsdUhBQUEsZ0JBQWdCLE9BQUE7QUFFekIsdURBQXFDO0FBQ3JDLHlEQUFnRTtBQUF2RCwwSEFBQSxPQUFPLE9BQWE7QUFDN0Isd0ZBQStGO0FBQXRGLDBJQUFBLE9BQU8sT0FBcUI7QUFDckMsOEZBQXFHO0FBQTVGLGdKQUFBLE9BQU8sT0FBd0I7QUFDeEMsOEVBQXFGO0FBQTVFLG9JQUFBLE9BQU8sT0FBa0I7QUFDbEMsOEVBQXFGO0FBQTVFLG9JQUFBLE9BQU8sT0FBa0I7QUFDbEMseURBQXVDIn0=
|
|
@@ -1,5 +1,23 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import * as pkijs from 'pkijs';
|
|
3
|
+
import { Buffer as Blob } from 'buffer';
|
|
4
|
+
import { BinaryType, TeeSgxQuoteDataType, TeeSgxReportDataType, ChunkedX509Cert, TeeTdxQuoteDataType, TeeTdxBodyType, TeeTdxHeaderData, QuoteType } from './types.js';
|
|
5
|
+
export declare abstract class TeeParser {
|
|
6
|
+
protected extractRS(cert: pkijs.Certificate): {
|
|
7
|
+
r: string;
|
|
8
|
+
s: string;
|
|
9
|
+
derSignature: string;
|
|
10
|
+
};
|
|
11
|
+
protected parsePem(pem: string): ChunkedX509Cert;
|
|
12
|
+
protected getDataAndAdvance(blob: {
|
|
13
|
+
data: Blob;
|
|
14
|
+
}, size: number): Blob;
|
|
15
|
+
static determineQuoteType(quote: BinaryType): {
|
|
16
|
+
type: QuoteType;
|
|
17
|
+
version: number;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export declare class TeeSgxParser extends TeeParser {
|
|
3
21
|
static readonly quoteHeaderSize = 48;
|
|
4
22
|
static readonly pceSvnOffset = 10;
|
|
5
23
|
static readonly reportSize = 384;
|
|
@@ -19,9 +37,45 @@ export declare class TeeSgxParser {
|
|
|
19
37
|
static readonly reportUserDataSHA256Size = 32;
|
|
20
38
|
static readonly ecdsaP256SignatureSize = 64;
|
|
21
39
|
static readonly ecdsaP256PublicKeySize = 64;
|
|
22
|
-
private getDataAndAdvance;
|
|
23
|
-
private extractRS;
|
|
24
|
-
private parsePem;
|
|
25
40
|
parseQuote(data: BinaryType): TeeSgxQuoteDataType;
|
|
26
41
|
parseReport(data: BinaryType): TeeSgxReportDataType;
|
|
27
42
|
}
|
|
43
|
+
export declare class TeeTdxParser extends TeeParser {
|
|
44
|
+
static readonly quoteHeaderSize = 48;
|
|
45
|
+
static readonly tdQuoteBodySize = 584;
|
|
46
|
+
static readonly quoteSignatureDataLen = 4;
|
|
47
|
+
static readonly headerVersionSize = 2;
|
|
48
|
+
static readonly headerAttestationKeyTypeSize = 2;
|
|
49
|
+
static readonly headerTeeTypeSize = 4;
|
|
50
|
+
static readonly headerReserved1Size = 2;
|
|
51
|
+
static readonly headerReserved2Size = 2;
|
|
52
|
+
static readonly headerQeVendorIdSize = 16;
|
|
53
|
+
static readonly headerUserDataSize = 20;
|
|
54
|
+
static readonly bodyTeeTcbSvnSize = 16;
|
|
55
|
+
static readonly bodyMrSeamSize = 48;
|
|
56
|
+
static readonly bodyMrSignerSeamSize = 48;
|
|
57
|
+
static readonly bodySeamAttributesSize = 8;
|
|
58
|
+
static readonly bodyTdAttributesSize = 8;
|
|
59
|
+
static readonly bodyXfamSize = 8;
|
|
60
|
+
static readonly bodyMrTdSize = 48;
|
|
61
|
+
static readonly bodyMrConfigIdSize = 48;
|
|
62
|
+
static readonly bodyMrOwnerSize = 48;
|
|
63
|
+
static readonly bodyMrOwnerConfigSize = 48;
|
|
64
|
+
static readonly bodyRtmr0Size = 48;
|
|
65
|
+
static readonly bodyRtmr1Size = 48;
|
|
66
|
+
static readonly bodyRtmr2Size = 48;
|
|
67
|
+
static readonly bodyRtmr3Size = 48;
|
|
68
|
+
static readonly bodyReportDataSize = 64;
|
|
69
|
+
static readonly sigQuoteSignatureSize = 64;
|
|
70
|
+
static readonly sigAttestationKeySize = 64;
|
|
71
|
+
static readonly sigCertDataTypeSize = 2;
|
|
72
|
+
static readonly sigCertDataSzSize = 4;
|
|
73
|
+
static readonly sigQeReportSize = 384;
|
|
74
|
+
static readonly sigQeReportSignatureSize = 64;
|
|
75
|
+
static readonly sigQeAuthenticationDataSzSize = 2;
|
|
76
|
+
static readonly sigSignatureTypeSize = 2;
|
|
77
|
+
static readonly sigSignatureSzSize = 4;
|
|
78
|
+
parseQuote(data: BinaryType): TeeTdxQuoteDataType;
|
|
79
|
+
parseHeader(data: BinaryType): TeeTdxHeaderData;
|
|
80
|
+
parseBody(data: BinaryType): TeeTdxBodyType;
|
|
81
|
+
}
|
|
@@ -23,38 +23,15 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.TeeSgxParser = void 0;
|
|
26
|
+
exports.TeeTdxParser = exports.TeeSgxParser = exports.TeeParser = void 0;
|
|
27
27
|
const x509_1 = require("@fidm/x509");
|
|
28
28
|
const asn1js = __importStar(require("asn1js"));
|
|
29
29
|
const pkijs = __importStar(require("pkijs"));
|
|
30
30
|
const buffer_1 = require("buffer");
|
|
31
31
|
const errors_js_1 = require("./errors.js");
|
|
32
|
+
const types_js_1 = require("./types.js");
|
|
32
33
|
const helpers_js_1 = require("./helpers.js");
|
|
33
|
-
class
|
|
34
|
-
static quoteHeaderSize = 48;
|
|
35
|
-
static pceSvnOffset = 10;
|
|
36
|
-
static reportSize = 384;
|
|
37
|
-
static userDataOffset = 28;
|
|
38
|
-
static userDataSize = 20;
|
|
39
|
-
static cpuSvnSize = 16;
|
|
40
|
-
static reportMrEnclaveOffset = 64;
|
|
41
|
-
static reportMrEnclaveSize = 32;
|
|
42
|
-
static reportMrSignerOffset = TeeSgxParser.reportMrEnclaveOffset + TeeSgxParser.reportMrEnclaveSize + /* reserved */ 32;
|
|
43
|
-
static reportMrSignerSize = 32;
|
|
44
|
-
static reportIsvProdIdOffset = TeeSgxParser.reportMrSignerOffset + TeeSgxParser.reportMrSignerSize + /* reserved */ 96;
|
|
45
|
-
static reportIsvProdIdSize = 2;
|
|
46
|
-
static reportIsvSvnOffset = TeeSgxParser.reportIsvProdIdOffset + TeeSgxParser.reportIsvProdIdSize;
|
|
47
|
-
static reportIsvSvnSize = 2;
|
|
48
|
-
static reportDataOffset = TeeSgxParser.reportIsvSvnOffset + TeeSgxParser.reportIsvSvnSize + /* reserved */ 60;
|
|
49
|
-
static reportUserDataSize = 64;
|
|
50
|
-
static reportUserDataSHA256Size = 32; /* 64 in report, but we need 32 only for sha256 hash */
|
|
51
|
-
static ecdsaP256SignatureSize = 64;
|
|
52
|
-
static ecdsaP256PublicKeySize = 64;
|
|
53
|
-
getDataAndAdvance(blob, size) {
|
|
54
|
-
const buf = buffer_1.Buffer.from(blob.data.subarray(0, size));
|
|
55
|
-
blob.data = buffer_1.Buffer.from(blob.data.subarray(size));
|
|
56
|
-
return buf;
|
|
57
|
-
}
|
|
34
|
+
class TeeParser {
|
|
58
35
|
extractRS(cert) {
|
|
59
36
|
const derSignature = Buffer.from(cert.signatureValue.valueBlock.valueHexView).toString('hex');
|
|
60
37
|
const parsedSignature = helpers_js_1.Signature.importFromDER(derSignature);
|
|
@@ -81,6 +58,53 @@ class TeeSgxParser {
|
|
|
81
58
|
signature: x509Signature,
|
|
82
59
|
};
|
|
83
60
|
}
|
|
61
|
+
getDataAndAdvance(blob, size) {
|
|
62
|
+
const buf = buffer_1.Buffer.from(blob.data.subarray(0, size));
|
|
63
|
+
blob.data = buffer_1.Buffer.from(blob.data.subarray(size));
|
|
64
|
+
return buf;
|
|
65
|
+
}
|
|
66
|
+
static determineQuoteType(quote) {
|
|
67
|
+
let type = types_js_1.QuoteType.SGX;
|
|
68
|
+
if (quote.length < 48) {
|
|
69
|
+
throw new errors_js_1.TeeQuoteParserError('data has invalid length');
|
|
70
|
+
}
|
|
71
|
+
const version = Buffer.from(quote).readUInt16LE(0);
|
|
72
|
+
if (version === 4) {
|
|
73
|
+
const quoteType = Buffer.from(quote).readUInt32LE(4);
|
|
74
|
+
if (quoteType === 0x00000081) {
|
|
75
|
+
type = types_js_1.QuoteType.TDX;
|
|
76
|
+
}
|
|
77
|
+
else if (quoteType !== 0x00000000) {
|
|
78
|
+
throw new errors_js_1.TeeQuoteParserError(`Unknown quote type ${quoteType}`);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
else if (version !== 3) {
|
|
82
|
+
throw new errors_js_1.TeeQuoteParserError(`Unknown quote version ${version}`);
|
|
83
|
+
}
|
|
84
|
+
return { type, version };
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
exports.TeeParser = TeeParser;
|
|
88
|
+
class TeeSgxParser extends TeeParser {
|
|
89
|
+
static quoteHeaderSize = 48;
|
|
90
|
+
static pceSvnOffset = 10;
|
|
91
|
+
static reportSize = 384;
|
|
92
|
+
static userDataOffset = 28;
|
|
93
|
+
static userDataSize = 20;
|
|
94
|
+
static cpuSvnSize = 16;
|
|
95
|
+
static reportMrEnclaveOffset = 64;
|
|
96
|
+
static reportMrEnclaveSize = 32;
|
|
97
|
+
static reportMrSignerOffset = TeeSgxParser.reportMrEnclaveOffset + TeeSgxParser.reportMrEnclaveSize + /* reserved */ 32;
|
|
98
|
+
static reportMrSignerSize = 32;
|
|
99
|
+
static reportIsvProdIdOffset = TeeSgxParser.reportMrSignerOffset + TeeSgxParser.reportMrSignerSize + /* reserved */ 96;
|
|
100
|
+
static reportIsvProdIdSize = 2;
|
|
101
|
+
static reportIsvSvnOffset = TeeSgxParser.reportIsvProdIdOffset + TeeSgxParser.reportIsvProdIdSize;
|
|
102
|
+
static reportIsvSvnSize = 2;
|
|
103
|
+
static reportDataOffset = TeeSgxParser.reportIsvSvnOffset + TeeSgxParser.reportIsvSvnSize + /* reserved */ 60;
|
|
104
|
+
static reportUserDataSize = 64;
|
|
105
|
+
static reportUserDataSHA256Size = 32; /* 64 in report, but we need 32 only for sha256 hash */
|
|
106
|
+
static ecdsaP256SignatureSize = 64;
|
|
107
|
+
static ecdsaP256PublicKeySize = 64;
|
|
84
108
|
parseQuote(data) {
|
|
85
109
|
const { quoteHeaderSize, pceSvnOffset, reportSize, userDataOffset, userDataSize, ecdsaP256SignatureSize, ecdsaP256PublicKeySize, } = TeeSgxParser;
|
|
86
110
|
if (data.length < quoteHeaderSize + reportSize) {
|
|
@@ -126,6 +150,7 @@ class TeeSgxParser {
|
|
|
126
150
|
const certsPems = (0, helpers_js_1.splitChain)(qeCertificationData.toString()); // [device, platform, root]
|
|
127
151
|
const certsData = certsPems.map((pem) => this.parsePem(pem));
|
|
128
152
|
return {
|
|
153
|
+
quoteType: types_js_1.QuoteType.SGX,
|
|
129
154
|
rawHeader: quoteHeader,
|
|
130
155
|
header: {
|
|
131
156
|
version,
|
|
@@ -186,4 +211,171 @@ class TeeSgxParser {
|
|
|
186
211
|
}
|
|
187
212
|
}
|
|
188
213
|
exports.TeeSgxParser = TeeSgxParser;
|
|
189
|
-
|
|
214
|
+
class TeeTdxParser extends TeeParser {
|
|
215
|
+
//High-level quote structure
|
|
216
|
+
static quoteHeaderSize = 48;
|
|
217
|
+
static tdQuoteBodySize = 584;
|
|
218
|
+
static quoteSignatureDataLen = 4;
|
|
219
|
+
// Header fields
|
|
220
|
+
static headerVersionSize = 2;
|
|
221
|
+
static headerAttestationKeyTypeSize = 2;
|
|
222
|
+
static headerTeeTypeSize = 4;
|
|
223
|
+
static headerReserved1Size = 2;
|
|
224
|
+
static headerReserved2Size = 2;
|
|
225
|
+
static headerQeVendorIdSize = 16;
|
|
226
|
+
static headerUserDataSize = 20;
|
|
227
|
+
// Body fiedls
|
|
228
|
+
static bodyTeeTcbSvnSize = 16;
|
|
229
|
+
static bodyMrSeamSize = 48;
|
|
230
|
+
static bodyMrSignerSeamSize = 48;
|
|
231
|
+
static bodySeamAttributesSize = 8;
|
|
232
|
+
static bodyTdAttributesSize = 8;
|
|
233
|
+
static bodyXfamSize = 8;
|
|
234
|
+
static bodyMrTdSize = 48;
|
|
235
|
+
static bodyMrConfigIdSize = 48;
|
|
236
|
+
static bodyMrOwnerSize = 48;
|
|
237
|
+
static bodyMrOwnerConfigSize = 48;
|
|
238
|
+
static bodyRtmr0Size = 48;
|
|
239
|
+
static bodyRtmr1Size = 48;
|
|
240
|
+
static bodyRtmr2Size = 48;
|
|
241
|
+
static bodyRtmr3Size = 48;
|
|
242
|
+
static bodyReportDataSize = 64;
|
|
243
|
+
// Signature fields
|
|
244
|
+
static sigQuoteSignatureSize = 64;
|
|
245
|
+
static sigAttestationKeySize = 64;
|
|
246
|
+
static sigCertDataTypeSize = 2;
|
|
247
|
+
static sigCertDataSzSize = 4;
|
|
248
|
+
static sigQeReportSize = 384;
|
|
249
|
+
static sigQeReportSignatureSize = 64;
|
|
250
|
+
static sigQeAuthenticationDataSzSize = 2;
|
|
251
|
+
static sigSignatureTypeSize = 2;
|
|
252
|
+
static sigSignatureSzSize = 4;
|
|
253
|
+
parseQuote(data) {
|
|
254
|
+
const { quoteHeaderSize, tdQuoteBodySize, quoteSignatureDataLen, sigQuoteSignatureSize, sigAttestationKeySize, sigCertDataTypeSize, sigCertDataSzSize, sigQeReportSize, sigQeReportSignatureSize, sigQeAuthenticationDataSzSize, sigSignatureTypeSize, sigSignatureSzSize, } = TeeTdxParser;
|
|
255
|
+
const expectedSize = quoteHeaderSize + tdQuoteBodySize + quoteSignatureDataLen;
|
|
256
|
+
if (data.length < expectedSize) {
|
|
257
|
+
throw new errors_js_1.TeeQuoteParserError(`quote has invalid length ${data.length}, expected not less than ${expectedSize}`);
|
|
258
|
+
}
|
|
259
|
+
const quoteRemainder = { data: buffer_1.Buffer.from(data) };
|
|
260
|
+
const rawHeader = this.getDataAndAdvance(quoteRemainder, quoteHeaderSize);
|
|
261
|
+
const tdQuoteBody = this.getDataAndAdvance(quoteRemainder, tdQuoteBodySize);
|
|
262
|
+
const signatureLen = this.getDataAndAdvance(quoteRemainder, quoteSignatureDataLen);
|
|
263
|
+
const certificationDataSize = signatureLen.readUInt32LE(0);
|
|
264
|
+
const expectedQuoteLen = quoteHeaderSize + tdQuoteBodySize + quoteSignatureDataLen + certificationDataSize;
|
|
265
|
+
if (data.length < expectedQuoteLen) {
|
|
266
|
+
throw new errors_js_1.TeeQuoteParserError(`quote has invalid length ${data.length}, expected not less than ${expectedQuoteLen}`);
|
|
267
|
+
}
|
|
268
|
+
const signature = { data: this.getDataAndAdvance(quoteRemainder, certificationDataSize) };
|
|
269
|
+
const quoteSignature = this.getDataAndAdvance(signature, sigQuoteSignatureSize);
|
|
270
|
+
const ecdsaAttestationKey = this.getDataAndAdvance(signature, sigAttestationKeySize);
|
|
271
|
+
const certDataType = this.getDataAndAdvance(signature, sigCertDataTypeSize).readUint16LE(); //expected 6
|
|
272
|
+
if (certDataType !== 6)
|
|
273
|
+
throw new errors_js_1.TeeQuoteParserError(`certDataType has invalid value ${certDataType}, expected 6`);
|
|
274
|
+
const certDataSize = this.getDataAndAdvance(signature, sigCertDataSzSize).readUint32LE();
|
|
275
|
+
if (signature.data.length < certDataSize)
|
|
276
|
+
throw new errors_js_1.TeeQuoteParserError(`certData has invalid length ${data.length}, expected not less than ${certDataSize}`);
|
|
277
|
+
const qeReport = this.getDataAndAdvance(signature, sigQeReportSize);
|
|
278
|
+
const qeReportSignature = this.getDataAndAdvance(signature, sigQeReportSignatureSize);
|
|
279
|
+
const qeAuthenticationDataSize = this.getDataAndAdvance(signature, sigQeAuthenticationDataSzSize).readUint16LE();
|
|
280
|
+
if (signature.data.length < qeAuthenticationDataSize)
|
|
281
|
+
throw new errors_js_1.TeeQuoteParserError(`qeAuthenticationData has invalid length ${data.length}, expected not less than ${qeAuthenticationDataSize}`);
|
|
282
|
+
const qeAuthenticationData = this.getDataAndAdvance(signature, qeAuthenticationDataSize);
|
|
283
|
+
const qeCertificationDataType = this.getDataAndAdvance(signature, sigSignatureTypeSize).readUint16LE(); //expected 5
|
|
284
|
+
if (qeCertificationDataType !== 5)
|
|
285
|
+
throw new errors_js_1.TeeQuoteParserError(`signatureType has invalid value ${qeCertificationDataType}, expected 5`);
|
|
286
|
+
const signatureSize = this.getDataAndAdvance(signature, sigSignatureSzSize).readUint32LE();
|
|
287
|
+
if (signature.data.length < signatureSize)
|
|
288
|
+
throw new errors_js_1.TeeQuoteParserError(`certChain has invalid length ${data.length}, expected not less than ${signatureSize}`);
|
|
289
|
+
const qeCertificationData = this.getDataAndAdvance(signature, signatureSize);
|
|
290
|
+
const certsPems = (0, helpers_js_1.splitChain)(qeCertificationData.toString()); // [device, platform, root]
|
|
291
|
+
const certsData = certsPems.map((pem) => this.parsePem(pem));
|
|
292
|
+
return {
|
|
293
|
+
quoteType: types_js_1.QuoteType.TDX,
|
|
294
|
+
rawHeader,
|
|
295
|
+
header: this.parseHeader(rawHeader),
|
|
296
|
+
tdQuoteBody,
|
|
297
|
+
quoteSignature,
|
|
298
|
+
ecdsaAttestationKey,
|
|
299
|
+
certDataType,
|
|
300
|
+
qeReport,
|
|
301
|
+
qeReportSignature,
|
|
302
|
+
qeAuthenticationData,
|
|
303
|
+
qeCertificationDataType,
|
|
304
|
+
qeCertificationData,
|
|
305
|
+
certificates: {
|
|
306
|
+
device: {
|
|
307
|
+
pem: certsPems[0],
|
|
308
|
+
x509Data: certsData[0],
|
|
309
|
+
},
|
|
310
|
+
platform: {
|
|
311
|
+
pem: certsPems[1],
|
|
312
|
+
x509Data: certsData[1],
|
|
313
|
+
},
|
|
314
|
+
root: {
|
|
315
|
+
pem: certsPems[2],
|
|
316
|
+
x509Data: certsData[2],
|
|
317
|
+
},
|
|
318
|
+
},
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
parseHeader(data) {
|
|
322
|
+
const { headerVersionSize, headerAttestationKeyTypeSize, headerTeeTypeSize, headerReserved1Size, headerReserved2Size, headerQeVendorIdSize, headerUserDataSize, } = TeeTdxParser;
|
|
323
|
+
const headerRemainder = { data: buffer_1.Buffer.from(data) };
|
|
324
|
+
const version = this.getDataAndAdvance(headerRemainder, headerVersionSize).readUInt16LE();
|
|
325
|
+
const attestationKeyType = this.getDataAndAdvance(headerRemainder, headerAttestationKeyTypeSize).readUInt16LE();
|
|
326
|
+
const teeType = this.getDataAndAdvance(headerRemainder, headerTeeTypeSize).readUInt32LE();
|
|
327
|
+
const reserved1 = this.getDataAndAdvance(headerRemainder, headerReserved1Size);
|
|
328
|
+
const reserved2 = this.getDataAndAdvance(headerRemainder, headerReserved2Size);
|
|
329
|
+
const qeVendorId = this.getDataAndAdvance(headerRemainder, headerQeVendorIdSize);
|
|
330
|
+
const userData = this.getDataAndAdvance(headerRemainder, headerUserDataSize);
|
|
331
|
+
return {
|
|
332
|
+
version,
|
|
333
|
+
attestationKeyType,
|
|
334
|
+
teeType,
|
|
335
|
+
reserved1,
|
|
336
|
+
reserved2,
|
|
337
|
+
qeVendorId,
|
|
338
|
+
userData,
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
parseBody(data) {
|
|
342
|
+
const { bodyTeeTcbSvnSize, bodyMrSeamSize, bodyMrSignerSeamSize, bodySeamAttributesSize, bodyTdAttributesSize, bodyXfamSize, bodyMrTdSize, bodyMrConfigIdSize, bodyMrOwnerSize, bodyMrOwnerConfigSize, bodyRtmr0Size, bodyRtmr1Size, bodyRtmr2Size, bodyRtmr3Size, bodyReportDataSize, } = TeeTdxParser;
|
|
343
|
+
const bodyRemainder = { data: buffer_1.Buffer.from(data) };
|
|
344
|
+
if (bodyRemainder.data.length !== TeeTdxParser.tdQuoteBodySize)
|
|
345
|
+
throw new errors_js_1.TeeQuoteParserError(`body has invalid length ${bodyRemainder.data.length}, expected ${TeeTdxParser.tdQuoteBodySize}`);
|
|
346
|
+
const teeTcbSvn = this.getDataAndAdvance(bodyRemainder, bodyTeeTcbSvnSize);
|
|
347
|
+
const mrSeam = this.getDataAndAdvance(bodyRemainder, bodyMrSeamSize);
|
|
348
|
+
const mrSignerSeam = this.getDataAndAdvance(bodyRemainder, bodyMrSignerSeamSize);
|
|
349
|
+
const seamAttributes = this.getDataAndAdvance(bodyRemainder, bodySeamAttributesSize);
|
|
350
|
+
const tdAttributes = this.getDataAndAdvance(bodyRemainder, bodyTdAttributesSize);
|
|
351
|
+
const xfam = this.getDataAndAdvance(bodyRemainder, bodyXfamSize);
|
|
352
|
+
const mrTd = this.getDataAndAdvance(bodyRemainder, bodyMrTdSize);
|
|
353
|
+
const mrConfigId = this.getDataAndAdvance(bodyRemainder, bodyMrConfigIdSize);
|
|
354
|
+
const mrOwner = this.getDataAndAdvance(bodyRemainder, bodyMrOwnerSize);
|
|
355
|
+
const mrOwnerConfig = this.getDataAndAdvance(bodyRemainder, bodyMrOwnerConfigSize);
|
|
356
|
+
const rtmr0 = this.getDataAndAdvance(bodyRemainder, bodyRtmr0Size);
|
|
357
|
+
const rtmr1 = this.getDataAndAdvance(bodyRemainder, bodyRtmr1Size);
|
|
358
|
+
const rtmr2 = this.getDataAndAdvance(bodyRemainder, bodyRtmr2Size);
|
|
359
|
+
const rtmr3 = this.getDataAndAdvance(bodyRemainder, bodyRtmr3Size);
|
|
360
|
+
const reportData = this.getDataAndAdvance(bodyRemainder, bodyReportDataSize);
|
|
361
|
+
return {
|
|
362
|
+
teeTcbSvn,
|
|
363
|
+
mrSeam,
|
|
364
|
+
mrSignerSeam,
|
|
365
|
+
seamAttributes,
|
|
366
|
+
tdAttributes,
|
|
367
|
+
xfam,
|
|
368
|
+
mrTd,
|
|
369
|
+
mrConfigId,
|
|
370
|
+
mrOwner,
|
|
371
|
+
mrOwnerConfig,
|
|
372
|
+
rtmr0,
|
|
373
|
+
rtmr1,
|
|
374
|
+
rtmr2,
|
|
375
|
+
rtmr3,
|
|
376
|
+
reportData,
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
exports.TeeTdxParser = TeeTdxParser;
|
|
381
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUXVvdGVQYXJzZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvdGVlL1F1b3RlUGFyc2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEscUNBQXlDO0FBQ3pDLCtDQUFpQztBQUNqQyw2Q0FBK0I7QUFDL0IsbUNBQXdDO0FBQ3hDLDJDQUFrRDtBQUNsRCx5Q0FTb0I7QUFDcEIsNkNBQXFEO0FBRXJELE1BQXNCLFNBQVM7SUFDbkIsU0FBUyxDQUFDLElBQXVCO1FBQ3pDLE1BQU0sWUFBWSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxVQUFVLENBQUMsWUFBWSxDQUFDLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzlGLE1BQU0sZUFBZSxHQUFHLHNCQUFTLENBQUMsYUFBYSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBRTlELE9BQU87WUFDTCxDQUFDLEVBQUUsZUFBZSxDQUFDLENBQUM7WUFDcEIsQ0FBQyxFQUFFLGVBQWUsQ0FBQyxDQUFDO1lBQ3BCLFlBQVk7U0FDYixDQUFDO0lBQ0osQ0FBQztJQUVTLFFBQVEsQ0FBQyxHQUFXO1FBQzVCLE1BQU0sSUFBSSxHQUFHLGtCQUFXLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUNuRCxNQUFNLGVBQWUsR0FBRyxNQUFNLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNqRCxNQUFNLFdBQVcsR0FBRyxJQUFJLEtBQUssQ0FBQyxXQUFXLENBQUMsRUFBRSxNQUFNLEVBQUUsZUFBZSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUM7UUFFOUUsTUFBTSxHQUFHLEdBQUcsV0FBVyxDQUFDLE9BQU8sQ0FBQztRQUVoQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxHQUFHLElBQUksQ0FBQyxT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
|