OpenNHP/opennhp · error

failed to download hsk_cek

Error message

failed to download hsk_cek: %v

What it means

During CSV (Hygon) attestation, verifyCertChain downloads the HSK/CEK certificate blob from Hygon's public CA endpoint (https://cert.hygon.cn/hsk_cek?snumber=<chipId>) unless it is already cached in a.hskCek. This error wraps any transport-level failure of that http.Get call (DNS failure, refused connection, TLS error, timeout). It means the verifier could not reach Hygon's certificate server at all, not that it returned a bad response.

Solutions

  1. Ensure the verifier host has outbound HTTPS connectivity to cert.hygon.cn (test with curl 'https://cert.hygon.cn/hsk_cek?snumber=<chipId>').
  2. Pre-populate the hskCek cache for the chipId so no network fetch is needed (a.hskCek is consulted before downloading).
  3. Add retry logic with a timeout around the download, since the failure is often transient.
  4. Configure HTTP(S)_PROXY or fix DNS if the environment requires a proxy or has resolution problems.

Example fix

// before
resp, err := http.Get(fmt.Sprintf("https://cert.hygon.cn/hsk_cek?snumber=%s", chipId))
if err != nil {
    return fmt.Errorf("failed to download hsk_cek: %v", err)
}
// after
client := &http.Client{Timeout: 15 * time.Second}
var resp *http.Response
var lastErr error
for i := 0; i < 3; i++ {
    resp, lastErr = client.Get(fmt.Sprintf("https://cert.hygon.cn/hsk_cek?snumber=%s", chipId))
    if lastErr == nil {
        break
    }
    time.Sleep(time.Duration(i+1) * time.Second)
}
if lastErr != nil {
    return fmt.Errorf("failed to download hsk_cek: %v", lastErr)
}
Defensive patterns

Strategy: retry

Validate before calling

conn, err := net.DialTimeout("tcp", "cert.hygon.cn:443", 5*time.Second)
if err != nil {
    return fmt.Errorf("hygon CA unreachable: %w", err)
}
conn.Close()

Try / catch

err := attestation.Verify(ctx, evidence)
var netErr net.Error
if err != nil {
    if errors.As(err, &netErr) || strings.Contains(err.Error(), "failed to download hsk_cek") {
        // transient network problem: retry with backoff or fall back to cached CEK
    }
}

Prevention

When it happens

Trigger: Calling Attestation.Verify (which calls verifyCertChain) on CSV evidence whose chipId is not yet in the hskCek cache while the host running the verifier has no outbound internet access, DNS for cert.hygon.cn fails, the endpoint is down, or a firewall/proxy blocks the HTTPS request.

Common situations: Running the verifier in an air-gapped or firewalled datacenter; CI environments without egress to Chinese endpoints (cert.hygon.cn is hosted in China and may be slow/blocked elsewhere); transient Hygon CA outages; misconfigured corporate proxies.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


AI-assisted analysis of OpenNHP/opennhp@6e04ca5ff0 (2026-09-07). Data as JSON: /api/errors/a623bfe630be1245. Report an issue: GitHub.

Appendix: source

Thrown at nhp/core/verifier/csv/csv.go:341

	if err := a.verifyHygonCertInfo(a.hrk, 0x03, 0, a.hrk[0x04:0x14]); err != nil {
		return err
	}

	// verify hrk cert signature (self-signed)
	hrkIdLen := int(binary.LittleEndian.Uint16(a.hrk[0xd4:0xd6]))
	if err := a.verifySm2SignatureWithId(
		a.hrk[0x44:0x64], a.hrk[0x8c:0xac],
		a.hrk[0x240:0x260], a.hrk[0x288:0x2a8],
		a.hrk[0xd6:0xd6+hrkIdLen], a.hrk[:0x240],
	); err != nil {
		return err
	}

	if _, ok := a.hskCek[chipId]; !ok {
		resp, err := http.Get(fmt.Sprintf("https://cert.hygon.cn/hsk_cek?snumber=%s", chipId))
		if err != nil {
			return fmt.Errorf("failed to download hsk_cek: %v", err)
		}
		defer resp.Body.Close()

		if resp.StatusCode != http.StatusOK {
			return fmt.Errorf("unexpected status code when download hsk_cek: %d", resp.StatusCode)
		}

		hskCekData, err := io.ReadAll(resp.Body)
		if err != nil {
			return fmt.Errorf("failed to read hsk_cek data: %v", err)
		}

		a.hskCek[chipId] = hskCekData
	}

	hskData := a.hskCek[chipId][:0x340]
	cekData := a.hskCek[chipId][0x340:]

View on GitHub (pinned to 6e04ca5ff0)