[SuiteCRM] [API] [OAuth] Unable to generate private key

Hello, everyone!

Trying to get access token for API using OAuth (SuiteCRM version 7.10.10)

What I’ve done already:

  1. Generated private and public key files for OAuth, as described here: https://docs.suitecrm.com/developer/api/version-8/json-api/#_generate_private_and_public_key_for_oauth2
  2. Configured auth access to some users (https://docs.suitecrm.com/developer/api/version-8/configure-authentication)

After that I try to call GET [color=#0088ff]http://[CRM_ROOT]/api/oauth/access_token?grant_type=client_credentials&client_id=4d4f9602-4599-16bd-18ea-5c23287b4c45&client_secret=somesecret[/color] and get an error:


{
   "errors":    [
            {
         "code": 8000,
         "title": "[SuiteCRM] [API] [OAuth] Unable to generate private key",
         "status": 400
      },
            {
         "id": "1",
         "links": {"about": null},
         "status": 500,
         "code": 8000,
         "title": "JSON API Error",
         "detail": "Api Version: 8",
         "source":          {
            "pointer": null,
            "parameter": null
         },
         "meta":          {
            "about": "Exception",
            "code": 8000,
            "langMessage": null
         }
      }
   ],
   "meta": {"suiteapi":    {
      "major": 8,
      "minor": 0,
      "patch": 0,
      "stability": "ALPHA"
   }},
   "jsonapi": {"version": "1.0"}
}

Here is an extract from my suitecrm.log:


Thu Dec 27 12:27:20 2018 [26627][-none-][DEBUG] Hook called: ::after_entry_point
Thu Dec 27 12:27:20 2018 [26627][-none-][DEBUG] Including module specific hook file for custom/modules
Thu Dec 27 12:27:20 2018 [26627][-none-][DEBUG] Including Ext hook file for custom/application
Thu Dec 27 12:27:20 2018 [26627][-none-][INFO] Found language file: en_us.lang.php
Thu Dec 27 12:27:20 2018 [26627][-none-][INFO] Found language file: ru_ru.lang.php
Thu Dec 27 12:27:20 2018 [26627][-none-][INFO] Found extended language file: en_us.lang.ext.php
Thu Dec 27 12:27:20 2018 [26627][-none-][INFO] Found custom language file: en_us.lang.php
Thu Dec 27 12:27:20 2018 [26627][-none-][INFO] Found extended language file: ru_ru.lang.ext.php
Thu Dec 27 12:27:20 2018 [26627][-none-][INFO] Found custom language file: ru_ru.lang.php
Thu Dec 27 12:27:23 2018 [26627][-none-][FATAL] [ERROR] [SuiteCRM] [API] [OAuth] Unable to generate private key
Thu Dec 27 12:27:23 2018 [26627][-none-][FATAL] [SuiteCRM] [API] [OAuth] Unable to generate private key
Thu Dec 27 12:27:23 2018 [26627][-none-][WARN] Invalid JSON API error object, invalid links
Thu Dec 27 12:27:23 2018 [26627][-none-][WARN] Invalid JSON API error object, invalid source
Thu Dec 27 12:27:23 2018 [26627][-none-][WARN] Invalid JSON API error object, invalid source
Thu Dec 27 12:27:23 2018 [26627][-none-][DEBUG] Hook called: ::server_round_trip
Thu Dec 27 12:27:23 2018 [26627][-none-][DEBUG] Calling MySQLi::disconnect()

Can someone, pls, direct me further - what I’ve missed? Where to look?

Hi,

to debug this, refer to the code in

lib/API/OAuth2/Keys.php

In line 91 you will see the error being thrown.

You can create the following php file to dig into this:


<?php
$config = array(
	'digest_alg' => 'sha512',
	'private_key_bits' => 2048,
	'private_key_type' => OPENSSL_KEYTYPE_RSA,
#	'config' => '/usr/local/etc/ssl/openssl.conf',
);

$resource= openssl_pkey_new($configArgs);

if ($resource===false) {
        echo "ERROR: No resource returned <br/>\n";

	if (($e=openssl_error_string()) ==false) {
		echo "No openssl errors";
	}
	else {
      		do {
              		echo $e . " <br/>\n";
	        } while($e=openssl_error_string());
	}
}

Please not that the variable “config”, which is commented out in my code, enables you to test against different openssl.cnf files.

In my case, openssl showed errors like this, indicating that it misses a configuration value, unfortunately it doesn’t say which:

error:0EFFF06C:configuration file routines:CRYPTO_internal:no value

Even after correcting the error, and openssl_pkey_new returning a valid resource, openssl_error_string() might still return these kind of errors, which you then can ignore.

In my case I could resolve the issue by removing the comment symbol # before “default_bits” in the section [ req ] of openssl.cnf:


[ req ]
default_bits            = 2048
1 Like

jansiero, TY very much! Will try to do as you’ve said!

Hi, I made a small mistake in the test code. it should be:


<?php
$configArgs = array(
	'digest_alg' => 'sha512',
	'private_key_bits' => 2048,
	'private_key_type' => OPENSSL_KEYTYPE_RSA,
#	'config' => '/usr/local/etc/ssl/openssl.cnf',
);

$resource= openssl_pkey_new($configArgs);

if ($resource===false) {
	echo "ERROR: No resource returned <br/>\n";

	if (($e=openssl_error_string()) ==false) {
		echo "No openssl errors";
	}
	else {
		do {
			echo $e . " <br/>\n";
		} while($e=openssl_error_string());
	}
}

Let us know if you were able to solve your issue.

Hello!

Thanxx again. with your help I’ve managed to determine and fix a problem - private and public keys were in the wrong folder.

Now I can get a token with user/password auth, but only if my OAuth client is configured as non-confidential. If I set “Is Confidential” flag, I get an error:

{
“error”: “invalid_client”,
“message”: “Client authentication failed”
}

Looking to source code it seems that php password_verify function fails…
Maybe I’m doing something wrong again?

Here are my request params: grant_type=password&client_id=5ef4ef69-3db9-fa0e-5a3f-5c35e34814d1&client_secret=mysecret&username=integration&password=mypassword&scope=standard%3Aread

Hi,

it seems that the password is saved in a different hash type than the way it is checked.

Compare:


/modules/OAuth2Clients/OAuth2Clients.php

function save

With:

/lib/API/OAuth2/Repositories/ClientRepository.php

public function getClientEntity

As this seems all a work-in-progress, you could temporarily save the password hash directly by
[ul]
[li] creating the hash by creating a temporary php file:


<?php
echo password_hash('mysecretpassword',  PASSWORD_DEFAULT);

[/li]
[li] Saving it in the database table “oauth2clients”, field “secret”
[/li]
[/ul]