Error when attempting to register a client for FHIR (Authorisation)

Situation
I installed OpenEMR 6.0 for Windows using xampp and was hoping to try using FHIR to search for patients using Postman. I am currently only using this installation for testing purposes (not for development).

I have ensured that all of the REST and FHIR API connectors have been enabled in Administration → Globals → Connectors. I have also set a site address.

I have been following both: openemr/API_README.md at master · openemr/openemr · GitHub and openemr/FHIR_README.md at master · openemr/openemr · GitHub

When I attempt to register a client, I am receiving a 500 internal server error in Postman with the following:

{
    "error": "server_error",
    "error_description": "The authorization server encountered an unexpected condition which prevented it from fulfilling the request: Security error - problem with authorization server keys.",
    "message": "The authorization server encountered an unexpected condition which prevented it from fulfilling the request: Security error - problem with authorization server keys."
}

Note: This error is returned when I send the registration request to https://<openemr_url>/openemr/oauth2/<site_parameter>/registration rather than https://<openemr_url>/oauth2/<site_parameter>/registration. https://<openemr_url>/oauth2/<site_parameter>/registration returns a 404 error.

My problem seems similar to Getting Error While Calling the Authorization Code Grant - #13 by mohit, so I tried following some of the guidance within that thread and enabled debug logs and checked the openEMR database for oauth2key and oauth2passphrase. My database only has oauth2key.

I checked C:\xampp\htdocs\openemr\sites\default\documents\certificates and neither keys are present. As far as I can tell, there is not a permission issue with the folder as everything is running as a Windows service.

I deleted the oauth2key, restarted everything, and issued another registration request from Postman. A new oauth2key was generated, but not oauth2passphrase and there are no keys in C:\xampp\htdocs\openemr\sites\default\documents\certificates.

A bit stuck on how to proceed here. Any help or guidance is greatly appreciated.

OpenEMR Version
I’m using OpenEMR version 6.0

Browser:
I’m using: Google Chrome (91.0.4472.124)
The database administration opened in Internet Explorer, but should not impact anything.

Operating System
I’m using: Microsoft Windows Server 2019 Data Centre (1809)

Logs

[Thu Jul 01 18:08:17.268416 2021] [php:notice] [pid 4484:tid 1908] [client ::1:62376] [2021-07-01T20:08:17.267167+02:00] OpenEMR.DEBUG: oauth2 request received {"endpoint":"/default/registration"} []
[Thu Jul 01 18:08:17.278417 2021] [php:notice] [pid 4484:tid 1908] [client ::1:62376] [2021-07-01T20:08:17.278401+02:00] OpenEMR.ERROR: OpenEMR error - oauth2 passphrase is missing, so forced exit [] []

Hi Brent,

This looks like a windows file permission issue but there may be something else going on here since it looks like you’ve checked that.

You could try the following to get more detailed information of what is going wrong. I’m assuming you are on release 6.0.2. First, delete your oauth2key in the database again. Then replace lines 136-175 in src/RestControllers/AuthorizationController.php with the snippet I’ve pasted below. Then run your request again and give me back the logs that were generated. This will help us figure out where exactly the process is failing for you on your windows machine. We have a windows guy that tests these things out, but he’s pretty occupied at the moment. Thank you for helping us figure this out!

