OpenNHP/opennhp · error
invalid n
Error message
invalid n: %w
What it means
parseTeePubkey decodes the JWK-style RSA public key fields with base64.RawURLEncoding. This error is returned when the teePubKey.n field is not valid unpadded base64url, so the modulus cannot be decoded. The underlying decode error is wrapped in 'invalid n: %w'.
Solutions
- Fix the client to emit n as unpadded base64url (base64.RawURLEncoding on the producer side)
- Strip any '=' padding before decoding: base64.RawURLEncoding.DecodeString(strings.TrimRight(pubkey.N, "="))
- Try a tolerant decoder that attempts RawURLEncoding then RawStdEncoding
- Validate the n field on receipt and return a clear 400 to the client instead of an internal 500
Example fix
// before
nBytes, err := base64.RawURLEncoding.DecodeString(pubkey.N)
if err != nil {
return nil, fmt.Errorf("invalid n: %w", err)
}
// after
nBytes, err := base64.RawURLEncoding.DecodeString(strings.TrimRight(pubkey.N, "="))
if err != nil {
return nil, fmt.Errorf("invalid n encoding (expect unpadded base64url): %w", err)
} Defensive patterns
Strategy: validation
Validate before calling
var jwk struct{ Kty, N, E string }
if err := json.Unmarshal(body, &jwk); err != nil || jwk.Kty != "RSA" {
return fmt.Errorf("expect RSA JWK")
}
if _, err := base64.RawURLEncoding.DecodeString(jwk.N); err != nil {
return fmt.Errorf("n is not unpadded base64url")
} Type guard
func isValidRawURLBase64(s string) bool {
_, err := base64.RawURLEncoding.DecodeString(s)
return err == nil && s != ""
} Try / catch
pubkey, err := parseTeePubkey(body)
if err != nil {
if strings.HasPrefix(err.Error(), "invalid n") || strings.HasPrefix(err.Error(), "invalid e") {
http.Error(w, "malformed TEK public key", http.StatusBadRequest)
return
}
return err
} Prevention
- Encode JWK fields with base64.RawURLEncoding on the client
- Never send padded or standard-base64 JWK values
- Validate n/e decode before submitting attestation requests
- Test against both "AQAB" and decimal exponent forms to pin down the contract
When it happens
Trigger: Attest receives a TEK pubkey JSON whose n contains padded base64 ('=' chars), standard-base64 symbols ('+','/'), whitespace, or other invalid characters, and RawURLEncoding.DecodeString fails.
Common situations: Clients producing JWKs with padded base64url; a JSON value that got percent-encoded or newline-wrapped; hand-edited keys; mixing standard and URL-safe alphabets between signer and verifier.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- invalid e
- failed to decode evidence
- unsupported key type, expect RSA
- JWT signing key is not initialized
- TEE public key is not found for specified token
AI-assisted analysis of OpenNHP/opennhp@6e04ca5ff0 (2026-09-07).
Data as JSON: /api/errors/5af6083ab1a5a832.
Report an issue: GitHub.
Appendix: source
Thrown at endpoints/server/kbs/attest/attest.go:108
"kbs-session-id",
sessionID,
3600,
"/", "", true, true, // Secure: only send over HTTPS
)
c.JSON(http.StatusOK, gin.H{
"token": token,
})
}
func parseTeePubkey(pubkey TeePubkey) (*rsa.PublicKey, error) {
if pubkey.Kty != "RSA" {
return nil, errors.New("unsupported key type, expect RSA")
}
nBytes, err := base64.RawURLEncoding.DecodeString(pubkey.N)
if err != nil {
return nil, fmt.Errorf("invalid n: %w", err)
}
eBytes, err := base64.RawURLEncoding.DecodeString(pubkey.E)
if err != nil {
return nil, fmt.Errorf("invalid e: %w", err)
}
e := 0
for _, b := range eBytes {
e = e<<8 | int(b)
}
return &rsa.PublicKey{
N: new(big.Int).SetBytes(nBytes),
E: e,
}, nil
}
View on GitHub (pinned to 6e04ca5ff0)