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

  1. Fix the client to encode e as unpadded base64url (e.g. "AQAB" for 65537)
  2. Trim '=' padding before decoding, as with n
  3. Accept both decimal and base64url forms by trying strconv.Atoi first, then RawURLEncoding
  4. 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

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


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)