Skip to main content

Python Bindings for DCAP-QVL

Python bindings for parsing and verifying Intel SGX/TDX DCAP (Data Center Attestation Primitives) quotes. Built on a Rust implementation for use in TEE (Trusted Execution Environment) remote attestation workflows.

Quick Start

# Install from PyPI
pip install dcap-qvl

# Basic usage
python -c "
import dcap_qvl
print('DCAP-QVL Python bindings successfully installed!')
print(f'Available functions: {dcap_qvl.__all__}')
"

Features

  • Parse and inspect SGX/TDX quotes (headers, reports, embedded certificates)
  • Extract PCK certificate extension fields (FMSPC, PPID, CPU SVN, etc.) or look up arbitrary OIDs
  • Verify SGX and TDX quotes against collateral data
  • Handle quote collateral data (serialize/deserialize JSON)
  • Asynchronous collateral fetching from PCCS/PCS with async/await support
  • Pure Rust implementation with Python bindings
  • Cross-platform compatibility (Linux, macOS, Windows)
  • Compatible with Python 3.8+

Installation

From PyPI (recommended)

pip install dcap-qvl

Using uv

uv add dcap-qvl

Usage

Parsing Quotes

import dcap_qvl

raw = open("quote.bin", "rb").read()
quote = dcap_qvl.parse_quote(raw)

# Quote type
print(quote.quote_type())  # "SGX" or "TDX"
print(quote.fmspc())       # e.g. "B0C06F000000"

# Header fields
hdr = quote.header
print(hdr.version, hdr.tee_type, hdr.attestation_key_type)

# Report body (TdReport10, TdReport15, or SgxEnclaveReport)
report = quote.report
if quote.is_tdx():
    print(report.mr_td.hex())
    print(report.rt_mr0.hex())
else:
    print(report.mr_enclave.hex())
    print(report.mr_signer.hex())
print(report.report_data.hex())

# Embedded PEM certificate chain
pem = quote.cert_chain_pem_bytes()  # bytes or None

PCK Extension Parsing

# From a parsed quote
ext = quote.pck_extension()  # PckExtension or None
if ext:
    print(ext.fmspc.hex())   # 6-byte FMSPC
    print(ext.ppid.hex())    # PPID
    print(ext.cpu_svn.hex()) # CPU SVN
    print(ext.pce_svn)       # PCE SVN (int)
    print(ext.pce_id.hex())  # PCE ID
    print(ext.sgx_type)      # SGX type (int)

# From a PEM certificate chain directly
ext = dcap_qvl.parse_pck_extension_from_pem(pem_bytes)
print(ext.fmspc.hex())

# Look up any OID in the Intel SGX extension (recursive search)
value = ext.get_value("1.2.840.113741.1.13.1.2.17")  # PCESVN
if value is not None:
    print(value.hex())

Basic Quote Verification

import dcap_qvl
import json
import time

# Load quote data (binary)
with open("path/to/quote", "rb") as f:
    quote_data = f.read()

# Load collateral data (JSON)
with open("path/to/collateral.json", "r") as f:
    collateral_json = json.load(f)

# Create collateral object
collateral = dcap_qvl.QuoteCollateralV3.from_json(json.dumps(collateral_json))

# Verify the quote
now = int(time.time())
try:
    result = dcap_qvl.verify(quote_data, collateral, now)
    print(f"Verification successful! Status: {result.status}")
    print(f"Advisory IDs: {result.advisory_ids}")
except ValueError as e:
    print(f"Verification failed: {e}")

Working with Collateral Data

# Create collateral manually
collateral = dcap_qvl.QuoteCollateralV3(
    pck_crl_issuer_chain="...",
    root_ca_crl=b"...",  # bytes
    pck_crl=b"...",      # bytes
    tcb_info_issuer_chain="...",
    tcb_info="...",      # JSON string
    tcb_info_signature=b"...",  # bytes
    qe_identity_issuer_chain="...",
    qe_identity="...",   # JSON string
    qe_identity_signature=b"...",  # bytes
)