if (!file_exists($this->privateKey)) {
            $this->logger->debug("private key on filesystem missing.  Generating private key.");
            // create the private/public key pair (store in filesystem) with a random passphrase (store in database)
            // first, create the passphrase (removing any prior passphrases)
            sqlStatementNoLog("DELETE FROM `keys` WHERE `name` = 'oauth2passphrase'");
            $this->passphrase = RandomGenUtils::produceRandomString(60, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
            if (empty($this->passphrase)) {
                // if empty, then force exit
                $this->logger->error("OpenEMR error - random generator broken during oauth2 key passphrase generation, so forced exit");
                throw OAuthServerException::serverError("Security error - problem with authorization server keys.");
            }
            $this->logger->debug("private key passphrase generated.");
            // second, create and store the private/public key pair
            $keysConfig = [
                "default_md" => "sha256",
                "private_key_type" => OPENSSL_KEYTYPE_RSA,
                "private_key_bits" => 2048,
                "encrypt_key" => true,
                "encrypt_key_cipher" => OPENSSL_CIPHER_AES_256_CBC
            ];
            $keys = \openssl_pkey_new($keysConfig);
            if ($keys === false) {
                // if unable to create keys, then force exit
                $this->logger->error("OpenEMR error - key generation broken during oauth2, so forced exit");
                throw OAuthServerException::serverError("Security error - problem with authorization server keys.");
            }
            $this->logger->debug("openssl private key generated.");
            $privkey = '';
            openssl_pkey_export($keys, $privkey, $this->passphrase, $keysConfig);
            $pubkey = openssl_pkey_get_details($keys);
            $pubkey = $pubkey["key"];
            if (empty($privkey) || empty($pubkey)) {
                // if unable to construct keys, then force exit
                $this->logger->error("OpenEMR error - key construction broken during oauth2, so forced exit");
                throw OAuthServerException::serverError("Security error - problem with authorization server keys.");
            }
            $this->logger->debug("public key and private key exported into string format");
            // third, store the keys on drive and store the passphrase in the database
            file_put_contents($this->privateKey, $privkey);
            $this->logger->debug("private key stored on file system.");
            chmod($this->privateKey, 0640);
            $this->logger->debug("private key permissions changed to 0640.");
            file_put_contents($this->publicKey, $pubkey);
            $this->logger->debug("public key stored on filesystem.");
            chmod($this->publicKey, 0660);
            $this->logger->debug("public key permission set to 0660.");
            sqlStatementNoLog("INSERT INTO `keys` (`name`, `value`) VALUES ('oauth2passphrase', ?)", [$this->cryptoGen->encryptStandard($this->passphrase)]);
            $this->logger->debug("private key passphrase stored on filesystem.");
        }

@brent Now that windows is mentioned there is a security issue with windows when saving files from the internet, especially zips, that the block property is set on file properties. “This file came from another computer and might be blocked to protect this computer”

Read this: Windows install of 600 can't load patients

@adunsulag @sjpadgett Thanks for the replies. It seems that I was a little behind on the latest patch release. I was on 6.0.0.

I believe that I followed the guide for installation with respect to unblocking the zip file after downloading but decided to try again from a clean slate to be sure:

  • I uninstalled OpenEMR and deleted my existing OpenEMR database
  • I downloaded a fresh copy of OpenEMR 6.0.0 and then ensured that I set the security properties of the zip to unblock
  • I installed OpenEMR 6.0.0, completed the initial set-up, enabled debug logging, and enabled the FHIR settings
  • I applied the latest patch to OpenEMR
  • I replaced lines 136-175 in src/RestControllers/AuthorizationController.php with the snippet

I then made a request to https://<openemr_url>/openemr/oauth2/<site_parameter>/registration rather than https://<openemr_url>/oauth2/<site_parameter>/registration . https://<openemr_url>/oauth2/<site_parameter>/registration returns a 404 error (maybe this will be a different forum post). I received the same error as before.

I deleted the oauth2key in the database and tried the same procedure as before and received the following logs:

[Fri Jul 02 17:48:40.390545 2021] [mpm_winnt:notice] [pid 4656:tid 640] AH00364: Child: All worker threads have exited.
[Fri Jul 02 17:48:41.003565 2021] [mpm_winnt:notice] [pid 2412:tid 708] AH00430: Parent: Child process 4656 exited successfully.
[Fri Jul 02 17:49:32.844367 2021] [ssl:warn] [pid 8844:tid 708] AH01909: www.example.com:443:0 server certificate does NOT include an ID which matches the server name
[Fri Jul 02 17:49:32.904366 2021] [ssl:warn] [pid 8844:tid 708] AH01909: www.example.com:443:0 server certificate does NOT include an ID which matches the server name
[Fri Jul 02 17:49:32.953368 2021] [mpm_winnt:notice] [pid 8844:tid 708] AH00455: Apache/2.4.48 (Win64) OpenSSL/1.1.1k PHP/8.0.7 configured -- resuming normal operations
[Fri Jul 02 17:49:32.954368 2021] [mpm_winnt:notice] [pid 8844:tid 708] AH00456: Apache Lounge VS16 Server built: May 18 2021 10:45:56
[Fri Jul 02 17:49:32.954368 2021] [core:notice] [pid 8844:tid 708] AH00094: Command line: 'C:\\xampp\\apache\\bin\\httpd.exe -d C:/xampp/apache'
[Fri Jul 02 17:49:32.973373 2021] [mpm_winnt:notice] [pid 8844:tid 708] AH00418: Parent: Created child process 8968
[Fri Jul 02 17:49:33.378378 2021] [ssl:warn] [pid 8968:tid 640] AH01909: www.example.com:443:0 server certificate does NOT include an ID which matches the server name
[Fri Jul 02 17:49:33.435368 2021] [ssl:warn] [pid 8968:tid 640] AH01909: www.example.com:443:0 server certificate does NOT include an ID which matches the server name
[Fri Jul 02 17:49:33.520374 2021] [mpm_winnt:notice] [pid 8968:tid 640] AH00354: Child: Starting 150 worker threads.
[Fri Jul 02 17:49:46.183368 2021] [php:warn] [pid 8968:tid 1920] [client ::1:52790] PHP Warning:  Array to string conversion in C:\\xampp\\htdocs\\openemr\\custom\\code_types.inc.php on line 78, referer: http://localhost/openemr/interface/main/tabs/timeout_iframe.php
[Fri Jul 02 17:49:46.183368 2021] [php:warn] [pid 8968:tid 1920] [client ::1:52790] PHP Warning:  Array to string conversion in C:\\xampp\\htdocs\\openemr\\custom\\code_types.inc.php on line 78, referer: http://localhost/openemr/interface/main/tabs/timeout_iframe.php
[Fri Jul 02 17:49:46.183368 2021] [php:warn] [pid 8968:tid 1920] [client ::1:52790] PHP Warning:  Array to string conversion in C:\\xampp\\htdocs\\openemr\\custom\\code_types.inc.php on line 78, referer: http://localhost/openemr/interface/main/tabs/timeout_iframe.php
[Fri Jul 02 17:50:00.363361 2021] [php:warn] [pid 8968:tid 1912] [client ::1:52797] PHP Warning:  Array to string conversion in C:\\xampp\\htdocs\\openemr\\custom\\code_types.inc.php on line 78
[Fri Jul 02 17:50:00.363361 2021] [php:warn] [pid 8968:tid 1912] [client ::1:52797] PHP Warning:  Array to string conversion in C:\\xampp\\htdocs\\openemr\\custom\\code_types.inc.php on line 78
[Fri Jul 02 17:50:00.364363 2021] [php:warn] [pid 8968:tid 1912] [client ::1:52797] PHP Warning:  Array to string conversion in C:\\xampp\\htdocs\\openemr\\custom\\code_types.inc.php on line 78
[Fri Jul 02 17:50:00.484363 2021] [php:notice] [pid 8968:tid 1912] [client ::1:52797] [2021-07-02T19:50:00.482793+02:00] OpenEMR.DEBUG: oauth2 request received {"endpoint":"/default/registration"} []
[Fri Jul 02 17:50:00.498371 2021] [php:notice] [pid 8968:tid 1912] [client ::1:52797] [2021-07-02T19:50:00.498215+02:00] OpenEMR.DEBUG: private key on filesystem missing.  Generating private key. [] []
[Fri Jul 02 17:50:00.500370 2021] [php:notice] [pid 8968:tid 1912] [client ::1:52797] [2021-07-02T19:50:00.500354+02:00] OpenEMR.DEBUG: private key passphrase generated. [] []
[Fri Jul 02 17:50:00.500370 2021] [php:notice] [pid 8968:tid 1912] [client ::1:52797] [2021-07-02T19:50:00.500788+02:00] OpenEMR.ERROR: OpenEMR error - key generation broken during oauth2, so forced exit [] []

To try to eliminate the issue as a folder permission problem, I set the Everyone group to have full access to the C:\xampp\htdocs\openemr\sites\default\documents\certificates folder and retried. I received the same error as before. I cannot say that this fully eliminates a permission issue, but it does lead me to believe that it may not be related to permissions. I will have to read some more if there is a way to fully verify that.

Any thoughts or other logs that I can provide?

@sjpadgett So this means the openssl_pkey_new command is breaking on brent’s machine on windows. Do you have any thoughts on why that would be Jerry?

@mohit had to change his ssl configuration in this post Getting Error While Calling the Authorization Code Grant - #20 by mohit

To the following in order to get his to work:

$keysConfig = [
“config” => “D:/Xampp-7.3.20/php/extras/openssl/openssl.cnf”,
‘private_key_bits’=> 2048,
‘default_md’ => “sha256”,
];
$keys = \openssl_pkey_new($keysConfig);

Is there something different with our key configuration on windows?

hi, this looks like a similar situation

2 Likes

Thanks, the new environment variable appears to have resolved the issue for me. Both certificates are now present in the directory and I received the expected response in Postman.

For reference, I had to set the variable value to: C:\xampp\apache\conf\openssl.cnf

1 Like

Setting the windows environment variable
OPENSSL_CONF = c\xampp\apache\conf\openssl.cnf
and restarting windows worked for me as well!
Thanks for pointing us in the right direction
I am now able to register an app and get the app id and aud uri
My config: openemr v 7.0.0 (1)
xampp 3.3.0

1 Like

Here is a clearer answer for Linux users an a mention a possible reason why you might be running into this error. In my case I was attempting to send via a CURL request ( the sample that is found in the OpenEMR API) to a virtual host instance that was using an existing test database.

The curl request was working on other virtual hosts (different test Databases that had never been used) for both OpenEMR6.0 and OpenEMR7.0 but the two vhosts (I was upgrading one customer from 6.1 to 7.0) wouldn’t work on my machine. Everything else seemed to work but I kept on getting this error when I was using Postman:

{“error”:“server_error”,“error_description”:“The authorization server encountered an unexpected condition which prevented it from fulfilling the request: Security error - problem with authorization server keys.”,“message”:“The authorization server encountered an unexpected condition which prevented it from fulfilling the request: Security error - problem with authorization server keys.”}

I wet to check the apache error log at /var/log/apache/error.log and I saw a hint to what was causing the issue. I saw this:

[Wed Jan 04 12:11:23.782365 2023] [php7:notice] [pid 206733] [client 127.0.0.1:43834] OpenEMR Error : Decryption failed authentication.

[Wed Jan 04 12:11:23.782531 2023] [php7:notice] [pid 206733] [client 127.0.0.1:43834] [2023-01-04T13:11:23.782471-07:00] OpenEMR.ERROR: OpenEMR error - oauth2 key was blank after it was decrypted, so forced exit

After doing some research I saw that there should be keys in the sites/default/documents/certificates/ folder but it was empty. These keys get generated when new keys are generated when OpenEMR starts. If there are existing keys in the DB and if this folder is empty, nothing gets put in the certs folder. This means that the API and FHIR won’t work.

My test database had previous keys in the keys table. My certs folder was empty.

To resolve this, I verified that the credentials folder was empty then I deleted the 2 oauth keys in the keys table. The keys were regenerated the next time I logged into OpenEMR and now I have successful ability to get to the API.

image|466x194

Just a note: I’m not sure if this should be done on a production site, these steps I took on a dev instance.

1 Like