feat(reality): warn when target cert chain is too small for ML-DSA-65 (#6470)

* feat(reality): warn when target cert chain is too small for ML-DSA-65

Expose peer cert-chain DER size from the REALITY scanner and surface a UI
warning when ML-DSA-65 is enabled but the chain is under xray-core's 3500-byte
minimum, so silent fallback failures are easier to catch.

Fixes #5973

* fix(reality): gate scanner ML-DSA tag and sync docs OpenAPI

Only warn on short cert chains in the target scanner when ML-DSA-65 is
enabled. Copy frontend/public/openapi.json to docs/public/openapi.json
and fix oxfmt wrapping in the new test.

---------

Co-authored-by: mrchatam <287639636+mrchatam@users.noreply.github.com>
This commit is contained in:
mrchatam
2026-09-12 12:43:45 +03:30
committed by GitHub
parent 5fbd2b490c
commit b467d4c676
23 changed files with 221 additions and 5 deletions
+1
View File
@@ -916,6 +916,7 @@ export const EXAMPLES: Record<string, unknown> = {
},
"RealityScanResult": {
"alpn": "h2",
"certChainBytes": 3427,
"certChainValid": true,
"certIssuer": "Google Trust Services",
"certSubject": "cloudflare.com",
+6
View File
@@ -3684,6 +3684,11 @@ export const SCHEMAS: Record<string, unknown> = {
"example": "h2",
"type": "string"
},
"certChainBytes": {
"description": "CertChainBytes is the sum of DER lengths of the presented peer chain.\nxray-core ML-DSA-65 REALITY needs \u003e= 3500 bytes (constant lives in xray-core).",
"example": 3427,
"type": "integer"
},
"certChainValid": {
"description": "CertChainValid ignores the name: a trusted chain presented for other names\nstill has serverNames the panel can offer instead of the failing SNI.",
"example": true,
@@ -3766,6 +3771,7 @@ export const SCHEMAS: Record<string, unknown> = {
},
"required": [
"alpn",
"certChainBytes",
"certChainValid",
"certIssuer",
"certSubject",
+1
View File
@@ -835,6 +835,7 @@ export interface ProbeResultUI {
export interface RealityScanResult {
alpn: string;
certChainBytes: number;
certChainValid: boolean;
certIssuer: string;
certSubject: string;
+1
View File
@@ -892,6 +892,7 @@ export type ProbeResultUI = z.infer<typeof ProbeResultUISchema>;
export const RealityScanResultSchema = z.object({
alpn: z.string(),
certChainBytes: z.number().int(),
certChainValid: z.boolean(),
certIssuer: z.string(),
certSubject: z.string(),