# Serialize to JSON
json_str = collateral.to_json()

# Deserialize from JSON
collateral = dcap_qvl.QuoteCollateralV3.from_json(json_str)

API Reference

Async Collateral Functions

All collateral functions are asynchronous and must be awaited. They use the Rust async runtime for optimal performance.

async get_collateral(pccs_url: str, raw_quote: bytes) -> QuoteCollateralV3

Fetch full collateral (PCK cert chain, TCB info, QE identity, CRLs) for a raw DCAP quote from the given PCCS / PCS URL. Handles every supported certification data type (including cert_type 2 / 3 where the PCK cert is retrieved from PCCS via encrypted PPID).

Parameters:

Returns:

  • QuoteCollateralV3: Quote collateral data (with PCK certificate chain attached)

Raises:

  • ValueError: If the quote is invalid, the HTTP client can't be built, or the PCCS / PCS fetch fails

Example:

import asyncio
import dcap_qvl

async def main():
    pccs_url = "https://api.trustedservices.intel.com"
    quote_data = open("quote.bin", "rb").read()
    collateral = await dcap_qvl.get_collateral(pccs_url, quote_data)
    print(f"Got collateral: {len(collateral.tcb_info)} chars")

asyncio.run(main())

async get_collateral_from_pcs(raw_quote: bytes) -> QuoteCollateralV3

Get collateral from Intel's PCS (default).

Parameters:

  • raw_quote: Raw quote data as bytes

Returns:

  • QuoteCollateralV3: Quote collateral data

Raises:

  • ValueError: If quote is invalid or FMSPC cannot be extracted
  • RuntimeError: If network request fails

Example:

import asyncio
import dcap_qvl

async def main():
    quote_data = open("quote.bin", "rb").read()
    collateral = await dcap_qvl.get_collateral_from_pcs(quote_data)
    print(f"Got collateral from Intel PCS")

asyncio.run(main())

async get_collateral_and_verify(raw_quote: bytes, pccs_url: Optional[str] = None) -> VerifiedReport

Get collateral and verify quote in one step.

Parameters:

  • raw_quote: Raw quote data as bytes
  • pccs_url: Optional PCCS URL (uses Intel PCS if None)

Returns:

  • VerifiedReport: Verification results

Raises:

  • ValueError: If quote is invalid or verification fails
  • RuntimeError: If network request fails

Example:

import asyncio
import dcap_qvl

async def main():
    quote_data = open("quote.bin", "rb").read()
    result = await dcap_qvl.get_collateral_and_verify(quote_data)
    print(f"Status: {result.status}")
    print(f"Advisory IDs: {result.advisory_ids}")

asyncio.run(main())

Classes

QuoteCollateralV3

Represents quote collateral data required for verification.

Constructor:

QuoteCollateralV3(
    pck_crl_issuer_chain: str,
    root_ca_crl: bytes,
    pck_crl: bytes,
    tcb_info_issuer_chain: str,
    tcb_info: str,
    tcb_info_signature: bytes,
    qe_identity_issuer_chain: str,
    qe_identity: str,
    qe_identity_signature: bytes,
)

Methods:

  • to_json() -> str: Serialize to JSON string
  • from_json(json_str: str) -> QuoteCollateralV3: Create from JSON string (static method)

Properties:

  • pck_crl_issuer_chain: str
  • root_ca_crl: bytes
  • pck_crl: bytes
  • tcb_info_issuer_chain: str
  • tcb_info: str
  • tcb_info_signature: bytes
  • qe_identity_issuer_chain: str
  • qe_identity: str
  • qe_identity_signature: bytes

VerifiedReport

Contains the results of quote verification.

Properties:

  • status: str: Verification status (e.g., "OK", "SW_HARDENING_NEEDED", "CONFIGURATION_NEEDED", "OUT_OF_DATE", "REVOKED")
  • advisory_ids: List[str]: List of Intel security advisory IDs (e.g., "INTEL-SA-00334")
  • ppid: bytes: Platform PPID parsed from the PCK certificate

Methods:

  • to_json() -> str: Serialize to JSON string

