static CC *ed25519FromJSON(const cJSON *params, char *err) { size_t binsz; cJSON *pk_item = cJSON_GetObjectItem(params, "publicKey"); if (!cJSON_IsString(pk_item)) { strcpy(err, "publicKey must be a string"); return NULL; } unsigned char *pk = base64_decode(pk_item->valuestring, &binsz); if (32 != binsz) { strcpy(err, "publicKey has incorrect length"); free(pk); return NULL; } cJSON *signature_item = cJSON_GetObjectItem(params, "signature"); unsigned char *sig = NULL; if (signature_item && !cJSON_IsNull(signature_item)) { if (!cJSON_IsString(signature_item)) { strcpy(err, "signature must be null or a string"); return NULL; } sig = base64_decode(signature_item->valuestring, &binsz); if (64 != binsz) { strcpy(err, "signature has incorrect length"); free(sig); return NULL; } } CC *cond = cc_new(CC_Ed25519); cond->publicKey = pk; cond->signature = sig; return cond; }
CJSON_PUBLIC(cJSON *) cJSONUtils_MergePatch(cJSON *target, cJSON *patch) { if (!cJSON_IsObject(patch)) { /* scalar value, array or NULL, just duplicate */ cJSON_Delete(target); return cJSON_Duplicate(patch, 1); } if (!cJSON_IsObject(target)) { cJSON_Delete(target); target = cJSON_CreateObject(); } patch = patch->child; while (patch) { if (cJSON_IsNull(patch)) { /* NULL is the indicator to remove a value, see RFC7396 */ cJSON_DeleteItemFromObject(target, patch->string); } else { cJSON *replaceme = cJSON_DetachItemFromObject(target, patch->string); cJSON_AddItemToObject(target, patch->string, cJSONUtils_MergePatch(replaceme, patch)); } patch = patch->next; } return target; }
static cJSON *merge_patch(cJSON *target, const cJSON * const patch, const cJSON_bool case_sensitive) { cJSON *patch_child = NULL; if (!cJSON_IsObject(patch)) { /* scalar value, array or NULL, just duplicate */ cJSON_Delete(target); return cJSON_Duplicate(patch, 1); } if (!cJSON_IsObject(target)) { cJSON_Delete(target); target = cJSON_CreateObject(); } patch_child = patch->child; while (patch_child != NULL) { if (cJSON_IsNull(patch_child)) { /* NULL is the indicator to remove a value, see RFC7396 */ if (case_sensitive) { cJSON_DeleteItemFromObjectCaseSensitive(target, patch_child->string); } else { cJSON_DeleteItemFromObject(target, patch_child->string); } } else { cJSON *replace_me = NULL; cJSON *replacement = NULL; if (case_sensitive) { replace_me = cJSON_DetachItemFromObjectCaseSensitive(target, patch_child->string); } else { replace_me = cJSON_DetachItemFromObject(target, patch_child->string); } replacement = merge_patch(replace_me, patch_child, case_sensitive); if (replacement == NULL) { return NULL; } cJSON_AddItemToObject(target, patch_child->string, replacement); } patch_child = patch_child->next; } return target; }