{"record":{"id":"ec6fe7891c6c88f8","repo":"passbolt/passbolt_api","slug":"invalid-fingerprint","errorCode":null,"errorMessage":"Invalid fingerprint.","messagePattern":"Invalid fingerprint\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/Utility/OpenPGP/OpenPGPBackend.php","lineNumber":166,"sourceCode":"            return false;\n        }\n\n        return preg_match('/^[A-F0-9]{40}$/', $fingerprint) === 1;\n    }\n\n    // ---------------------------\n    // MISC UTILITIES\n    // ---------------------------\n\n    /**\n     * @param string $fingerprint 40 char\n     * @return string long key id 16 char\n     * @throws \\Exception\n     */\n    public static function fingerprintToKeyId(string $fingerprint): string\n    {\n        if (strlen($fingerprint) !== 40) {\n            throw new Exception('Invalid fingerprint.');\n        }\n\n        return substr($fingerprint, -16);\n    }\n\n    /**\n     * Key with extra breakline after checksum and before the end block\n     * are known to cause compatibility issues with gopenpgp\n     *\n     * @param string $armoredKey armored key block\n     * @return bool\n     */\n    public static function hasExtraBreakLine(string $armoredKey): bool\n    {\n        $armoredKey = trim($armoredKey);\n        $array = explode(\"\\n\", $armoredKey);\n        $size = count($array);\n        if ($size < 2) {","sourceCodeStart":148,"sourceCodeEnd":184,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/src/Utility/OpenPGP/OpenPGPBackend.php#L148-L184","documentation":"fingerprintToKeyId() converts a 40-character hex OpenPGP fingerprint into the 16-character long key id by taking the last 16 chars. It throws a plain Exception('Invalid fingerprint.') when strlen($fingerprint) !== 40, because a wrong-length input would produce a meaningless key id. Called from getKeyInfo.","triggerScenarios":"getKeyInfo() → fingerprintToKeyId() receives a fingerprint string whose length is not exactly 40: empty string, truncated fingerprint, key id (16 chars) passed instead of a fingerprint, or a fingerprint with spaces/whitespace inflating the length.","commonSituations":"Storing fingerprints with embedded spaces in config/DB then passing them untrimmed; passing a short key id where a fingerprint is expected; user-submitted keys metadata with malformed fingerprints.","solutions":["Normalize before calling: strip spaces and uppercase: `$fp = strtoupper(str_replace(' ', '', $fingerprint));` then check strlen === 40.","Pass the full 40-char V4 fingerprint, not the 16-char long key id or 8-char short id.","Validate the format with a hex regex before calling getKeyInfo.","Check the data source (config/DB/form input) producing the fingerprint for truncation (e.g. VARCHAR too short)."],"exampleFix":"// before\n$keyId = OpenPGPBackend::fingerprintToKeyId($fp); // $fp = '3D29 24D9 ...' with spaces\n// after\n$fp = strtoupper(preg_replace('/\\s+/', '', $fp));\nif (strlen($fp) !== 40) {\n    throw new \\InvalidArgumentException('fingerprint must be 40 hex chars');\n}\n$keyId = OpenPGPBackend::fingerprintToKeyId($fp);","handlingStrategy":"validation","validationCode":"$fp = strtoupper(preg_replace('/\\s+/', '', $fingerprint ?? ''));\nif (!preg_match('/^[0-9A-F]{40}$/', $fp)) {\n    throw new \\InvalidArgumentException('Expected a 40-hex-char OpenPGP fingerprint.');\n}","typeGuard":"function isValidFingerprint(mixed $fp): bool {\n    return is_string($fp) && preg_match('/^[0-9A-Fa-f]{40}$/', str_replace(' ', '', $fp)) === 1;\n}","tryCatchPattern":"try {\n    $keyId = OpenPGPBackend::fingerprintToKeyId($fp);\n} catch (\\Exception $e) {\n    if ($e->getMessage() === 'Invalid fingerprint.') {\n        // normalize/log the raw value to find the data source problem\n    }\n    throw $e;\n}","preventionTips":["Normalize fingerprints (strip spaces, uppercase) at storage time so raw values are always 40 hex chars.","Use a DB column of adequate length (CHAR(40)) to prevent silent truncation.","Centralize fingerprint parsing in one helper instead of passing around raw strings."],"tags":["openpgp","fingerprint","invalid-argument","validation"],"backgroundTag":"invalid-identifier-format","analyzedSha":"31c1bbc10f32808a607fa9bd81891e898779c0bc","analyzedAt":"2026-09-17T00:04:38.960Z","contentChangedAt":"2026-09-17T00:04:38.960Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}