otp: fix return type of register_otp_string()
What changed, and why it matters
This commit fixes a mismatch between what a function called register_otp_string() actually returns and what callers expect. The function used to claim it returned a simple true/false value, but it was really returning numeric error codes. The fix changes the declared return type from bool to int so the code matches reality. This is a cleanup that prevents callers from misinterpreting error codes as plain failure, but the diff does not show an active exploit path on its own.
Review all call sites of register_otp_string() to ensure they now handle the int return value and the CBOR_RPC_* constants correctly. Verify that no caller still treats the result as a plain boolean. Consider adding static-analysis checks to catch type mismatches between declarations and definitions.
Security signals we found
Return-type mismatch between function signature and implementation (bool vs int error codes)
Use of CBOR_RPC_* numeric error codes where a boolean was declared
Potential for callers to misinterpret coerced boolean return values as success/failure rather than specific RPC error codes
Evidence from the diff
register_otp_string() was declared as returning bool, yet its implementation returned CBOR_RPC_* integer constants (e.g., CBOR_RPC_INTERNAL_ERROR, CBOR_RPC_USER_CANCELLED). In C, a bool return value is converted to 0 or 1, so callers receiving these constants through a bool prototype would see them coerced. The patch changes the return type to int and updates the forward declaration in qrmode.c to match. The diff is small and only covers the type change and the three return statements shown; the actual caller(s) that consume the int are not visible in this commit.
Changed components
main/process/register_otp.cmain/qrmode.cregister_otp_string() OTP registration APIInspect captured patch +5 / −5
diff --git a/main/process/register_otp.c b/main/process/register_otp.c
index 7735b1b..387ffa9 100644
--- a/main/process/register_otp.c
+++ b/main/process/register_otp.c
@@ -380,7 +380,7 @@ cleanup:
return ret;
}
-bool register_otp_string(const char* otp_uri, const size_t uri_len, const char** errmsg)
+int register_otp_string(const char* otp_uri, const size_t uri_len, const char** errmsg)
{
JADE_ASSERT(otp_uri);
JADE_ASSERT(uri_len);
@@ -391,7 +391,7 @@ bool register_otp_string(const char* otp_uri, const size_t uri_len, const char**
otpauth_ctx_t otp_ctx = { .name = "otp_string" };
if (!otp_uri_to_ctx(otp_uri, uri_len, &otp_ctx)) {
*errmsg = "Failed to parse otp record";
- return false;
+ return CBOR_RPC_INTERNAL_ERROR;
}
// Check keychain has seed data
@@ -400,7 +400,7 @@ bool register_otp_string(const char* otp_uri, const size_t uri_len, const char**
*errmsg = "Failed to parse otp record";
const char* message[] = { "Feature requires Jade reset" };
await_error_activity(message, 1);
- return false;
+ return CBOR_RPC_INTERNAL_ERROR;
}
// Get OTP Name (only) from kb
@@ -409,7 +409,7 @@ bool register_otp_string(const char* otp_uri, const size_t uri_len, const char**
// User abandoned
JADE_LOGW("User abandoned (entering otp name)");
*errmsg = "User abandoned entering otp name";
- return false;
+ return CBOR_RPC_USER_CANCELLED;
}
// Validate and persist the new otp uri
diff --git a/main/qrmode.c b/main/qrmode.c
index 5b1baf0..a9254ca 100644
--- a/main/qrmode.c
+++ b/main/qrmode.c
@@ -71,7 +71,7 @@ gui_activity_t* make_show_qr_activity(const char* message[], size_t message_size
gui_activity_t* make_qr_options_activity(gui_view_node_t** density_textbox, gui_view_node_t** framerate_textbox);
bool import_mnemonic(const uint8_t* bytes, size_t bytes_len, char* buf, size_t buf_len, size_t* written);
-bool register_otp_string(const char* otp_uri, size_t uri_len, const char** errmsg);
+int register_otp_string(const char* otp_uri, size_t uri_len, const char** errmsg);
int register_multisig_file(const char* multisig_file, size_t multisig_file_len, const char** errmsg);
int update_pinserver(const CborValue* const params, const char** errmsg);
int params_set_epoch_time(CborValue* params, const char** errmsg);
Why this scored 26/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.