{"record":{"id":"13b4ff2ed8bbcbaa","repo":"NationalSecurityAgency/ghidra","slug":"pki-authentication-requested-but-certificate-auth","errorCode":null,"errorMessage":"PKI authentication requested, but certificate authority file not provided","messagePattern":"PKI authentication requested, but certificate authority file not provided","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/BSimControlLaunchable.java","lineNumber":845,"sourceCode":"\t\tif (hostMethod == null || hostMethod.equals(TRUST_METHOD)) {\n\t\t\thostAuthentication = AUTHENTICATION_NONE;\n\t\t}\n\t\telse if (hostMethod.equals(PASSWORD_METHOD)) {\n\t\t\thostAuthentication = AUTHENTICATION_PASSWORD;\n\t\t}\n\t\telse if (hostMethod.equals(CERTIFICATE_METHOD)) {\n\t\t\thostAuthentication = AUTHENTICATION_PKI;\n\t\t}\n\t}\n\n\t/**\n\t * Make sure certificate authority needed for pki was provided by user, otherwise throw exception\n\t * @throws IOException if the cert file is invalid\n\t * @throws GeneralSecurityException if the cert file is not a valid certificate\n\t */\n\tprivate void checkCertAuthorityFile() throws IOException, GeneralSecurityException {\n\t\tif (certAuthorityFile == null) {\n\t\t\tthrow new IOException(\n\t\t\t\t\"PKI authentication requested, but certificate authority file not provided\");\n\t\t}\n\t\tif (!certAuthorityFile.isFile()) {\n\t\t\tthrow new IOException(\n\t\t\t\tcertAuthorityFile.getAbsolutePath() + \" is not a valid certification authority\");\n\t\t}\n\t\tif (!verifyPEMFormat(certAuthorityFile)) {\n\t\t\tthrow new GeneralSecurityException(\n\t\t\t\t\"File \" + certAuthorityFile.getName() + \" does not appear to be a certificate\");\n\t\t}\n\t}\n\n\t/**\n\t * Locate the PostgreSQL configuration and authentication files (postgresql.conf and pg_hba.conf)\n\t * and recover the settings pertinent to BSimControl.  If the data directory has not been initialized yet,\n\t * run PostgreSQL's init command to perform the initialization and then tailor the configuration\n\t * based on BSimControl's command-line options and the Ghidra specific configuration options\n\t * @throws IOException if the module data file cannot be retrieved","sourceCodeStart":827,"sourceCodeEnd":863,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/BSimControlLaunchable.java#L827-L863","documentation":"Thrown by checkCertAuthorityFile() when BSim's PKI (certificate) authentication mode was selected but no certificate authority file was supplied. BSim requires the server's CA root to validate client certificates, so PKI cannot be configured without it. It is an IOException raised during data-directory initialization, start, changeauth, or add/drop-user flows whenever hostAuthentication == AUTHENTICATION_PKI.","triggerScenarios":"Running `bsim_ctl start` (or adduser/dropuser/changeauth) with `--auth cert` but omitting `--cafile <path>`. The option parser sets hostAuthentication/localAuthentication to AUTHENTICATION_PKI on `--auth cert` and leaves certAuthorityFile null; checkCertAuthorityFile() then throws.","commonSituations":"Operator forgets the --cafile flag after switching to certificate auth; copy-pasting a start command from a password-auth setup into a PKI deployment; misreading --cert (client cert) for --cafile (server CA).","solutions":["Add `--cafile /path/to/ca/root.crt` to the bsim_ctl command line.","Verify the file exists and is readable: `test -f root.crt`.","If you did not intend PKI, use `--auth scram-sha-256` (password) or `--auth trust` instead.","For adduser/dropuser against an already-PKI-configured server, ensure the CA file is still present and pass --cafile again."],"exampleFix":"// before\nbsim_ctl start --auth cert --port 8080\n// after\nbsim_ctl start --auth cert --cafile /etc/bsim/root.crt --dn \"CN=admin\" --cert /etc/bsim/client.crt --port 8080","handlingStrategy":"validation","validationCode":"// Before calling BSimControlLaunchable / building the command, validate PKI inputs.\nboolean pkiRequested = \"cert\".equals(authMode);\nif (pkiRequested && (caFilePath == null || caFilePath.isBlank())) {\n    throw new IllegalArgumentException(\n        \"--cafile <path> is required when --auth cert is used\");\n}","typeGuard":"// Narrow a parsed options object before invoking BSim control.\npublic boolean isPkiConfigComplete(BsimCtlOptions o) {\n    if (!\"cert\".equals(o.auth)) return true;          // not PKI -> nothing to check\n    return o.cafile != null && new File(o.cafile).isFile()\n        && o.dn != null && o.dn.contains(\"CN=\")\n        && o.cert != null;\n}","tryCatchPattern":"try {\n    bsimControl.start(args);\n} catch (IOException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"certificate authority file not provided\")) {\n        // surface a user-facing hint to add --cafile\n        throw new UserFacingException(\"PKI auth requires --cafile <CA path>\", e);\n    }\n    throw e;\n}","preventionTips":["Treat --auth cert, --cafile, --dn, and --cert as a single required group in any wrapper script.","Validate the option group before invoking bsim_ctl and fail fast with a clear message.","Keep a checked-in example command per auth mode."],"tags":["pki","authentication","configuration","bsim","cli","postgresql"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}