Skip to content

feat(go-sdk): add RA-TLS certificate verification package#512

Open
Leechael wants to merge 1 commit intofeature-sdk-golangfrom
feature-sdk-golang-ratls
Open

feat(go-sdk): add RA-TLS certificate verification package#512
Leechael wants to merge 1 commit intofeature-sdk-golangfrom
feature-sdk-golang-ratls

Conversation

@Leechael
Copy link
Collaborator

@Leechael Leechael commented Feb 16, 2026

Summary

Add sdk/go/ratls package for RA-TLS (Remote Attestation TLS) certificate verification, enabling Go applications to verify that a TLS peer is running inside a genuine TDX TEE.

Verification chain (matches Rust ra-tls / dstack-attest)

  1. Extract TDX quote from X.509 certificate extension (OID 1.3.6.1.4.1.62397.1.1)
  2. Verify quote via dcap-qvl (fetch collateral from PCCS + verify Intel signature)
  3. Validate TCB attributes — reject debug mode, check mr_signer_seam / mr_service_td are zero
  4. Verify report_data binds to certificate public key — SHA512("ratls-cert:" || SubjectPublicKeyInfo DER)
  5. Replay RTMR3 from event log (OID 1.3.6.1.4.1.62397.1.2) — filter event_type == 0x08000001, compute SHA384(event_type_le_bytes || ":" || event || ":" || payload), accumulate mr = SHA384(mr || digest)

API

// Verify a certificate extracted from a TLS connection
result, err := ratls.VerifyCert(cert, ratls.WithPCCSURL("https://pccs.phala.network"))

// Or use TLSConfig for automatic verification during TLS handshake
tlsCfg := ratls.TLSConfig(
    ratls.WithOnVerified(func(r *ratls.VerifyResult) {
        fmt.Println(r.Report.Status, r.Quote.Report.Type)
    }),
)
conn, err := tls.Dial("tcp", "endpoint:443", tlsCfg)

Module structure

sdk/go/ratls is a separate Go module (sdk/go/ratls/go.mod) to isolate the dcap-qvl CGO dependency from the base SDK module. This avoids pulling go-ethereum and other unrelated transitive dependencies into the base sdk/go/go.mod.

Consistency with Rust

Check Rust source Go implementation
Quote extraction CertExt::get_extension_bytes() + yasna::parse_der getExtensionBytes() + asn1.Unmarshal
DCAP verification dcap_qvl::verify() dcap.GetCollateralAndVerify()
TCB validation validate_tcb() in dstack-attest validateTCB()
report_data binding QuoteContentType::RaTlsCert.to_report_data() SHA512("ratls-cert:" || RawSubjectPublicKeyInfo)
RTMR3 replay replay_runtime_events::<Sha384>() verifyRTMR3()
Event digest RuntimeEvent::digest::<Sha384>() with to_ne_bytes() (LE on x86_64) binary.LittleEndian.PutUint32
Hex JSON decoding serde_human_bytes dcap.HexBytes

Test plan

  • Run against a live RA-TLS endpoint:
    RATLS_TEST_ENDPOINT=host:port \
    CGO_LDFLAGS="-L/path/to/libdcap_qvl" \
    go test -v ./sdk/go/ratls/
  • Verify consistency with Rust RA-TLS by comparing verification results on the same endpoint
  • Demo integration: phala-cloud-gin-starter with go build -tags ratls

Add sdk/go/ratls as a separate Go module providing RA-TLS certificate
verification for dstack TEE applications. The implementation matches
the Rust ra-tls/dstack-attest verification chain:

- Extract TDX quote from X.509 certificate extension (OID 1.3.6.1.4.1.62397.1.1)
- Verify quote via dcap-qvl (fetch collateral from PCCS + verify Intel signature)
- Validate TCB attributes (reject debug mode, check mr_signer_seam/mr_service_td)
- Verify report_data binds to certificate public key (SHA512 of "ratls-cert:" prefix)
- Replay RTMR3 from event log and compare with quote

Exposed API:
- VerifyCert(cert, opts...) - verify a single X.509 certificate
- TLSConfig(opts...) - return *tls.Config for RA-TLS handshake verification
- WithPCCSURL / WithOnVerified options

Uses github.com/Phala-Network/dcap-qvl/golang-bindings for quote
parsing and verification. Separate go.mod keeps the dcap-qvl CGO
dependency isolated from the base SDK module.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant