dcap-qvl 0.1.2__cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl → 0.3.2__cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
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.
Potentially problematic release.
This version of dcap-qvl might be problematic. Click here for more details.
- dcap_qvl/__init__.py +141 -4
- dcap_qvl/__init__.pyi +355 -0
- dcap_qvl/dcap_qvl.abi3.so +0 -0
- dcap_qvl-0.3.2.dist-info/METADATA +389 -0
- dcap_qvl-0.3.2.dist-info/RECORD +6 -0
- {dcap_qvl-0.1.2.dist-info → dcap_qvl-0.3.2.dist-info}/WHEEL +1 -1
- dcap_qvl-0.1.2.dist-info/METADATA +0 -75
- dcap_qvl-0.1.2.dist-info/RECORD +0 -6
- dcap_qvl-0.1.2.dist-info/licenses/LICENSE +0 -21
dcap_qvl/__init__.py
CHANGED
|
@@ -1,5 +1,142 @@
|
|
|
1
|
-
|
|
1
|
+
"""
|
|
2
|
+
DCAP Quote Verification Library
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
This package provides Python bindings for the DCAP (Data Center Attestation Primitives)
|
|
5
|
+
quote verification library implemented in Rust.
|
|
6
|
+
|
|
7
|
+
Main classes:
|
|
8
|
+
- QuoteCollateralV3: Represents quote collateral data
|
|
9
|
+
- VerifiedReport: Contains verification results
|
|
10
|
+
|
|
11
|
+
Main functions:
|
|
12
|
+
- verify: Verify a quote with collateral data
|
|
13
|
+
- get_collateral: Get collateral from PCCS URL
|
|
14
|
+
- get_collateral_from_pcs: Get collateral from Intel PCS
|
|
15
|
+
- get_collateral_and_verify: Get collateral and verify quote
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
import time
|
|
19
|
+
import json
|
|
20
|
+
from typing import Optional, Union
|
|
21
|
+
|
|
22
|
+
try:
|
|
23
|
+
import requests
|
|
24
|
+
except ImportError:
|
|
25
|
+
requests = None
|
|
26
|
+
|
|
27
|
+
from .dcap_qvl import (
|
|
28
|
+
PyQuoteCollateralV3 as QuoteCollateralV3,
|
|
29
|
+
PyVerifiedReport as VerifiedReport,
|
|
30
|
+
PyQuote as Quote,
|
|
31
|
+
py_verify as verify,
|
|
32
|
+
parse_quote,
|
|
33
|
+
get_collateral_for_fmspc,
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
# Default Intel PCS URL
|
|
37
|
+
PCS_URL = "https://api.trustedservices.intel.com"
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
# Note: These functions are now implemented in Rust and imported above
|
|
41
|
+
# The manual parsing logic has been replaced with proper Rust-based parsing
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def _make_pcs_request(url: str) -> bytes:
|
|
45
|
+
"""Make HTTP request to PCS endpoint."""
|
|
46
|
+
if requests is None:
|
|
47
|
+
raise ImportError(
|
|
48
|
+
"requests library is required for collateral fetching. Install with: pip install requests")
|
|
49
|
+
|
|
50
|
+
try:
|
|
51
|
+
response = requests.get(url, timeout=30, verify=False)
|
|
52
|
+
response.raise_for_status()
|
|
53
|
+
return response.content
|
|
54
|
+
except requests.RequestException as e:
|
|
55
|
+
raise RuntimeError(f"Failed to fetch from {url}: {e}")
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
async def get_collateral(pccs_url: str, raw_quote: bytes) -> QuoteCollateralV3:
|
|
59
|
+
"""Get collateral from PCCS URL.
|
|
60
|
+
|
|
61
|
+
Args:
|
|
62
|
+
pccs_url: PCCS server URL
|
|
63
|
+
raw_quote: Raw quote bytes
|
|
64
|
+
|
|
65
|
+
Returns:
|
|
66
|
+
QuoteCollateralV3: Quote collateral data
|
|
67
|
+
|
|
68
|
+
Raises:
|
|
69
|
+
ValueError: If quote is invalid or FMSPC cannot be extracted
|
|
70
|
+
RuntimeError: If network request fails
|
|
71
|
+
ImportError: If requests library is not available
|
|
72
|
+
"""
|
|
73
|
+
if not isinstance(raw_quote, (bytes, bytearray)):
|
|
74
|
+
raise TypeError("raw_quote must be bytes")
|
|
75
|
+
|
|
76
|
+
quote = Quote.parse(raw_quote)
|
|
77
|
+
fmspc = quote.fmspc()
|
|
78
|
+
is_sgx = quote.is_sgx()
|
|
79
|
+
ca = quote.ca()
|
|
80
|
+
return await get_collateral_for_fmspc(pccs_url, fmspc, ca, is_sgx)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
async def get_collateral_from_pcs(raw_quote: bytes) -> QuoteCollateralV3:
|
|
84
|
+
"""Get collateral from Intel PCS.
|
|
85
|
+
|
|
86
|
+
Args:
|
|
87
|
+
raw_quote: Raw quote bytes
|
|
88
|
+
|
|
89
|
+
Returns:
|
|
90
|
+
QuoteCollateralV3: Quote collateral data
|
|
91
|
+
|
|
92
|
+
Raises:
|
|
93
|
+
ValueError: If quote is invalid or FMSPC cannot be extracted
|
|
94
|
+
RuntimeError: If network request fails
|
|
95
|
+
ImportError: If requests library is not available
|
|
96
|
+
"""
|
|
97
|
+
return await get_collateral(PCS_URL, raw_quote)
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
async def get_collateral_and_verify(raw_quote: bytes, pccs_url: Optional[str] = None) -> VerifiedReport:
|
|
101
|
+
"""Get collateral and verify the quote.
|
|
102
|
+
|
|
103
|
+
Args:
|
|
104
|
+
raw_quote: Raw quote bytes
|
|
105
|
+
pccs_url: Optional PCCS URL (defaults to Intel PCS)
|
|
106
|
+
|
|
107
|
+
Returns:
|
|
108
|
+
VerifiedReport: Verification result
|
|
109
|
+
|
|
110
|
+
Raises:
|
|
111
|
+
ValueError: If quote is invalid or verification fails
|
|
112
|
+
RuntimeError: If network request fails
|
|
113
|
+
ImportError: If requests library is not available
|
|
114
|
+
"""
|
|
115
|
+
# Use provided PCCS URL or default to Intel PCS
|
|
116
|
+
url = pccs_url.strip() if pccs_url else PCS_URL
|
|
117
|
+
if not url:
|
|
118
|
+
url = PCS_URL
|
|
119
|
+
|
|
120
|
+
# Get collateral
|
|
121
|
+
collateral = await get_collateral(url, raw_quote)
|
|
122
|
+
|
|
123
|
+
# Get current time
|
|
124
|
+
now_secs = int(time.time())
|
|
125
|
+
|
|
126
|
+
print("Collateral:", collateral.to_json())
|
|
127
|
+
# Verify quote
|
|
128
|
+
return verify(raw_quote, collateral, now_secs)
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
__all__ = [
|
|
132
|
+
"QuoteCollateralV3",
|
|
133
|
+
"VerifiedReport",
|
|
134
|
+
"Quote",
|
|
135
|
+
"verify",
|
|
136
|
+
"get_collateral",
|
|
137
|
+
"get_collateral_from_pcs",
|
|
138
|
+
"get_collateral_and_verify",
|
|
139
|
+
"get_collateral_for_fmspc",
|
|
140
|
+
]
|
|
141
|
+
|
|
142
|
+
__version__ = "0.3.2"
|
dcap_qvl/__init__.pyi
ADDED
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Type stubs for dcap_qvl Python bindings.
|
|
3
|
+
|
|
4
|
+
This file provides type hints for the compiled Rust extension, enabling better
|
|
5
|
+
IDE support, type checking with mypy, and improved developer experience.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from typing import List
|
|
9
|
+
|
|
10
|
+
__version__: str
|
|
11
|
+
__all__: List[str]
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class QuoteCollateralV3:
|
|
15
|
+
"""
|
|
16
|
+
Represents quote collateral data required for DCAP quote verification.
|
|
17
|
+
|
|
18
|
+
This class contains all the necessary certificate chains, CRLs, and
|
|
19
|
+
attestation information needed to verify an SGX or TDX quote.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
def __init__(
|
|
23
|
+
self,
|
|
24
|
+
pck_crl_issuer_chain: str,
|
|
25
|
+
root_ca_crl: bytes,
|
|
26
|
+
pck_crl: bytes,
|
|
27
|
+
tcb_info_issuer_chain: str,
|
|
28
|
+
tcb_info: str,
|
|
29
|
+
tcb_info_signature: bytes,
|
|
30
|
+
qe_identity_issuer_chain: str,
|
|
31
|
+
qe_identity: str,
|
|
32
|
+
qe_identity_signature: bytes,
|
|
33
|
+
) -> None:
|
|
34
|
+
"""
|
|
35
|
+
Create a new QuoteCollateralV3 instance.
|
|
36
|
+
|
|
37
|
+
Args:
|
|
38
|
+
pck_crl_issuer_chain: PCK CRL issuer certificate chain (PEM format)
|
|
39
|
+
root_ca_crl: Root CA certificate revocation list
|
|
40
|
+
pck_crl: PCK certificate revocation list
|
|
41
|
+
tcb_info_issuer_chain: TCB info issuer certificate chain (PEM format)
|
|
42
|
+
tcb_info: TCB (Trusted Computing Base) information (JSON string)
|
|
43
|
+
tcb_info_signature: Signature for the TCB info
|
|
44
|
+
qe_identity_issuer_chain: QE identity issuer certificate chain (PEM format)
|
|
45
|
+
qe_identity: Quoting Enclave identity information (JSON string)
|
|
46
|
+
qe_identity_signature: Signature for the QE identity
|
|
47
|
+
"""
|
|
48
|
+
...
|
|
49
|
+
|
|
50
|
+
@property
|
|
51
|
+
def pck_crl_issuer_chain(self) -> str:
|
|
52
|
+
"""PCK CRL issuer certificate chain in PEM format."""
|
|
53
|
+
...
|
|
54
|
+
|
|
55
|
+
@property
|
|
56
|
+
def root_ca_crl(self) -> bytes:
|
|
57
|
+
"""Root CA certificate revocation list."""
|
|
58
|
+
...
|
|
59
|
+
|
|
60
|
+
@property
|
|
61
|
+
def pck_crl(self) -> bytes:
|
|
62
|
+
"""PCK certificate revocation list."""
|
|
63
|
+
...
|
|
64
|
+
|
|
65
|
+
@property
|
|
66
|
+
def tcb_info_issuer_chain(self) -> str:
|
|
67
|
+
"""TCB info issuer certificate chain in PEM format."""
|
|
68
|
+
...
|
|
69
|
+
|
|
70
|
+
@property
|
|
71
|
+
def tcb_info(self) -> str:
|
|
72
|
+
"""TCB (Trusted Computing Base) information as JSON string."""
|
|
73
|
+
...
|
|
74
|
+
|
|
75
|
+
@property
|
|
76
|
+
def tcb_info_signature(self) -> bytes:
|
|
77
|
+
"""Signature for the TCB info."""
|
|
78
|
+
...
|
|
79
|
+
|
|
80
|
+
@property
|
|
81
|
+
def qe_identity_issuer_chain(self) -> str:
|
|
82
|
+
"""QE identity issuer certificate chain in PEM format."""
|
|
83
|
+
...
|
|
84
|
+
|
|
85
|
+
@property
|
|
86
|
+
def qe_identity(self) -> str:
|
|
87
|
+
"""Quoting Enclave identity information as JSON string."""
|
|
88
|
+
...
|
|
89
|
+
|
|
90
|
+
@property
|
|
91
|
+
def qe_identity_signature(self) -> bytes:
|
|
92
|
+
"""Signature for the QE identity."""
|
|
93
|
+
...
|
|
94
|
+
|
|
95
|
+
def to_json(self) -> str:
|
|
96
|
+
"""
|
|
97
|
+
Serialize the collateral to a JSON string.
|
|
98
|
+
|
|
99
|
+
Returns:
|
|
100
|
+
JSON string representation of the collateral data
|
|
101
|
+
|
|
102
|
+
Raises:
|
|
103
|
+
ValueError: If serialization fails
|
|
104
|
+
"""
|
|
105
|
+
...
|
|
106
|
+
|
|
107
|
+
@staticmethod
|
|
108
|
+
def from_json(json_str: str) -> "QuoteCollateralV3":
|
|
109
|
+
"""
|
|
110
|
+
Create a QuoteCollateralV3 instance from a JSON string.
|
|
111
|
+
|
|
112
|
+
Args:
|
|
113
|
+
json_str: JSON string containing collateral data
|
|
114
|
+
|
|
115
|
+
Returns:
|
|
116
|
+
New QuoteCollateralV3 instance
|
|
117
|
+
|
|
118
|
+
Raises:
|
|
119
|
+
ValueError: If JSON parsing fails or data is invalid
|
|
120
|
+
"""
|
|
121
|
+
...
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
class VerifiedReport:
|
|
125
|
+
"""
|
|
126
|
+
Contains the results of DCAP quote verification.
|
|
127
|
+
|
|
128
|
+
This class holds the verification status and any security advisories
|
|
129
|
+
that were found during the quote verification process.
|
|
130
|
+
"""
|
|
131
|
+
|
|
132
|
+
@property
|
|
133
|
+
def status(self) -> str:
|
|
134
|
+
"""
|
|
135
|
+
Verification status string.
|
|
136
|
+
|
|
137
|
+
Common values include:
|
|
138
|
+
- "OK": Verification successful, no issues
|
|
139
|
+
- "SW_HARDENING_NEEDED": Software hardening recommended
|
|
140
|
+
- "CONFIGURATION_NEEDED": Platform configuration required
|
|
141
|
+
- "OUT_OF_DATE": TCB is out of date
|
|
142
|
+
- "REVOKED": Certificate or key has been revoked
|
|
143
|
+
"""
|
|
144
|
+
...
|
|
145
|
+
|
|
146
|
+
@property
|
|
147
|
+
def advisory_ids(self) -> List[str]:
|
|
148
|
+
"""
|
|
149
|
+
List of security advisory IDs that apply to this quote.
|
|
150
|
+
|
|
151
|
+
These are Intel security advisory identifiers (e.g., "INTEL-SA-00334")
|
|
152
|
+
that indicate known security issues affecting the attested platform.
|
|
153
|
+
"""
|
|
154
|
+
...
|
|
155
|
+
|
|
156
|
+
def to_json(self) -> str:
|
|
157
|
+
"""
|
|
158
|
+
Serialize the verification report to a JSON string.
|
|
159
|
+
|
|
160
|
+
Returns:
|
|
161
|
+
JSON string representation of the verification report
|
|
162
|
+
|
|
163
|
+
Raises:
|
|
164
|
+
ValueError: If serialization fails
|
|
165
|
+
"""
|
|
166
|
+
...
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
class Quote:
|
|
170
|
+
"""
|
|
171
|
+
Represents a parsed SGX or TDX quote.
|
|
172
|
+
|
|
173
|
+
This class provides access to quote metadata and identifiers
|
|
174
|
+
without requiring collateral data for verification.
|
|
175
|
+
"""
|
|
176
|
+
|
|
177
|
+
@staticmethod
|
|
178
|
+
def parse(raw_quote: bytes) -> "Quote":
|
|
179
|
+
"""
|
|
180
|
+
Parse a raw quote from bytes.
|
|
181
|
+
|
|
182
|
+
Args:
|
|
183
|
+
raw_quote: Raw quote data as bytes (SGX or TDX format)
|
|
184
|
+
|
|
185
|
+
Returns:
|
|
186
|
+
Quote instance with parsed quote data
|
|
187
|
+
|
|
188
|
+
Raises:
|
|
189
|
+
ValueError: If quote parsing fails due to invalid format or corrupted data
|
|
190
|
+
|
|
191
|
+
Example:
|
|
192
|
+
>>> import dcap_qvl
|
|
193
|
+
>>>
|
|
194
|
+
>>> with open("quote.bin", "rb") as f:
|
|
195
|
+
... quote_data = f.read()
|
|
196
|
+
>>>
|
|
197
|
+
>>> quote = dcap_qvl.Quote.parse(quote_data)
|
|
198
|
+
>>> print(f"Quote type: {quote.quote_type()}")
|
|
199
|
+
>>> print(f"FMSPC: {quote.fmspc()}")
|
|
200
|
+
"""
|
|
201
|
+
...
|
|
202
|
+
|
|
203
|
+
def fmspc(self) -> str:
|
|
204
|
+
"""
|
|
205
|
+
Extract the FMSPC (Family-Model-Stepping-Platform-CustomSKU) identifier.
|
|
206
|
+
|
|
207
|
+
The FMSPC is a 6-byte identifier that uniquely identifies the
|
|
208
|
+
platform's TCB level and is used for collateral retrieval.
|
|
209
|
+
|
|
210
|
+
Returns:
|
|
211
|
+
FMSPC as uppercase hexadecimal string (12 characters)
|
|
212
|
+
|
|
213
|
+
Raises:
|
|
214
|
+
ValueError: If FMSPC cannot be extracted from the quote
|
|
215
|
+
|
|
216
|
+
Example:
|
|
217
|
+
>>> quote = dcap_qvl.Quote.parse(quote_data)
|
|
218
|
+
>>> fmspc = quote.fmspc()
|
|
219
|
+
>>> print(f"FMSPC: {fmspc}") # e.g., "00606A000000"
|
|
220
|
+
"""
|
|
221
|
+
...
|
|
222
|
+
|
|
223
|
+
def ca(self) -> str:
|
|
224
|
+
"""
|
|
225
|
+
Extract the CA (Certificate Authority) identifier.
|
|
226
|
+
|
|
227
|
+
The CA identifier indicates which certificate authority
|
|
228
|
+
should be used for quote verification.
|
|
229
|
+
|
|
230
|
+
Returns:
|
|
231
|
+
CA identifier as string
|
|
232
|
+
|
|
233
|
+
Raises:
|
|
234
|
+
ValueError: If CA identifier cannot be extracted from the quote
|
|
235
|
+
"""
|
|
236
|
+
...
|
|
237
|
+
|
|
238
|
+
def is_tdx(self) -> bool:
|
|
239
|
+
"""
|
|
240
|
+
Check if this is a TDX (Trust Domain Extensions) quote.
|
|
241
|
+
|
|
242
|
+
Returns:
|
|
243
|
+
True if the quote is TDX format, False if SGX format
|
|
244
|
+
|
|
245
|
+
Example:
|
|
246
|
+
>>> quote = dcap_qvl.Quote.parse(quote_data)
|
|
247
|
+
>>> if quote.is_tdx():
|
|
248
|
+
... print("This is a TDX quote")
|
|
249
|
+
... else:
|
|
250
|
+
... print("This is an SGX quote")
|
|
251
|
+
"""
|
|
252
|
+
...
|
|
253
|
+
|
|
254
|
+
def is_sgx(self) -> bool:
|
|
255
|
+
"""
|
|
256
|
+
Check if this is an SGX quote.
|
|
257
|
+
|
|
258
|
+
Returns:
|
|
259
|
+
True if the quote is SGX format, False if TDX format
|
|
260
|
+
|
|
261
|
+
Example:
|
|
262
|
+
>>> quote = dcap_qvl.Quote.parse(quote_data)
|
|
263
|
+
>>> if quote.is_sgx():
|
|
264
|
+
... print("This is an SGX quote")
|
|
265
|
+
... else:
|
|
266
|
+
... print("This is a TDX quote")
|
|
267
|
+
"""
|
|
268
|
+
...
|
|
269
|
+
|
|
270
|
+
def quote_type(self) -> str:
|
|
271
|
+
"""
|
|
272
|
+
Get the quote type as a string.
|
|
273
|
+
|
|
274
|
+
Returns:
|
|
275
|
+
"TDX" for TDX quotes, "SGX" for SGX quotes
|
|
276
|
+
|
|
277
|
+
Example:
|
|
278
|
+
>>> quote = dcap_qvl.Quote.parse(quote_data)
|
|
279
|
+
>>> print(f"Quote type: {quote.quote_type()}")
|
|
280
|
+
"""
|
|
281
|
+
...
|
|
282
|
+
|
|
283
|
+
# Synchronous functions
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
def verify(
|
|
287
|
+
raw_quote: bytes,
|
|
288
|
+
collateral: QuoteCollateralV3,
|
|
289
|
+
now_secs: int
|
|
290
|
+
) -> VerifiedReport:
|
|
291
|
+
"""
|
|
292
|
+
Verify an SGX or TDX quote with the provided collateral data.
|
|
293
|
+
|
|
294
|
+
This function performs cryptographic verification of the quote against
|
|
295
|
+
the provided collateral information, checking certificates, signatures,
|
|
296
|
+
and revocation status.
|
|
297
|
+
|
|
298
|
+
Args:
|
|
299
|
+
raw_quote: Raw quote data as bytes (SGX or TDX format)
|
|
300
|
+
collateral: Quote collateral containing certificates and attestation data
|
|
301
|
+
now_secs: Current timestamp in seconds since Unix epoch for time-based checks
|
|
302
|
+
|
|
303
|
+
Returns:
|
|
304
|
+
VerifiedReport containing verification status and advisory information
|
|
305
|
+
|
|
306
|
+
Raises:
|
|
307
|
+
ValueError: If verification fails due to invalid data, expired certificates,
|
|
308
|
+
revoked keys, or other verification errors
|
|
309
|
+
|
|
310
|
+
Example:
|
|
311
|
+
>>> import dcap_qvl
|
|
312
|
+
>>> import time
|
|
313
|
+
>>>
|
|
314
|
+
>>> # Load quote and collateral data
|
|
315
|
+
>>> with open("quote.bin", "rb") as f:
|
|
316
|
+
... quote_data = f.read()
|
|
317
|
+
>>>
|
|
318
|
+
>>> collateral = dcap_qvl.QuoteCollateralV3.from_json(collateral_json)
|
|
319
|
+
>>> result = dcap_qvl.verify(quote_data, collateral, int(time.time()))
|
|
320
|
+
>>> print(f"Status: {result.status}")
|
|
321
|
+
"""
|
|
322
|
+
...
|
|
323
|
+
|
|
324
|
+
|
|
325
|
+
def parse_quote(raw_quote: bytes) -> Quote:
|
|
326
|
+
"""
|
|
327
|
+
Parse a raw quote from bytes (convenience function).
|
|
328
|
+
|
|
329
|
+
This is a convenience function that calls Quote.parse() directly.
|
|
330
|
+
|
|
331
|
+
Args:
|
|
332
|
+
raw_quote: Raw quote data as bytes (SGX or TDX format)
|
|
333
|
+
|
|
334
|
+
Returns:
|
|
335
|
+
Quote instance with parsed quote data
|
|
336
|
+
|
|
337
|
+
Raises:
|
|
338
|
+
ValueError: If quote parsing fails due to invalid format or corrupted data
|
|
339
|
+
|
|
340
|
+
Example:
|
|
341
|
+
>>> import dcap_qvl
|
|
342
|
+
>>>
|
|
343
|
+
>>> with open("quote.bin", "rb") as f:
|
|
344
|
+
... quote_data = f.read()
|
|
345
|
+
>>>
|
|
346
|
+
>>> quote = dcap_qvl.parse_quote(quote_data)
|
|
347
|
+
>>> print(f"Quote type: {quote.quote_type()}")
|
|
348
|
+
>>> print(f"FMSPC: {quote.fmspc()}")
|
|
349
|
+
"""
|
|
350
|
+
...
|
|
351
|
+
|
|
352
|
+
|
|
353
|
+
async def get_collateral_for_fmspc(pccs_url: str, fmspc: str, ca: str, is_sgx: bool) -> QuoteCollateralV3:
|
|
354
|
+
"""Get collateral for a specific FMSPC from PCCS URL."""
|
|
355
|
+
...
|
dcap_qvl/dcap_qvl.abi3.so
CHANGED
|
Binary file
|
|
@@ -0,0 +1,389 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: dcap-qvl
|
|
3
|
+
Version: 0.3.2
|
|
4
|
+
Classifier: Development Status :: 4 - Beta
|
|
5
|
+
Classifier: Intended Audience :: Developers
|
|
6
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
13
|
+
Classifier: Programming Language :: Rust
|
|
14
|
+
Classifier: Topic :: Security :: Cryptography
|
|
15
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
16
|
+
Summary: Python bindings for DCAP (Data Center Attestation Primitives) quote verification library
|
|
17
|
+
Keywords: sgx,tdx,dcap,attestation,verification,cryptography
|
|
18
|
+
Author-email: Kevin Wang <wy721@qq.com>
|
|
19
|
+
License: MIT
|
|
20
|
+
Requires-Python: >=3.8
|
|
21
|
+
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
22
|
+
Project-URL: Homepage, https://github.com/Phala-Network/dcap-qvl
|
|
23
|
+
Project-URL: Repository, https://github.com/Phala-Network/dcap-qvl
|
|
24
|
+
Project-URL: Issues, https://github.com/Phala-Network/dcap-qvl/issues
|
|
25
|
+
|
|
26
|
+
# Python Bindings for DCAP-QVL
|
|
27
|
+
|
|
28
|
+
This package provides Python bindings for the DCAP (Data Center Attestation Primitives) quote verification library implemented in Rust.
|
|
29
|
+
|
|
30
|
+
## Quick Start
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
# Install from PyPI
|
|
34
|
+
pip install dcap-qvl
|
|
35
|
+
|
|
36
|
+
# Basic usage
|
|
37
|
+
python -c "
|
|
38
|
+
import dcap_qvl
|
|
39
|
+
print('DCAP-QVL Python bindings successfully installed!')
|
|
40
|
+
print(f'Available functions: {dcap_qvl.__all__}')
|
|
41
|
+
"
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Features
|
|
45
|
+
|
|
46
|
+
- Verify SGX and TDX quotes
|
|
47
|
+
- Handle quote collateral data
|
|
48
|
+
- Parse verification results
|
|
49
|
+
- Pure Rust implementation with Python bindings
|
|
50
|
+
- Cross-platform compatibility (Linux, macOS, Windows)
|
|
51
|
+
- Asynchronous collateral fetching from PCCS/PCS with async/await support
|
|
52
|
+
- Compatible with Python 3.8+
|
|
53
|
+
|
|
54
|
+
## Installation
|
|
55
|
+
|
|
56
|
+
### From PyPI (recommended)
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
pip install dcap-qvl
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Using uv
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
uv add dcap-qvl
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Usage
|
|
69
|
+
|
|
70
|
+
### Basic Quote Verification
|
|
71
|
+
|
|
72
|
+
```python
|
|
73
|
+
import dcap_qvl
|
|
74
|
+
import json
|
|
75
|
+
import time
|
|
76
|
+
|
|
77
|
+
# Load quote data (binary)
|
|
78
|
+
with open("path/to/quote", "rb") as f:
|
|
79
|
+
quote_data = f.read()
|
|
80
|
+
|
|
81
|
+
# Load collateral data (JSON)
|
|
82
|
+
with open("path/to/collateral.json", "r") as f:
|
|
83
|
+
collateral_json = json.load(f)
|
|
84
|
+
|
|
85
|
+
# Create collateral object
|
|
86
|
+
collateral = dcap_qvl.QuoteCollateralV3.from_json(json.dumps(collateral_json))
|
|
87
|
+
|
|
88
|
+
# Verify the quote
|
|
89
|
+
now = int(time.time())
|
|
90
|
+
try:
|
|
91
|
+
result = dcap_qvl.verify(quote_data, collateral, now)
|
|
92
|
+
print(f"Verification successful! Status: {result.status}")
|
|
93
|
+
print(f"Advisory IDs: {result.advisory_ids}")
|
|
94
|
+
except ValueError as e:
|
|
95
|
+
print(f"Verification failed: {e}")
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Working with Collateral Data
|
|
99
|
+
|
|
100
|
+
```python
|
|
101
|
+
# Create collateral manually
|
|
102
|
+
collateral = dcap_qvl.QuoteCollateralV3(
|
|
103
|
+
pck_crl_issuer_chain="...",
|
|
104
|
+
root_ca_crl=b"...", # bytes
|
|
105
|
+
pck_crl=b"...", # bytes
|
|
106
|
+
tcb_info_issuer_chain="...",
|
|
107
|
+
tcb_info="...", # JSON string
|
|
108
|
+
tcb_info_signature=b"...", # bytes
|
|
109
|
+
qe_identity_issuer_chain="...",
|
|
110
|
+
qe_identity="...", # JSON string
|
|
111
|
+
qe_identity_signature=b"...", # bytes
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
# Serialize to JSON
|
|
115
|
+
json_str = collateral.to_json()
|
|
116
|
+
|
|
117
|
+
# Deserialize from JSON
|
|
118
|
+
collateral = dcap_qvl.QuoteCollateralV3.from_json(json_str)
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## API Reference
|
|
122
|
+
|
|
123
|
+
### Async Collateral Functions
|
|
124
|
+
|
|
125
|
+
All collateral functions are asynchronous and must be awaited. They use the Rust async runtime for optimal performance.
|
|
126
|
+
|
|
127
|
+
#### `async get_collateral_for_fmspc(pccs_url: str, fmspc: str, ca: str, is_sgx: bool) -> QuoteCollateralV3`
|
|
128
|
+
|
|
129
|
+
Get collateral for a specific FMSPC directly from PCCS URL (Rust async export).
|
|
130
|
+
|
|
131
|
+
**Parameters:**
|
|
132
|
+
- `pccs_url`: PCCS URL (e.g., "https://api.trustedservices.intel.com")
|
|
133
|
+
- `fmspc`: FMSPC value as hex string (e.g., "B0C06F000000")
|
|
134
|
+
- `ca`: Certificate Authority ("processor" or "platform")
|
|
135
|
+
- `is_sgx`: True for SGX quotes, False for TDX quotes
|
|
136
|
+
|
|
137
|
+
**Returns:**
|
|
138
|
+
- `QuoteCollateralV3`: Quote collateral data
|
|
139
|
+
|
|
140
|
+
**Raises:**
|
|
141
|
+
- `ValueError`: If FMSPC is invalid or collateral cannot be retrieved
|
|
142
|
+
- `RuntimeError`: If network request fails
|
|
143
|
+
|
|
144
|
+
**Example:**
|
|
145
|
+
```python
|
|
146
|
+
import asyncio
|
|
147
|
+
import dcap_qvl
|
|
148
|
+
|
|
149
|
+
async def main():
|
|
150
|
+
collateral = await dcap_qvl.get_collateral_for_fmspc(
|
|
151
|
+
pccs_url="https://api.trustedservices.intel.com",
|
|
152
|
+
fmspc="B0C06F000000",
|
|
153
|
+
ca="processor",
|
|
154
|
+
is_sgx=True
|
|
155
|
+
)
|
|
156
|
+
print(f"Got collateral: {len(collateral.tcb_info)} chars")
|
|
157
|
+
|
|
158
|
+
asyncio.run(main())
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
#### `async get_collateral(pccs_url: str, raw_quote: bytes) -> QuoteCollateralV3`
|
|
162
|
+
|
|
163
|
+
Get collateral from a custom PCCS URL by parsing the quote.
|
|
164
|
+
|
|
165
|
+
**Parameters:**
|
|
166
|
+
- `pccs_url`: PCCS URL (e.g., "https://api.trustedservices.intel.com")
|
|
167
|
+
- `raw_quote`: Raw quote data as bytes
|
|
168
|
+
|
|
169
|
+
**Returns:**
|
|
170
|
+
- `QuoteCollateralV3`: Quote collateral data
|
|
171
|
+
|
|
172
|
+
**Raises:**
|
|
173
|
+
- `ValueError`: If quote is invalid or FMSPC cannot be extracted
|
|
174
|
+
- `RuntimeError`: If network request fails
|
|
175
|
+
|
|
176
|
+
**Example:**
|
|
177
|
+
```python
|
|
178
|
+
import asyncio
|
|
179
|
+
import dcap_qvl
|
|
180
|
+
|
|
181
|
+
async def main():
|
|
182
|
+
pccs_url = "https://api.trustedservices.intel.com"
|
|
183
|
+
quote_data = open("quote.bin", "rb").read()
|
|
184
|
+
collateral = await dcap_qvl.get_collateral(pccs_url, quote_data)
|
|
185
|
+
print(f"Got collateral: {len(collateral.tcb_info)} chars")
|
|
186
|
+
|
|
187
|
+
asyncio.run(main())
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
#### `async get_collateral_from_pcs(raw_quote: bytes) -> QuoteCollateralV3`
|
|
191
|
+
|
|
192
|
+
Get collateral from Intel's PCS (default).
|
|
193
|
+
|
|
194
|
+
**Parameters:**
|
|
195
|
+
- `raw_quote`: Raw quote data as bytes
|
|
196
|
+
|
|
197
|
+
**Returns:**
|
|
198
|
+
- `QuoteCollateralV3`: Quote collateral data
|
|
199
|
+
|
|
200
|
+
**Raises:**
|
|
201
|
+
- `ValueError`: If quote is invalid or FMSPC cannot be extracted
|
|
202
|
+
- `RuntimeError`: If network request fails
|
|
203
|
+
|
|
204
|
+
**Example:**
|
|
205
|
+
```python
|
|
206
|
+
import asyncio
|
|
207
|
+
import dcap_qvl
|
|
208
|
+
|
|
209
|
+
async def main():
|
|
210
|
+
quote_data = open("quote.bin", "rb").read()
|
|
211
|
+
collateral = await dcap_qvl.get_collateral_from_pcs(quote_data)
|
|
212
|
+
print(f"Got collateral from Intel PCS")
|
|
213
|
+
|
|
214
|
+
asyncio.run(main())
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
#### `async get_collateral_and_verify(raw_quote: bytes, pccs_url: Optional[str] = None) -> VerifiedReport`
|
|
218
|
+
|
|
219
|
+
Get collateral and verify quote in one step.
|
|
220
|
+
|
|
221
|
+
**Parameters:**
|
|
222
|
+
- `raw_quote`: Raw quote data as bytes
|
|
223
|
+
- `pccs_url`: Optional PCCS URL (uses Intel PCS if None)
|
|
224
|
+
|
|
225
|
+
**Returns:**
|
|
226
|
+
- `VerifiedReport`: Verification results
|
|
227
|
+
|
|
228
|
+
**Raises:**
|
|
229
|
+
- `ValueError`: If quote is invalid or verification fails
|
|
230
|
+
- `RuntimeError`: If network request fails
|
|
231
|
+
|
|
232
|
+
**Example:**
|
|
233
|
+
```python
|
|
234
|
+
import asyncio
|
|
235
|
+
import dcap_qvl
|
|
236
|
+
|
|
237
|
+
async def main():
|
|
238
|
+
quote_data = open("quote.bin", "rb").read()
|
|
239
|
+
result = await dcap_qvl.get_collateral_and_verify(quote_data)
|
|
240
|
+
print(f"Status: {result.status}")
|
|
241
|
+
print(f"Advisory IDs: {result.advisory_ids}")
|
|
242
|
+
|
|
243
|
+
asyncio.run(main())
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
### Classes
|
|
247
|
+
|
|
248
|
+
#### `QuoteCollateralV3`
|
|
249
|
+
|
|
250
|
+
Represents quote collateral data required for verification.
|
|
251
|
+
|
|
252
|
+
**Constructor:**
|
|
253
|
+
```python
|
|
254
|
+
QuoteCollateralV3(
|
|
255
|
+
pck_crl_issuer_chain: str,
|
|
256
|
+
root_ca_crl: bytes,
|
|
257
|
+
pck_crl: bytes,
|
|
258
|
+
tcb_info_issuer_chain: str,
|
|
259
|
+
tcb_info: str,
|
|
260
|
+
tcb_info_signature: bytes,
|
|
261
|
+
qe_identity_issuer_chain: str,
|
|
262
|
+
qe_identity: str,
|
|
263
|
+
qe_identity_signature: bytes,
|
|
264
|
+
)
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
**Methods:**
|
|
268
|
+
- `to_json() -> str`: Serialize to JSON string
|
|
269
|
+
- `from_json(json_str: str) -> QuoteCollateralV3`: Create from JSON string (static method)
|
|
270
|
+
|
|
271
|
+
**Properties:**
|
|
272
|
+
- `pck_crl_issuer_chain: str`
|
|
273
|
+
- `root_ca_crl: bytes`
|
|
274
|
+
- `pck_crl: bytes`
|
|
275
|
+
- `tcb_info_issuer_chain: str`
|
|
276
|
+
- `tcb_info: str`
|
|
277
|
+
- `tcb_info_signature: bytes`
|
|
278
|
+
- `qe_identity_issuer_chain: str`
|
|
279
|
+
- `qe_identity: str`
|
|
280
|
+
- `qe_identity_signature: bytes`
|
|
281
|
+
|
|
282
|
+
#### `VerifiedReport`
|
|
283
|
+
|
|
284
|
+
Contains the results of quote verification.
|
|
285
|
+
|
|
286
|
+
**Properties:**
|
|
287
|
+
- `status: str`: Verification status
|
|
288
|
+
- `advisory_ids: List[str]`: List of advisory IDs
|
|
289
|
+
|
|
290
|
+
**Methods:**
|
|
291
|
+
- `to_json() -> str`: Serialize to JSON string
|
|
292
|
+
|
|
293
|
+
### Functions
|
|
294
|
+
|
|
295
|
+
#### `verify(raw_quote: bytes, collateral: QuoteCollateralV3, now_secs: int) -> VerifiedReport`
|
|
296
|
+
|
|
297
|
+
Verify a quote with the provided collateral data.
|
|
298
|
+
|
|
299
|
+
**Parameters:**
|
|
300
|
+
- `raw_quote`: Raw quote data as bytes
|
|
301
|
+
- `collateral`: Quote collateral data
|
|
302
|
+
- `now_secs`: Current timestamp in seconds since Unix epoch
|
|
303
|
+
|
|
304
|
+
**Returns:**
|
|
305
|
+
- `VerifiedReport`: Verification results
|
|
306
|
+
|
|
307
|
+
**Raises:**
|
|
308
|
+
- `ValueError`: If verification fails
|
|
309
|
+
|
|
310
|
+
## Development
|
|
311
|
+
|
|
312
|
+
### Building from Source
|
|
313
|
+
|
|
314
|
+
If you want to build from source or contribute to development:
|
|
315
|
+
|
|
316
|
+
```bash
|
|
317
|
+
# Clone the repository
|
|
318
|
+
git clone https://github.com/Phala-Network/dcap-qvl.git
|
|
319
|
+
cd dcap-qvl/python-bindings
|
|
320
|
+
|
|
321
|
+
# Install development dependencies (including maturin)
|
|
322
|
+
uv sync
|
|
323
|
+
|
|
324
|
+
# Build and install the Python extension in development mode
|
|
325
|
+
uv run maturin develop --features python
|
|
326
|
+
|
|
327
|
+
# Run tests
|
|
328
|
+
uv run python -m pytest tests/test_python_bindings.py
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
**Note:** maturin is only required for building from source. Regular users installing from PyPI don't need maturin.
|
|
332
|
+
|
|
333
|
+
### Running Examples
|
|
334
|
+
|
|
335
|
+
After installing the package, you can run the examples:
|
|
336
|
+
|
|
337
|
+
```bash
|
|
338
|
+
# Download the examples from the repository
|
|
339
|
+
git clone https://github.com/Phala-Network/dcap-qvl.git
|
|
340
|
+
cd dcap-qvl/python-bindings
|
|
341
|
+
|
|
342
|
+
# Basic functionality test
|
|
343
|
+
python examples/basic_test.py
|
|
344
|
+
|
|
345
|
+
# Full example (requires sample data files)
|
|
346
|
+
python examples/python_example.py
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
Or if you're using uv for development:
|
|
350
|
+
|
|
351
|
+
```bash
|
|
352
|
+
# Basic functionality test
|
|
353
|
+
uv run python examples/basic_test.py
|
|
354
|
+
|
|
355
|
+
# Full example (requires sample data files)
|
|
356
|
+
uv run python examples/python_example.py
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
### Testing Across Python Versions
|
|
360
|
+
|
|
361
|
+
The project includes comprehensive testing across all supported Python versions:
|
|
362
|
+
|
|
363
|
+
```bash
|
|
364
|
+
# Quick test across all Python versions
|
|
365
|
+
make test_python_versions
|
|
366
|
+
|
|
367
|
+
# Test current Python version only
|
|
368
|
+
make test_python
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
See [PYTHON_TESTING.md](PYTHON_TESTING.md) for detailed information about Python version compatibility testing.
|
|
372
|
+
|
|
373
|
+
## Requirements
|
|
374
|
+
|
|
375
|
+
### For regular usage (installing from PyPI):
|
|
376
|
+
- Python 3.8+
|
|
377
|
+
|
|
378
|
+
### For development (building from source):
|
|
379
|
+
- Python 3.8+
|
|
380
|
+
- Rust toolchain (rustc, cargo)
|
|
381
|
+
- maturin (automatically installed with `uv sync`)
|
|
382
|
+
|
|
383
|
+
## License
|
|
384
|
+
|
|
385
|
+
MIT License - see [LICENSE](LICENSE) for details.
|
|
386
|
+
|
|
387
|
+
## Contributing
|
|
388
|
+
|
|
389
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
dcap_qvl-0.3.2.dist-info/METADATA,sha256=3N6XPbmZkdJvADf6A4b-V9uPiyFCqiJTZs1Ay82i8us,9879
|
|
2
|
+
dcap_qvl-0.3.2.dist-info/WHEEL,sha256=vJwryDy_XN4_OrKBO4Z-Wqfyse3zdCl4cNM2nSll1k0,129
|
|
3
|
+
dcap_qvl/__init__.py,sha256=3c5mhP5xFUou8kcx8ykjMLA34RMPXiD5Q2ATiEsy4_w,3910
|
|
4
|
+
dcap_qvl/__init__.pyi,sha256=eXZBGDagPBOg2T34FFd1GA_xIj-5GxaQUkNWaUHyvMc,9960
|
|
5
|
+
dcap_qvl/dcap_qvl.abi3.so,sha256=btcfbCNk-wdPmegwsEySjY0w9FmyA5BGWYrQliUDdzo,5436064
|
|
6
|
+
dcap_qvl-0.3.2.dist-info/RECORD,,
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: dcap-qvl
|
|
3
|
-
Version: 0.1.2
|
|
4
|
-
Requires-Dist: maturin>=1.8.2
|
|
5
|
-
Requires-Dist: twine>=6.1.0
|
|
6
|
-
License-File: LICENSE
|
|
7
|
-
Summary: Add your description here
|
|
8
|
-
Author: Kevin Wang <wy721@qq.com>
|
|
9
|
-
Author-email: Kevin Wang <wy721@qq.com>
|
|
10
|
-
License: MIT
|
|
11
|
-
Requires-Python: >=3.10, <4
|
|
12
|
-
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
<!-- cargo-rdme start -->
|
|
16
|
-
|
|
17
|
-
# dcap-qvl
|
|
18
|
-
|
|
19
|
-
This crate implements the quote verification logic for DCAP (Data Center Attestation Primitives) in pure Rust. It supports both SGX (Software Guard Extensions) and TDX (Trust Domain Extensions) quotes.
|
|
20
|
-
|
|
21
|
-
# Features
|
|
22
|
-
- Verify SGX and TDX quotes
|
|
23
|
-
- Get collateral from PCCS
|
|
24
|
-
- Extract information from quotes
|
|
25
|
-
|
|
26
|
-
# Usage
|
|
27
|
-
Add the following dependency to your `Cargo.toml` file to use this crate:
|
|
28
|
-
```toml
|
|
29
|
-
[dependencies]
|
|
30
|
-
dcap-qvl = "0.1.0"
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
# Examples
|
|
34
|
-
|
|
35
|
-
## Get Collateral from PCCS_URL and Verify Quote
|
|
36
|
-
|
|
37
|
-
To get collateral from a PCCS_URL and verify a quote, you can use the following example code:
|
|
38
|
-
```rust
|
|
39
|
-
use dcap_qvl::collateral::get_collateral;
|
|
40
|
-
use dcap_qvl::verify::verify;
|
|
41
|
-
|
|
42
|
-
#[tokio::main]
|
|
43
|
-
async fn main() {
|
|
44
|
-
// Get PCCS_URL from environment variable. The URL is like "https://localhost:8081/sgx/certification/v4/".
|
|
45
|
-
let pccs_url = std::env::var("PCCS_URL").expect("PCCS_URL is not set");
|
|
46
|
-
let quote = std::fs::read("tdx_quote").expect("tdx_quote is not found");
|
|
47
|
-
let collateral = get_collateral(&pccs_url, "e, std::time::Duration::from_secs(10)).await.expect("failed to get collateral");
|
|
48
|
-
let now = std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH).unwrap().as_secs();
|
|
49
|
-
let tcb = verify("e, &collateral, now).expect("failed to verify quote");
|
|
50
|
-
println!("{:?}", tcb);
|
|
51
|
-
}
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
## Get Collateral from Intel PCS and Verify Quote
|
|
55
|
-
|
|
56
|
-
```rust
|
|
57
|
-
use dcap_qvl::collateral::get_collateral_from_pcs;
|
|
58
|
-
use dcap_qvl::verify::verify;
|
|
59
|
-
|
|
60
|
-
#[tokio::main]
|
|
61
|
-
async fn main() {
|
|
62
|
-
let quote = std::fs::read("tdx_quote").expect("tdx_quote is not found");
|
|
63
|
-
let collateral = get_collateral_from_pcs("e, std::time::Duration::from_secs(10)).await.expect("failed to get collateral");
|
|
64
|
-
let now = std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH).unwrap().as_secs();
|
|
65
|
-
let tcb = verify("e, &collateral, now).expect("failed to verify quote");
|
|
66
|
-
println!("{:?}", tcb);
|
|
67
|
-
}
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
<!-- cargo-rdme end -->
|
|
71
|
-
|
|
72
|
-
# License
|
|
73
|
-
|
|
74
|
-
This crate is licensed under the MIT license. See the LICENSE file for details.
|
|
75
|
-
|
dcap_qvl-0.1.2.dist-info/RECORD
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
dcap_qvl-0.1.2.dist-info/METADATA,sha256=8264XXvSE1TjkaVJRT-f4haIjoXqj8XdwlaN_a981YQ,2422
|
|
2
|
-
dcap_qvl-0.1.2.dist-info/WHEEL,sha256=enHAT78HPHhu3XKDSOZi_EBRo8KIHOWyiLnoj9YUFq8,129
|
|
3
|
-
dcap_qvl-0.1.2.dist-info/licenses/LICENSE,sha256=070OEM_OefwwbasTPBxtOyVDy8cUurlbqN-rehf9meo,1070
|
|
4
|
-
dcap_qvl/__init__.py,sha256=RMQOVBmpT6U8PaT8rRlDneVa0kLXFJ-nMTVqBaDVatw,115
|
|
5
|
-
dcap_qvl/dcap_qvl.abi3.so,sha256=MVIV2ptafdYvnmIp0jMmg1QPLU14ZHv1UVFhgNtmXJo,6588896
|
|
6
|
-
dcap_qvl-0.1.2.dist-info/RECORD,,
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2024 Phala Network
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|