Quote

Represents a parsed SGX or TDX quote. Created via parse_quote() or Quote.parse().

Properties:

  • header: QuoteHeader: Parsed quote header
  • report: Union[TdReport10, TdReport15, SgxEnclaveReport]: Parsed report body

Methods:

  • parse(raw_quote: bytes) -> Quote: Parse from raw bytes (static method)
  • fmspc() -> str: FMSPC as uppercase hex string
  • ca() -> str: Certificate Authority identifier
  • is_sgx() -> bool / is_tdx() -> bool: Check quote type
  • quote_type() -> str: Returns "SGX" or "TDX"
  • cert_chain_pem_bytes() -> Optional[bytes]: Embedded PEM certificate chain
  • pck_extension() -> Optional[PckExtension]: Parse Intel SGX extension from leaf PCK cert

QuoteHeader

Properties:

  • version: int, attestation_key_type: int, tee_type: int
  • qe_svn: int, pce_svn: int
  • qe_vendor_id: bytes (16 bytes), user_data: bytes (20 bytes)

TdReport10 / TdReport15

TDX TDREPORT structures. TdReport15 extends TdReport10 with tee_tcb_svn2 and mr_service_td.

Properties (TdReport10):

  • tee_tcb_svn: bytes, mr_seam: bytes, mr_signer_seam: bytes, seam_attributes: bytes
  • td_attributes: bytes, xfam: bytes, mr_td: bytes, mr_config_id: bytes
  • mr_owner: bytes, mr_owner_config: bytes
  • rt_mr0: bytes, rt_mr1: bytes, rt_mr2: bytes, rt_mr3: bytes
  • report_data: bytes

SgxEnclaveReport

Properties:

  • cpu_svn: bytes, attributes: bytes
  • mr_enclave: bytes, mr_signer: bytes
  • report_data: bytes

PckExtension

Parsed values from the Intel SGX extension in the PCK leaf certificate.

Properties:

  • ppid: bytes, cpu_svn: bytes, pce_svn: int, pce_id: bytes
  • fmspc: bytes (6 bytes), sgx_type: int
  • platform_instance_id: Optional[bytes]

Methods:

  • get_value(oid: str) -> Optional[bytes]: Look up any OID in the Intel SGX extension by dotted-decimal string. Returns raw DER value bytes, or None if not found.

Functions

parse_quote(raw_quote: bytes) -> Quote

Parse a raw SGX or TDX quote from bytes.

parse_pck_extension_from_pem(pem_bytes: bytes) -> PckExtension

Parse the Intel SGX extension from a PEM-encoded certificate chain (uses the first/leaf certificate).

verify(raw_quote: bytes, collateral: QuoteCollateralV3, now_secs: int) -> VerifiedReport

Verify a quote with the provided collateral data.

Parameters:

  • raw_quote: Raw quote data as bytes
  • collateral: Quote collateral data
  • now_secs: Current timestamp in seconds since Unix epoch

Returns:

  • VerifiedReport: Verification results

Raises:

  • ValueError: If verification fails

verify_with_root_ca(raw_quote: bytes, collateral: QuoteCollateralV3, root_ca_der: bytes, now_secs: int) -> VerifiedReport

Verify a quote with a custom root CA certificate (DER format) instead of the built-in Intel root CA.

Development

Building from Source

If you want to build from source or contribute to development:

# Clone the repository
git clone https://github.com/Phala-Network/dcap-qvl.git
cd dcap-qvl/python-bindings

# Install development dependencies (including maturin)
uv sync

# Build and install the Python extension in development mode
uv run maturin develop --features python

# Run tests
uv run pytest tests/ -v

Note: maturin is only required for building from source. Regular users installing from PyPI don't need maturin.

Running Examples

After installing the package, you can run the examples:

# Download the examples from the repository
git clone https://github.com/Phala-Network/dcap-qvl.git
cd dcap-qvl/python-bindings

# Basic functionality test
python examples/basic_test.py

# Full example (requires sample data files)
python examples/python_example.py

