OpenNHP/opennhp · error
invalid e
Error message
invalid e: %w
What it means
parseTeePubkey decodes the RSA exponent field pubkey.E with base64.RawURLEncoding. This error is returned when E is not valid unpadded base64url, so the exponent cannot be decoded. The underlying decode error is wrapped in 'invalid e: %w'.
Solutions
- Fix the client to encode e as unpadded base64url (e.g. "AQAB" for 65537)
- Trim '=' padding before decoding, as with n
- Accept both decimal and base64url forms by trying strconv.Atoi first, then RawURLEncoding
- Validate e client-side before sending and return a descriptive error to the caller
Example fix
// before
eBytes, err := base64.RawURLEncoding.DecodeString(pubkey.E)
if err != nil {
return nil, fmt.Errorf("invalid e: %w", err)
}
// after
eBytes, err := base64.RawURLEncoding.DecodeString(strings.TrimRight(pubkey.E, "="))
if err != nil {
return nil, fmt.Errorf("invalid e (expect unpadded base64url, e.g. \"AQAB\"): %w", err)
} Defensive patterns
Strategy: validation
Validate before calling
if pubkey.E == "" {
return fmt.Errorf("missing exponent")
}
if _, err := base64.RawURLEncoding.DecodeString(pubkey.E); err != nil {
return fmt.Errorf("e 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 e") {
http.Error(w, "malformed exponent (expect base64url like \"AQAB\")", http.StatusBadRequest)
return
}
return err
} Prevention
- Use "AQAB" (base64url) for the standard exponent 65537
- Avoid sending e as a decimal string
- Strip '=' padding before decoding when interoperating with lenient clients
- Share one JWK encoder library between client and server
When it happens
Trigger: Attest receives a TEK pubkey whose e field is malformed base64url (padding, '+', '/', whitespace) or is empty, causing RawURLEncoding.DecodeString to fail.
Common situations: Client serializes e as the decimal string "65537" instead of base64url "AQAB"; padded base64 output; empty string for e; key produced by a library using standard base64.
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 n
- 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/35c6b0272d90e859.
Report an issue: GitHub.
Appendix: source
Thrown at endpoints/server/kbs/attest/attest.go:113
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
}
func generateJWT() (string, error) {
if jwtSigningKey == nil {
return "", errors.New("JWT signing key is not initialized")
}
View on GitHub (pinned to 6e04ca5ff0)