core_processor.c
Go to the documentation of this file.
1 
9 #include "core_processor.h"
10 #include "http_definitions.h"
11 #include "json_util.h"
12 #include "list.h"
13 #include "definitions.h"
14 #include "jwt.h"
15 #include "security.h"
16 #include "random.h"
17 #include "string_util.h"
18 #include "time_util.h"
19 #include "mcl_core/mcl_assert.h"
21 #include "mcl_core/mcl_file_util.h"
22 #include "mcl_core/mcl_memory.h"
23 
24 #define JSON_NAME_CLIENT_ID "client_id"
25 #define JSON_NAME_TOKEN_ENDPOINT_AUTH_METHOD "token_endpoint_auth_method"
26 #define JSON_NAME_GRANT_TYPES "grant_types"
27 #define JSON_NAME_CLIENT_SECRET "client_secret"
28 #define JSON_NAME_CLIENT_SECRET_EXPIRES_AT "client_secret_expires_at"
29 #define JSON_NAME_REGISTRATION_ACCESS_TOKEN "registration_access_token"
30 #define JSON_NAME_REGISTRATION_CLIENT_URI "registration_client_uri"
31 #define JSON_NAME_JWKS "jwks"
32 #define JSON_NAME_KEYS "keys"
33 #define JSON_NAME_E "e"
34 #define JSON_NAME_N "n"
35 #define JSON_NAME_KTY "kty"
36 #define JSON_NAME_KID "kid"
37 #define JSON_NAME_ACCESS_TOKEN "access_token"
38 
39 #define REGISTER_URI_PATH "/register"
40 #define ACCESS_TOKEN_URI_PATH "/token"
41 
42 #define CORRELATION_ID_BYTE_LENGTH 16
43 
44 static const char _bearer_format[] = "Bearer %s";
45 static const char _client_id_format[] = "{\"client_id\":\"%s\"}";
46 static const char _string_identifier[] = "%s";
47 
51 typedef enum E_ENDPOINT_URI
52 {
57 
65 {
70 
71 // This function processes the HTTP response to an onboarding or key rotation request for shared secret security profile.
73 
74 // This function processes the HTTP response to an onboarding or key rotation request for shared RSA 3072 security profile.
76 
77 // This is the array for endpoints.
78 static const char *endpoint_uri[ENDPOINT_URI_END] =
79 {
80  "/api/agentmanagement/v3/oauth/token",
81  "/api/agentmanagement/v3/register"
82 };
83 
84 // Content type values.
86 {
87  "application/json",
88  "application/x-www-form-urlencoded"
89 };
90 
91 // Composes JSON string for onboarding with RSA security profile.
92 static mcl_error_t _compose_rsa_onboarding_json(security_handler_t *security_handler, char **payload);
93 
94 // Composes JSON string for key rotation with RSA security profile.
95 static mcl_error_t _compose_rsa_key_rotation_json(security_handler_t *security_handler, char **payload);
96 
97 // Adds jwks to root json.
98 static mcl_error_t _add_jwks(mcl_json_t *root, security_handler_t *security_handler);
99 
100 // Adds key json object to keys json array.
101 static mcl_error_t _add_key_to_keys_array(mcl_json_t *root, mcl_json_t **json_object);
102 
103 // Use custom function for loading register info.
105 static mcl_error_t _generate_correlation_id_string(char **correlation_id);
106 
107 // Saves credentials.
108 static mcl_error_t _save_credentials(core_processor_t *core_processor);
109 
110 // Compose the payload for the request to be sent to /token endpoint.
111 static mcl_error_t _compose_access_token_request_payload(core_processor_t *core_processor, char **request_payload);
112 
113 // Function to load initial credentials.
115 
116 // Function to process registration response.
117 static mcl_error_t _process_registration_response(core_processor_t *core_processor, mcl_http_response_t *http_response, char *correlation_id);
118 
119 // Function to check if client secret is already up to date or not.
120 static mcl_error_t _check_client_secret(core_processor_t *core_processor, char *registration_access_token, char *client_secret);
121 
122 // Function to check if RSA private key is already up to date or not.
123 static mcl_error_t _check_rsa_private_key(core_processor_t *core_processor, char *private_key);
124 
126 {
127  // Return code for the functions to be called.
128  mcl_error_t return_code;
129 
130  // We need http_client_configuration temporarily, no need for dynamic allocation.
131  mcl_http_client_configuration_t http_client_configuration;
132 
133  MCL_DEBUG_ENTRY("core_configuration_t *configuration = <%p>, core_processor_t **core_processor = <%p>", configuration, core_processor);
134 
135  // Initialize json module.
137 
138  // Initialize security module.
139  return_code = security_initialize();
140  MCL_ASSERT_CODE_MESSAGE(MCL_OK == return_code, return_code, "Security initialization failed.");
141 
142  // Create core processor handle.
143  MCL_NEW(*core_processor);
144  MCL_ASSERT_CODE_MESSAGE(MCL_NULL != *core_processor, MCL_OUT_OF_MEMORY, "Memory can not be allocated for core processor.");
145 
146  // Make sure pointer members of core_processor which will be created inside this function are null initially.
147  // This is necessary for an unexpected call to core_processor_destroy() function.
148  (*core_processor)->http_client = MCL_NULL;
149  (*core_processor)->security_handler = MCL_NULL;
150 
151  // Set pointer to configuration parameters.
152  (*core_processor)->configuration = configuration;
153 
154  // Initialize http client configuration.
155  http_client_configuration.certificate = configuration->mindsphere_certificate;
156  http_client_configuration.proxy_hostname = configuration->proxy_hostname;
157  http_client_configuration.proxy_username = configuration->proxy_username;
158  http_client_configuration.proxy_domain = configuration->proxy_domain;
159  http_client_configuration.user_agent = configuration->user_agent;
160  http_client_configuration.proxy_password = configuration->proxy_password;
161  http_client_configuration.http_request_timeout = configuration->http_request_timeout;
162  http_client_configuration.port = configuration->mindsphere_port;
163  http_client_configuration.proxy_port = configuration->proxy_port;
164  http_client_configuration.proxy_type = configuration->proxy_type;
165  http_client_configuration.certificate_is_file = configuration->certificate_is_file;
166 
167  // Initialize http client.
168  return_code = mcl_http_client_initialize(&http_client_configuration, &((*core_processor)->http_client));
169  MCL_ASSERT_STATEMENT_CODE_MESSAGE(MCL_OK == return_code, core_processor_destroy(core_processor), return_code, "Http client initialization failed.");
170  MCL_DEBUG("Http client is successfully initialized.");
171 
172  // Initialize security handler.
173  return_code = security_handler_initialize(&((*core_processor)->security_handler));
174  MCL_ASSERT_STATEMENT_CODE_MESSAGE(MCL_OK == return_code, core_processor_destroy(core_processor), return_code, "Security handler initialization failed.");
175  MCL_DEBUG("Security handler is successfully initialized.");
176 
177  // Load credentials via custom functions if both function pointers are not null.
178  if ((MCL_NULL != (*core_processor)->configuration->credentials_load_callback.rsa) &&
179  (MCL_NULL != (*core_processor)->configuration->credentials_save_callback.rsa))
180  {
181  return_code = _custom_load_register_info(*core_processor);
182 
183  if (MCL_OK == return_code)
184  {
185  MCL_INFO("MCL is initialized with the credentials provided by the callback function.");
186  }
187  else if (MCL_CREDENTIALS_NOT_LOADED == return_code)
188  {
189  return_code = _load_initial_credentials(*core_processor);
190  }
191  else
192  {
193  MCL_INFO("Credentials could not be loaded.");
194  core_processor_destroy(core_processor);
195  }
196  }
197  else
198  {
199  return_code = _load_initial_credentials(*core_processor);
200  }
201 
202  // Populate endpoints in configuration.
203  if (MCL_OK == return_code)
204  {
205  return_code = string_util_concatenate((*core_processor)->configuration->mindsphere_hostname, endpoint_uri[ENDPOINT_URI_REGISTER],
206  &(*core_processor)->configuration->register_endpoint);
207  }
208 
209  if (MCL_OK == return_code)
210  {
211  return_code = string_util_concatenate((*core_processor)->configuration->mindsphere_hostname, endpoint_uri[ENDPOINT_URI_ACCESS_TOKEN],
212  &(*core_processor)->configuration->token_endpoint);
213  }
214 
215  if (MCL_OK != return_code)
216  {
217  core_processor_destroy(core_processor);
218  }
219 
220  MCL_DEBUG_LEAVE("retVal = <%d>", return_code);
221  return return_code;
222 }
223 
225 {
226  mcl_error_t code = MCL_OK;
227 
228  MCL_DEBUG_ENTRY("core_processor_t *core_processor = <%p>", core_processor);
229 
230  if (MCL_NULL == core_processor->configuration->initial_access_token)
231  {
232  MCL_ERROR("No credential is provided.");
234  }
235  else
236  {
237  // Generate RSA keys if RSA security profile is selected.
238  if (MCL_SECURITY_RSA_3072 == core_processor->configuration->security_profile)
239  {
240  code = security_handler_generate_rsa_key(core_processor->security_handler);
241  MCL_ASSERT_CODE_MESSAGE(MCL_OK == code, code, "RSA keys can not be generated.");
242  MCL_DEBUG("RSA keys are generated.");
243  }
244  MCL_INFO("MCL is initialized to onboard with initial access token.");
245  code = MCL_OK;
246  }
247 
248  MCL_DEBUG_LEAVE("retVal = <%d>", code);
249  return code;
250 }
251 
253 {
254  mcl_error_t result = MCL_FAIL;
255  mcl_uint32_t auth_header_value_length;
256  mcl_http_request_t *http_request = MCL_NULL;
257  mcl_http_response_t *http_response = MCL_NULL;
258  char *auth_header_value = MCL_NULL;
259  char *registration_uri = MCL_NULL;
260  char *payload = MCL_NULL;
261  char *correlation_id = MCL_NULL;
262  char *token_for_auth = MCL_NULL;
263  mcl_size_t payload_length;
264  E_MCL_HTTP_METHOD http_method;
265 
266  MCL_DEBUG_ENTRY("core_processor_t *core_processor = <%p>", core_processor);
267 
268  // Determine if onboarding or key rotation is requested.
269  if (MCL_NULL == core_processor->security_handler->registration_access_token)
270  {
271  // Compose payload of the request.
273  {
274  payload = MCL_MALLOC(2 + MCL_NULL_CHAR_SIZE);
275 
276  if (MCL_NULL != payload)
277  {
278  result = string_util_snprintf(payload, 2 + MCL_NULL_CHAR_SIZE, "{}");
279  }
280  else
281  {
282  result = MCL_OUT_OF_MEMORY;
283  }
284  }
285  else if (MCL_SECURITY_RSA_3072 == core_processor->configuration->security_profile)
286  {
287  result = _compose_rsa_onboarding_json(core_processor->security_handler, &payload);
288  }
289 
290  token_for_auth = core_processor->configuration->initial_access_token;
291  http_method = MCL_HTTP_POST;
292  registration_uri = core_processor->configuration->register_endpoint;
293  }
294  else
295  {
296  // Compose payload of the request.
298  {
299  // Payload length including null character size.
300  payload_length = (mcl_uint32_t) ((sizeof(_client_id_format) - sizeof(_string_identifier)) +
302  payload = MCL_MALLOC(payload_length);
303  if (MCL_NULL != payload)
304  {
305  result = string_util_snprintf(payload, payload_length, _client_id_format, core_processor->security_handler->client_id);
306  }
307  else
308  {
309  result = MCL_OUT_OF_MEMORY;
310  }
311  }
312  else if (MCL_SECURITY_RSA_3072 == core_processor->configuration->security_profile)
313  {
314  result = _compose_rsa_key_rotation_json(core_processor->security_handler, &payload);
315  }
316 
317  token_for_auth = core_processor->security_handler->registration_access_token;
318  http_method = MCL_HTTP_PUT;
319  registration_uri = core_processor->security_handler->registration_uri;
320  }
321 
322  MCL_ASSERT_STATEMENT_CODE_MESSAGE(MCL_OK == result, MCL_FREE(payload), result, "Payload for register endpoint can not be constructed.");
323 
324  // Auth header value length including null character size.
325  auth_header_value_length = (mcl_uint32_t) ((sizeof(_bearer_format) - sizeof(_string_identifier)) + string_util_strlen(token_for_auth) + MCL_NULL_CHAR_SIZE);
326  auth_header_value = MCL_MALLOC(auth_header_value_length);
327 
328  if (MCL_NULL != auth_header_value)
329  {
330  result = string_util_snprintf(auth_header_value, auth_header_value_length, _bearer_format, token_for_auth);
331  }
332  else
333  {
334  MCL_FREE(payload);
335  result = MCL_OUT_OF_MEMORY;
336  }
337 
338  if (MCL_OK == result)
339  {
340  result = mcl_http_request_initialize(&http_request);
341  }
342 
343  if (MCL_OK == result)
344  {
345  result = mcl_http_request_set_parameter(http_request, MCL_HTTP_REQUEST_PARAMETER_METHOD, &http_method);
346  }
347 
348  if (MCL_OK == result)
349  {
350  result = mcl_http_request_set_parameter(http_request, MCL_HTTP_REQUEST_PARAMETER_URL, registration_uri);
351  }
352 
353  if (MCL_OK == result)
354  {
355  result = mcl_http_request_set_parameter(http_request, MCL_HTTP_REQUEST_PARAMETER_BODY, payload);
356  }
357 
358  if (MCL_OK == result)
359  {
360  payload_length = string_util_strlen(payload);
361  result = mcl_http_request_set_parameter(http_request, MCL_HTTP_REQUEST_PARAMETER_BODY_SIZE, &payload_length);
362  }
363 
364  // Compose headers of HTTP request.
365  if (MCL_OK == result)
366  {
368  }
369 
370  if (MCL_OK == result)
371  {
373  }
374 
375  if (MCL_OK == result)
376  {
377  result = mcl_http_request_add_header(http_request, http_header_names[HTTP_HEADER_AUTHORIZATION], auth_header_value);
378  }
379 
380  if (MCL_OK == result)
381  {
382  result = _generate_correlation_id_string(&correlation_id);
383  }
384 
385  if (MCL_OK == result)
386  {
387  result = mcl_http_request_add_header(http_request, http_header_names[HTTP_HEADER_CORRELATION_ID], correlation_id);
388  }
389 
390  // Send the request and get the response.
391  if (MCL_OK == result)
392  {
393  // Send the onboarding request and retrieve the response.
394  if (MCL_OK != (result = mcl_http_client_send(core_processor->http_client, http_request, &http_response)))
395  {
396  MCL_ERROR("HTTP client error when accessing /register endpoint.");
397  }
398  else
399  {
400  result = _process_registration_response(core_processor, http_response, correlation_id);
401  }
402  }
403 
404  // Clean up.
405  MCL_FREE(correlation_id);
406  MCL_FREE(payload);
407  MCL_FREE(auth_header_value);
408  mcl_http_request_destroy(&http_request);
409  mcl_http_response_destroy(&http_response);
410 
411  MCL_DEBUG_LEAVE("retVal = <%d>", result);
412  return result;
413 }
414 
415 static mcl_error_t _process_registration_response(core_processor_t *core_processor, mcl_http_response_t *http_response, char *correlation_id)
416 {
417  mcl_error_t code;
418  mcl_error_t server_response;
419  mcl_bool_t is_onboard_request;
420 
421  MCL_DEBUG_ENTRY("core_processor_t *core_processor = <%p>, mcl_http_response_t *http_response = <%p>, char *correlation_id = <%p> ",
422  core_processor, http_response, correlation_id);
423 
424  server_response = mcl_http_response_get_status(http_response);
425  is_onboard_request = (MCL_NULL == core_processor->security_handler->registration_access_token) ? MCL_TRUE : MCL_FALSE;
426 
427  if (MCL_TRUE == is_onboard_request)
428  {
429  if (MCL_OK == server_response)
430  {
431  // HTTP 201 should have been received instead of 200.
433  }
434  else if (MCL_CREATED == server_response)
435  {
436  code = MCL_OK;
437  }
438  else
439  {
440  code = server_response;
441  }
442  }
443  else
444  {
445  code = server_response;
446  }
447 
448  if (MCL_OK == code)
449  {
450  MCL_INFO("Correlation-ID = \"%s\"", correlation_id);
451 
453  {
454  code = _process_registration_response_shared_secret(core_processor, http_response);
455  }
456  else
457  {
458  code = _process_registration_response_rsa_3072(core_processor, http_response);
459  }
460 
461  if (MCL_OK == code)
462  {
463  code = _save_credentials(core_processor);
464  }
465  }
466  else
467  {
468  MCL_ERROR("HTTP <%d> received from server for the request with correlation-id = \"%s\".", http_response->status_code, correlation_id);
469 
470  if (MCL_NULL != http_response->payload)
471  {
472  MCL_ERROR("HTTP Response Body:\n%.*s", http_response->payload_size, http_response->payload);
473  }
474  }
475 
476  MCL_DEBUG_LEAVE("retVal = <%d>", code);
477  return code;
478 }
479 
481 {
482  mcl_error_t code;
483  mcl_size_t length;
484  mcl_bool_t callbacks_are_used;
485 
486  // These will be used in any security profile.
487  char *client_id = MCL_NULL;
488  char *registration_access_token = MCL_NULL;
489  char *registration_uri = MCL_NULL;
490 
491  // For shared secret.
492  char *client_secret = MCL_NULL;
493 
494  // For RSA 3072.
495  char *public_key = MCL_NULL;
496  char *private_key = MCL_NULL;
497 
498  MCL_DEBUG_ENTRY("core_processor_t *core_processor = <%p>", core_processor);
499 
500  callbacks_are_used = (MCL_NULL != core_processor->configuration->credentials_load_callback.shared_secret) &&
502  MCL_ASSERT_CODE_MESSAGE(MCL_TRUE == callbacks_are_used, MCL_FAIL, "There is no way to update credentials.");
503 
505  {
506  code = core_processor->configuration->credentials_load_callback.shared_secret(&client_id, &client_secret,
507  &registration_access_token, &registration_uri);
508  }
509  else
510  {
511  code = core_processor->configuration->credentials_load_callback.rsa(&client_id, &public_key, &private_key,
512  &registration_access_token, &registration_uri);
513  }
514 
515  // If loading credentials is failed, user must have set all parameters to NULL. No need to clean up.
516  MCL_ASSERT_CODE_MESSAGE(MCL_OK == code, code, "Security information cannot be loaded.");
517 
518  // Registration URI will not be used.
519  MCL_FREE(registration_uri);
520 
521  // Check whether client id is correct.
522  length = string_util_strlen(core_processor->security_handler->client_id);
523  code = MCL_FAIL;
524 
525  if (length == string_util_strlen(client_id))
526  {
527  code = string_util_strncmp(client_id, core_processor->security_handler->client_id, length);
528  }
529 
530  MCL_FREE(client_id);
531 
532  if (MCL_OK == code)
533  {
535  {
536  code = _check_client_secret(core_processor, registration_access_token, client_secret);
537  }
538  else
539  {
540  code = _check_rsa_private_key(core_processor, private_key);
541  }
542 
543  // If code == MCL_OK, client secret is not different from what we have.
544  code = (MCL_OK == code) ? MCL_CREDENTIALS_UP_TO_DATE : MCL_OK;
545  }
546 
547  if (MCL_OK == code)
548  {
549  // Everything is fine, now we can replace old information.
550  // There is no need to check security profile, unrelated parameters will be just reassigned to NULL.
552  MCL_FREE((core_processor->security_handler->client_secret));
553  MCL_FREE(core_processor->security_handler->rsa.public_key);
554  MCL_FREE(core_processor->security_handler->rsa.private_key);
555 
556  core_processor->security_handler->registration_access_token = registration_access_token;
557  core_processor->security_handler->client_secret = client_secret;
558  core_processor->security_handler->rsa.public_key = public_key;
559  core_processor->security_handler->rsa.private_key = private_key;
560  }
561  else
562  {
563  MCL_FREE(registration_access_token);
564  MCL_FREE(client_secret);
565  MCL_FREE(public_key);
566  MCL_FREE(private_key);
567  }
568 
569  MCL_DEBUG_LEAVE("retVal = <%d>", code);
570  return code;
571 }
572 
573 static mcl_error_t _check_client_secret(core_processor_t *core_processor, char *registration_access_token, char *client_secret)
574 {
575  mcl_size_t length;
576  mcl_error_t code = MCL_FAIL;
577 
578  MCL_DEBUG_ENTRY("core_processor_t *core_processor = <%p>, char *registration_access_token = <%p>, char *client_secret = <%p>",
579  core_processor, registration_access_token, client_secret);
580 
581  length = string_util_strlen(core_processor->security_handler->client_secret);
582 
583  if (string_util_strlen(client_secret) == length)
584  {
585  code = string_util_strncmp(client_secret, core_processor->security_handler->client_secret, length);
586  }
587 
588  if (MCL_OK == code)
589  {
590 
592  code = MCL_FAIL;
593 
594  if (string_util_strlen(registration_access_token) == length)
595  {
596  code = string_util_strncmp(registration_access_token, core_processor->security_handler->registration_access_token, length);
597  }
598  }
599 
600  MCL_DEBUG_LEAVE("retVal = <%d>", code);
601  return code;
602 }
603 
604 static mcl_error_t _check_rsa_private_key(core_processor_t *core_processor, char *private_key)
605 {
606  mcl_size_t length;
607  mcl_error_t code = MCL_FAIL;
608 
609  MCL_DEBUG_ENTRY("core_processor_t *core_processor = <%p>, char *private_key = <%p>", core_processor, private_key);
610 
611  length = string_util_strlen(core_processor->security_handler->rsa.private_key);
612 
613  if (string_util_strlen(private_key) == length)
614  {
615  code = string_util_strncmp(private_key, core_processor->security_handler->rsa.private_key, length);
616  }
617 
618  MCL_DEBUG_LEAVE("retVal = <%d>", code);
619  return code;
620 }
621 
623 {
624  mcl_error_t code;
625  char *request_payload = MCL_NULL;
626  char *correlation_id = MCL_NULL;
627  mcl_http_request_t *request = MCL_NULL;
628  mcl_http_response_t *response = MCL_NULL;
629  char *server_time_header = MCL_NULL;
630  mcl_json_t *response_payload_json = MCL_NULL;
631  mcl_json_t *access_token = MCL_NULL;
632  E_MCL_HTTP_METHOD http_method = MCL_HTTP_POST;
633 
634  MCL_DEBUG_ENTRY("core_processor_t *core_processor = <%p>", core_processor);
635 
636  // Create access token request payload.
637  code = _compose_access_token_request_payload(core_processor, &request_payload);
638 
639  // Initialize HTTP request.
640  if (MCL_OK == code)
641  {
642  code = mcl_http_request_initialize(&request);
643  }
644 
645  if (MCL_OK == code)
646  {
648  }
649 
650  if (MCL_OK == code)
651  {
653  }
654 
655  // Add headers to the request.
656  if (MCL_OK == code)
657  {
659  }
660 
661  if (MCL_OK == code)
662  {
663  code = _generate_correlation_id_string(&correlation_id);
664  }
665 
666  if (MCL_OK == code)
667  {
669  }
670 
671  // Add payload to the request.
672  if (MCL_OK == code)
673  {
674  code = mcl_http_request_set_parameter(request, MCL_HTTP_REQUEST_PARAMETER_BODY, request_payload);
675  }
676 
677  if (MCL_OK == code)
678  {
679  mcl_size_t payload_length = string_util_strlen(request_payload);
681  }
682 
683  // Send the request.
684  if (MCL_OK == code)
685  {
686  code = mcl_http_client_send(core_processor->http_client, request, &response);
687  }
688 
689  mcl_http_request_destroy(&request);
690  MCL_FREE(request_payload);
691 
692  // Get server time which is an optional header in the response.
693  if (MCL_OK == code)
694  {
695  mcl_error_t optional_field_code = mcl_http_response_get_header(response, http_header_names[HTTP_HEADER_SERVER_TIME], &server_time_header);
696 
697  if (MCL_OK == optional_field_code)
698  {
699  MCL_FREE((core_processor->security_handler->last_token_time));
700  core_processor->security_handler->last_token_time = server_time_header;
701  }
702 
703  code = mcl_http_response_get_status(response);
704 
705  if (MCL_OK == code)
706  {
707  MCL_INFO("Correlation-ID = \"%s\"", correlation_id);
708  }
709  else
710  {
711  MCL_ERROR("HTTP <%d> received from server for the request with correlation-id = \"%s\".", response->status_code, correlation_id);
712 
713  if (MCL_NULL != response->payload)
714  {
715  MCL_ERROR("HTTP Response:\n%.*s", response->payload_size, response->payload);
716  }
717  }
718  }
719  else
720  {
721  MCL_ERROR("Http client error when accessing /token endpoint.");
722  }
723 
724  MCL_FREE(correlation_id);
725 
726  // Parse the response to get access token.
727  if (MCL_OK == code)
728  {
729  code = json_util_parse((char *)response->payload, response->payload_size, &response_payload_json);
730  }
731 
732  mcl_http_response_destroy(&response);
733 
734  if (MCL_OK == code)
735  {
736  code = json_util_get_object_item(response_payload_json, JSON_NAME_ACCESS_TOKEN, &access_token);
737  }
738 
739  MCL_FREE(core_processor->security_handler->access_token);
740 
741  if (MCL_OK == code)
742  {
743  code = json_util_get_string(access_token, &core_processor->security_handler->access_token);
744  }
745 
746  json_util_destroy(&response_payload_json);
747 
748  MCL_DEBUG_LEAVE("retVal = <%d>", code);
749  return code;
750 }
751 
753 {
754  MCL_DEBUG_ENTRY("core_processor_t **core_processor = <%p>", core_processor);
755 
756  if (MCL_NULL != *core_processor)
757  {
758  // Destroy http client handler.
759  mcl_http_client_destroy(&((*core_processor)->http_client));
760 
761  // Destroy security handler.
762  security_handler_destroy(&((*core_processor)->security_handler));
763 
764  MCL_FREE((*core_processor)->configuration->token_endpoint);
765  MCL_FREE((*core_processor)->configuration->register_endpoint);
766 
767  // Free core_processor handle.
768  MCL_FREE(*core_processor);
769 
770  MCL_DEBUG("Core processor handle is destroyed.");
771  }
772  else
773  {
774  MCL_DEBUG("Core processor handle is already NULL.");
775  }
776 
777  MCL_DEBUG_LEAVE("retVal = void");
778 }
779 
781 {
782  mcl_error_t code;
783  mcl_json_t *json_root = MCL_NULL;
784  mcl_json_t *client_id = MCL_NULL;
785  mcl_json_t *client_secret = MCL_NULL;
786  mcl_json_t *registration_access_token = MCL_NULL;
787  mcl_json_t *registration_client_uri = MCL_NULL;
788 
789  MCL_DEBUG_ENTRY("core_processor_t *core_processor = <%p>, mcl_http_response_t *http_response = <%p>", core_processor, http_response);
790 
791  code = json_util_parse((char *)http_response->payload, http_response->payload_size, &json_root);
792 
793  if (MCL_OK == code)
794  {
795  code = json_util_get_object_item(json_root, JSON_NAME_CLIENT_ID, &client_id);
796  }
797 
798  if (MCL_OK == code)
799  {
800  code = json_util_get_object_item(json_root, JSON_NAME_CLIENT_SECRET, &client_secret);
801  }
802 
803  if (MCL_OK == code)
804  {
805  code = json_util_get_object_item(json_root, JSON_NAME_REGISTRATION_ACCESS_TOKEN, &registration_access_token);
806  }
807 
808  if (MCL_OK == code)
809  {
810  code = json_util_get_object_item(json_root, JSON_NAME_REGISTRATION_CLIENT_URI, &registration_client_uri);
811  }
812 
813  if (MCL_OK == code)
814  {
815  char *temp_client_id = MCL_NULL;
816  char *temp_client_secret = MCL_NULL;
817  char *temp_registration_access_token = MCL_NULL;
818  char *temp_registration_uri = MCL_NULL;
819 
820  code = json_util_get_string(client_id, &temp_client_id);
821 
822  if (MCL_OK == code)
823  {
824  code = json_util_get_string(client_secret, &temp_client_secret);
825  }
826 
827  if (MCL_OK == code)
828  {
829  code = json_util_get_string(registration_access_token, &temp_registration_access_token);
830  }
831 
832  if (MCL_OK == code)
833  {
834  code = json_util_get_string(registration_client_uri, &temp_registration_uri);
835  }
836 
837  // If everything is fine, we can replace credentials.
838  if (MCL_OK == code)
839  {
840  MCL_FREE(core_processor->security_handler->client_id);
841  MCL_FREE(core_processor->security_handler->client_secret);
843  MCL_FREE(core_processor->security_handler->registration_uri);
844 
845  core_processor->security_handler->client_id = temp_client_id;
846  core_processor->security_handler->client_secret = temp_client_secret;
847  core_processor->security_handler->registration_access_token = temp_registration_access_token;
848  core_processor->security_handler->registration_uri = temp_registration_uri;
849  }
850  else
851  {
852  MCL_FREE(temp_client_id);
853  MCL_FREE(temp_client_secret);
854  MCL_FREE(temp_registration_access_token);
855  MCL_FREE(temp_registration_uri);
856  }
857  }
858 
859  json_util_destroy(&json_root);
860 
861  MCL_DEBUG_LEAVE("retVal = <%d>", code);
862  return code;
863 }
864 
866 {
867  mcl_error_t code;
868  mcl_json_t *json_root = MCL_NULL;
869  mcl_json_t *client_id = MCL_NULL;
870  mcl_json_t *registration_access_token = MCL_NULL;
871  mcl_json_t *registration_client_uri = MCL_NULL;
872 
873  MCL_DEBUG_ENTRY("core_processor_t *core_processor = <%p>, mcl_http_response_t *http_response = <%p>", core_processor, http_response);
874 
875  code = json_util_parse((char *)http_response->payload, http_response->payload_size, &json_root);
876 
877  if (MCL_OK == code)
878  {
879  code = json_util_get_object_item(json_root, JSON_NAME_CLIENT_ID, &client_id);
880  }
881 
882  if (MCL_OK == code)
883  {
884  code = json_util_get_object_item(json_root, JSON_NAME_REGISTRATION_ACCESS_TOKEN, &registration_access_token);
885  }
886 
887  if (MCL_OK == code)
888  {
889  code = json_util_get_object_item(json_root, JSON_NAME_REGISTRATION_CLIENT_URI, &registration_client_uri);
890  }
891 
892  if (MCL_OK == code)
893  {
894  char *temp_client_id = MCL_NULL;
895  char *temp_registration_access_token = MCL_NULL;
896  char *temp_registration_uri = MCL_NULL;
897 
898  code = json_util_get_string(client_id, &temp_client_id);
899 
900  if (MCL_OK == code)
901  {
902  code = json_util_get_string(registration_access_token, &temp_registration_access_token);
903  }
904 
905  if (MCL_OK == code)
906  {
907  code = json_util_get_string(registration_client_uri, &temp_registration_uri);
908  }
909 
910  // If everything is fine, we can replace credentials.
911  if (MCL_OK == code)
912  {
913  MCL_FREE(core_processor->security_handler->client_id);
915  MCL_FREE(core_processor->security_handler->registration_uri);
916 
917  core_processor->security_handler->client_id = temp_client_id;
918  core_processor->security_handler->registration_access_token = temp_registration_access_token;
919  core_processor->security_handler->registration_uri = temp_registration_uri;
920  }
921  else
922  {
923  MCL_FREE(temp_client_id);
924  MCL_FREE(temp_registration_access_token);
925  MCL_FREE(temp_registration_uri);
926  }
927  }
928 
929  // Child json objects are reference to their parts in root json. So we only free the struct.
930  json_util_destroy(&json_root);
931 
932  MCL_DEBUG_LEAVE("retVal = <%d>", code);
933  return code;
934 }
935 
936 static mcl_error_t _compose_rsa_onboarding_json(security_handler_t *security_handler, char **payload)
937 {
938  mcl_error_t code;
939  mcl_json_t *root = MCL_NULL;
940 
941  MCL_DEBUG_ENTRY("security_handler_t *security_handler = <%p>, char **payload = <%p>", security_handler, payload);
942 
943  code = json_util_initialize(MCL_JSON_OBJECT, &root);
944 
945  if (MCL_OK == code)
946  {
947  code = _add_jwks(root, security_handler);
948  }
949 
950  if (MCL_OK == code)
951  {
952  code = json_util_to_string(root, payload);
953  }
954 
955  if (MCL_OK != code)
956  {
957  MCL_FREE(*payload);
958  }
959 
960  json_util_destroy(&root);
961 
962  MCL_DEBUG_LEAVE("retVal = <%d>", code);
963  return code;
964 }
965 
966 static mcl_error_t _compose_rsa_key_rotation_json(security_handler_t *security_handler, char **payload)
967 {
968  mcl_error_t code;
969  mcl_json_t *root = MCL_NULL;
970 
971  MCL_DEBUG_ENTRY("security_handler_t *security_handler = <%p>, char **payload = <%p>", security_handler, payload);
972 
973  MCL_FREE(security_handler->rsa.public_key);
974  MCL_FREE(security_handler->rsa.private_key);
975  code = security_handler_generate_rsa_key(security_handler);
976 
977  if (MCL_OK == code)
978  {
979  code = json_util_initialize(MCL_JSON_OBJECT, &root);
980  }
981 
982  if (MCL_OK == code)
983  {
984  code = json_util_add_string(root, JSON_NAME_CLIENT_ID, security_handler->client_id);
985  }
986 
987  if (MCL_OK == code)
988  {
989  code = _add_jwks(root, security_handler);
990  }
991 
992  if (MCL_OK == code)
993  {
994  code = json_util_to_string(root, payload);
995  }
996 
997  if (MCL_OK != code)
998  {
999  MCL_FREE(*payload);
1000  }
1001 
1002  json_util_destroy(&root);
1003 
1004  MCL_DEBUG_LEAVE("retVal = <%d>", code);
1005  return code;
1006 }
1007 
1008 static mcl_error_t _add_jwks(mcl_json_t *root, security_handler_t *security_handler)
1009 {
1010  mcl_error_t code;
1011  mcl_json_t *jwks = MCL_NULL;
1012  mcl_json_t *keys = MCL_NULL;
1013  mcl_json_t *key = MCL_NULL;
1014  char *modulus = MCL_NULL;
1015  char *public_exponent = MCL_NULL;
1016  char *kid = MCL_NULL;
1017 
1018  MCL_DEBUG_ENTRY("mcl_json_t *root = <%p>, security_handler_t *security_handler = <%p>", root, security_handler);
1019 
1020  code = security_rsa_get_modulus_and_exponent(security_handler->rsa.public_key, &modulus, &public_exponent);
1021 
1022  if (MCL_OK == code)
1023  {
1024  code = json_util_start_object(root, JSON_NAME_JWKS, &jwks);
1025  }
1026 
1027  if (MCL_OK == code)
1028  {
1029  code = json_util_start_array(jwks, JSON_NAME_KEYS, &keys);
1030  }
1031 
1032  if (MCL_OK == code)
1033  {
1034  code = _add_key_to_keys_array(keys, &key);
1035  }
1036 
1037  if (MCL_OK == code)
1038  {
1039  code = json_util_add_string(key, JSON_NAME_E, public_exponent);
1040  }
1041 
1042  if (MCL_OK == code)
1043  {
1044  code = json_util_add_string(key, JSON_NAME_N, modulus);
1045  }
1046 
1047  if (MCL_OK == code)
1048  {
1049  code = json_util_add_string(key, JSON_NAME_KTY, "RSA");
1050  }
1051 
1052  if (MCL_OK == code)
1053  {
1054  code = random_generate_guid(&kid);
1055  }
1056 
1057  if (MCL_OK == code)
1058  {
1059  code = json_util_add_string(key, JSON_NAME_KID, kid);
1060  }
1061 
1062  MCL_FREE(modulus);
1063  MCL_FREE(public_exponent);
1064  MCL_FREE(kid);
1065 
1066  MCL_DEBUG_LEAVE("retVal = <%d>", code);
1067  return code;
1068 }
1069 
1071 {
1072  mcl_error_t code;
1073 
1074  MCL_DEBUG_ENTRY("json_t *root = <%p>, mcl_json_t **json_object = <%p>", root, json_object);
1075 
1076  code = json_util_initialize(MCL_JSON_OBJECT, json_object);
1077 
1078  if (MCL_OK == code)
1079  {
1080  json_util_add_item_to_array(root, *json_object);
1081  }
1082 
1083  MCL_DEBUG_LEAVE("retVal = <%d>", code);
1084  return code;
1085 }
1086 
1088 {
1089  mcl_error_t code;
1090 
1091  MCL_DEBUG_ENTRY("core_processor_t *core_processor = <%p>", core_processor);
1092 
1094  {
1095  code = core_processor->configuration->credentials_load_callback.shared_secret(
1096  &(core_processor->security_handler->client_id),
1097  &(core_processor->security_handler->client_secret),
1098  &(core_processor->security_handler->registration_access_token),
1099  &(core_processor->security_handler->registration_uri));
1100  }
1101  else
1102  {
1103  code = core_processor->configuration->credentials_load_callback.rsa(
1104  &(core_processor->security_handler->client_id),
1105  &(core_processor->security_handler->rsa.public_key),
1106  &(core_processor->security_handler->rsa.private_key),
1107  &(core_processor->security_handler->registration_access_token),
1108  &(core_processor->security_handler->registration_uri));
1109  }
1110 
1111  MCL_DEBUG_LEAVE("retVal = <%d>", code);
1112  return code;
1113 }
1114 
1115 static mcl_error_t _generate_correlation_id_string(char **correlation_id)
1116 {
1117  mcl_error_t code;
1118  mcl_uint16_t index;
1119  uint8_t random_bytes[CORRELATION_ID_BYTE_LENGTH] = { 0 };
1120  *correlation_id = MCL_NULL;
1121 
1122  MCL_DEBUG_ENTRY("char **correlation_id = <%p>", correlation_id);
1123 
1125 
1126  if (MCL_OK == code)
1127  {
1128  *correlation_id = MCL_MALLOC(CORRELATION_ID_BYTE_LENGTH * 2 + MCL_NULL_CHAR_SIZE);
1129 
1130  if (MCL_NULL == *correlation_id)
1131  {
1132  code = MCL_OUT_OF_MEMORY;
1133  }
1134  }
1135 
1136  for (index = 0; (index < CORRELATION_ID_BYTE_LENGTH) && (MCL_OK == code); ++index)
1137  {
1138  code = string_util_snprintf(&((*correlation_id)[index * 2]), 3, "%02x", random_bytes[index]);
1139  }
1140 
1141  if (MCL_OK != code)
1142  {
1143  MCL_FREE(*correlation_id);
1144  }
1145 
1146  MCL_DEBUG_LEAVE("retVal = <%d>", code);
1147  return code;
1148 }
1149 
1151 {
1152  // Set default return code to MCL_OK assuming if no storage option is provided agent does not want to save data.
1153  mcl_error_t result = MCL_OK;
1154 
1155  MCL_DEBUG_ENTRY("core_processor_t *core_processor = <%p>", core_processor);
1156 
1157  // Store credentials via custom functions if both function pointers are not null.
1158  if ((MCL_NULL != core_processor->configuration->credentials_load_callback.rsa) &&
1159  (MCL_NULL != core_processor->configuration->credentials_save_callback.rsa))
1160  {
1162  {
1163  result = core_processor->configuration->credentials_save_callback.shared_secret(
1164  core_processor->security_handler->client_id,
1165  core_processor->security_handler->client_secret,
1167  core_processor->security_handler->registration_uri);
1168  }
1169  else
1170  {
1171  result = core_processor->configuration->credentials_save_callback.rsa(
1172  core_processor->security_handler->client_id,
1173  (char *) core_processor->security_handler->rsa.public_key,
1174  (char *) core_processor->security_handler->rsa.private_key,
1176  core_processor->security_handler->registration_uri);
1177  }
1178  }
1179  else
1180  {
1181  MCL_WARN("Credentials will not be saved because callback functions to load/save credentials are not provided.");
1182  }
1183 
1184  MCL_DEBUG_LEAVE("retVal = <%d>", result);
1185  return result;
1186 }
1187 
1188 static mcl_error_t _compose_access_token_request_payload(core_processor_t *core_processor, char **request_payload)
1189 {
1190  mcl_error_t code;
1191  jwt_t *jwt = MCL_NULL;
1192  char *jwt_string = MCL_NULL;
1193  const char *head = "grant_type=client_credentials&client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer&client_assertion=";
1194 
1195  MCL_DEBUG_ENTRY("core_processor_t *core_processor = <%p>", core_processor);
1196 
1197  // Create a new self issued jwt.
1198  code = jwt_initialize(core_processor->security_handler, core_processor->configuration->security_profile, core_processor->configuration->tenant, &jwt);
1199 
1200  // Compose jwt string.
1201  if (MCL_OK == code)
1202  {
1203  jwt_string = jwt_get_token(jwt);
1204  jwt_destroy(&jwt);
1205  if (MCL_NULL == jwt_string)
1206  {
1207  code = MCL_FAIL;
1208  }
1209  }
1210 
1211  // Form the final request payload.
1212  if (MCL_OK == code)
1213  {
1214  code = string_util_concatenate(head, jwt_string, request_payload);
1215  }
1216 
1217  MCL_FREE(jwt_string);
1218 
1219  MCL_DEBUG_LEAVE("retVal = <%d>", code);
1220  return code;
1221 }
HTTP definitions module header file.
MCL_CORE_EXPORT mcl_error_t mcl_http_request_initialize(mcl_http_request_t **http_request)
Definition: http_request.c:18
mcl_credentials_save_rsa_callback_t rsa
Callback type to save RSA key.
mcl_error_t json_util_get_string(mcl_json_t *json, char **string_value)
Definition: json_util.c:754
static mcl_error_t _process_registration_response(core_processor_t *core_processor, mcl_http_response_t *http_response, char *correlation_id)
Http accept header.
uint16_t mcl_uint16_t
char * client_id
Client id.
char * proxy_hostname
Proxy hostname. Optional.
size_t mcl_size_t
Credentials of the mcl_core are already up to date.
Credentials are not loaded.
E_MCL_HTTP_STATUS_CODE status_code
Status code of http response.
#define JSON_NAME_ACCESS_TOKEN
void json_util_add_item_to_array(mcl_json_t *root, mcl_json_t *object)
Definition: json_util.c:554
Assert module header file.
Success.
mcl_size_t payload_size
Payload size of http response.
mcl_uint16_t proxy_port
Proxy port number. Mandatory if proxy host name is set, ineffective otherwise.
#define JSON_NAME_CLIENT_SECRET
E_ENDPOINT_URI
#define MCL_DEBUG(...)
Definition: mcl_log_util.h:114
Size of the body of the http request in bytes as mcl_size_t.
#define JSON_NAME_N
#define JSON_NAME_E
Json utility module header file.
void mcl_json_t
Definition: mcl_json_util.h:24
MCL_CORE_EXPORT mcl_error_t mcl_http_request_set_parameter(mcl_http_request_t *http_request, E_MCL_HTTP_REQUEST_PARAMETER parameter, const void *value)
Definition: http_request.c:97
MCL_CORE_EXPORT void mcl_http_client_destroy(mcl_http_client_t **http_client)
Json object.
Definition: mcl_json_util.h:32
mcl_int32_t mcl_error_t
If the response of server is unexpected.
#define JSON_NAME_KTY
#define JSON_NAME_REGISTRATION_CLIENT_URI
mcl_uint16_t mindsphere_port
Mindsphere port number.
MCL_CORE_EXPORT mcl_error_t mcl_http_client_initialize(mcl_http_client_configuration_t *configuration, mcl_http_client_t **http_client)
static mcl_error_t _compose_rsa_key_rotation_json(security_handler_t *security_handler, char **payload)
static const char _string_identifier[]
mcl_error_t security_generate_random_bytes(unsigned char *buffer, mcl_size_t size)
mcl_credentials_load_callback_t credentials_load_callback
Custom function for loading credentials. If both credentials_load_callback and credentials_save_callb...
char * jwt_get_token(jwt_t *jwt)
Definition: jwt.c:90
#define MCL_DEBUG_ENTRY(...)
Definition: mcl_log_util.h:115
static mcl_error_t _generate_correlation_id_string(char **correlation_id)
Http put method.
uint32_t mcl_uint32_t
mcl_credentials_save_callback_t credentials_save_callback
Custom function for saving credentials. If both credentials_load_callback and credentials_save_callba...
mcl_http_client_t * http_client
Http client handle.
#define MCL_FALSE
const char * user_agent
User agent.
Http Correlation-ID header name.
mcl_error_t json_util_parse(const char *json_string, mcl_size_t size, mcl_json_t **root)
Definition: json_util.c:844
const char * proxy_username
Proxy username. Optional if proxy host name is set, ineffective otherwise.
E_MCL_PROXY proxy_type
Proxy type E_MCL_PROXY. Mandatory if proxy host name is set, ineffective otherwise.
String utility module header file.
const char * http_header_names[HTTP_HEADER_NAMES_END]
Content type is application json.
mcl_credentials_load_rsa_callback_t rsa
Callback type to load RSA key.
MCL_CORE_EXPORT mcl_error_t mcl_http_request_add_header(mcl_http_request_t *http_request, const char *header_name, const char *header_value)
Definition: http_request.c:57
mcl_error_t json_util_to_string(mcl_json_t *root, char **json_string)
Definition: json_util.c:809
static const char _client_id_format[]
#define JSON_NAME_JWKS
#define MCL_ASSERT_CODE_MESSAGE(condition, return_code,...)
Definition: mcl_assert.h:77
char * tenant
Tenant name.
static mcl_error_t _compose_rsa_onboarding_json(security_handler_t *security_handler, char **payload)
static mcl_error_t _add_jwks(mcl_json_t *root, security_handler_t *security_handler)
#define MCL_NEW(p)
Definition: mcl_memory.h:55
mcl_bool_t certificate_is_file
Flag to check if certificate is given as file or string.
mcl_uint16_t proxy_port
Proxy port number. Mandatory if proxy host name is set, ineffective otherwise.
E_MCL_HTTP_METHOD
#define MCL_NULL
Url of the http request as char*.
Neither initial access token nor loading/saving credentials callback functions are provided...
void json_util_destroy(mcl_json_t **root)
Definition: json_util.c:913
#define MCL_ERROR(...)
Definition: mcl_log_util.h:142
End of uri endpoint.
char * user_agent
User agent.
void security_handler_destroy(security_handler_t **security_handler)
static mcl_error_t _add_key_to_keys_array(mcl_json_t *root, mcl_json_t **json_object)
char * public_key
Public key.
mcl_error_t string_util_concatenate(const char *string_1, const char *string_2, char **result)
Definition: string_util.c:467
const char * certificate
Certificate. If it is NULL, default CA certificate store will be used (if available).
E_MCL_SECURITY_PROFILE security_profile
Security profile E_MCL_SECURITY_PROFILE.
mcl_error_t json_util_start_object(mcl_json_t *root, const char *object_name, mcl_json_t **json_object)
Definition: json_util.c:226
If the response of server is HTTP 201.
mcl_error_t jwt_initialize(security_handler_t *security_handler, E_MCL_SECURITY_PROFILE security_profile, char *tenant, jwt_t **jwt)
Definition: jwt.c:62
#define MCL_FREE(p)
Definition: mcl_memory.h:59
static mcl_error_t _process_registration_response_shared_secret(core_processor_t *core_processor, mcl_http_response_t *http_response)
List module header file.
Http authorization header.
char * last_token_time
The time at which the last access token is generated by MindSphere.
static mcl_error_t _custom_load_register_info(core_processor_t *core_processor)
mcl_error_t security_handler_initialize(security_handler_t **security_handler)
E_CONTENT_TYPE_VALUES
mcl_uint32_t http_request_timeout
Timeout value (in seconds) for HTTP requests. Default timeout is 300 seconds.
MCL_CORE_EXPORT void mcl_http_request_destroy(mcl_http_request_t **http_request)
Definition: http_request.c:155
Content type is application/x-www-form-urlencoded.
char * private_key
Private key.
static mcl_error_t _process_registration_response_rsa_3072(core_processor_t *core_processor, mcl_http_response_t *http_response)
mcl_uint8_t * payload
Payload of http response.
Definitions module header file.
static const char * _content_type_values[CONTENT_TYPE_VALUES_END]
core_configuration_t * configuration
Configuration parameters.
Http content type header.
#define MCL_ASSERT_STATEMENT_CODE_MESSAGE(condition, statement, return_code,...)
Definition: mcl_assert.h:93
End of content type values.
char * proxy_username
Proxy username. Optional if proxy host name is set, ineffective otherwise.
security_handler_t * security_handler
Security handler.
static mcl_error_t _check_rsa_private_key(core_processor_t *core_processor, char *private_key)
rsa_t rsa
RSA handle.
E_MCL_PROXY proxy_type
Proxy type E_MCL_PROXY. Mandatory if proxy host name is set, ineffective otherwise.
Body of the http request as char*. HTTP Request neither copies the buffer, nor takes ownership...
mcl_error_t json_util_start_array(mcl_json_t *root, const char *array_name, mcl_json_t **json_array)
Definition: json_util.c:107
mcl_bool_t certificate_is_file
Flag to check if certificate is given as file or string.
void jwt_destroy(jwt_t **jwt)
Definition: jwt.c:124
Core processor module header file.
static mcl_error_t _compose_access_token_request_payload(core_processor_t *core_processor, char **request_payload)
MCL_CORE_EXPORT mcl_error_t mcl_http_response_get_status(mcl_http_response_t *http_response)
mcl_error_t security_initialize(void)
MCL_CORE_EXPORT mcl_error_t mcl_http_client_send(mcl_http_client_t *http_client, mcl_http_request_t *http_request, mcl_http_response_t **http_response)
mcl_error_t string_util_snprintf(char *string, mcl_size_t length, const char *format,...)
Definition: string_util.c:177
mcl_uint32_t http_request_timeout
Timeout value (in seconds) for HTTP requests. Default timeout is 300 seconds.
mcl_error_t core_processor_initialize(core_configuration_t *configuration, core_processor_t **core_processor)
Http post method.
char * proxy_domain
Proxy domain. Optional if proxy host name and proxy username are set, ineffective otherwise...
void core_processor_destroy(core_processor_t **core_processor)
mcl_credentials_save_shared_secret_callback_t shared_secret
Callback type to save shared secret.
mcl_error_t json_util_get_object_item(mcl_json_t *json_parent, const char *child_name, mcl_json_t **json_child)
Definition: json_util.c:581
Server-Time header name.
char * register_endpoint
Uri for register endpoint.
#define JSON_NAME_REGISTRATION_ACCESS_TOKEN
Uri for registration endpoint.
char * client_secret
Client secret.
static const char * endpoint_uri[ENDPOINT_URI_END]
const char * proxy_domain
Proxy domain. Optional if proxy host name and proxy username are set, ineffective otherwise...
static mcl_error_t _check_client_secret(core_processor_t *core_processor, char *registration_access_token, char *client_secret)
mcl_uint8_t mcl_bool_t
const char * proxy_password
Proxy password. Mandatory if proxy host name and proxy username are set, ineffective otherwise...
#define JSON_NAME_CLIENT_ID
mcl_uint16_t port
Port number.
mcl_error_t security_rsa_get_modulus_and_exponent(char *public_key, char **modulus, char **exponent)
mcl_error_t core_processor_get_access_token(core_processor_t *core_processor)
Security interface header file.
char * registration_uri
Registration URI.
static mcl_error_t _save_credentials(core_processor_t *core_processor)
MCL_CORE_EXPORT void mcl_http_response_destroy(mcl_http_response_t **http_response)
char * registration_access_token
Registration access token.
Memory allocation fail.
File utility module header file.
#define MCL_NULL_CHAR_SIZE
mcl_error_t json_util_add_string(mcl_json_t *root, const char *object_name, const char *object_value)
Definition: json_util.c:273
MCL_CORE_EXPORT mcl_error_t mcl_http_response_get_header(mcl_http_response_t *http_response, const char *header_name, char **header_value)
Definition: http_response.c:44
#define MCL_MALLOC(bytes)
Definition: mcl_memory.h:54
void json_util_initialize_json_library(void)
Definition: json_util.c:30
Random module header file.
mcl_error_t json_util_initialize(E_MCL_JSON_TYPE mcl_json_type, mcl_json_t **root)
Definition: json_util.c:57
static mcl_error_t _load_initial_credentials(core_processor_t *core_processor)
char * access_token
Access token.
char * initial_access_token
Initial access token.
Definition: jwt.h:20
mcl_error_t core_processor_update_credentials(core_processor_t *core_processor)
mcl_error_t string_util_strncmp(const char *string_1, const char *string_2, mcl_size_t count)
Definition: string_util.c:135
const char * proxy_hostname
Proxy hostname. Optional.
mcl_credentials_load_shared_secret_callback_t shared_secret
Callback type to load shared secret.
Uri for access token endpoint.
#define MCL_DEBUG_LEAVE(...)
Definition: mcl_log_util.h:116
char * mindsphere_certificate
Mindsphere certificate. Optional. If NULL, MCL will use default CA certificate store (if provided at ...
#define MCL_TRUE
static const char _bearer_format[]
char * token_endpoint
Uri for token endpoint.
Internal failure in MCL.
Method of the http request as E_MCL_HTTP_METHOD.
JWT module header file.
#define JSON_NAME_KID
mcl_error_t random_generate_guid(char **guid)
Definition: random.c:80
Common module interface header file.
char * proxy_password
Proxy password. Mandatory if proxy host name and proxy username are set, ineffective otherwise...
mcl_size_t string_util_strlen(const char *buffer)
Definition: string_util.c:35
#define CORRELATION_ID_BYTE_LENGTH
#define MCL_INFO(...)
Definition: mcl_log_util.h:126
Time utility module header file.
#define JSON_NAME_KEYS
#define MCL_WARN(...)
Definition: mcl_log_util.h:134
mcl_error_t core_processor_register(core_processor_t *core_processor)
mcl_error_t security_handler_generate_rsa_key(security_handler_t *security_handler)
Memory module interface header file.