Or if you're using uv for development:

# Basic functionality test
uv run python examples/basic_test.py

# Full example (requires sample data files)
uv run python examples/python_example.py

Testing Across Python Versions

The project includes comprehensive testing across all supported Python versions:

# Quick test across all Python versions
make test_python_versions

# Test current Python version only
make test_python

See PYTHON_TESTING.md for detailed information about Python version compatibility testing.

Requirements

For regular usage (installing from PyPI):

  • Python 3.8+

For development (building from source):

  • Python 3.8+
  • Rust toolchain (rustc, cargo) 1.83+
  • maturin (automatically installed with uv sync)

License

MIT License - see LICENSE for details.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dcap_qvl-0.6.1.tar.gz (288.3 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

dcap_qvl-0.6.1-cp38-abi3-win_amd64.whl (2.1 MB view details)

Uploaded CPython 3.8+Windows x86-64

dcap_qvl-0.6.1-cp38-abi3-musllinux_1_1_x86_64.whl (2.7 MB view details)

Uploaded CPython 3.8+musllinux: musl 1.1+ x86-64

dcap_qvl-0.6.1-cp38-abi3-musllinux_1_1_aarch64.whl (2.6 MB view details)

Uploaded CPython 3.8+musllinux: musl 1.1+ ARM64

dcap_qvl-0.6.1-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (2.7 MB view details)

Uploaded CPython 3.8+manylinux: glibc 2.17+ x86-64

dcap_qvl-0.6.1-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (2.6 MB view details)

Uploaded CPython 3.8+manylinux: glibc 2.17+ ARM64

dcap_qvl-0.6.1-cp38-abi3-macosx_11_0_arm64.whl (2.3 MB view details)

Uploaded CPython 3.8+macOS 11.0+ ARM64

dcap_qvl-0.6.1-cp38-abi3-macosx_10_12_x86_64.whl (2.4 MB view details)

Uploaded CPython 3.8+macOS 10.12+ x86-64

File details

Details for the file dcap_qvl-0.6.1.tar.gz.

File metadata

  • Download URL: dcap_qvl-0.6.1.tar.gz
  • Upload date:
  • Size: 288.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for dcap_qvl-0.6.1.tar.gz
Algorithm Hash digest
SHA256 c44265ea103d8d3606a4e8e4391ed9ba727952f3f63405327a58580d03216953
MD5 a590ebacdd41b08429b795d0526f3d8a
BLAKE2b-256 bbd1d289adf8f5c562187ea4d7468292133de75cdd3efbcd164890e01c6140b5

See more details on using hashes here.

Provenance

The following attestation bundles were made for dcap_qvl-0.6.1.tar.gz:

Publisher: python-wheels.yml on Phala-Network/dcap-qvl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file dcap_qvl-0.6.1-cp38-abi3-win_amd64.whl.

File metadata

  • Download URL: dcap_qvl-0.6.1-cp38-abi3-win_amd64.whl
  • Upload date:
  • Size: 2.1 MB
  • Tags: CPython 3.8+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for dcap_qvl-0.6.1-cp38-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 2a2039ea72de1c3f6fa8938c809a77d17934c56e7d6175f20524e5dc0c846c6f
MD5 78bd2e297405666654e6023d1de0c334
BLAKE2b-256 34e7aaaf7fe9c3e4b15ba10d59d6bd294fc7e9f02bb7ce154a835e395f4d9d3c

See more details on using hashes here.

Provenance

The following attestation bundles were made for dcap_qvl-0.6.1-cp38-abi3-win_amd64.whl:

Publisher: python-wheels.yml on Phala-Network/dcap-qvl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file dcap_qvl-0.6.1-cp38-abi3-musllinux_1_1_x86_64.whl.

File metadata

File hashes

Hashes for dcap_qvl-0.6.1-cp38-abi3-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 4471b9ddb1a77488013fee774af6d469d96b8bd72d94c094dd48a2bb9e04fd00
MD5 73de96285cad170479a50bca3848d37b
BLAKE2b-256 0016d878bf346a0f96fd9a77ee5b67fd02ede54204ac2749b40698e1c4c4d77c

See more details on using hashes here.

Provenance

The following attestation bundles were made for dcap_qvl-0.6.1-cp38-abi3-musllinux_1_1_x86_64.whl:

Publisher: python-wheels.yml on Phala-Network/dcap-qvl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file dcap_qvl-0.6.1-cp38-abi3-musllinux_1_1_aarch64.whl.

File metadata

File hashes

Hashes for dcap_qvl-0.6.1-cp38-abi3-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 dcba212c881f19b7f93c61807e96747794a7b986492f1834acc70a685659450a
MD5 e5d3cc534b6d21f6ba42908bb21cff18
BLAKE2b-256 dea407df292f7275cfc4ac78941a31ad7fe364e8171f14ac75668aebb8345afc

See more details on using hashes here.

Provenance

The following attestation bundles were made for dcap_qvl-0.6.1-cp38-abi3-musllinux_1_1_aarch64.whl:

Publisher: python-wheels.yml on Phala-Network/dcap-qvl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file dcap_qvl-0.6.1-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for dcap_qvl-0.6.1-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 08aacb2dc4393f4745dbd712b241b150fe35f5244e374abe8e32725a0f647018
MD5 9d8ad4a7768a33b671e543ba4d1f22f8
BLAKE2b-256 4d1dfc743c2e0ebe22e5d8d986dd7123f89e2e1de1ff43d079a351c1c59baf34

See more details on using hashes here.

Provenance

The following attestation bundles were made for dcap_qvl-0.6.1-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: python-wheels.yml on Phala-Network/dcap-qvl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file dcap_qvl-0.6.1-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for dcap_qvl-0.6.1-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 5c3bfcd6e3c962ce5dc6f3481b309268e7b6581ebb80798280f2ad84f06aa147
MD5 faf5f9097b4f43001b8e35c3bdbb06cd
BLAKE2b-256 3e51023db2cef672f2d28790ad0194158521c8029ea70d8964a7fca1d2eb9ad1

See more details on using hashes here.

Provenance

The following attestation bundles were made for dcap_qvl-0.6.1-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: python-wheels.yml on Phala-Network/dcap-qvl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file dcap_qvl-0.6.1-cp38-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for dcap_qvl-0.6.1-cp38-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 b09b5c20f17bcb44b3ed65d873b0d055f241aff5549d0d098637608892261c6e
MD5 70e32e703d4fb7accc538c2ce810c240
BLAKE2b-256 f5b17ed5e44e559351b3294104cc221ef842d927b7ff8087a6ff26b5f0a7f320

See more details on using hashes here.

Provenance

The following attestation bundles were made for dcap_qvl-0.6.1-cp38-abi3-macosx_11_0_arm64.whl:

Publisher: python-wheels.yml on Phala-Network/dcap-qvl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file dcap_qvl-0.6.1-cp38-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for dcap_qvl-0.6.1-cp38-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 fc64c271a41413b44dd9185c8ceff7d48033b8708047cc89e9899f0442003d4a
MD5 e96666e2a86518139756300e6e4fdbf7
BLAKE2b-256 18be63aa4549089fab5aa7e8da3af2dca6d3c23469307a1f7f67886799c04aae

See more details on using hashes here.

Provenance

The following attestation bundles were made for dcap_qvl-0.6.1-cp38-abi3-macosx_10_12_x86_64.whl:

Publisher: python-wheels.yml on Phala-Network/dcap-qvl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.6.1 This release

8 files

0.6.0

8 files

0.5.3

8 files

0.5.2

8 files

0.4.0

8 files

0.3.13

8 files

0.3.12

8 files

0.3.11

8 files

0.3.10

8 files

0.3.9

8 files

0.3.8

8 files

0.3.7

8 files

0.3.6

8 files

0.3.5

8 files

0.3.4

8 files

0.3.2

8 files

0.3.0

8 files

0.2.2

2 files

0.1.3

2 files

0.1.2

1 file

0.1.1

1 file

0.1.0

3 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page