{"record":{"id":"48368b7faeeba770","repo":"NationalSecurityAgency/ghidra","slug":"file-does-not-appear-to-be-a-certificate","errorCode":null,"errorMessage":"File {} does not appear to be a certificate","messagePattern":"File (.+?) does not appear to be a certificate","errorType":"exception","errorClass":"GeneralSecurityException","httpStatus":null,"severity":"error","filePath":"Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/BSimControlLaunchable.java","lineNumber":853,"sourceCode":"\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\n\t * @throws InterruptedException if the postgres command is interrupted\n\t * @throws SAXException if tuneConfig fails\n\t * @throws GeneralSecurityException if the cert file cannot be processed\n\t */\n\tprivate void initializeDataDirectory()\n\t\t\tthrows IOException, InterruptedException, SAXException, GeneralSecurityException {\n\t\tFile configFile = new File(dataDirectory, POSTGRES_CONFIGFILE);\n\t\tFile hbaFile = new File(dataDirectory, POSTGRES_CONNECTFILE);","sourceCodeStart":835,"sourceCodeEnd":871,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/BSimControlLaunchable.java#L835-L871","documentation":"Thrown by checkCertAuthorityFile() (as GeneralSecurityException) when the CA file exists and is a regular file but fails verifyPEMFormat(), i.e. its contents are not a valid PEM-encoded certificate. BSim requires a real X.509 CA in PEM form to act as PostgreSQL's ssl_ca_file (root.crt).","triggerScenarios":"Pointing --cafile at a DER-encoded cert, a private key, a concatenated bundle without BEGIN CERTIFICATE, a text file, or a truncated/corrupt PEM.","commonSituations":"Using a .der (binary) cert where PEM is required; passing a .key by mistake; PEM headers stripped or base64 mangled by copy/paste or transfer; pointing at a Java keystore (.jks) instead of an exported PEM.","solutions":["Confirm the file contains a PEM block: it should have `-----BEGIN CERTIFICATE-----` / `-----END CERTIFICATE-----`.","Convert DER to PEM: `openssl x509 -in ca.der -inform DER -out root.crt -outform PEM`.","Export the CA from a keystore to PEM using keytool/openssl.","Validate the cert independently: `openssl x509 -in root.crt -noout -text`."],"exampleFix":"// before (cafile is a DER binary)\nbsim_ctl start --auth cert --cafile ca.der\n// after\nopenssl x509 -in ca.der -inform DER -out root.crt -outform PEM\nbsim_ctl start --auth cert --cafile root.crt","handlingStrategy":"validation","validationCode":"// Mirror BSim's PEM check before invoking.\nprivate static final Pattern PEM =\n    Pattern.compile(\"(?s).*-----BEGIN CERTIFICATE-----.*-----END CERTIFICATE-----.*\");\nString body = Files.readString(Path.of(caFilePath));\nif (!PEM.matcher(body).matches()) {\n    throw new IllegalArgumentException(caFilePath + \" is not a PEM certificate\");\n}","typeGuard":"public boolean looksLikePemCert(File f) throws IOException {\n    if (!f.isFile()) return false;\n    String s = Files.readString(f.toPath());\n    return s.contains(\"-----BEGIN CERTIFICATE-----\")\n        && s.contains(\"-----END CERTIFICATE-----\");\n}","tryCatchPattern":"try {\n    bsimControl.start(args);\n} catch (GeneralSecurityException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"does not appear to be a certificate\")) {\n        throw new UserFacingException(\"Convert the CA to PEM (openssl x509 -inform DER -outform PEM)\", e);\n    }\n    throw e;\n}","preventionTips":["Standardize on PEM CA files in your provisioning pipeline.","Validate with `openssl x509 -in root.crt -noout -text` before deploying.","Reject .der/.jks/.key files at the wrapper layer."],"tags":["pki","authentication","certificate","configuration","bsim","cli"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}