From c062bc996062af20631f794c68248fef098b3f19 Mon Sep 17 00:00:00 2001 From: rjewell Date: Mon, 17 Jan 2022 16:42:18 -0500 Subject: [PATCH 1/5] Add attribute names encode/decode Add "Get Attributes" request payload encode/decode --- include/kmip.h | 26 +++- include/kmip_io.h | 2 + src/kmip.c | 246 +++++++++++++++++++++++++++++++++++ src/kmip_io.c | 36 ++++++ tests/tests.c | 320 ++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 627 insertions(+), 3 deletions(-) diff --git a/include/kmip.h b/include/kmip.h index 293d7f5..e4dd42b 100644 --- a/include/kmip.h +++ b/include/kmip.h @@ -883,6 +883,11 @@ typedef struct attributes LinkedList *attribute_list; } Attributes; +typedef struct attribute_names +{ + LinkedList *name_list; +} AttributeNames; + typedef struct name { struct text_string *value; @@ -1226,6 +1231,13 @@ typedef struct application_namespaces LinkedList *app_namespace_list; } ApplicationNamespaces; */ +typedef struct get_attributes_request_payload +{ + TextString *unique_identifier; + AttributeNames *attribute_names; +} GetAttributesRequestPayload; + + typedef struct query_request_payload { @@ -1530,9 +1542,11 @@ void kmip_free_response_message(KMIP *, ResponseMessage *); void kmip_free_query_functions(KMIP *ctx, Functions*); void kmip_free_query_request_payload(KMIP *, QueryRequestPayload *); void kmip_free_query_response_payload(KMIP *, QueryResponsePayload *); -void kmip_free_operations(KMIP *ctx, Operations *value); -void kmip_free_objects(KMIP *ctx, ObjectTypes* value); -void kmip_free_server_information(KMIP* ctx, ServerInformation* value); +void kmip_free_operations(KMIP *, Operations *); +void kmip_free_objects(KMIP *, ObjectTypes*); +void kmip_free_server_information(KMIP*, ServerInformation*); +void kmip_free_attribute_names(KMIP *, AttributeNames*); +void kmip_free_get_attributes_request_payload(KMIP *, GetAttributesRequestPayload*); /* Copying Functions @@ -1602,6 +1616,8 @@ int kmip_compare_server_information(const ServerInformation *a, const ServerInfo int kmip_compare_alternative_endpoints(const AltEndpoints* a, const AltEndpoints* b); int kmip_compare_query_request_payload(const QueryRequestPayload *, const QueryRequestPayload *); int kmip_compare_query_response_payload(const QueryResponsePayload *, const QueryResponsePayload *); +int kmip_compare_attribute_names(const AttributeNames*, const AttributeNames*); +int kmip_compare_get_attributes_request_payload(const GetAttributesRequestPayload*, const GetAttributesRequestPayload*); /* Encoding Functions @@ -1625,6 +1641,7 @@ int kmip_encode_attribute_v1(KMIP *, const Attribute *); int kmip_encode_attribute_v2(KMIP *, const Attribute *); int kmip_encode_attribute(KMIP *, const Attribute *); int kmip_encode_attributes(KMIP *, const Attributes *); +int kmip_encode_attribute_names(KMIP *, const AttributeNames*); int kmip_encode_template_attribute(KMIP *, const TemplateAttribute *); int kmip_encode_protocol_version(KMIP *, const ProtocolVersion *); int kmip_encode_protection_storage_masks(KMIP *, const ProtectionStorageMasks *); @@ -1660,6 +1677,7 @@ int kmip_encode_request_batch_item(KMIP *, const RequestBatchItem *); int kmip_encode_response_batch_item(KMIP *, const ResponseBatchItem *); int kmip_encode_request_message(KMIP *, const RequestMessage *); int kmip_encode_response_message(KMIP *, const ResponseMessage *); +int kmip_encode_get_attributes_request_payload(KMIP *ctx, const GetAttributesRequestPayload *); int kmip_encode_query_functions(KMIP *ctx, const Functions*); int kmip_encode_query_request_payload(KMIP *, const QueryRequestPayload *); int kmip_encode_query_response_payload(KMIP *, const QueryResponsePayload *); @@ -1685,6 +1703,7 @@ int kmip_decode_attribute_v1(KMIP *, Attribute *); int kmip_decode_attribute_v2(KMIP *, Attribute *); int kmip_decode_attribute(KMIP *, Attribute *); int kmip_decode_attributes(KMIP *, Attributes *); +int kmip_decode_attribute_names(KMIP *ctx, AttributeNames*); int kmip_decode_template_attribute(KMIP *, TemplateAttribute *); int kmip_decode_protocol_version(KMIP *, ProtocolVersion *); int kmip_decode_transparent_symmetric_key(KMIP *, TransparentSymmetricKey *); @@ -1726,6 +1745,7 @@ int kmip_decode_object_types(KMIP *, ObjectTypes *); int kmip_decode_query_request_payload(KMIP *, QueryRequestPayload *); int kmip_decode_query_response_payload(KMIP *, QueryResponsePayload *); int kmip_decode_server_information(KMIP *ctx, ServerInformation *); +int kmip_decode_get_attributes_request_payload(KMIP *ctx, GetAttributesRequestPayload *); #endif /* KMIP_H */ diff --git a/include/kmip_io.h b/include/kmip_io.h index e65d232..5a316fa 100644 --- a/include/kmip_io.h +++ b/include/kmip_io.h @@ -94,5 +94,7 @@ void kmip_print_object_types(FILE*, int, ObjectTypes*); void kmip_print_query_request_payload(FILE*, int, QueryRequestPayload *); void kmip_print_query_response_payload(FILE*, int, QueryResponsePayload *); void kmip_print_server_information(FILE*, int, ServerInformation*); +void kmip_print_attribute_names(FILE*, int, AttributeNames*); +void kmip_print_get_attributes_request_payload(FILE*, int, GetAttributesRequestPayload*); #endif /* KMIP_IO_H */ diff --git a/src/kmip.c b/src/kmip.c index 7974346..cd32d02 100644 --- a/src/kmip.c +++ b/src/kmip.c @@ -3911,6 +3911,54 @@ kmip_compare_attributes(const Attributes *a, const Attributes *b) return(KMIP_TRUE); } +void +kmip_free_attribute_names(KMIP *ctx, AttributeNames* value) +{ + if(value != NULL) + { + if(value->name_list != NULL) + { + LinkedListItem *curr = kmip_linked_list_pop(value->name_list); + while(curr != NULL) + { + kmip_free_text_string(ctx, curr->data); + ctx->free_func(ctx->state, curr->data); + curr->data = NULL; + ctx->free_func(ctx->state, curr); + curr = kmip_linked_list_pop(value->name_list); + } + ctx->free_func(ctx->state, value->name_list); + value->name_list= NULL; + } + } + return; +} + +void +kmip_free_get_attributes_request_payload(KMIP *ctx, GetAttributesRequestPayload* value) +{ + if(value != NULL) + { + if(value->unique_identifier != NULL) + { + kmip_free_text_string(ctx, value->unique_identifier); + + ctx->free_func(ctx->state, value->unique_identifier); + value->unique_identifier = NULL; + } + + if(value->attribute_names != NULL) + { + kmip_free_attribute_names(ctx, value->attribute_names); + + ctx->free_func(ctx->state, value->attribute_names); + value->attribute_names = NULL; + } + } + + return; +} + int kmip_compare_template_attribute(const TemplateAttribute *a, const TemplateAttribute *b) { @@ -6134,6 +6182,81 @@ kmip_compare_query_response_payload(const QueryResponsePayload *a, const QueryRe return(KMIP_TRUE); } +int +kmip_compare_attribute_names(const AttributeNames* a, const AttributeNames* b) +{ + if(a != b) + { + if((a == NULL) || (b == NULL)) + { + return(KMIP_FALSE); + } + + if((a->name_list != b->name_list)) + { + if((a->name_list == NULL) || (b->name_list == NULL)) + { + return(KMIP_FALSE); + } + + if((a->name_list->size != b->name_list->size)) + { + return(KMIP_FALSE); + } + + LinkedListItem *a_item = a->name_list->head; + LinkedListItem *b_item = b->name_list->head; + if (kmip_compare_linklist_items_textstring(a_item, b_item) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + } + + return(KMIP_TRUE); +} + +int +kmip_compare_get_attributes_request_payload(const GetAttributesRequestPayload* a, const GetAttributesRequestPayload* b) +{ + if(a != b) + { + if((a == NULL) || (b == NULL)) + { + return(KMIP_FALSE); + } + + if(a->unique_identifier != b->unique_identifier) + { + if((a->unique_identifier == NULL) || (b->unique_identifier == NULL)) + { + return(KMIP_FALSE); + } + + if(kmip_compare_text_string(a->unique_identifier, b->unique_identifier) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + + if(a->attribute_names != b->attribute_names) + { + if((a->attribute_names == NULL) || + (b->attribute_names == NULL)) + { + return(KMIP_FALSE); + } + + if(kmip_compare_attribute_names(a->attribute_names, b->attribute_names) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + } + + return(KMIP_TRUE); +} + /* Encoding Functions @@ -6501,6 +6624,29 @@ kmip_encode_attribute_name(KMIP *ctx, enum attribute_type value) return(KMIP_OK); } +int +kmip_encode_attribute_names(KMIP *ctx, const AttributeNames *value) +{ + CHECK_ENCODE_ARGS(ctx, value); + + int result = 0; + + if(value->name_list != NULL) + { + LinkedListItem *curr = value->name_list->head; + while(curr != NULL) + { + TextString *attribute_name =(TextString*)curr->data; + result = kmip_encode_text_string(ctx, KMIP_TAG_ATTRIBUTE_NAME, attribute_name); + CHECK_RESULT(ctx, result); + + curr = curr->next; + } + } + + return(KMIP_OK); +} + int kmip_encode_attribute_v1(KMIP *ctx, const Attribute *value) { @@ -8389,6 +8535,76 @@ kmip_encode_response_message(KMIP *ctx, const ResponseMessage *value) return(KMIP_OK); } +int +kmip_encode_get_attributes_request_payload(KMIP *ctx, const GetAttributesRequestPayload *value) +{ + int result = 0; + result = kmip_encode_int32_be(ctx, TAG_TYPE(KMIP_TAG_REQUEST_PAYLOAD, KMIP_TYPE_STRUCTURE)); + CHECK_RESULT(ctx, result); + + uint8 *length_index = ctx->index; + uint8 *value_index = ctx->index += 4; + + if(value->unique_identifier != NULL) + { + result = kmip_encode_text_string(ctx, KMIP_TAG_UNIQUE_IDENTIFIER, value->unique_identifier); + CHECK_RESULT(ctx, result); + } + + if (value->attribute_names) + { + result = kmip_encode_attribute_names(ctx, value->attribute_names); + CHECK_RESULT(ctx, result); + } + + uint8 *curr_index = ctx->index; + ctx->index = length_index; + + kmip_encode_int32_be(ctx, curr_index - value_index); + + ctx->index = curr_index; + + return(KMIP_OK); +} + +int +kmip_decode_get_attributes_request_payload(KMIP *ctx, GetAttributesRequestPayload *value) +{ + CHECK_DECODE_ARGS(ctx, value); + CHECK_BUFFER_FULL(ctx, 8); + + int result = 0; + int32 tag_type = 0; + uint32 length = 0; + + kmip_decode_int32_be(ctx, &tag_type); + CHECK_TAG_TYPE(ctx, tag_type, KMIP_TAG_REQUEST_PAYLOAD, KMIP_TYPE_STRUCTURE); + + kmip_decode_length(ctx, &length); + CHECK_BUFFER_FULL(ctx, length); + + if(kmip_is_tag_next(ctx, KMIP_TAG_UNIQUE_IDENTIFIER)) + { + value->unique_identifier = ctx->calloc_func(ctx->state, 1, sizeof(TextString)); + CHECK_NEW_MEMORY(ctx, value->unique_identifier, sizeof(TextString), "UniqueIdentifier text string"); + + result = kmip_decode_text_string(ctx, KMIP_TAG_UNIQUE_IDENTIFIER, value->unique_identifier); + CHECK_RESULT(ctx, result); + } + + if(kmip_is_tag_next(ctx, KMIP_TAG_ATTRIBUTE_NAME)) + { + value->attribute_names = ctx->calloc_func(ctx->state, 1, sizeof(AttributeNames)); + CHECK_NEW_MEMORY(ctx, value->attribute_names, sizeof(AttributeNames), "AttributeNames structure"); + + result = kmip_decode_attribute_names(ctx, value->attribute_names); + CHECK_RESULT(ctx, result); + } + + return(KMIP_OK); +} + + int kmip_encode_query_functions(KMIP *ctx, const Functions* value) { @@ -9339,6 +9555,36 @@ kmip_decode_attributes(KMIP *ctx, Attributes *value) return(KMIP_OK); } +int +kmip_decode_attribute_names(KMIP *ctx, AttributeNames *value) +{ + CHECK_DECODE_ARGS(ctx, value); + CHECK_BUFFER_FULL(ctx, 8); + + int result = 0; + + value->name_list = ctx->calloc_func(ctx->state, 1, sizeof(LinkedList)); + CHECK_NEW_MEMORY(ctx, value->name_list, sizeof(LinkedList), "LinkedList"); + + uint32 tag = kmip_peek_tag(ctx); + while(tag == KMIP_TAG_ATTRIBUTE_NAME) + { + LinkedListItem *item = ctx->calloc_func(ctx->state, 1, sizeof(LinkedListItem)); + CHECK_NEW_MEMORY(ctx, item, sizeof(LinkedListItem), "LinkedListItem"); + kmip_linked_list_enqueue(value->name_list, item); + + item->data = ctx->calloc_func(ctx->state, 1, sizeof(TextString)); + CHECK_NEW_MEMORY(ctx, item->data, sizeof(TextString), "Attribute Name text string"); + + result = kmip_decode_text_string(ctx, KMIP_TAG_ATTRIBUTE_NAME, item->data); + CHECK_RESULT(ctx, result); + + tag = kmip_peek_tag(ctx); + } + + return(KMIP_OK); +} + int kmip_decode_template_attribute(KMIP *ctx, TemplateAttribute *value) { diff --git a/src/kmip_io.c b/src/kmip_io.c index 528c7d5..02e907e 100644 --- a/src/kmip_io.c +++ b/src/kmip_io.c @@ -3330,3 +3330,39 @@ kmip_print_query_request_payload(FILE* f, int indent, QueryRequestPayload *value if(value != NULL) kmip_print_query_functions(f, indent, value->functions); } + +void +kmip_print_attribute_names(FILE* f, int indent, AttributeNames* value) +{ + fprintf(f, "%*sAttribute Names @ %p\n", indent, "", (void *)value); + + if(value != NULL && + value->name_list != NULL) + { + fprintf(f, "%*sNames: %zu\n", indent + 2, "", value->name_list->size); + LinkedListItem *curr = value->name_list->head; + size_t count = 1; + while(curr != NULL) + { + fprintf(f, "%*sName: %zu: ", indent + 4, "", count); + TextString* attrname = (TextString*)curr->data; + kmip_print_text_string(f, indent + 2, "Attribute Name", attrname); + fprintf(f, "\n"); + + curr = curr->next; + count++; + } + } +} + +void +kmip_print_get_attributes_request_payload(FILE* f, int indent, GetAttributesRequestPayload *value) +{ + fprintf(f,"%*sGet Attributes Request Payload @ %p\n", indent, "", (void *)value); + + if(value != NULL) + { + kmip_print_text_string(f, indent + 2, "Unique Identifier", value->unique_identifier); + kmip_print_attribute_names(f, indent + 2, value->attribute_names); + } +} diff --git a/tests/tests.c b/tests/tests.c index 48f6d9b..d7abc93 100644 --- a/tests/tests.c +++ b/tests/tests.c @@ -11902,6 +11902,321 @@ test_decode_response_header_kmip_2_0(TestTracker *tracker) return(result); } +int +test_encode_attribute_names(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + /* + Tag: Attribute Name (0x42000A), Type: Text String (0x07), Data: Object Group + Tag: Attribute Name (0x42000A), Type: Text String (0x07), Data: Application Specific Information + */ + + uint8 expected[] = { + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x0C, // attr: object group + 0x4F, 0x62, 0x6A, 0x65, 0x63, 0x74, 0x20, 0x47, + 0x72, 0x6F, 0x75, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x20, // attr: appl spec info + 0x41, 0x70, 0x70, 0x6C, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x20, 0x53, 0x70, 0x65, 0x63, + 0x69, 0x66, 0x69, 0x63, 0x20, 0x49, 0x6E, 0x66, + 0x6F, 0x72, 0x6D, 0x61, 0x74, 0x69, 0x6F, 0x6E, + }; + + uint8 observed[8*8] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0); + + TextString val0 = {0}; + val0.value = "Object Group"; + val0.size = 12; + + TextString val1 = {0}; + val1.value = "Application Specific Information"; + val1.size = 32; + + AttributeNames names = {0}; + + LinkedList list = {0}; + LinkedListItem item_1 = {0}; + LinkedListItem item_2 = {0}; + item_1.data = &val0; + item_2.data = &val1; + + kmip_linked_list_enqueue(&list, &item_1); + kmip_linked_list_enqueue(&list, &item_2); + + names.name_list = &list; + + int result = kmip_encode_attribute_names(&ctx, &names); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_decode_attribute_names(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + /* + Tag: Attribute Name (0x42000A), Type: Text String (0x07), Data: Object Group + Tag: Attribute Name (0x42000A), Type: Text String (0x07), Data: Application Specific Information + */ + + uint8 encoding[] = { + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x0C, // attr: object group + 0x4F, 0x62, 0x6A, 0x65, 0x63, 0x74, 0x20, 0x47, + 0x72, 0x6F, 0x75, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x20, // attr: appl spec info + 0x41, 0x70, 0x70, 0x6C, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x20, 0x53, 0x70, 0x65, 0x63, + 0x69, 0x66, 0x69, 0x63, 0x20, 0x49, 0x6E, 0x66, + 0x6F, 0x72, 0x6D, 0x61, 0x74, 0x69, 0x6F, 0x6E, + }; + + struct kmip ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0); + + TextString val0 = {0}; + val0.value = "Object Group"; + val0.size = 12; + + TextString val1 = {0}; + val1.value = "Application Specific Information"; + val1.size = 32; + + + LinkedList list = {0}; + LinkedListItem item_1 = {0}; + LinkedListItem item_2 = {0}; + item_1.data = &val0; + item_2.data = &val1; + + kmip_linked_list_enqueue(&list, &item_1); + kmip_linked_list_enqueue(&list, &item_2); + + AttributeNames expected = {0}; + expected.name_list = &list; + + AttributeNames observed = {0}; + int result = kmip_decode_attribute_names(&ctx, &observed); + + int comparison = kmip_compare_attribute_names(&expected, &observed); + if (!comparison) + { + printf("observed\n"); + kmip_print_attribute_names(stderr, 1, &observed); + printf("expected\n"); + kmip_print_attribute_names(stderr, 1, &expected); + } + result = report_decoding_test_result( + tracker, + &ctx, + comparison, + result, + __func__); + kmip_free_attribute_names(&ctx, &observed); + kmip_destroy(&ctx); + + return (result); +} + +int +test_encode_get_attributes_request_payload(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + /* + Tag: Request Payload (0x420079), Type: Structure (0x01), Data: + Tag: Unique Identifier (0x420094), Type: Text String (0x07), Data: 1703250b-4d40-4de2-93a0-c494a1d4ae40 + Tag: Attribute Name (0x42000A), Type: Text String (0x07), Data: Object Group + Tag: Attribute Name (0x42000A), Type: Text String (0x07), Data: Application Specific Information + Tag: Attribute Name (0x42000A), Type: Text String (0x07), Data: Contact Information + Tag: Attribute Name (0x42000A), Type: Text String (0x07), Data: x-Purpose + */ + + uint8 expected[] = { + 0x42, 0x00, 0x79, 0x01, 0x00, 0x00, 0x00, 0xA8, // req payload + 0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, // uuid + 0x31, 0x37, 0x30, 0x33, 0x32, 0x35, 0x30, 0x62, + 0x2D, 0x34, 0x64, 0x34, 0x30, 0x2D, 0x34, 0x64, + 0x65, 0x32, 0x2D, 0x39, 0x33, 0x61, 0x30, 0x2D, + 0x63, 0x34, 0x39, 0x34, 0x61, 0x31, 0x64, 0x34, + 0x61, 0x65, 0x34, 0x30, 0x00, 0x00, 0x00, 0x00, + + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x0C, // attr: object group + 0x4F, 0x62, 0x6A, 0x65, 0x63, 0x74, 0x20, 0x47, + 0x72, 0x6F, 0x75, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x20, // attr: appl spec info + 0x41, 0x70, 0x70, 0x6C, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x20, 0x53, 0x70, 0x65, 0x63, + 0x69, 0x66, 0x69, 0x63, 0x20, 0x49, 0x6E, 0x66, + 0x6F, 0x72, 0x6D, 0x61, 0x74, 0x69, 0x6F, 0x6E, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x13, // attr: contact + 0x43, 0x6F, 0x6E, 0x74, 0x61, 0x63, 0x74, 0x20, + 0x49, 0x6E, 0x66, 0x6F, 0x72, 0x6D, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x09, // attr: x-purp + 0x78, 0x2D, 0x50, 0x75, 0x72, 0x70, 0x6F, 0x73, + 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + + uint8 observed[22*8] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0); + + struct text_string uuid = {0}; + uuid.value = "1703250b-4d40-4de2-93a0-c494a1d4ae40"; + uuid.size = 36; + + TextString txt[4] = {{0}}; + + txt[0].value = "Object Group"; + txt[0].size = 12; + txt[1].value = "Application Specific Information"; + txt[1].size = 32; + txt[2].value = "Contact Information"; + txt[2].size = 19; + txt[3].value = "x-Purpose"; + txt[3].size = 9; + + LinkedList list = {0}; + LinkedListItem items[4] = {{0}}; + items[0].data = &txt[0]; + items[1].data = &txt[1]; + items[2].data = &txt[2]; + items[3].data = &txt[3]; + kmip_linked_list_enqueue(&list, &items[0]); + kmip_linked_list_enqueue(&list, &items[1]); + kmip_linked_list_enqueue(&list, &items[2]); + kmip_linked_list_enqueue(&list, &items[3]); + + AttributeNames names = {0}; + + names.name_list = &list; + + GetAttributesRequestPayload garp = {0}; + garp.unique_identifier = &uuid; + garp.attribute_names = &names; + + int result = kmip_encode_get_attributes_request_payload(&ctx, &garp); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_decode_get_attributes_request_payload(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + /* + Tag: Request Payload (0x420079), Type: Structure (0x01), Data: + Tag: Unique Identifier (0x420094), Type: Text String (0x07), Data: 1703250b-4d40-4de2-93a0-c494a1d4ae40 + Tag: Attribute Name (0x42000A), Type: Text String (0x07), Data: Object Group + Tag: Attribute Name (0x42000A), Type: Text String (0x07), Data: Application Specific Information + Tag: Attribute Name (0x42000A), Type: Text String (0x07), Data: Contact Information + Tag: Attribute Name (0x42000A), Type: Text String (0x07), Data: x-Purpose + */ + + uint8 encoded[] = { + 0x42, 0x00, 0x79, 0x01, 0x00, 0x00, 0x00, 0xA8, // req payload + 0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, // uuid + 0x31, 0x37, 0x30, 0x33, 0x32, 0x35, 0x30, 0x62, + 0x2D, 0x34, 0x64, 0x34, 0x30, 0x2D, 0x34, 0x64, + 0x65, 0x32, 0x2D, 0x39, 0x33, 0x61, 0x30, 0x2D, + 0x63, 0x34, 0x39, 0x34, 0x61, 0x31, 0x64, 0x34, + 0x61, 0x65, 0x34, 0x30, 0x00, 0x00, 0x00, 0x00, + + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x0C, // attr: object group + 0x4F, 0x62, 0x6A, 0x65, 0x63, 0x74, 0x20, 0x47, + 0x72, 0x6F, 0x75, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x20, // attr: appl spec info + 0x41, 0x70, 0x70, 0x6C, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x20, 0x53, 0x70, 0x65, 0x63, + 0x69, 0x66, 0x69, 0x63, 0x20, 0x49, 0x6E, 0x66, + 0x6F, 0x72, 0x6D, 0x61, 0x74, 0x69, 0x6F, 0x6E, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x13, // attr: contact + 0x43, 0x6F, 0x6E, 0x74, 0x61, 0x63, 0x74, 0x20, + 0x49, 0x6E, 0x66, 0x6F, 0x72, 0x6D, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x09, // attr: x-purp + 0x78, 0x2D, 0x50, 0x75, 0x72, 0x70, 0x6F, 0x73, + 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + + struct kmip ctx = {0}; + kmip_init(&ctx, encoded, ARRAY_LENGTH(encoded), KMIP_1_0); + + struct text_string uuid = {0}; + uuid.value = "1703250b-4d40-4de2-93a0-c494a1d4ae40"; + uuid.size = 36; + + TextString txt[4] = {{0}}; + + txt[0].value = "Object Group"; + txt[0].size = 12; + txt[1].value = "Application Specific Information"; + txt[1].size = 32; + txt[2].value = "Contact Information"; + txt[2].size = 19; + txt[3].value = "x-Purpose"; + txt[3].size = 9; + + LinkedList list = {0}; + LinkedListItem items[4] = {{0}}; + items[0].data = &txt[0]; + items[1].data = &txt[1]; + items[2].data = &txt[2]; + items[3].data = &txt[3]; + kmip_linked_list_enqueue(&list, &items[0]); + kmip_linked_list_enqueue(&list, &items[1]); + kmip_linked_list_enqueue(&list, &items[2]); + kmip_linked_list_enqueue(&list, &items[3]); + + AttributeNames names = {0}; + names.name_list = &list; + + GetAttributesRequestPayload expected = {0}; + expected.unique_identifier = &uuid; + expected.attribute_names = &names; + + GetAttributesRequestPayload observed = {0}; + int result = kmip_decode_get_attributes_request_payload(&ctx, &observed); + + int comparison = kmip_compare_get_attributes_request_payload(&expected, &observed); + if (!comparison) + { + printf("observed\n"); + kmip_print_get_attributes_request_payload(stderr, 1, &observed); + printf("expected\n"); + kmip_print_get_attributes_request_payload(stderr, 1, &expected); + } + result = report_decoding_test_result( + tracker, + &ctx, + comparison, + result, + __func__); + kmip_free_get_attributes_request_payload(&ctx, &observed); + + kmip_destroy(&ctx); + return(result); +} + int test_compare_query_functions(TestTracker *tracker) { @@ -13031,6 +13346,8 @@ run_tests(void) test_decode_object_types(&tracker); test_compare_query_functions(&tracker); test_decode_query_response_payload(&tracker); + test_decode_attribute_names(&tracker); + test_decode_get_attributes_request_payload(&tracker); printf("\n"); test_encode_integer(&tracker); @@ -13094,6 +13411,9 @@ run_tests(void) test_encode_template_attribute(&tracker); test_encode_query_functions(&tracker); test_encode_query_request_payload(&tracker); + test_encode_attribute_names(&tracker); + test_encode_get_attributes_request_payload(&tracker); + printf("\nKMIP 1.1 Feature Tests\n"); printf("----------------------\n"); From 685f628a024f8a7cd68b429d5656c97ac06b8170 Mon Sep 17 00:00:00 2001 From: rjewell Date: Fri, 4 Feb 2022 17:39:43 -0500 Subject: [PATCH 2/5] Add get attributes encode/decode and tests --- include/kmip.h | 76 +++++- include/kmip_bio.h | 3 + include/kmip_io.h | 5 +- src/kmip.c | 650 ++++++++++++++++++++++++++++++--------------- src/kmip_io.c | 97 ++++--- tests/tests.c | 310 ++++++++++++++++++++- 6 files changed, 880 insertions(+), 261 deletions(-) diff --git a/include/kmip.h b/include/kmip.h index e4dd42b..c70d3d3 100644 --- a/include/kmip.h +++ b/include/kmip.h @@ -97,7 +97,59 @@ enum attribute_type KMIP_ATTR_DEACTIVATION_DATE = 11, KMIP_ATTR_PROCESS_START_DATE = 12, KMIP_ATTR_PROTECT_STOP_DATE = 13, - KMIP_ATTR_CRYPTOGRAPHIC_PARAMETERS = 14 + KMIP_ATTR_CRYPTOGRAPHIC_PARAMETERS = 14, + + KMIP_ATTR_ARCHIVE_DATE , + KMIP_ATTR_CERTIFICATE_IDENTIFIER , + KMIP_ATTR_CERTIFICATE_ISSUER , + KMIP_ATTR_CERTIFICATE_SUBJECT , + KMIP_ATTR_CERTIFICATE_TYPE , + KMIP_ATTR_COMPROMISE_DATE , + KMIP_ATTR_COMPROMISE_OCCURRENCE_DATE , + KMIP_ATTR_CONTACT_INFORMATION , + KMIP_ATTR_CRYPTOGRAPHIC_DOMAIN_PARAMETERS , + KMIP_ATTR_CUSTOM_ATTRIBUTE , + KMIP_ATTR_DESTROY_DATE , + KMIP_ATTR_DIGEST , + KMIP_ATTR_INITIAL_DATE , + KMIP_ATTR_LAST_CHANGE_DATE , + KMIP_ATTR_LEASE_TIME , + KMIP_ATTR_LINK , + KMIP_ATTR_REVOCATION_REASON , + KMIP_ATTR_USAGE_LIMITS , + + //_KMIP_1.2 + KMIP_ATTR_ALTERNATIVE_NAME , + KMIP_ATTR_CERTIFICATE_LENGTH , + KMIP_ATTR_DIGITAL_SIGNATURE_ALGORITHM , + KMIP_ATTR_FRESH , + KMIP_ATTR_KEY_VALUE_LOCATION , + KMIP_ATTR_KEY_VALUE_PRESENT , + KMIP_ATTR_ORIGINAL_CREATION_DATE , + + //_KMIP_2.0 + KMIP_ATTR_ALWAYS_SENSITIVE , + KMIP_ATTR_CERTIFICATE_ATTRIBUTES , + KMIP_ATTR_COMMENT , + KMIP_ATTR_DESCRIPTION , + KMIP_ATTR_EXTRACTABLE , + KMIP_ATTR_KEY_FORMAT_TYPE , + KMIP_ATTR_NEVER_EXTRACTABLE , + KMIP_ATTR_NIST_KEY_TYPE , + KMIP_ATTR_OPAQUE_DATA_TYPE , + KMIP_ATTR_PKCS12_FRIENDLY_NAME , + KMIP_ATTR_PROTECTION_LEVEL , + KMIP_ATTR_PROTECTION_PERIOD , + KMIP_ATTR_PROTECTION_STORAGE_MASK , + KMIP_ATTR_QUANTUM_SAFE , + KMIP_ATTR_RANDOM_NUMBER_GENERATOR , + KMIP_ATTR_SENSITIVE , + KMIP_ATTR_SHORT_UNIQUE_IDENTIFIER , + KMIP_ATTR_VENDOR_ATTRIBUTE , + KMIP_ATTR_X509_CERTIFICATE_IDENTIFIER , + KMIP_ATTR_X509_CERTIFICATE_ISSUER , + KMIP_ATTR_X509_CERTIFICATE_SUBJECT , + }; enum batch_error_continuation_option @@ -1237,7 +1289,11 @@ typedef struct get_attributes_request_payload AttributeNames *attribute_names; } GetAttributesRequestPayload; - +typedef struct get_attributes_response_payload +{ + TextString *unique_identifier; + Attributes *attributes; +} GetAttributesResponsePayload; typedef struct query_request_payload { @@ -1539,14 +1595,15 @@ void kmip_free_request_header(KMIP *, RequestHeader *); void kmip_free_response_header(KMIP *, ResponseHeader *); void kmip_free_request_message(KMIP *, RequestMessage *); void kmip_free_response_message(KMIP *, ResponseMessage *); +void kmip_free_attribute_names(KMIP *, AttributeNames*); +void kmip_free_get_attributes_request_payload(KMIP *, GetAttributesRequestPayload*); +void kmip_free_get_attributes_response_payload(KMIP *, GetAttributesResponsePayload*); void kmip_free_query_functions(KMIP *ctx, Functions*); void kmip_free_query_request_payload(KMIP *, QueryRequestPayload *); void kmip_free_query_response_payload(KMIP *, QueryResponsePayload *); void kmip_free_operations(KMIP *, Operations *); void kmip_free_objects(KMIP *, ObjectTypes*); void kmip_free_server_information(KMIP*, ServerInformation*); -void kmip_free_attribute_names(KMIP *, AttributeNames*); -void kmip_free_get_attributes_request_payload(KMIP *, GetAttributesRequestPayload*); /* Copying Functions @@ -1612,12 +1669,13 @@ int kmip_compare_response_message(const ResponseMessage *, const ResponseMessage int kmip_compare_query_functions(const Functions *, const Functions *); int kmip_compare_operations(const Operations *, const Operations *); int kmip_compare_objects(const ObjectTypes *, const ObjectTypes *); +int kmip_compare_attribute_names(const AttributeNames*, const AttributeNames*); +int kmip_compare_get_attributes_request_payload(const GetAttributesRequestPayload*, const GetAttributesRequestPayload*); +int kmip_compare_get_attributes_response_payload(const GetAttributesResponsePayload*, const GetAttributesResponsePayload*); int kmip_compare_server_information(const ServerInformation *a, const ServerInformation *b); int kmip_compare_alternative_endpoints(const AltEndpoints* a, const AltEndpoints* b); int kmip_compare_query_request_payload(const QueryRequestPayload *, const QueryRequestPayload *); int kmip_compare_query_response_payload(const QueryResponsePayload *, const QueryResponsePayload *); -int kmip_compare_attribute_names(const AttributeNames*, const AttributeNames*); -int kmip_compare_get_attributes_request_payload(const GetAttributesRequestPayload*, const GetAttributesRequestPayload*); /* Encoding Functions @@ -1641,6 +1699,7 @@ int kmip_encode_attribute_v1(KMIP *, const Attribute *); int kmip_encode_attribute_v2(KMIP *, const Attribute *); int kmip_encode_attribute(KMIP *, const Attribute *); int kmip_encode_attributes(KMIP *, const Attributes *); +int kmip_encode_attribute_list(KMIP *, const LinkedList*); int kmip_encode_attribute_names(KMIP *, const AttributeNames*); int kmip_encode_template_attribute(KMIP *, const TemplateAttribute *); int kmip_encode_protocol_version(KMIP *, const ProtocolVersion *); @@ -1678,6 +1737,7 @@ int kmip_encode_response_batch_item(KMIP *, const ResponseBatchItem *); int kmip_encode_request_message(KMIP *, const RequestMessage *); int kmip_encode_response_message(KMIP *, const ResponseMessage *); int kmip_encode_get_attributes_request_payload(KMIP *ctx, const GetAttributesRequestPayload *); +int kmip_encode_get_attributes_response_payload(KMIP *ctx, const GetAttributesResponsePayload *); int kmip_encode_query_functions(KMIP *ctx, const Functions*); int kmip_encode_query_request_payload(KMIP *, const QueryRequestPayload *); int kmip_encode_query_response_payload(KMIP *, const QueryResponsePayload *); @@ -1689,6 +1749,7 @@ Decoding Functions int kmip_decode_int8_be(KMIP *, void *); int kmip_decode_int32_be(KMIP *, void *); int kmip_decode_int64_be(KMIP *, void *); +int kmip_decode_length(KMIP *, uint32 *); int kmip_decode_integer(KMIP *, enum tag, int32 *); int kmip_decode_long(KMIP *, enum tag, int64 *); int kmip_decode_enum(KMIP *, enum tag, void *); @@ -1742,10 +1803,11 @@ int kmip_decode_response_message(KMIP *, ResponseMessage *); int kmip_decode_query_functions(KMIP *ctx, Functions*); int kmip_decode_operations(KMIP *, Operations *); int kmip_decode_object_types(KMIP *, ObjectTypes *); +int kmip_decode_get_attributes_request_payload(KMIP *ctx, GetAttributesRequestPayload *); +int kmip_decode_get_attributes_response_payload(KMIP *ctx, GetAttributesResponsePayload *); int kmip_decode_query_request_payload(KMIP *, QueryRequestPayload *); int kmip_decode_query_response_payload(KMIP *, QueryResponsePayload *); int kmip_decode_server_information(KMIP *ctx, ServerInformation *); -int kmip_decode_get_attributes_request_payload(KMIP *ctx, GetAttributesRequestPayload *); #endif /* KMIP_H */ diff --git a/include/kmip_bio.h b/include/kmip_bio.h index 9ae0f6a..45384b5 100644 --- a/include/kmip_bio.h +++ b/include/kmip_bio.h @@ -42,7 +42,10 @@ int kmip_bio_create_symmetric_key_with_context(KMIP *, BIO *, TemplateAttribute int kmip_bio_get_symmetric_key_with_context(KMIP *, BIO *, char *, int, char **, int *); int kmip_bio_destroy_symmetric_key_with_context(KMIP *, BIO *, char *, int); +int kmip_bio_get_attributes_with_context(KMIP *ctx, BIO *bio, Attribute* attribs, size_t attrib_count, LocateResponse* locate_result); + int kmip_bio_query_with_context(KMIP *ctx, BIO *bio, enum query_function queries[], size_t query_count, QueryResponse* query_result); int kmip_bio_send_request_encoding(KMIP *, BIO *, char *, int, char **, int *); +int kmip_bio_locate_with_context(KMIP *ctx, BIO *bio, Attribute* attribs, size_t attrib_count, LocateResponse* locate_result); #endif /* KMIP_BIO_H */ diff --git a/include/kmip_io.h b/include/kmip_io.h index 5a316fa..cc154f8 100644 --- a/include/kmip_io.h +++ b/include/kmip_io.h @@ -91,10 +91,11 @@ void kmip_print_query_function_enum(FILE*, int, enum query_function); void kmip_print_query_functions(FILE*, int, Functions*); void kmip_print_operations(FILE*, int, Operations *); void kmip_print_object_types(FILE*, int, ObjectTypes*); +void kmip_print_attribute_names(FILE*, int, AttributeNames*); +void kmip_print_get_attributes_request_payload(FILE*, int, GetAttributesRequestPayload*); +void kmip_print_get_attributes_response_payload(FILE*, int, GetAttributesResponsePayload*); void kmip_print_query_request_payload(FILE*, int, QueryRequestPayload *); void kmip_print_query_response_payload(FILE*, int, QueryResponsePayload *); void kmip_print_server_information(FILE*, int, ServerInformation*); -void kmip_print_attribute_names(FILE*, int, AttributeNames*); -void kmip_print_get_attributes_request_payload(FILE*, int, GetAttributesRequestPayload*); #endif /* KMIP_IO_H */ diff --git a/src/kmip.c b/src/kmip.c index cd32d02..a916037 100644 --- a/src/kmip.c +++ b/src/kmip.c @@ -1952,6 +1952,12 @@ kmip_free_attribute(KMIP *ctx, Attribute *value) } break; + case KMIP_ATTR_CONTACT_INFORMATION: + { + kmip_free_text_string(ctx, value->value); + } + break; + case KMIP_ATTR_ACTIVATION_DATE: case KMIP_ATTR_DEACTIVATION_DATE: case KMIP_ATTR_PROCESS_START_DATE: @@ -2555,6 +2561,80 @@ kmip_free_destroy_response_payload(KMIP *ctx, DestroyResponsePayload *value) return; } + +void +kmip_free_attribute_names(KMIP *ctx, AttributeNames* value) +{ + if(value != NULL) + { + if(value->name_list != NULL) + { + LinkedListItem *curr = kmip_linked_list_pop(value->name_list); + while(curr != NULL) + { + kmip_free_text_string(ctx, curr->data); + ctx->free_func(ctx->state, curr->data); + curr->data = NULL; + ctx->free_func(ctx->state, curr); + curr = kmip_linked_list_pop(value->name_list); + } + ctx->free_func(ctx->state, value->name_list); + value->name_list= NULL; + } + } + return; +} + +void +kmip_free_get_attributes_request_payload(KMIP *ctx, GetAttributesRequestPayload* value) +{ + if(value != NULL) + { + if(value->unique_identifier != NULL) + { + kmip_free_text_string(ctx, value->unique_identifier); + + ctx->free_func(ctx->state, value->unique_identifier); + value->unique_identifier = NULL; + } + + if(value->attribute_names != NULL) + { + kmip_free_attribute_names(ctx, value->attribute_names); + + ctx->free_func(ctx->state, value->attribute_names); + value->attribute_names = NULL; + } + } + + return; +} + +void +kmip_free_get_attributes_response_payload(KMIP *ctx, GetAttributesResponsePayload* value) +{ + if(value != NULL) + { + if(value->unique_identifier != NULL) + { + kmip_free_text_string(ctx, value->unique_identifier); + + ctx->free_func(ctx->state, value->unique_identifier); + value->unique_identifier = NULL; + } + + if(value->attributes != NULL) + { + kmip_free_attributes(ctx, value->attributes); + ctx->free_func(ctx->state, value->attributes); + value->attributes = NULL; + } + } + + return; +} + + void kmip_free_request_batch_item(KMIP *ctx, RequestBatchItem *value) { @@ -3427,6 +3507,7 @@ kmip_deep_copy_attribute(KMIP *ctx, const Attribute *value) case KMIP_ATTR_UNIQUE_IDENTIFIER: case KMIP_ATTR_OPERATION_POLICY_NAME: case KMIP_ATTR_OBJECT_GROUP: + case KMIP_ATTR_CONTACT_INFORMATION: { copy->value = kmip_deep_copy_text_string(ctx, (TextString *)value->value); if(copy->value == NULL) @@ -3831,6 +3912,12 @@ kmip_compare_attribute(const Attribute *a, const Attribute *b) } break; + case KMIP_ATTR_CONTACT_INFORMATION: + { + return(kmip_compare_text_string((TextString *)a->value, (TextString *)b->value)); + } + break; + case KMIP_ATTR_ACTIVATION_DATE: case KMIP_ATTR_DEACTIVATION_DATE: case KMIP_ATTR_PROCESS_START_DATE: @@ -3911,54 +3998,6 @@ kmip_compare_attributes(const Attributes *a, const Attributes *b) return(KMIP_TRUE); } -void -kmip_free_attribute_names(KMIP *ctx, AttributeNames* value) -{ - if(value != NULL) - { - if(value->name_list != NULL) - { - LinkedListItem *curr = kmip_linked_list_pop(value->name_list); - while(curr != NULL) - { - kmip_free_text_string(ctx, curr->data); - ctx->free_func(ctx->state, curr->data); - curr->data = NULL; - ctx->free_func(ctx->state, curr); - curr = kmip_linked_list_pop(value->name_list); - } - ctx->free_func(ctx->state, value->name_list); - value->name_list= NULL; - } - } - return; -} - -void -kmip_free_get_attributes_request_payload(KMIP *ctx, GetAttributesRequestPayload* value) -{ - if(value != NULL) - { - if(value->unique_identifier != NULL) - { - kmip_free_text_string(ctx, value->unique_identifier); - - ctx->free_func(ctx->state, value->unique_identifier); - value->unique_identifier = NULL; - } - - if(value->attribute_names != NULL) - { - kmip_free_attribute_names(ctx, value->attribute_names); - - ctx->free_func(ctx->state, value->attribute_names); - value->attribute_names = NULL; - } - } - - return; -} - int kmip_compare_template_attribute(const TemplateAttribute *a, const TemplateAttribute *b) { @@ -5992,6 +6031,121 @@ kmip_compare_objects(const ObjectTypes *a, const ObjectTypes *b) return(KMIP_TRUE); } +int +kmip_compare_attribute_names(const AttributeNames* a, const AttributeNames* b) +{ + if(a != b) + { + if((a == NULL) || (b == NULL)) + { + return(KMIP_FALSE); + } + + if((a->name_list != b->name_list)) + { + if((a->name_list == NULL) || (b->name_list == NULL)) + { + return(KMIP_FALSE); + } + + if((a->name_list->size != b->name_list->size)) + { + return(KMIP_FALSE); + } + + LinkedListItem *a_item = a->name_list->head; + LinkedListItem *b_item = b->name_list->head; + if (kmip_compare_linklist_items_textstring(a_item, b_item) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + } + + return(KMIP_TRUE); +} + +int +kmip_compare_get_attributes_request_payload(const GetAttributesRequestPayload* a, const GetAttributesRequestPayload* b) +{ + if(a != b) + { + if((a == NULL) || (b == NULL)) + { + return(KMIP_FALSE); + } + + if(a->unique_identifier != b->unique_identifier) + { + if((a->unique_identifier == NULL) || (b->unique_identifier == NULL)) + { + return(KMIP_FALSE); + } + + if(kmip_compare_text_string(a->unique_identifier, b->unique_identifier) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + + if(a->attribute_names != b->attribute_names) + { + if((a->attribute_names == NULL) || + (b->attribute_names == NULL)) + { + return(KMIP_FALSE); + } + + if(kmip_compare_attribute_names(a->attribute_names, b->attribute_names) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + } + + return(KMIP_TRUE); +} + +int +kmip_compare_get_attributes_response_payload(const GetAttributesResponsePayload* a, const GetAttributesResponsePayload* b) +{ + if(a != b) + { + if((a == NULL) || (b == NULL)) + { + return(KMIP_FALSE); + } + + if(a->unique_identifier != b->unique_identifier) + { + if((a->unique_identifier == NULL) || (b->unique_identifier == NULL)) + { + return(KMIP_FALSE); + } + + if(kmip_compare_text_string(a->unique_identifier, b->unique_identifier) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + + if(a->attributes != b->attributes) + { + if((a->attributes == NULL) || (b->attributes == NULL)) + { + return(KMIP_FALSE); + } + + if(kmip_compare_attributes(a->attributes, b->attributes) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + } + + return(KMIP_TRUE); +} + int kmip_compare_alternative_endpoints(const AltEndpoints* a, const AltEndpoints* b) { @@ -6182,88 +6336,14 @@ kmip_compare_query_response_payload(const QueryResponsePayload *a, const QueryRe return(KMIP_TRUE); } + + +/* +Encoding Functions +*/ + int -kmip_compare_attribute_names(const AttributeNames* a, const AttributeNames* b) -{ - if(a != b) - { - if((a == NULL) || (b == NULL)) - { - return(KMIP_FALSE); - } - - if((a->name_list != b->name_list)) - { - if((a->name_list == NULL) || (b->name_list == NULL)) - { - return(KMIP_FALSE); - } - - if((a->name_list->size != b->name_list->size)) - { - return(KMIP_FALSE); - } - - LinkedListItem *a_item = a->name_list->head; - LinkedListItem *b_item = b->name_list->head; - if (kmip_compare_linklist_items_textstring(a_item, b_item) == KMIP_FALSE) - { - return(KMIP_FALSE); - } - } - } - - return(KMIP_TRUE); -} - -int -kmip_compare_get_attributes_request_payload(const GetAttributesRequestPayload* a, const GetAttributesRequestPayload* b) -{ - if(a != b) - { - if((a == NULL) || (b == NULL)) - { - return(KMIP_FALSE); - } - - if(a->unique_identifier != b->unique_identifier) - { - if((a->unique_identifier == NULL) || (b->unique_identifier == NULL)) - { - return(KMIP_FALSE); - } - - if(kmip_compare_text_string(a->unique_identifier, b->unique_identifier) == KMIP_FALSE) - { - return(KMIP_FALSE); - } - } - - if(a->attribute_names != b->attribute_names) - { - if((a->attribute_names == NULL) || - (b->attribute_names == NULL)) - { - return(KMIP_FALSE); - } - - if(kmip_compare_attribute_names(a->attribute_names, b->attribute_names) == KMIP_FALSE) - { - return(KMIP_FALSE); - } - } - } - - return(KMIP_TRUE); -} - - -/* -Encoding Functions -*/ - -int -kmip_encode_int8_be(KMIP *ctx, int8 value) +kmip_encode_int8_be(KMIP *ctx, int8 value) { CHECK_BUFFER_FULL(ctx, sizeof(int8)); @@ -6612,6 +6692,12 @@ kmip_encode_attribute_name(KMIP *ctx, enum attribute_type value) attribute_name.size = 24; } break; + case KMIP_ATTR_CONTACT_INFORMATION: + { + attribute_name.value = "Contact Information"; + attribute_name.size = 19; + } break; + default: kmip_push_error_frame(ctx, __func__, __LINE__); return(KMIP_ERROR_ATTR_UNSUPPORTED); @@ -6737,6 +6823,12 @@ kmip_encode_attribute_v1(KMIP *ctx, const Attribute *value) } break; + case KMIP_ATTR_CONTACT_INFORMATION: + { + result = kmip_encode_text_string(ctx, t, (TextString*)value->value); + } + break; + case KMIP_ATTR_ACTIVATION_DATE: case KMIP_ATTR_DEACTIVATION_DATE: case KMIP_ATTR_PROCESS_START_DATE: @@ -6880,6 +6972,16 @@ kmip_encode_attribute_v2(KMIP *ctx, const Attribute *value) } break; + case KMIP_ATTR_CONTACT_INFORMATION: + { + result = kmip_encode_text_string( + ctx, + KMIP_TAG_OBJECT_GROUP, + (TextString*)value->value + ); + } + break; + case KMIP_ATTR_ACTIVATION_DATE: { result = kmip_encode_date_time( @@ -6968,18 +7070,8 @@ kmip_encode_attributes(KMIP *ctx, const Attributes *value) uint8 *length_index = ctx->index; uint8 *value_index = ctx->index += 4; - if(value->attribute_list != NULL) - { - LinkedListItem *curr = value->attribute_list->head; - while(curr != NULL) - { - Attribute *attribute = (Attribute *)curr->data; - result = kmip_encode_attribute(ctx, attribute); - CHECK_RESULT(ctx, result); - - curr = curr->next; - } - } + result = kmip_encode_attribute_list(ctx, value->attribute_list); + CHECK_RESULT(ctx, result); uint8 *curr_index = ctx->index; ctx->index = length_index; @@ -6992,6 +7084,26 @@ kmip_encode_attributes(KMIP *ctx, const Attributes *value) return(KMIP_OK); } +int +kmip_encode_attribute_list(KMIP *ctx, const LinkedList* value) +{ + CHECK_ENCODE_ARGS(ctx, value); + + int result = 0; + + LinkedListItem *curr = value->head; + while(curr != NULL) + { + Attribute *attribute = (Attribute *)curr->data; + result = kmip_encode_attribute(ctx, attribute); + CHECK_RESULT(ctx, result); + + curr = curr->next; + } + + return(KMIP_OK); +} + int kmip_encode_template_attribute(KMIP *ctx, const TemplateAttribute *value) { @@ -7937,6 +8049,70 @@ kmip_encode_destroy_response_payload(KMIP *ctx, const DestroyResponsePayload *va return(KMIP_OK); } +int +kmip_encode_get_attributes_request_payload(KMIP *ctx, const GetAttributesRequestPayload *value) +{ + int result = 0; + result = kmip_encode_int32_be(ctx, TAG_TYPE(KMIP_TAG_REQUEST_PAYLOAD, KMIP_TYPE_STRUCTURE)); + CHECK_RESULT(ctx, result); + + uint8 *length_index = ctx->index; + uint8 *value_index = ctx->index += 4; + + if(value->unique_identifier != NULL) + { + result = kmip_encode_text_string(ctx, KMIP_TAG_UNIQUE_IDENTIFIER, value->unique_identifier); + CHECK_RESULT(ctx, result); + } + + if (value->attribute_names) + { + result = kmip_encode_attribute_names(ctx, value->attribute_names); + CHECK_RESULT(ctx, result); + } + + uint8 *curr_index = ctx->index; + ctx->index = length_index; + + kmip_encode_int32_be(ctx, curr_index - value_index); + + ctx->index = curr_index; + + return(KMIP_OK); +} + +int +kmip_encode_get_attributes_response_payload(KMIP *ctx, const GetAttributesResponsePayload *value) +{ + int result = 0; + result = kmip_encode_int32_be(ctx, TAG_TYPE(KMIP_TAG_RESPONSE_PAYLOAD, KMIP_TYPE_STRUCTURE)); + CHECK_RESULT(ctx, result); + + uint8 *length_index = ctx->index; + uint8 *value_index = ctx->index += 4; + + if(value->unique_identifier != NULL) + { + result = kmip_encode_text_string(ctx, KMIP_TAG_UNIQUE_IDENTIFIER, value->unique_identifier); + CHECK_RESULT(ctx, result); + } + + if (value->attributes) + { + result = kmip_encode_attribute_list(ctx, value->attributes->attribute_list); + CHECK_RESULT(ctx, result); + } + + uint8 *curr_index = ctx->index; + ctx->index = length_index; + + kmip_encode_int32_be(ctx, curr_index - value_index); + + ctx->index = curr_index; + + return(KMIP_OK); +} + int kmip_encode_nonce(KMIP *ctx, const Nonce *value) { @@ -8535,76 +8711,6 @@ kmip_encode_response_message(KMIP *ctx, const ResponseMessage *value) return(KMIP_OK); } -int -kmip_encode_get_attributes_request_payload(KMIP *ctx, const GetAttributesRequestPayload *value) -{ - int result = 0; - result = kmip_encode_int32_be(ctx, TAG_TYPE(KMIP_TAG_REQUEST_PAYLOAD, KMIP_TYPE_STRUCTURE)); - CHECK_RESULT(ctx, result); - - uint8 *length_index = ctx->index; - uint8 *value_index = ctx->index += 4; - - if(value->unique_identifier != NULL) - { - result = kmip_encode_text_string(ctx, KMIP_TAG_UNIQUE_IDENTIFIER, value->unique_identifier); - CHECK_RESULT(ctx, result); - } - - if (value->attribute_names) - { - result = kmip_encode_attribute_names(ctx, value->attribute_names); - CHECK_RESULT(ctx, result); - } - - uint8 *curr_index = ctx->index; - ctx->index = length_index; - - kmip_encode_int32_be(ctx, curr_index - value_index); - - ctx->index = curr_index; - - return(KMIP_OK); -} - -int -kmip_decode_get_attributes_request_payload(KMIP *ctx, GetAttributesRequestPayload *value) -{ - CHECK_DECODE_ARGS(ctx, value); - CHECK_BUFFER_FULL(ctx, 8); - - int result = 0; - int32 tag_type = 0; - uint32 length = 0; - - kmip_decode_int32_be(ctx, &tag_type); - CHECK_TAG_TYPE(ctx, tag_type, KMIP_TAG_REQUEST_PAYLOAD, KMIP_TYPE_STRUCTURE); - - kmip_decode_length(ctx, &length); - CHECK_BUFFER_FULL(ctx, length); - - if(kmip_is_tag_next(ctx, KMIP_TAG_UNIQUE_IDENTIFIER)) - { - value->unique_identifier = ctx->calloc_func(ctx->state, 1, sizeof(TextString)); - CHECK_NEW_MEMORY(ctx, value->unique_identifier, sizeof(TextString), "UniqueIdentifier text string"); - - result = kmip_decode_text_string(ctx, KMIP_TAG_UNIQUE_IDENTIFIER, value->unique_identifier); - CHECK_RESULT(ctx, result); - } - - if(kmip_is_tag_next(ctx, KMIP_TAG_ATTRIBUTE_NAME)) - { - value->attribute_names = ctx->calloc_func(ctx->state, 1, sizeof(AttributeNames)); - CHECK_NEW_MEMORY(ctx, value->attribute_names, sizeof(AttributeNames), "AttributeNames structure"); - - result = kmip_decode_attribute_names(ctx, value->attribute_names); - CHECK_RESULT(ctx, result); - } - - return(KMIP_OK); -} - - int kmip_encode_query_functions(KMIP *ctx, const Functions* value) { @@ -9029,6 +9135,10 @@ kmip_decode_attribute_name(KMIP *ctx, enum attribute_type *value) { *value = KMIP_ATTR_CRYPTOGRAPHIC_PARAMETERS; } + else if((19 == n.size) && (strncmp(n.value, "Contact Information", 24) == 0)) + { + *value = KMIP_ATTR_CONTACT_INFORMATION; + } /* TODO (ph) Add all remaining attributes here. */ else { @@ -9268,6 +9378,15 @@ kmip_decode_attribute_v1(KMIP *ctx, Attribute *value) } break; + case KMIP_ATTR_CONTACT_INFORMATION: + { + value->value = ctx->calloc_func(ctx->state, 1, sizeof(TextString)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(TextString), "ContactInfo text string"); + result = kmip_decode_text_string(ctx, t, (TextString*)value->value); + CHECK_RESULT(ctx, result); + } + break; + case KMIP_ATTR_ACTIVATION_DATE: { value->value = ctx->calloc_func(ctx->state, 1, sizeof(int64)); @@ -9555,6 +9674,33 @@ kmip_decode_attributes(KMIP *ctx, Attributes *value) return(KMIP_OK); } +int +kmip_decode_attribute_list(KMIP *ctx, LinkedList *value) +{ + CHECK_DECODE_ARGS(ctx, value); + CHECK_BUFFER_FULL(ctx, 8); + + int result = 0; + + uint32 tag = kmip_peek_tag(ctx); + while(tag == KMIP_TAG_ATTRIBUTE) + { + LinkedListItem *item = ctx->calloc_func(ctx->state, 1, sizeof(LinkedListItem)); + CHECK_NEW_MEMORY(ctx, item, sizeof(LinkedListItem), "LinkedListItem"); + kmip_linked_list_enqueue(value, item); + + item->data = ctx->calloc_func(ctx->state, 1, sizeof(Attribute)); + CHECK_NEW_MEMORY(ctx, item->data, sizeof(Attribute), "Attribute"); + + result = kmip_decode_attribute(ctx, (Attribute *)item->data); + CHECK_RESULT(ctx, result); + + tag = kmip_peek_tag(ctx); + } + + return(KMIP_OK); +} + int kmip_decode_attribute_names(KMIP *ctx, AttributeNames *value) { @@ -10587,6 +10733,88 @@ kmip_decode_destroy_response_payload(KMIP *ctx, DestroyResponsePayload *value) return(KMIP_OK); } +int +kmip_decode_get_attributes_request_payload(KMIP *ctx, GetAttributesRequestPayload *value) +{ + CHECK_DECODE_ARGS(ctx, value); + CHECK_BUFFER_FULL(ctx, 8); + + int result = 0; + int32 tag_type = 0; + uint32 length = 0; + + kmip_decode_int32_be(ctx, &tag_type); + CHECK_TAG_TYPE(ctx, tag_type, KMIP_TAG_REQUEST_PAYLOAD, KMIP_TYPE_STRUCTURE); + + kmip_decode_length(ctx, &length); + CHECK_BUFFER_FULL(ctx, length); + + if(kmip_is_tag_next(ctx, KMIP_TAG_UNIQUE_IDENTIFIER)) + { + value->unique_identifier = ctx->calloc_func(ctx->state, 1, sizeof(TextString)); + CHECK_NEW_MEMORY(ctx, value->unique_identifier, sizeof(TextString), "UniqueIdentifier text string"); + + result = kmip_decode_text_string(ctx, KMIP_TAG_UNIQUE_IDENTIFIER, value->unique_identifier); + CHECK_RESULT(ctx, result); + } + + if(kmip_is_tag_next(ctx, KMIP_TAG_ATTRIBUTE_NAME)) + { + value->attribute_names = ctx->calloc_func(ctx->state, 1, sizeof(AttributeNames)); + CHECK_NEW_MEMORY(ctx, value->attribute_names, sizeof(AttributeNames), "AttributeNames structure"); + + result = kmip_decode_attribute_names(ctx, value->attribute_names); + CHECK_RESULT(ctx, result); + } + + return(KMIP_OK); +} + +int +kmip_decode_get_attributes_response_payload(KMIP *ctx, GetAttributesResponsePayload *value) +{ + CHECK_BUFFER_FULL(ctx, 8); + + int result = 0; + int32 tag_type = 0; + uint32 length = 0; + + kmip_decode_int32_be(ctx, &tag_type); + CHECK_TAG_TYPE(ctx, tag_type, KMIP_TAG_RESPONSE_PAYLOAD, KMIP_TYPE_STRUCTURE); + + kmip_decode_length(ctx, &length); + CHECK_BUFFER_FULL(ctx, length); + + value->unique_identifier = ctx->calloc_func(ctx->state, 1, sizeof(TextString)); + CHECK_NEW_MEMORY(ctx, value->unique_identifier, sizeof(TextString), "UniqueIdentifier text string"); + + result = kmip_decode_text_string(ctx, KMIP_TAG_UNIQUE_IDENTIFIER, value->unique_identifier); + CHECK_RESULT(ctx, result); + + uint32 tag = kmip_peek_tag(ctx); + if (tag == KMIP_TAG_ATTRIBUTE) + { + value->attributes = ctx->calloc_func(ctx->state, 1, sizeof(Attributes)); + CHECK_NEW_MEMORY(ctx, value->attributes, sizeof(Attributes), "Attributes"); + + value->attributes->attribute_list = ctx->calloc_func(ctx->state, 1, sizeof(LinkedList)); + CHECK_NEW_MEMORY(ctx, value->attributes->attribute_list, sizeof(LinkedList), "LinkedList"); + + result = kmip_decode_attribute_list(ctx, value->attributes->attribute_list); + if(result != KMIP_OK) + { + kmip_free_attributes(ctx, value->attributes); + ctx->free_func(ctx, value->attributes); + value->attributes = NULL; + + HANDLE_FAILURE(ctx, result); + } + } + + return(KMIP_OK); +} + + int kmip_decode_request_batch_item(KMIP *ctx, RequestBatchItem *value) { diff --git a/src/kmip_io.c b/src/kmip_io.c index 02e907e..4259207 100644 --- a/src/kmip_io.c +++ b/src/kmip_io.c @@ -1297,6 +1297,12 @@ kmip_print_attribute_type_enum(FILE *f, enum attribute_type value) } break; + case KMIP_ATTR_CONTACT_INFORMATION: + { + fprintf(f, "Contact Information"); + } + break; + case KMIP_ATTR_ACTIVATION_DATE: { fprintf(f, "Activation Date"); @@ -2523,6 +2529,13 @@ kmip_print_attribute_value(FILE *f, int indent, enum attribute_type type, void * } break; + case KMIP_ATTR_CONTACT_INFORMATION: + { + fprintf(f, "\n"); + kmip_print_text_string(f, indent + 2, "Contact Information", value); + } + break; + case KMIP_ATTR_ACTIVATION_DATE: case KMIP_ATTR_DEACTIVATION_DATE: case KMIP_ATTR_PROCESS_START_DATE: @@ -3263,6 +3276,54 @@ kmip_print_object_types(FILE* f, int indent, ObjectTypes* value) } } +void +kmip_print_attribute_names(FILE* f, int indent, AttributeNames* value) +{ + fprintf(f, "%*sAttribute Names @ %p\n", indent, "", (void *)value); + + if(value != NULL && + value->name_list != NULL) + { + fprintf(f, "%*sNames: %zu\n", indent + 2, "", value->name_list->size); + LinkedListItem *curr = value->name_list->head; + size_t count = 1; + while(curr != NULL) + { + fprintf(f, "%*sName: %zu: ", indent + 4, "", count); + TextString* attrname = (TextString*)curr->data; + kmip_print_text_string(f, indent + 2, "Attribute Name", attrname); + fprintf(f, "\n"); + + curr = curr->next; + count++; + } + } +} + +void +kmip_print_get_attributes_request_payload(FILE* f, int indent, GetAttributesRequestPayload *value) +{ + fprintf(f,"%*sGet Attributes Request Payload @ %p\n", indent, "", (void *)value); + + if(value != NULL) + { + kmip_print_text_string(f, indent + 2, "Unique Identifier", value->unique_identifier); + kmip_print_attribute_names(f, indent + 2, value->attribute_names); + } +} + +void +kmip_print_get_attributes_response_payload(FILE* f, int indent, GetAttributesResponsePayload *value) +{ + fprintf(f,"%*sGet Attributes Response Payload @ %p\n", indent, "", (void *)value); + + if(value != NULL) + { + kmip_print_text_string(f, indent + 2, "Unique Identifier", value->unique_identifier); + kmip_print_attributes(f, indent + 2, value->attributes); + } +} + void kmip_print_alternative_endpoints(FILE* f, int indent, AltEndpoints* value) { @@ -3307,7 +3368,6 @@ kmip_print_server_information(FILE* f, int indent, ServerInformation* value) } } - void kmip_print_query_response_payload(FILE* f, int indent, QueryResponsePayload *value) { @@ -3331,38 +3391,3 @@ kmip_print_query_request_payload(FILE* f, int indent, QueryRequestPayload *value kmip_print_query_functions(f, indent, value->functions); } -void -kmip_print_attribute_names(FILE* f, int indent, AttributeNames* value) -{ - fprintf(f, "%*sAttribute Names @ %p\n", indent, "", (void *)value); - - if(value != NULL && - value->name_list != NULL) - { - fprintf(f, "%*sNames: %zu\n", indent + 2, "", value->name_list->size); - LinkedListItem *curr = value->name_list->head; - size_t count = 1; - while(curr != NULL) - { - fprintf(f, "%*sName: %zu: ", indent + 4, "", count); - TextString* attrname = (TextString*)curr->data; - kmip_print_text_string(f, indent + 2, "Attribute Name", attrname); - fprintf(f, "\n"); - - curr = curr->next; - count++; - } - } -} - -void -kmip_print_get_attributes_request_payload(FILE* f, int indent, GetAttributesRequestPayload *value) -{ - fprintf(f,"%*sGet Attributes Request Payload @ %p\n", indent, "", (void *)value); - - if(value != NULL) - { - kmip_print_text_string(f, indent + 2, "Unique Identifier", value->unique_identifier); - kmip_print_attribute_names(f, indent + 2, value->attribute_names); - } -} diff --git a/tests/tests.c b/tests/tests.c index d7abc93..b68c469 100644 --- a/tests/tests.c +++ b/tests/tests.c @@ -12028,6 +12028,98 @@ test_decode_attribute_names(TestTracker *tracker) return (result); } +int +test_encode_attribute_contact_information(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + /* This encoding matches the following values: + * Attribute + * Attribute Name - Contact Information + * Attribute Value - Foo + */ + uint8 expected[56] = { + 0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x13, // attr: contact + 0x43, 0x6F, 0x6E, 0x74, 0x61, 0x63, 0x74, 0x20, + 0x49, 0x6E, 0x66, 0x6F, 0x72, 0x6D, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x0B, 0x07, 0x00, 0x00, 0x00, 0x03, // Foo + 0x46, 0x6F, 0x6F, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + + uint8 observed[56] = {0}; + KMIP ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0); + + TextString contact = {0}; + contact.value = "Foo"; + contact.size = 3; + + Attribute attr = {0}; + kmip_init_attribute(&attr); + + attr.type = KMIP_ATTR_CONTACT_INFORMATION; + attr.value = &contact; + + int result = kmip_encode_attribute(&ctx, &attr); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_decode_attribute_contact_information(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + /* This encoding matches the following values: + * Attribute + * Attribute Name - Contact Information + * Attribute Value - Foo + */ + uint8 encoding[56] = { + 0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x13, // attr: contact + 0x43, 0x6F, 0x6E, 0x74, 0x61, 0x63, 0x74, 0x20, + 0x49, 0x6E, 0x66, 0x6F, 0x72, 0x6D, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x0B, 0x07, 0x00, 0x00, 0x00, 0x03, // Foo + 0x46, 0x6F, 0x6F, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + + struct kmip ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0); + + struct text_string contact = {0}; + contact.value = "Foo"; + contact.size = 3; + + struct attribute expected = {0}; + kmip_init_attribute(&expected); + expected.type = KMIP_ATTR_CONTACT_INFORMATION; + expected.value = &contact; + struct attribute observed = {0}; + kmip_init_attribute(&observed); + + int result = kmip_decode_attribute(&ctx, &observed); + result = report_decoding_test_result( + tracker, + &ctx, + kmip_compare_attribute(&expected, &observed), + result, + __func__); + kmip_free_attribute(&ctx, &observed); + kmip_destroy(&ctx); + return(result); +} + int test_encode_get_attributes_request_payload(TestTracker *tracker) { @@ -12140,7 +12232,6 @@ test_decode_get_attributes_request_payload(TestTracker *tracker) 0x65, 0x32, 0x2D, 0x39, 0x33, 0x61, 0x30, 0x2D, 0x63, 0x34, 0x39, 0x34, 0x61, 0x31, 0x64, 0x34, 0x61, 0x65, 0x34, 0x30, 0x00, 0x00, 0x00, 0x00, - 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x0C, // attr: object group 0x4F, 0x62, 0x6A, 0x65, 0x63, 0x74, 0x20, 0x47, 0x72, 0x6F, 0x75, 0x70, 0x00, 0x00, 0x00, 0x00, @@ -12217,6 +12308,211 @@ test_decode_get_attributes_request_payload(TestTracker *tracker) return(result); } +int +test_decode_get_attributes_response_payload(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + /* Tag: Unique Identifier (0x420094), Type: Text String (0x07), Data: b4faee10-aa2a-4446-8ad4-0881f3422959 + Tag: Attribute (0x420008), Type: Structure (0x01), Data: + Tag: Attribute Name (0x42000A), Type: Text String (0x07), Data: Name + Tag: Attribute Value (0x42000B), Type: Structure (0x01), Data: + Tag: Name Value (0x420055), Type: Text String (0x07), Data: Key1 + Tag: Name Type (0x420054), Type: Enumeration (0x05), Data: 0x00000001 (Uninterpreted Text String) + Tag: Attribute (0x420008), Type: Structure (0x01), Data: + Tag: Attribute Name (0x42000A), Type: Text String (0x07), Data: Contact Information + Tag: Attribute Value (0x42000B), Type: Text String (0x07), Data: Foo + */ + + + uint8 encoded[] = { + 0x42, 0x00, 0x7C, 0x01, 0x00, 0x00, 0x00, 0xA8, + 0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, + 0x62, 0x34, 0x66, 0x61, 0x65, 0x65, 0x31, 0x30, + 0x2D, 0x61, 0x61, 0x32, 0x61, 0x2D, 0x34, 0x34, + 0x34, 0x36, 0x2D, 0x38, 0x61, 0x64, 0x34, 0x2D, + 0x30, 0x38, 0x38, 0x31, 0x66, 0x33, 0x34, 0x32, + 0x32, 0x39, 0x35, 0x39, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x38, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x04, + 0x4E, 0x61, 0x6D, 0x65, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x0B, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x42, 0x00, 0x55, 0x07, 0x00, 0x00, 0x00, 0x04, + 0x4B, 0x65, 0x79, 0x31, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x54, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x13, + 0x43, 0x6F, 0x6E, 0x74, 0x61, 0x63, 0x74, 0x20, + 0x49, 0x6E, 0x66, 0x6F, 0x72, 0x6D, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x0B, 0x07, 0x00, 0x00, 0x00, 0x03, + 0x46, 0x6F, 0x6F, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + + struct kmip ctx = {0}; + kmip_init(&ctx, encoded, ARRAY_LENGTH(encoded), KMIP_1_0); + + struct text_string uuid = {0}; + uuid.value = "b4faee10-aa2a-4446-8ad4-0881f3422959"; + uuid.size = 36; + + struct attribute a[2] = {{0}}; + for(int i = 0; i < 2; i++) + { + kmip_init_attribute(&a[i]); + } + + struct text_string value = {0}; + value.value = "Key1"; + value.size = 4; + + struct name name = {0}; + name.value = &value; + name.type = KMIP_NAME_UNINTERPRETED_TEXT_STRING; + a[0].type = KMIP_ATTR_NAME; + a[0].value = &name; + + struct text_string n = {0}; + n.value = "Foo"; + n.size = 3; + + a[1].type = KMIP_ATTR_CONTACT_INFORMATION; + a[1].value = &n; + + Attributes attributes = {0}; + LinkedList list = {0}; + LinkedListItem item_1 = {0}; + item_1.data = &a[0]; + + LinkedListItem item_2 = {0}; + item_2.data = &a[1]; + + kmip_linked_list_enqueue(&list, &item_1); + kmip_linked_list_enqueue(&list, &item_2); + attributes.attribute_list = &list; + + GetAttributesResponsePayload expected = {0}; + expected.unique_identifier = &uuid; + expected.attributes = &attributes; + + GetAttributesResponsePayload observed = {0}; + + int result = kmip_decode_get_attributes_response_payload(&ctx, &observed); + result = report_decoding_test_result( + tracker, + &ctx, + kmip_compare_get_attributes_response_payload(&expected, &observed), + result, + __func__); + kmip_free_get_attributes_response_payload(&ctx, &observed); + kmip_destroy(&ctx); + + return(result); + +} + +int +test_encode_get_attributes_response_payload(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + /* Tag: Unique Identifier (0x420094), Type: Text String (0x07), Data: b4faee10-aa2a-4446-8ad4-0881f3422959 + Tag: Attribute (0x420008), Type: Structure (0x01), Data: + Tag: Attribute Name (0x42000A), Type: Text String (0x07), Data: Name + Tag: Attribute Value (0x42000B), Type: Structure (0x01), Data: + Tag: Name Value (0x420055), Type: Text String (0x07), Data: Key1 + Tag: Name Type (0x420054), Type: Enumeration (0x05), Data: 0x00000001 (Uninterpreted Text String) + Tag: Attribute (0x420008), Type: Structure (0x01), Data: + Tag: Attribute Name (0x42000A), Type: Text String (0x07), Data: Contact Information + Tag: Attribute Value (0x42000B), Type: Text String (0x07), Data: Foo + */ + + uint8 expected[] = { + 0x42, 0x00, 0x7C, 0x01, 0x00, 0x00, 0x00, 0xA8, + 0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, + 0x62, 0x34, 0x66, 0x61, 0x65, 0x65, 0x31, 0x30, + 0x2D, 0x61, 0x61, 0x32, 0x61, 0x2D, 0x34, 0x34, + 0x34, 0x36, 0x2D, 0x38, 0x61, 0x64, 0x34, 0x2D, + 0x30, 0x38, 0x38, 0x31, 0x66, 0x33, 0x34, 0x32, + 0x32, 0x39, 0x35, 0x39, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x38, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x04, + 0x4E, 0x61, 0x6D, 0x65, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x0B, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x42, 0x00, 0x55, 0x07, 0x00, 0x00, 0x00, 0x04, + 0x4B, 0x65, 0x79, 0x31, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x54, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x13, + 0x43, 0x6F, 0x6E, 0x74, 0x61, 0x63, 0x74, 0x20, + 0x49, 0x6E, 0x66, 0x6F, 0x72, 0x6D, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x0B, 0x07, 0x00, 0x00, 0x00, 0x03, + 0x46, 0x6F, 0x6F, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + + uint8 observed[22*8] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0); + + struct text_string uuid = {0}; + uuid.value = "b4faee10-aa2a-4446-8ad4-0881f3422959"; + uuid.size = 36; + + struct attribute a[2] = {{0}}; + for(int i = 0; i < 2; i++) + { + kmip_init_attribute(&a[i]); + } + + struct text_string value = {0}; + value.value = "Key1"; + value.size = 4; + + struct name name = {0}; + name.value = &value; + name.type = KMIP_NAME_UNINTERPRETED_TEXT_STRING; + a[0].type = KMIP_ATTR_NAME; + a[0].value = &name; + + struct text_string n = {0}; + n.value = "Foo"; + n.size = 3; + + a[1].type = KMIP_ATTR_CONTACT_INFORMATION; + a[1].value = &n; + + Attributes attributes = {0}; + LinkedList list = {0}; + LinkedListItem item_1 = {0}; + item_1.data = &a[0]; + + LinkedListItem item_2 = {0}; + item_2.data = &a[1]; + + kmip_linked_list_enqueue(&list, &item_1); + kmip_linked_list_enqueue(&list, &item_2); + attributes.attribute_list = &list; + + + GetAttributesResponsePayload garp = {0}; + garp.unique_identifier = &uuid; + garp.attributes = &attributes; + + int result = kmip_encode_get_attributes_response_payload(&ctx, &garp); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + int test_compare_query_functions(TestTracker *tracker) { @@ -13309,6 +13605,7 @@ run_tests(void) test_decode_attribute_process_start_date(&tracker); test_decode_attribute_protect_stop_date(&tracker); test_decode_attribute_cryptographic_parameters(&tracker); + test_decode_attribute_contact_information(&tracker); test_decode_template_attribute(&tracker); test_decode_protocol_version(&tracker); test_decode_key_material_byte_string(&tracker); @@ -13341,13 +13638,14 @@ run_tests(void) test_decode_request_batch_item_get_payload(&tracker); test_decode_request_message_get(&tracker); test_decode_response_message_get(&tracker); + test_decode_attribute_names(&tracker); + test_decode_get_attributes_request_payload(&tracker); + test_decode_get_attributes_response_payload(&tracker); test_decode_query_functions(&tracker); test_decode_operations(&tracker); test_decode_object_types(&tracker); test_compare_query_functions(&tracker); test_decode_query_response_payload(&tracker); - test_decode_attribute_names(&tracker); - test_decode_get_attributes_request_payload(&tracker); printf("\n"); test_encode_integer(&tracker); @@ -13409,10 +13707,12 @@ run_tests(void) test_encode_request_message_get(&tracker); test_encode_response_message_get(&tracker); test_encode_template_attribute(&tracker); - test_encode_query_functions(&tracker); - test_encode_query_request_payload(&tracker); test_encode_attribute_names(&tracker); + test_encode_attribute_contact_information(&tracker); test_encode_get_attributes_request_payload(&tracker); + test_encode_get_attributes_response_payload(&tracker); + test_encode_query_functions(&tracker); + test_encode_query_request_payload(&tracker); printf("\nKMIP 1.1 Feature Tests\n"); From 77be6a4651291af3107a31d1e08d50c5207ac3a0 Mon Sep 17 00:00:00 2001 From: rjewell Date: Fri, 4 Feb 2022 20:02:43 -0500 Subject: [PATCH 3/5] Add support for KMIP Locate command --- Makefile | 9 +- demos/demo_locate.c | 608 +++++++++++++++++++++++++++++++++++++++++++ include/kmip.h | 57 ++++ include/kmip_bio.h | 2 + include/kmip_io.h | 3 + src/kmip.c | 527 ++++++++++++++++++++++++++++++++++++- src/kmip_bio.c | 159 ++++++++++++ src/kmip_io.c | 64 +++++ tests/tests.c | 618 +++++++++++++++++++++++++++++++++++++++++++- 9 files changed, 2032 insertions(+), 15 deletions(-) create mode 100755 demos/demo_locate.c diff --git a/Makefile b/Makefile index bd98d7e..05aab07 100644 --- a/Makefile +++ b/Makefile @@ -70,6 +70,7 @@ DEMO_O_FILES = $(OBJ_DIR)/demo_get.o DEMO_O_FILES += $(OBJ_DIR)/demo_create.o DEMO_O_FILES += $(OBJ_DIR)/demo_destroy.o DEMO_O_FILES += $(OBJ_DIR)/demo_query.o +DEMO_O_FILES += $(OBJ_DIR)/demo_locate.o TEST_O_FILES = $(OBJ_DIR)/tests.o @@ -86,7 +87,8 @@ demos: objs \ $(BIN_DIR)/demo_get \ $(BIN_DIR)/demo_create \ $(BIN_DIR)/demo_destroy \ - $(BIN_DIR)/demo_query + $(BIN_DIR)/demo_query \ + $(BIN_DIR)/demo_locate tests: objs \ $(TEST_O_FILES) \ @@ -104,6 +106,8 @@ $(BIN_DIR)/demo_destroy: $(OBJ_DIR)/demo_destroy.o $(SRC_O_FILES) $(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS) $(BIN_DIR)/demo_query: $(OBJ_DIR)/demo_query.o $(SRC_O_FILES) $(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS) +$(BIN_DIR)/demo_locate: $(OBJ_DIR)/demo_locate.o $(SRC_O_FILES) + $(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS) $(BIN_DIR)/tests: $(TEST_O_FILES) $(OBJ_DIR)/kmip.o $(OBJ_DIR)/kmip_io.o $(OBJ_DIR)/kmip_memset.o $(CC) $(LDFLAGS) -o $@ $^ @@ -126,6 +130,8 @@ $(OBJ_DIR)/demo_destroy.o: $(DEMO_DIR)/demo_destroy.c $(H_FILES) $(CC) $(CFLAGS) $(INC_FLAGS) -c $< -o $@ $(OBJ_DIR)/demo_query.o: $(DEMO_DIR)/demo_query.c $(H_FILES) $(CC) $(CFLAGS) $(INC_FLAGS) -c $< -o $@ +$(OBJ_DIR)/demo_locate.o: $(DEMO_DIR)/demo_locate.c $(H_FILES) + $(CC) $(CFLAGS) $(INC_FLAGS) -c $< -o $@ $(OBJ_DIR)/tests.o: $(TEST_DIR)/tests.c $(INC_DIR)/kmip.h $(INC_DIR)/kmip_io.h $(INC_DIR)/kmip_memset.h $(CC) $(CFLAGS) $(INC_FLAGS) -c $< -o $@ @@ -175,6 +181,7 @@ install: all cp $(BIN_DIR)/demo_get $(DEST_DIR)$(PREFIX)/bin/$(KMIP) cp $(BIN_DIR)/demo_destroy $(DEST_DIR)$(PREFIX)/bin/$(KMIP) cp $(BIN_DIR)/demo_query $(DEST_DIR)$(PREFIX)/bin/$(KMIP) + cp $(BIN_DIR)/demo_locate $(DEST_DIR)$(PREFIX)/bin/$(KMIP) cp -r $(DOCS_DIR)/source/. $(DEST_DIR)$(PREFIX)/share/doc/$(KMIP)/src cp $(SRC_DIR)/*.c $(DEST_DIR)$(PREFIX)/src/$(KMIP) cp $(INC_DIR)/*.h $(DEST_DIR)$(PREFIX)/include/$(KMIP) diff --git a/demos/demo_locate.c b/demos/demo_locate.c new file mode 100755 index 0000000..e67dff5 --- /dev/null +++ b/demos/demo_locate.c @@ -0,0 +1,608 @@ +/* Copyright (c) 2018 The Johns Hopkins University/Applied Physics Labora`tory + * All Rights Reserved. + * + * This file is dual licensed under the terms of the Apache 2.0 License and + * the BSD 3-Clause License. See the LICENSE file in the root of this + * repository for more information. + */ + +#include +#include +#include +#include +#include + +#include "kmip.h" +#include "kmip_io.h" +#include "kmip_bio.h" +#include "kmip_memset.h" + +void +print_help(const char *app) +{ + printf("Usage: %s [flag value | flag] ...\n\n", app); + printf("Flags:\n"); + printf("-a addr : the IP address of the KMIP server\n"); + printf("-c path : path to client certificate file\n"); + printf("-h : print this help info\n"); + printf("-k path : path to client key file\n"); + printf("-p port : the port number of the KMIP server\n"); + printf("-r path : path to CA certificate file\n"); + printf("-n name : name of new key\n"); + printf("-g group : name of object group\n"); +} + +int +parse_arguments(int argc, char **argv, + char **server_address, char **server_port, + char **client_certificate, char **client_key, char **ca_certificate, + char **key_name, + char **group, + int *print_usage) +{ + if(argc <= 1) + { + print_help(argv[0]); + return(-1); + } + + for(int i = 1; i < argc; i++) + { + if(strncmp(argv[i], "-a", 2) == 0) + { + *server_address = argv[++i]; + } + else if(strncmp(argv[i], "-c", 2) == 0) + { + *client_certificate = argv[++i]; + } + else if(strncmp(argv[i], "-h", 2) == 0) + { + *print_usage = 1; + } + else if(strncmp(argv[i], "-k", 2) == 0) + { + *client_key = argv[++i]; + } + else if(strncmp(argv[i], "-p", 2) == 0) + { + *server_port = argv[++i]; + } + else if(strncmp(argv[i], "-r", 2) == 0) + { + *ca_certificate = argv[++i]; + } + else if(strncmp(argv[i], "-n", 2) == 0) + *key_name = argv[++i]; + else if(strncmp(argv[i], "-g", 2) == 0) + *group = argv[++i]; + else + { + printf("Invalid option: '%s'\n", argv[i]); + print_help(argv[0]); + return(-1); + } + } + + return(0); +} + + +void * +demo_calloc(void *state, size_t num, size_t size) +{ + void* ptr = calloc(num, size); + printf("demo_calloc called: state = %p, num = %zu, size = %zu, ptr = %p\n", state, num, size, ptr); + return(ptr); +} + +void * +demo_realloc(void *state, void *ptr, size_t size) +{ + void* reptr = realloc(ptr, size); + printf("demo_realloc called: state = %p, ptr = %p, size = %zu, reptr = %p\n", state, ptr, size, reptr); + return(realloc(reptr, size)); +} + +void +demo_free(void *state, void *ptr) +{ + printf("demo_free called: state = %p, ptr = %p\n", state, ptr); + free(ptr); + return; +} + + +int use_low_level_api(KMIP *ctx, BIO *bio, Attribute* attribs, size_t attrib_count, LocateResponse* locate_result) +{ + if (ctx == NULL || bio == NULL || attribs == NULL || attrib_count == 0 || locate_result == NULL) + { + return(KMIP_ARG_INVALID); + } + + printf("bio locate start \n"); + + size_t buffer_blocks = 1; + size_t buffer_block_size = 1024; + size_t buffer_total_size = buffer_blocks * buffer_block_size; + + uint8 *encoding = ctx->calloc_func(ctx->state, buffer_blocks, buffer_block_size); + if(encoding == NULL) + { + kmip_destroy(ctx); + return(KMIP_MEMORY_ALLOC_FAILED); + } + printf("encoding = %p\n", encoding); + kmip_set_buffer(ctx, encoding, buffer_total_size); + + /* Build the request message. */ + ProtocolVersion pv = {0}; + kmip_init_protocol_version(&pv, ctx->version); + + RequestHeader rh = {0}; + kmip_init_request_header(&rh); + + rh.protocol_version = &pv; + rh.maximum_response_size = ctx->max_message_size; + rh.time_stamp = time(NULL); + rh.batch_count = 1; + + // copy input array to list + LinkedList *attribute_list = ctx->calloc_func(ctx->state, 1, sizeof(LinkedList)); + for(size_t i = 0; i < attrib_count; i++) + { + LinkedListItem *item = ctx->calloc_func(ctx->state, 1, sizeof(LinkedListItem)); + item->data = kmip_deep_copy_attribute(ctx, &attribs[i]); + kmip_linked_list_enqueue(attribute_list, item); + } + + LocateRequestPayload lrp = {0}; + lrp.maximum_items = 12; + lrp.offset_items = 0; + lrp.storage_status_mask = 0; + lrp.group_member_option = 0; + lrp.attributes = attribute_list; + + RequestBatchItem rbi = {0}; + kmip_init_request_batch_item(&rbi); + rbi.operation = KMIP_OP_LOCATE; + rbi.request_payload = &lrp; + + RequestMessage rm = {0}; + rm.request_header = &rh; + rm.batch_items = &rbi; + rm.batch_count = 1; + + /* Encode the request message. Dynamically resize the encoding buffer */ + /* if it's not big enough. Once encoding succeeds, send the request */ + /* message. */ + int encode_result = kmip_encode_request_message(ctx, &rm); + while(encode_result == KMIP_ERROR_BUFFER_FULL) + { + kmip_reset(ctx); + ctx->free_func(ctx->state, encoding); + + buffer_blocks += 1; + buffer_total_size = buffer_blocks * buffer_block_size; + + encoding = ctx->calloc_func(ctx->state, buffer_blocks, buffer_block_size); + if(encoding == NULL) + { + printf("Failure: Could not automatically enlarge the encoding "); + printf("buffer for the Locate request.\n"); + + kmip_destroy(ctx); + return(KMIP_MEMORY_ALLOC_FAILED); + } + printf("encoding = %p\n", encoding); + + kmip_set_buffer(ctx, encoding, buffer_total_size); + encode_result = kmip_encode_request_message(ctx, &rm); + } + + if(encode_result != KMIP_OK) + { + printf("An error occurred while encoding the Locate request.\n"); + printf("Error Code: %d\n", encode_result); + printf("Error Name: "); + kmip_print_error_string(stdout, encode_result); + printf("\n"); + printf("Context Error: %s\n", ctx->error_message); + printf("Stack trace:\n"); + kmip_print_stack_trace(stdout, ctx); + + kmip_free_buffer(ctx, encoding, buffer_total_size); + encoding = NULL; + kmip_set_buffer(ctx, NULL, 0); + kmip_destroy(ctx); + return(encode_result); + } + + kmip_print_request_message(stdout, &rm); + printf("\n"); + + char *response = NULL; + int response_size = 0; + + printf("bio locate send request\n"); + + int result = kmip_bio_send_request_encoding(ctx, bio, (char *)encoding, + ctx->index - ctx->buffer, + &response, &response_size); + + printf("bio locate response = %p\n", response); + + + printf("\n"); + if(result < 0) + { + printf("An error occurred in locate request.\n"); + printf("Error Code: %d\n", result); + printf("Error Name: "); + kmip_print_error_string(stderr, result); + printf("\n"); + printf("Context Error: %s\n", ctx->error_message); + printf("Stack trace:\n"); + kmip_print_stack_trace(stderr, ctx); + + kmip_free_buffer(ctx, encoding, buffer_total_size); + kmip_free_buffer(ctx, response, response_size); + encoding = NULL; + response = NULL; + kmip_set_buffer(ctx, NULL, 0); + kmip_destroy(ctx); + return(result); + } + + kmip_free_locate_request_payload(ctx, &lrp); + + if (response) + { + FILE* out = fopen( "/tmp/kmip_locate.dat", "w" ); + if (out) + { + if (fwrite( response, response_size, 1, out ) != 1 ) + fprintf(stderr, "failed writing dat file\n"); + fclose(out); + } + kmip_print_buffer(stdout, response, response_size); + } + + printf("bio locate free encoding = %p\n", encoding); + kmip_free_buffer(ctx, encoding, buffer_total_size); + encoding = NULL; + kmip_set_buffer(ctx, response, response_size); + + /* Decode the response message and retrieve the operation results. */ + ResponseMessage resp_m = {0}; + int decode_result = kmip_decode_response_message(ctx, &resp_m); + if(decode_result != KMIP_OK) + { + printf("An error occurred while decoding the Locate response.\n"); + printf("Error Code: %d\n", decode_result); + printf("Error Name: "); + kmip_print_error_string(stderr, decode_result); + printf("\n"); + printf("Context Error: %s\n", ctx->error_message); + printf("Stack trace:\n"); + kmip_print_stack_trace(stderr, ctx); + + kmip_free_response_message(ctx, &resp_m); + kmip_free_buffer(ctx, response, response_size); + response = NULL; + kmip_set_buffer(ctx, NULL, 0); + kmip_destroy(ctx); + return(decode_result); + } + + kmip_print_response_message(stdout, &resp_m); + printf("\n"); + + if(resp_m.batch_count != 1 || resp_m.batch_items == NULL) + { + printf("Expected to find one batch item in the Locate response.\n"); + kmip_free_response_message(ctx, &resp_m); + kmip_free_buffer(ctx, response, response_size); + response = NULL; + kmip_set_buffer(ctx, NULL, 0); + kmip_destroy(ctx); + return(KMIP_MALFORMED_RESPONSE); + } + + ResponseBatchItem req = resp_m.batch_items[0]; + enum result_status result_status = req.result_status; + + printf("The KMIP operation was executed with no errors.\n"); + printf("Result: "); + kmip_print_result_status_enum(stdout, result); + printf(" (%d)\n\n", result); + + if(result == KMIP_STATUS_SUCCESS) + { + kmip_copy_locate_result(locate_result, (LocateResponsePayload*) req.response_payload); + } + + printf("bio locate free response resp_m = %p, response = %p\n", (void*)&resp_m, response); + if (locate_result->ids_size) + { + printf("id[0] = %s\n", locate_result->ids[0]); + } + + /* Clean up the response message, the response buffer, and the KMIP */ + /* context. */ + kmip_free_response_message(ctx, &resp_m); + kmip_free_buffer(ctx, response, response_size); + response = NULL; + + kmip_set_buffer(ctx, NULL, 0); + kmip_destroy(ctx); + + printf("bio locate done \n"); + + return(result_status); +} + + +Credential* get_credential(char* device_serial_number,char* device_identifier, char* machine_identifier ) +{ + static Credential credential = {0}; + static DeviceCredential devc = {0}; + static TextString sn = {0}; + static TextString did = {0}; + static TextString mid = {0}; + + memset(&devc,0, sizeof(devc) ); + if (device_serial_number) + { + sn.value = device_serial_number; + sn.size = kmip_strnlen_s(device_serial_number, 50); + devc.device_serial_number = &sn; + } + if (device_identifier) + { + did.value = device_identifier; + did.size = kmip_strnlen_s(device_identifier, 50); + devc.device_identifier = &did; + } + if (machine_identifier) + { + mid.value = machine_identifier; + mid.size = kmip_strnlen_s(machine_identifier, 50); + devc.machine_identifier = ∣ + } + + credential.credential_type = KMIP_CRED_DEVICE; + credential.credential_value = &devc; + + return &credential; +} + +int +use_mid_level_api(BIO* bio, + char *key_name, + char *group, + LocateResponse* locate_result) +{ + int result; + + /* Set up the KMIP context and send the request message. */ + KMIP kmip_context = {0}; + + kmip_init(&kmip_context, NULL, 0, KMIP_1_0); + + +#define USE_DEVICE_CREDENTIALS +#ifdef USE_DEVICE_CREDENTIALS + + char device_serial_number[] = "J3003MFY"; + char device_identifier[] = "7X06"; + char machine_identifier[] = "ED98BF5CE30E11E7BA717ED30AE6BACF"; + + Credential* cred = get_credential(device_serial_number,device_identifier, machine_identifier ); + result = kmip_add_credential(&kmip_context, cred); + if(result != KMIP_OK) + { + printf("Failed to add credential to the KMIP context.\n"); + } +#endif // USE_DEVICE_CREDENTIALS + + /* Build the request message. */ + Attribute a[6] = {{0}}; + for(int i = 0; i < 6; i++) + kmip_init_attribute(&a[i]); + + + int idx = 0; + + // look for symmetric key + enum object_type loctype = KMIP_OBJTYPE_SYMMETRIC_KEY; + a[idx].type = KMIP_ATTR_OBJECT_TYPE; + a[idx].value = &loctype; + idx++; + + if (0) + { + enum cryptographic_algorithm algorithm = KMIP_CRYPTOALG_AES; + a[idx].type = KMIP_ATTR_CRYPTOGRAPHIC_ALGORITHM; + a[idx].value = &algorithm; + idx++; + + int32 length = 256; + a[idx].type = KMIP_ATTR_CRYPTOGRAPHIC_LENGTH; + a[idx].value = &length; + idx++; + + int32 mask = KMIP_CRYPTOMASK_ENCRYPT | KMIP_CRYPTOMASK_DECRYPT; + a[idx].type = KMIP_ATTR_CRYPTOGRAPHIC_USAGE_MASK; + a[idx].value = &mask; + idx++; + } + + TextString s = { 0 }; + Name n = { 0 }; + if (key_name) + { + s.value = (char*) key_name; + s.size = kmip_strnlen_s(key_name, 50); + + n.value = &s; + n.type = KMIP_NAME_UNINTERPRETED_TEXT_STRING; + + a[idx].type = KMIP_ATTR_NAME; + a[idx].value = &n; + + idx++; + } + + TextString g = { 0 }; + if (group) + { + g.value = (char*) group; + g.size = kmip_strnlen_s(group, 50); + + a[idx].type = KMIP_ATTR_OBJECT_GROUP; + a[idx].value = &g; + + idx++; + } + + int attrib_count = idx; + + result = kmip_bio_locate_with_context(&kmip_context, bio, a, attrib_count, locate_result); + //result = use_low_level_api(&kmip_context, bio, a, attrib_count, locate_result); + + /* Handle the response results. */ + printf("\n"); + if(result < 0) + { + printf("An error occurred while running the locate."); + printf("Error Code: %d\n", result); + printf("Error Name: "); + kmip_print_error_string(stderr, result); + printf("\n"); + printf("Context Error: %s\n", kmip_context.error_message); + printf("Stack trace:\n"); + kmip_print_stack_trace(stderr, &kmip_context); + } + else if(result >= 0) + { + printf("The KMIP operation was executed with no errors.\n"); + printf("Result: "); + kmip_print_result_status_enum(stdout, result); + printf(" (%d)\n", result); + + if(result == KMIP_STATUS_SUCCESS) + { + printf("Locate results: "); + printf("located: %d\n", locate_result->located_items); + printf("\n"); + } + } + + printf("\n"); + + /* Clean up the KMIP context and return the results. */ + kmip_set_buffer(&kmip_context, NULL, 0); + kmip_destroy(&kmip_context); + return(result); +} + +int +main(int argc, char **argv) +{ + char *server_address = NULL; + char *server_port = NULL; + char *client_certificate = NULL; + char *client_key = NULL; + char *ca_certificate = NULL; + char *key_name = NULL; + char *group = NULL; + int help = 0; + + int error = parse_arguments(argc, argv, &server_address, &server_port, + &client_certificate, &client_key, &ca_certificate, + &key_name, &group, &help); + if(error) + { + return(error); + } + if(help) + { + print_help(argv[0]); + return(0); + } + + /* Set up the TLS connection to the KMIP server. */ + SSL_CTX *ctx = NULL; + SSL *ssl = NULL; + OPENSSL_init_ssl(0, NULL); + ctx = SSL_CTX_new(TLS_client_method()); + + printf("\n"); + printf("Loading the client certificate: %s\n", client_certificate); + if(SSL_CTX_use_certificate_file(ctx, client_certificate, SSL_FILETYPE_PEM) != 1) + { + fprintf(stderr, "Loading the client certificate failed\n"); + ERR_print_errors_fp(stderr); + SSL_CTX_free(ctx); + return(-1); + } + + printf("Loading the client key: %s\n", client_key); + if(SSL_CTX_use_PrivateKey_file(ctx, client_key, SSL_FILETYPE_PEM) != 1) + { + fprintf(stderr, "Loading the client key failed\n"); + ERR_print_errors_fp(stderr); + SSL_CTX_free(ctx); + return(-1); + } + + printf("Loading the CA certificate: %s\n", ca_certificate); + if(SSL_CTX_load_verify_locations(ctx, ca_certificate, NULL) != 1) + { + fprintf(stderr, "Loading the CA file failed\n"); + ERR_print_errors_fp(stderr); + SSL_CTX_free(ctx); + return(-1); + } + + BIO *bio = NULL; + bio = BIO_new_ssl_connect(ctx); + if(bio == NULL) + { + fprintf(stderr, "BIO_new_ssl_connect failed\n"); + ERR_print_errors_fp(stderr); + SSL_CTX_free(ctx); + return(-1); + } + + BIO_get_ssl(bio, &ssl); + SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); + BIO_set_conn_hostname(bio, server_address); + BIO_set_conn_port(bio, server_port); + if(BIO_do_connect(bio) != 1) + { + fprintf(stderr, "BIO_do_connect failed\n"); + ERR_print_errors_fp(stderr); + BIO_free_all(bio); + SSL_CTX_free(ctx); + return(-1); + } + + LocateResponse locate_result = {0}; + int result = use_mid_level_api(bio, key_name, group, &locate_result); + + if(result == KMIP_STATUS_SUCCESS) + { + printf("Locate results: "); + printf("located items: %d\n", locate_result.located_items); + printf("returned items: %zu\n", locate_result.ids_size); + printf("id[0]= %s\n", locate_result.ids[0]); + printf("\n"); + } + + BIO_free_all(bio); + SSL_CTX_free(ctx); + + return(result); +} diff --git a/include/kmip.h b/include/kmip.h index 293d7f5..a8effb5 100644 --- a/include/kmip.h +++ b/include/kmip.h @@ -533,6 +533,13 @@ enum query_function KMIP_QUERY_STORAGE_PROTECTION_MASKS = 0x000E }; +enum group_member_option +{ + group_member_fresh = 0x00000001, + group_member_default = 0x00000002 +}; + + enum result_reason { /* KMIP 1.0 */ @@ -725,6 +732,7 @@ enum tag KMIP_TAG_MACHINE_IDENTIFIER = 0x4200A9, KMIP_TAG_MEDIA_IDENTIFIER = 0x4200AA, KMIP_TAG_NETWORK_IDENTIFIER = 0x4200AB, + KMIP_TAG_OBJECT_GROUP_MEMBER = 0x4200AC, KMIP_TAG_DIGITAL_SIGNATURE_ALGORITHM = 0x4200AE, KMIP_TAG_DEVICE_SERIAL_NUMBER = 0x4200B0, /* KMIP 1.2 */ @@ -742,6 +750,8 @@ enum tag KMIP_TAG_INITIAL_COUNTER_VALUE = 0x4200D1, KMIP_TAG_INVOCATION_FIELD_LENGTH = 0x4200D2, KMIP_TAG_ATTESTATION_CAPABLE_INDICATOR = 0x4200D3, + KMIP_TAG_OFFSET_ITEMS = 0x4200D4, + KMIP_TAG_LOCATED_ITEMS = 0x4200D5, /* KMIP 1.4 */ KMIP_TAG_KEY_WRAP_TYPE = 0x4200F8, KMIP_TAG_SALT_LENGTH = 0x420100, @@ -1273,6 +1283,39 @@ typedef struct query_response char cluster_info[MAX_QUERY_LEN]; } QueryResponse; + +typedef struct locate_request_payload +{ + int32 maximum_items; // An Integer object that indicates the maximum number of object identifiers the server MAY return. + int32 offset_items; // An Integer object that indicates the number of object identifiers to skip that satisfy the identification criteria specified in the request. + int32 storage_status_mask; // An Integer object (used as a bit mask) that indicates whether only on-line objects, only archived objects, destroyed objects or any combination of these, are to be searched. If omitted, then only on-line objects SHALL be returned. + enum group_member_option group_member_option; // An Enumeration object that indicates the object group member type. + Attributes *attributes; // Specifies an attribute and its value(s) that are REQUIRED to match those in a candidate object (according to the matching rules defined above). +} LocateRequestPayload; + + +typedef struct unique_identifiers +{ + LinkedList *unique_identifier_list; +} UniqueIdentifiers; + +typedef struct locate_response_payload +{ + int32 located_items; // KMIP 1.3+, Optional; Note that this may not equal the number of object identifiers returned in this payload + UniqueIdentifiers* unique_ids; +} LocateResponsePayload; + + +#define MAX_LOCATE_IDS 32 +#define MAX_LOCATE_LEN 128 + +typedef struct locate_response +{ + int located_items; // KMIP 1.3+, optional + size_t ids_size; + char ids[MAX_LOCATE_IDS][MAX_LOCATE_LEN]; +} LocateResponse; + /* Macros */ @@ -1533,6 +1576,9 @@ void kmip_free_query_response_payload(KMIP *, QueryResponsePayload *); void kmip_free_operations(KMIP *ctx, Operations *value); void kmip_free_objects(KMIP *ctx, ObjectTypes* value); void kmip_free_server_information(KMIP* ctx, ServerInformation* value); +void kmip_free_locate_request_payload(KMIP *, LocateRequestPayload *); +void kmip_free_locate_response_payload(KMIP *, LocateResponsePayload *); +void kmip_free_unique_identifiers(KMIP *ctx, UniqueIdentifiers* value); /* Copying Functions @@ -1550,6 +1596,7 @@ char* kmip_copy_textstring(char* dest, TextString* src, size_t size); void kmip_copy_objects(int objs[], size_t* objs_size, ObjectTypes *value, unsigned max_objs); void kmip_copy_operations(int ops[], size_t* ops_size, Operations *value, unsigned max_ops); void kmip_copy_query_result(QueryResponse* query_result, QueryResponsePayload *pld); +void kmip_copy_locate_result(LocateResponse* locate_result, LocateResponsePayload *pld); /* Comparison Functions @@ -1602,6 +1649,9 @@ int kmip_compare_server_information(const ServerInformation *a, const ServerInfo int kmip_compare_alternative_endpoints(const AltEndpoints* a, const AltEndpoints* b); int kmip_compare_query_request_payload(const QueryRequestPayload *, const QueryRequestPayload *); int kmip_compare_query_response_payload(const QueryResponsePayload *, const QueryResponsePayload *); +int kmip_compare_unique_identifiers(const UniqueIdentifiers*, const UniqueIdentifiers*); +int kmip_compare_locate_request_payload(const LocateRequestPayload *, const LocateRequestPayload *); +int kmip_compare_locate_response_payload(const LocateResponsePayload *, const LocateResponsePayload *); /* Encoding Functions @@ -1625,6 +1675,7 @@ int kmip_encode_attribute_v1(KMIP *, const Attribute *); int kmip_encode_attribute_v2(KMIP *, const Attribute *); int kmip_encode_attribute(KMIP *, const Attribute *); int kmip_encode_attributes(KMIP *, const Attributes *); +int kmip_encode_attribute_list(KMIP *, const LinkedList*); int kmip_encode_template_attribute(KMIP *, const TemplateAttribute *); int kmip_encode_protocol_version(KMIP *, const ProtocolVersion *); int kmip_encode_protection_storage_masks(KMIP *, const ProtectionStorageMasks *); @@ -1663,6 +1714,9 @@ int kmip_encode_response_message(KMIP *, const ResponseMessage *); int kmip_encode_query_functions(KMIP *ctx, const Functions*); int kmip_encode_query_request_payload(KMIP *, const QueryRequestPayload *); int kmip_encode_query_response_payload(KMIP *, const QueryResponsePayload *); +int kmip_encode_locate_request_payload(KMIP *, const LocateRequestPayload *); +int kmip_encode_locate_response_payload(KMIP *, const LocateResponsePayload *); +int kmip_encode_unique_identifiers(KMIP *, const UniqueIdentifiers*); /* Decoding Functions @@ -1726,6 +1780,9 @@ int kmip_decode_object_types(KMIP *, ObjectTypes *); int kmip_decode_query_request_payload(KMIP *, QueryRequestPayload *); int kmip_decode_query_response_payload(KMIP *, QueryResponsePayload *); int kmip_decode_server_information(KMIP *ctx, ServerInformation *); +int kmip_decode_locate_request_payload(KMIP *, LocateRequestPayload *); +int kmip_decode_locate_response_payload(KMIP *, LocateResponsePayload *); +int kmip_decode_unique_identifiers(KMIP* ctx, UniqueIdentifiers* value); #endif /* KMIP_H */ diff --git a/include/kmip_bio.h b/include/kmip_bio.h index 9ae0f6a..56caf27 100644 --- a/include/kmip_bio.h +++ b/include/kmip_bio.h @@ -45,4 +45,6 @@ int kmip_bio_destroy_symmetric_key_with_context(KMIP *, BIO *, char *, int); int kmip_bio_query_with_context(KMIP *ctx, BIO *bio, enum query_function queries[], size_t query_count, QueryResponse* query_result); int kmip_bio_send_request_encoding(KMIP *, BIO *, char *, int, char **, int *); +int kmip_bio_locate_with_context(KMIP *ctx, BIO *bio, Attribute* attribs, size_t attrib_count, LocateResponse* locate_result); + #endif /* KMIP_BIO_H */ diff --git a/include/kmip_io.h b/include/kmip_io.h index e65d232..1d8d26a 100644 --- a/include/kmip_io.h +++ b/include/kmip_io.h @@ -94,5 +94,8 @@ void kmip_print_object_types(FILE*, int, ObjectTypes*); void kmip_print_query_request_payload(FILE*, int, QueryRequestPayload *); void kmip_print_query_response_payload(FILE*, int, QueryResponsePayload *); void kmip_print_server_information(FILE*, int, ServerInformation*); +void kmip_print_locate_request_payload(FILE*, int, LocateRequestPayload *); +void kmip_print_locate_response_payload(FILE*, int, LocateResponsePayload *); +void kmip_print_unique_identifiers(FILE*, int indent, UniqueIdentifiers* value); #endif /* KMIP_IO_H */ diff --git a/src/kmip.c b/src/kmip.c index 7974346..aabe5fc 100644 --- a/src/kmip.c +++ b/src/kmip.c @@ -870,6 +870,7 @@ kmip_check_enum_value(enum kmip_version version, enum tag t, int value) case KMIP_OP_GET: case KMIP_OP_DESTROY: case KMIP_OP_QUERY: + case KMIP_OP_LOCATE: return(KMIP_OK); break; @@ -2587,6 +2588,10 @@ kmip_free_request_batch_item(KMIP *ctx, RequestBatchItem *value) kmip_free_query_request_payload(ctx, (QueryRequestPayload *)value->request_payload); break; + case KMIP_OP_LOCATE: + kmip_free_locate_request_payload(ctx, (LocateRequestPayload *)value->request_payload); + break; + default: /* NOTE (ph) Hitting this case means that we don't know */ /* what the actual type, size, or value of */ @@ -2656,6 +2661,10 @@ kmip_free_response_batch_item(KMIP *ctx, ResponseBatchItem *value) kmip_free_query_response_payload(ctx, (QueryResponsePayload *)value->response_payload); break; + case KMIP_OP_LOCATE: + kmip_free_locate_response_payload(ctx, (LocateResponsePayload *)value->response_payload); + break; + default: /* NOTE (ph) Hitting this case means that we don't know */ /* what the actual type, size, or value of */ @@ -3183,6 +3192,61 @@ kmip_free_server_information(KMIP* ctx, ServerInformation* value) kmip_free_text_string(ctx, value->cluster_info); } + +void +kmip_free_locate_response_payload(KMIP* ctx, LocateResponsePayload *value) +{ + if(value != NULL) + { + if(value->unique_ids) + { + kmip_free_unique_identifiers(ctx, value->unique_ids); + ctx->free_func(ctx->state, value->unique_ids); + value->unique_ids = NULL; + } + } +} + +void +kmip_free_locate_request_payload(KMIP* ctx, LocateRequestPayload *value) +{ + if(value != NULL) + { + if (value->attributes) + { + kmip_free_attributes(ctx, value->attributes); + ctx->free_func(ctx->state, value->attributes); + value->attributes = NULL; + } + } +} + +void +kmip_free_unique_identifiers(KMIP *ctx, UniqueIdentifiers* value) +{ + if(value != NULL) + { + if(value->unique_identifier_list != NULL) + { + LinkedListItem *curr = kmip_linked_list_pop(value->unique_identifier_list); + while(curr != NULL) + { + kmip_free_text_string(ctx, curr->data); + ctx->free_func(ctx->state, curr->data); + curr->data = NULL; + ctx->free_func(ctx->state, curr); + curr = kmip_linked_list_pop(value->unique_identifier_list); + } + ctx->free_func(ctx->state, value->unique_identifier_list); + value->unique_identifier_list= NULL; + } + } + return; +} + + + + /* Copying Functions */ @@ -3574,6 +3638,39 @@ kmip_copy_query_result(QueryResponse* query_result, QueryResponsePayload *pld) } } +void +kmip_copy_unique_identifiers(char ids[][MAX_LOCATE_LEN], size_t* id_size, UniqueIdentifiers* value, unsigned max_ids) +{ + size_t idx = 0; + if(value != NULL) + { + LinkedListItem *curr = value->unique_identifier_list->head; + while(curr != NULL && idx < max_ids) + { + kmip_copy_textstring(ids[idx], curr->data, MAX_LOCATE_LEN-1); + curr = curr->next; + idx++; + } + } + if (id_size != NULL) + { + *id_size = idx; + } +} + +void +kmip_copy_locate_result(LocateResponse* locate_result, LocateResponsePayload *pld) +{ + if(locate_result != NULL && + pld != NULL) + { + locate_result->located_items = pld->located_items; + + kmip_copy_unique_identifiers(locate_result->ids, &locate_result->ids_size, pld->unique_ids, MAX_LOCATE_IDS); + } +} + + /* Comparison Functions @@ -4993,6 +5090,13 @@ kmip_compare_request_batch_item(const RequestBatchItem *a, const RequestBatchIte } break; + case KMIP_OP_LOCATE: + if(kmip_compare_locate_request_payload((LocateRequestPayload *)a->request_payload, (LocateRequestPayload *)b->request_payload) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + break; + default: /* NOTE (ph) Unsupported payloads cannot be compared. */ return(KMIP_FALSE); @@ -5105,6 +5209,13 @@ kmip_compare_response_batch_item(const ResponseBatchItem *a, const ResponseBatch } break; + case KMIP_OP_LOCATE: + if(kmip_compare_locate_response_payload((LocateResponsePayload *)a->response_payload, (LocateResponsePayload *)b->response_payload) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + break; + default: /* NOTE (ph) Unsupported payloads cannot be compared. */ return(KMIP_FALSE); @@ -6134,6 +6245,115 @@ kmip_compare_query_response_payload(const QueryResponsePayload *a, const QueryRe return(KMIP_TRUE); } +int +kmip_compare_unique_identifiers(const UniqueIdentifiers* a, const UniqueIdentifiers* b) +{ + if(a != b) + { + if((a == NULL) || (b == NULL)) + { + return(KMIP_FALSE); + } + + if((a->unique_identifier_list != b->unique_identifier_list)) + { + if((a->unique_identifier_list == NULL) || (b->unique_identifier_list == NULL)) + { + return(KMIP_FALSE); + } + + if((a->unique_identifier_list->size != b->unique_identifier_list->size)) + { + return(KMIP_FALSE); + } + + LinkedListItem *a_item = a->unique_identifier_list->head; + LinkedListItem *b_item = b->unique_identifier_list->head; + if (kmip_compare_linklist_items_textstring(a_item, b_item) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + } + + return(KMIP_TRUE); +} + +int +kmip_compare_locate_request_payload(const LocateRequestPayload *a, const LocateRequestPayload *b) +{ + if(a != b) + { + if((a == NULL) || (b == NULL)) + { + return(KMIP_FALSE); + } + + if(a->maximum_items != b->maximum_items) + { + return(KMIP_FALSE); + } + if(a->offset_items != b->offset_items) + { + return(KMIP_FALSE); + } + if(a->storage_status_mask != b->storage_status_mask) + { + return(KMIP_FALSE); + } + if(a->group_member_option != b->group_member_option) + { + return(KMIP_FALSE); + } + + if(a->attributes != b->attributes) + { + if((a->attributes == NULL) || (b->attributes == NULL)) + { + return(KMIP_FALSE); + } + + if(kmip_compare_attributes(a->attributes, b->attributes) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + } + + return(KMIP_TRUE); +} +int +kmip_compare_locate_response_payload(const LocateResponsePayload *a, const LocateResponsePayload *b) +{ + if(a != b) + { + if((a == NULL) || (b == NULL)) + { + return(KMIP_FALSE); + } + + if(a->located_items != b->located_items) + { + return(KMIP_FALSE); + } + + if(a->unique_ids != b->unique_ids) + { + if((a->unique_ids == NULL) || (b->unique_ids == NULL)) + { + return(KMIP_FALSE); + } + + if(kmip_compare_unique_identifiers(a->unique_ids, b->unique_ids) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + } + + return(KMIP_TRUE); +} + /* Encoding Functions @@ -6822,18 +7042,8 @@ kmip_encode_attributes(KMIP *ctx, const Attributes *value) uint8 *length_index = ctx->index; uint8 *value_index = ctx->index += 4; - if(value->attribute_list != NULL) - { - LinkedListItem *curr = value->attribute_list->head; - while(curr != NULL) - { - Attribute *attribute = (Attribute *)curr->data; - result = kmip_encode_attribute(ctx, attribute); - CHECK_RESULT(ctx, result); - - curr = curr->next; - } - } + result = kmip_encode_attribute_list(ctx, value->attribute_list); + CHECK_RESULT(ctx, result); uint8 *curr_index = ctx->index; ctx->index = length_index; @@ -6846,6 +7056,26 @@ kmip_encode_attributes(KMIP *ctx, const Attributes *value) return(KMIP_OK); } +int +kmip_encode_attribute_list(KMIP *ctx, const LinkedList* value) +{ + CHECK_ENCODE_ARGS(ctx, value); + + int result = 0; + + LinkedListItem *curr = value->head; + while(curr != NULL) + { + Attribute *attribute = (Attribute *)curr->data; + result = kmip_encode_attribute(ctx, attribute); + CHECK_RESULT(ctx, result); + + curr = curr->next; + } + + return(KMIP_OK); +} + int kmip_encode_template_attribute(KMIP *ctx, const TemplateAttribute *value) { @@ -8235,6 +8465,10 @@ kmip_encode_request_batch_item(KMIP *ctx, const RequestBatchItem *value) result = kmip_encode_query_request_payload(ctx, (QueryRequestPayload*)value->request_payload); break; + case KMIP_OP_LOCATE: + result = kmip_encode_locate_request_payload(ctx, (LocateRequestPayload*)value->request_payload); + break; + default: kmip_push_error_frame(ctx, __func__, __LINE__); return(KMIP_NOT_IMPLEMENTED); @@ -8311,6 +8545,10 @@ kmip_encode_response_batch_item(KMIP *ctx, const ResponseBatchItem *value) result = kmip_encode_query_response_payload(ctx, (QueryResponsePayload*)value->response_payload); break; + case KMIP_OP_LOCATE: + result = kmip_encode_locate_response_payload(ctx, (LocateResponsePayload*)value->response_payload); + break; + default: kmip_push_error_frame(ctx, __func__, __LINE__); return(KMIP_NOT_IMPLEMENTED); @@ -8446,6 +8684,114 @@ kmip_encode_query_response_payload(KMIP *ctx, const QueryResponsePayload *value) return(KMIP_NOT_IMPLEMENTED); } +int +kmip_encode_unique_identifiers(KMIP *ctx, const UniqueIdentifiers* value) +{ + CHECK_ENCODE_ARGS(ctx, value); + + int result = 0; + if (value->unique_identifier_list) + { + LinkedListItem *curr = value->unique_identifier_list->head; + while(curr != NULL) + { + result = kmip_encode_text_string(ctx, KMIP_TAG_UNIQUE_IDENTIFIER, (TextString*)curr->data); + CHECK_RESULT(ctx, result); + + curr = curr->next; + } + } + + return(KMIP_OK); +} + +int +kmip_encode_locate_request_payload(KMIP* ctx, const LocateRequestPayload* value) +{ + int result = 0; + result = kmip_encode_int32_be(ctx, TAG_TYPE(KMIP_TAG_REQUEST_PAYLOAD, KMIP_TYPE_STRUCTURE)); + CHECK_RESULT(ctx, result); + + uint8 *length_index = ctx->index; + uint8 *value_index = ctx->index += 4; + + if(value->maximum_items) + { + result = kmip_encode_integer(ctx, KMIP_TAG_MAXIMUM_ITEMS, value->maximum_items); + CHECK_RESULT(ctx, result); + } + + if (value->offset_items) + { + result = kmip_encode_integer(ctx, KMIP_TAG_OFFSET_ITEMS, value->offset_items); + CHECK_RESULT(ctx, result); + } + + if (value->storage_status_mask) + { + result = kmip_encode_integer(ctx, KMIP_TAG_STORAGE_STATUS_MASK, value->storage_status_mask); + CHECK_RESULT(ctx, result); + } + + if (value->group_member_option) + { + result = kmip_encode_enum(ctx, KMIP_TAG_OBJECT_GROUP_MEMBER, value->group_member_option); + CHECK_RESULT(ctx, result); + } + + if (value->attributes) + { + result = kmip_encode_attribute_list(ctx, value->attributes->attribute_list); + CHECK_RESULT(ctx, result); + } + uint8 *curr_index = ctx->index; + ctx->index = length_index; + + kmip_encode_int32_be(ctx, curr_index - value_index); + + ctx->index = curr_index; + + return(KMIP_OK); +} + +int +kmip_encode_locate_response_payload(KMIP* ctx, const LocateResponsePayload *value) +{ + CHECK_ENCODE_ARGS(ctx, value); + int result = 0; + + result = kmip_encode_int32_be(ctx, TAG_TYPE(KMIP_TAG_RESPONSE_PAYLOAD, KMIP_TYPE_STRUCTURE)); + CHECK_RESULT(ctx, result); + + uint8 *length_index = ctx->index; + uint8 *value_index = ctx->index += 4; + + if(ctx->version >= KMIP_1_3) + { + if (value->located_items) + { + result = kmip_encode_integer(ctx, KMIP_TAG_LOCATED_ITEMS, value->located_items); + CHECK_RESULT(ctx, result); + } + } + + if (value->unique_ids) + { + result = kmip_encode_unique_identifiers(ctx, value->unique_ids); + CHECK_RESULT(ctx, result); + } + + uint8 *curr_index = ctx->index; + ctx->index = length_index; + + result = kmip_encode_length(ctx, curr_index - value_index); + CHECK_RESULT(ctx, result); + + ctx->index = curr_index; + + return (KMIP_OK); +} + /* Decoding Functions */ @@ -9339,6 +9685,33 @@ kmip_decode_attributes(KMIP *ctx, Attributes *value) return(KMIP_OK); } +int +kmip_decode_attribute_list(KMIP *ctx, LinkedList *value) +{ + CHECK_DECODE_ARGS(ctx, value); + CHECK_BUFFER_FULL(ctx, 8); + + int result = 0; + + uint32 tag = kmip_peek_tag(ctx); + while(tag == KMIP_TAG_ATTRIBUTE) + { + LinkedListItem *item = ctx->calloc_func(ctx->state, 1, sizeof(LinkedListItem)); + CHECK_NEW_MEMORY(ctx, item, sizeof(LinkedListItem), "LinkedListItem"); + kmip_linked_list_enqueue(value, item); + + item->data = ctx->calloc_func(ctx->state, 1, sizeof(Attribute)); + CHECK_NEW_MEMORY(ctx, item->data, sizeof(Attribute), "Attribute"); + + result = kmip_decode_attribute(ctx, (Attribute *)item->data); + CHECK_RESULT(ctx, result); + + tag = kmip_peek_tag(ctx); + } + + return(KMIP_OK); +} + int kmip_decode_template_attribute(KMIP *ctx, TemplateAttribute *value) { @@ -10404,6 +10777,12 @@ kmip_decode_request_batch_item(KMIP *ctx, RequestBatchItem *value) result = kmip_decode_query_request_payload(ctx, (QueryRequestPayload*)value->request_payload); break; + case KMIP_OP_LOCATE: + value->request_payload = ctx->calloc_func(ctx->state, 1, sizeof(LocateRequestPayload)); + CHECK_NEW_MEMORY(ctx, value->request_payload, sizeof(LocateRequestPayload), "LocateRequestPayload structure"); + result = kmip_decode_locate_request_payload(ctx, (LocateRequestPayload*)value->request_payload); + break; + default: kmip_push_error_frame(ctx, __func__, __LINE__); return(KMIP_NOT_IMPLEMENTED); @@ -10503,6 +10882,12 @@ kmip_decode_response_batch_item(KMIP *ctx, ResponseBatchItem *value) result = kmip_decode_query_response_payload(ctx, value->response_payload); break; + case KMIP_OP_LOCATE: + value->response_payload = ctx->calloc_func(ctx->state, 1, sizeof(LocateResponsePayload)); + CHECK_NEW_MEMORY(ctx, value->response_payload, sizeof(LocateResponsePayload), "LocateResponsePayload structure"); + result = kmip_decode_locate_response_payload(ctx, value->response_payload); + break; + default: kmip_push_error_frame(ctx, __func__, __LINE__); return(KMIP_NOT_IMPLEMENTED); @@ -11342,3 +11727,121 @@ kmip_decode_query_response_payload(KMIP *ctx, QueryResponsePayload *value) return(KMIP_OK); } +int +kmip_decode_locate_request_payload(KMIP* ctx, LocateRequestPayload *value) +{ + CHECK_BUFFER_FULL(ctx, 8); + + int result = 0; + int32 tag_type = 0; + uint32 length = 0; + + kmip_decode_int32_be(ctx, &tag_type); + CHECK_TAG_TYPE(ctx, tag_type, KMIP_TAG_REQUEST_PAYLOAD, KMIP_TYPE_STRUCTURE); + + kmip_decode_length(ctx, &length); + CHECK_BUFFER_FULL(ctx, length); + + if(kmip_is_tag_next(ctx, KMIP_TAG_MAXIMUM_ITEMS)) + { + result = kmip_decode_integer(ctx, KMIP_TAG_MAXIMUM_ITEMS, &value->maximum_items); + CHECK_RESULT(ctx, result); + } + if(kmip_is_tag_next(ctx, KMIP_TAG_OFFSET_ITEMS)) + { + result = kmip_decode_integer(ctx, KMIP_TAG_OFFSET_ITEMS, &value->offset_items); + CHECK_RESULT(ctx, result); + } + if(kmip_is_tag_next(ctx, KMIP_TAG_STORAGE_STATUS_MASK)) + { + result = kmip_decode_integer(ctx, KMIP_TAG_STORAGE_STATUS_MASK, &value->storage_status_mask); + CHECK_RESULT(ctx, result); + } + if(kmip_is_tag_next(ctx, KMIP_TAG_OBJECT_GROUP_MEMBER)) + { + result = kmip_decode_enum(ctx, KMIP_TAG_OBJECT_GROUP_MEMBER, &value->group_member_option); + CHECK_RESULT(ctx, result); + } + uint32 tag = kmip_peek_tag(ctx); + if (tag == KMIP_TAG_ATTRIBUTE) + { + value->attributes = ctx->calloc_func(ctx->state, 1, sizeof(Attributes)); + CHECK_NEW_MEMORY(ctx, value->attributes, sizeof(Attributes), "Attributes"); + + value->attributes->attribute_list = ctx->calloc_func(ctx->state, 1, sizeof(LinkedList)); + CHECK_NEW_MEMORY(ctx, value->attributes->attribute_list, sizeof(LinkedList), "LinkedList"); + + result = kmip_decode_attribute_list(ctx, value->attributes->attribute_list); + if(result != KMIP_OK) + { + kmip_free_attributes(ctx, value->attributes); + ctx->free_func(ctx, value->attributes); + value->attributes = NULL; + + HANDLE_FAILURE(ctx, result); + } + } + + return(KMIP_OK); +} + +int +kmip_decode_locate_response_payload(KMIP* ctx, LocateResponsePayload *value) +{ + CHECK_BUFFER_FULL(ctx, 8); + + int result = 0; + int32 tag_type = 0; + uint32 length = 0; + + kmip_decode_int32_be(ctx, &tag_type); + CHECK_TAG_TYPE(ctx, tag_type, KMIP_TAG_RESPONSE_PAYLOAD, KMIP_TYPE_STRUCTURE); + + kmip_decode_int32_be(ctx, &length); + CHECK_BUFFER_FULL(ctx, length); + + if(kmip_is_tag_next(ctx, KMIP_TAG_LOCATED_ITEMS)) + { + result = kmip_decode_integer(ctx, KMIP_TAG_LOCATED_ITEMS, &value->located_items); + CHECK_RESULT(ctx, result); + } + + if(kmip_is_tag_next(ctx, KMIP_TAG_UNIQUE_IDENTIFIER)) + { + value->unique_ids = ctx->calloc_func(ctx->state, 1, sizeof(UniqueIdentifiers)); + CHECK_NEW_MEMORY(ctx, value->unique_ids, sizeof(UniqueIdentifiers), "Unique_Identifiers"); + result = kmip_decode_unique_identifiers(ctx, value->unique_ids); + CHECK_RESULT(ctx, result); + } + + return(KMIP_OK); +} + +int +kmip_decode_unique_identifiers(KMIP* ctx, UniqueIdentifiers* value) +{ + int result = 0; + + //printf("** decode uniq ids \n"); + + value->unique_identifier_list = ctx->calloc_func(ctx->state, 1, sizeof(LinkedList)); + CHECK_NEW_MEMORY(ctx, value->unique_identifier_list, sizeof(LinkedList), "LinkedList"); + + uint32 tag = kmip_peek_tag(ctx); + while(tag == KMIP_TAG_UNIQUE_IDENTIFIER) + { + LinkedListItem *item = ctx->calloc_func(ctx->state, 1, sizeof(LinkedListItem)); + CHECK_NEW_MEMORY(ctx, item, sizeof(LinkedListItem), "LinkedListItem"); + kmip_linked_list_enqueue(value->unique_identifier_list, item); + + item->data = ctx->calloc_func(ctx->state, 1, sizeof(TextString)); + CHECK_NEW_MEMORY(ctx, item->data, sizeof(TextString), "Unique ID text string"); + + result = kmip_decode_text_string(ctx, KMIP_TAG_UNIQUE_IDENTIFIER, item->data); + CHECK_RESULT(ctx, result); + + tag = kmip_peek_tag(ctx); + } + + return(KMIP_OK); +} diff --git a/src/kmip_bio.c b/src/kmip_bio.c index c85b732..91b009f 100644 --- a/src/kmip_bio.c +++ b/src/kmip_bio.c @@ -1622,3 +1622,162 @@ int kmip_bio_query_with_context(KMIP *ctx, BIO *bio, enum query_function queries return(result_status); } +int kmip_bio_locate_with_context(KMIP *ctx, BIO *bio, Attribute* attribs, size_t attrib_count, LocateResponse* locate_result) +{ + if (ctx == NULL || bio == NULL || attribs == NULL || attrib_count == 0 || locate_result == NULL) + { + return(KMIP_ARG_INVALID); + } + + size_t buffer_blocks = 1; + size_t buffer_block_size = 1024; + size_t buffer_total_size = buffer_blocks * buffer_block_size; + + uint8 *encoding = ctx->calloc_func(ctx->state, buffer_blocks, buffer_block_size); + if(encoding == NULL) + { + return(KMIP_MEMORY_ALLOC_FAILED); + } + kmip_set_buffer(ctx, encoding, buffer_total_size); + + /* Build the request message. */ + + + ProtocolVersion pv = {0}; + kmip_init_protocol_version(&pv, ctx->version); + + RequestHeader rh = {0}; + kmip_init_request_header(&rh); + + rh.protocol_version = &pv; + rh.maximum_response_size = ctx->max_message_size; + rh.time_stamp = time(NULL); + rh.batch_count = 1; + + + // copy input array to list + LinkedList *attribute_list = ctx->calloc_func(ctx->state, 1, sizeof(LinkedList)); + for(size_t i = 0; i < attrib_count; i++) + { + LinkedListItem *item = ctx->calloc_func(ctx->state, 1, sizeof(LinkedListItem)); + item->data = kmip_deep_copy_attribute(ctx, &attribs[i]); + kmip_linked_list_enqueue(attribute_list, item); + } + + LocateRequestPayload lrp = {0}; + lrp.maximum_items = 12; + lrp.offset_items = 0; + lrp.storage_status_mask = 0; + lrp.group_member_option = 0; + lrp.attributes = attribute_list; + + RequestBatchItem rbi = {0}; + kmip_init_request_batch_item(&rbi); + rbi.operation = KMIP_OP_LOCATE; + rbi.request_payload = &lrp; + + RequestMessage rm = {0}; + rm.request_header = &rh; + rm.batch_items = &rbi; + rm.batch_count = 1; + + /* Encode the request message. Dynamically resize the encoding buffer */ + /* if it's not big enough. Once encoding succeeds, send the request */ + /* message. */ + int encode_result = kmip_encode_request_message(ctx, &rm); + while(encode_result == KMIP_ERROR_BUFFER_FULL) + { + kmip_reset(ctx); + ctx->free_func(ctx->state, encoding); + + buffer_blocks += 1; + buffer_total_size = buffer_blocks * buffer_block_size; + + encoding = ctx->calloc_func(ctx->state, buffer_blocks, buffer_block_size); + if(encoding == NULL) + { + return(KMIP_MEMORY_ALLOC_FAILED); + } + + kmip_set_buffer(ctx, encoding, buffer_total_size); + encode_result = kmip_encode_request_message(ctx, &rm); + } + + if(encode_result != KMIP_OK) + { + kmip_free_buffer(ctx, encoding, buffer_total_size); + encoding = NULL; + kmip_set_buffer(ctx, NULL, 0); + return(encode_result); + } + + char *response = NULL; + int response_size = 0; + + int result = kmip_bio_send_request_encoding(ctx, bio, (char *)encoding, ctx->index - ctx->buffer, &response, &response_size); + if(result < 0) + { + kmip_free_buffer(ctx, encoding, buffer_total_size); + kmip_free_buffer(ctx, response, response_size); + encoding = NULL; + response = NULL; + kmip_set_buffer(ctx, NULL, 0); + return(result); + } + + kmip_free_locate_request_payload(ctx, &lrp); + + + if (response) + { + FILE* out = fopen( "/tmp/kmip_locate.dat", "w" ); + if (out) + { + fwrite( response, response_size, 1, out ); + fclose(out); + } + } + + kmip_free_buffer(ctx, encoding, buffer_total_size); + encoding = NULL; + kmip_set_buffer(ctx, response, response_size); + + /* Decode the response message and retrieve the operation results. */ + ResponseMessage resp_m = {0}; + int decode_result = kmip_decode_response_message(ctx, &resp_m); + if(decode_result != KMIP_OK) + { + kmip_free_response_message(ctx, &resp_m); + kmip_free_buffer(ctx, response, response_size); + response = NULL; + kmip_set_buffer(ctx, NULL, 0); + return(decode_result); + } + + if(resp_m.batch_count != 1 || resp_m.batch_items == NULL) + { + kmip_free_response_message(ctx, &resp_m); + kmip_free_buffer(ctx, response, response_size); + response = NULL; + kmip_set_buffer(ctx, NULL, 0); + return(KMIP_MALFORMED_RESPONSE); + } + + ResponseBatchItem resp_item = resp_m.batch_items[0]; + enum result_status result_status = resp_item.result_status; + + kmip_set_last_result(&resp_item); + + if(result == KMIP_STATUS_SUCCESS) + { + kmip_copy_locate_result(locate_result, (LocateResponsePayload*) resp_item.response_payload); + } + + /* Clean up the response message, the response buffer, and the KMIP */ + /* context. */ + kmip_free_response_message(ctx, &resp_m); + kmip_free_buffer(ctx, response, response_size); + response = NULL; + + return(result_status); +} diff --git a/src/kmip_io.c b/src/kmip_io.c index 528c7d5..708784b 100644 --- a/src/kmip_io.c +++ b/src/kmip_io.c @@ -2838,6 +2838,10 @@ kmip_print_request_payload(FILE *f, int indent, enum operation type, void *value kmip_print_query_request_payload(f, indent, value); break; + case KMIP_OP_LOCATE: + kmip_print_locate_request_payload(f, indent, value); + break; + default: fprintf(f, "%*sUnknown Payload @ %p\n", indent, "", value); break; @@ -2865,6 +2869,10 @@ kmip_print_response_payload(FILE *f, int indent, enum operation type, void *valu kmip_print_query_response_payload(f, indent, value); break; + case KMIP_OP_LOCATE: + kmip_print_locate_response_payload(f, indent, value); + break; + default: fprintf(f, "%*sUnknown Payload @ %p\n", indent, "", value); break; @@ -3330,3 +3338,59 @@ kmip_print_query_request_payload(FILE* f, int indent, QueryRequestPayload *value if(value != NULL) kmip_print_query_functions(f, indent, value->functions); } + +void +kmip_print_locate_request_payload(FILE* f, int indent, LocateRequestPayload * value) +{ + fprintf(f, "%*sLocate Request Payload @ %p\n", indent, "", (void *)value); + if (value) + { + fprintf(f, "%*sMaximum items: ", indent + 2, ""); + kmip_print_integer(f, value->maximum_items); + fprintf(f, "\n"); + + fprintf(f, "%*sOffset items: ", indent + 2, ""); + kmip_print_integer(f, value->offset_items); + fprintf(f, "\n"); + + fprintf(f, "%*sStorage status: ", indent + 2, ""); + kmip_print_integer(f, value->storage_status_mask); + fprintf(f, "\n"); + + if(value->attributes) + kmip_print_attributes(f, indent + 2, value->attributes); + } +} + +void +kmip_print_locate_response_payload(FILE* f, int indent, LocateResponsePayload *value) +{ + fprintf(f, "%*sLocated Items: ", indent + 2, ""); + kmip_print_integer(f, value->located_items); + fprintf(f, "\n"); + + kmip_print_unique_identifiers(f, indent, value->unique_ids); +} + +void +kmip_print_unique_identifiers(FILE* f, int indent, UniqueIdentifiers* value) +{ + fprintf(f, "%*sUnique IDs @ %p\n", indent, "", (void *)value); + + if(value != NULL) + { + fprintf(f, "%*sUnique IDs: %zu\n", indent + 2, "", value->unique_identifier_list->size); + LinkedListItem *curr = value->unique_identifier_list->head; + size_t count = 1; + while(curr != NULL) + { + fprintf(f, "%*sUnique ID: %zu: ", indent + 4, "", count); + kmip_print_text_string(f, indent + 2, "", curr->data); + fprintf(f, "\n"); + + curr = curr->next; + count++; + } + } +} + diff --git a/tests/tests.c b/tests/tests.c index 48f6d9b..6f7f388 100644 --- a/tests/tests.c +++ b/tests/tests.c @@ -12308,6 +12308,418 @@ test_encode_query_request_payload(TestTracker *tracker) return(result); } +int +test_encode_locate_request_payload_2(TestTracker *tracker) +{ + TRACK_TEST(tracker); +/* From V1.1 3.13 + This encoding matches the following set of values: + Tag: Request Payload (0x420079), Type: Structure (0x01), Data: + Tag: Attribute (0x420008), Type: Structure (0x01), Data: + Tag: Attribute Name (0x42000A), Type: Text String (0x07), Data: Object Type + Tag: Attribute Value (0x42000B), Type: Enumeration (0x05), Data: 0x00000002 (Symmetric Key) + Tag: Attribute (0x420008), Type: Structure (0x01), Data: + Tag: Attribute Name (0x42000A), Type: Text String (0x07), Data: Name + Tag: Attribute Value (0x42000B), Type: Structure (0x01), Data: + Tag: Name Value (0x420055), Type: Text String (0x07), Data: Key1 + Tag: Name Type (0x420054), Type: Enumeration (0x05), Data: 0x00000001 (Uninterpreted Text String) +*/ + + uint8 expected[] = { + 0x42, 0x00, 0x79, 0x01, 0x00, 0x00, 0x00, 0x70, + 0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x28, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x0B, + 0x4F, 0x62, 0x6A, 0x65, 0x63, 0x74, 0x20, 0x54, + 0x79, 0x70, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x0B, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x38, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x04, + 0x4E, 0x61, 0x6D, 0x65, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x0B, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x42, 0x00, 0x55, 0x07, 0x00, 0x00, 0x00, 0x04, + 0x4B, 0x65, 0x79, 0x31, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x54, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + }; + + uint8 observed[8*15] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_1); + + Attribute a[4] = {0}; + for(int i = 0; i < 3; i++) + { + kmip_init_attribute(&a[i]); + } + + enum object_type t = KMIP_OBJTYPE_SYMMETRIC_KEY; + a[0].type = KMIP_ATTR_OBJECT_TYPE; + a[0].value = &t; + + struct text_string value = {0}; + value.value = "Key1"; + value.size = 4; + + struct name name = {0}; + name.value = &value; + name.type = KMIP_NAME_UNINTERPRETED_TEXT_STRING; + a[1].type = KMIP_ATTR_NAME; + a[1].value = &name; + + + Attributes attributes = {0}; + LinkedList list = {0}; + LinkedListItem item_1, item_2 = {0}; + item_1.data = &a[0]; + item_2.data = &a[1]; + kmip_linked_list_enqueue(&list, &item_1); + kmip_linked_list_enqueue(&list, &item_2); + attributes.attribute_list = &list; + + LocateRequestPayload lrp = {0}; + lrp.attributes = &attributes; + + int result = kmip_encode_locate_request_payload(&ctx, &lrp); + + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + + return(result); +} + +int +test_encode_locate_request_payload_1(TestTracker *tracker) +{ + TRACK_TEST(tracker); + +/* From V1.1 3.1.3 + Tag: Request Payload (0x420079), Type: Structure (0x01), Data: + Tag: Attribute (0x420008), Type: Structure (0x01), Data: + Tag: Attribute Name (0x42000A), Type: Text String (0x07), Data: Unique Identifier + Tag: Attribute Value (0x42000B), Type: Text String (0x07), Data: 49a1ca88-6bea-4fb2-b450-7e58802c3038 +*/ + + uint8 expected[] = { + + 0x42, 0x00, 0x79, 0x01, 0x00, 0x00, 0x00, 0x58, + 0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x50, + + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x11, + 0x55, 0x6E, 0x69, 0x71, 0x75, 0x65, 0x20, 0x49, + 0x64, 0x65, 0x6E, 0x74, 0x69, 0x66, 0x69, 0x65, + 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + 0x42, 0x00, 0x0B, 0x07, 0x00, 0x00, 0x00, 0x24, + 0x34, 0x39, 0x61, 0x31, 0x63, 0x61, 0x38, 0x38, + 0x2D, 0x36, 0x62, 0x65, 0x61, 0x2D, 0x34, 0x66, + 0x62, 0x32, 0x2D, 0x62, 0x34, 0x35, 0x30, 0x2D, + 0x37, 0x65, 0x35, 0x38, 0x38, 0x30, 0x32, 0x63, + 0x33, 0x30, 0x33, 0x38, 0x00, 0x00, 0x00, 0x00, + }; + + uint8 observed[8*12] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_1); + + Attribute a[1] = {0}; + for(int i = 0; i < 1; i++) + { + kmip_init_attribute(&a[i]); + } + + struct text_string value = {0}; + value.value = "49a1ca88-6bea-4fb2-b450-7e58802c3038"; + value.size = 36; + + a[0].type = KMIP_ATTR_UNIQUE_IDENTIFIER; + a[0].value = &value; + + + Attributes attributes = {0}; + LinkedList list = {0}; + LinkedListItem item_1 = {0}; + item_1.data = &a[0]; + kmip_linked_list_enqueue(&list, &item_1); + attributes.attribute_list = &list; + + LocateRequestPayload lrp = {0}; + lrp.attributes = &attributes; + + int result = kmip_encode_locate_request_payload(&ctx, &lrp); + + //printf("result=%d\n", result); + //printf("observed:\n"); + //kmip_print_locate_request_payload(stderr, 1, &lrp); + //kmip_print_buffer(stdout, ctx.buffer, ctx.size); + + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + + return(result); +} + +int +test_encode_locate_request_payload_group(TestTracker *tracker) +{ + TRACK_TEST(tracker); + +/* From V1.4 15.1 + Tag: Request Payload (0x420079), Type: Structure (0x01), Data: + Tag: Maximum Items (0x42004F), Type: Integer (0x02), Data: 0x00000001 (1) + Tag: Object Group Member (0x4200AC), Type: Enumeration (0x05), Data: 0x00000001 (Group Member Fresh) + Tag: Attribute (0x420008), Type: Structure (0x01), Data: + Tag: Attribute Name (0x42000A), Type: Text String (0x07), Data: Object Group + Tag: Attribute Value (0x42000B), Type: Text String (0x07), Data: default +*/ + + uint8 expected[] = { + 0x42, 0x00, 0x79, 0x01, 0x00, 0x00, 0x00, 0x50, + 0x42, 0x00, 0x4F, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xAC, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x28, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x0C, + 0x4F, 0x62, 0x6A, 0x65, 0x63, 0x74, 0x20, 0x47, + 0x72, 0x6F, 0x75, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x0B, 0x07, 0x00, 0x00, 0x00, 0x07, + 0x64, 0x65, 0x66, 0x61, 0x75, 0x6C, 0x74, 0x00, + }; + + uint8 observed[8*11] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_4); + + Attribute a[1] = {0}; + for(int i = 0; i < 1; i++) + { + kmip_init_attribute(&a[i]); + } + + + struct text_string value = {0}; + value.value = "default"; + value.size = 7; + + a[0].type = KMIP_ATTR_OBJECT_GROUP; + a[0].value = &value; + + Attributes attributes = {0}; + LinkedList list = {0}; + LinkedListItem item_1 = {0}; + item_1.data = &a[0]; + kmip_linked_list_enqueue(&list, &item_1); + attributes.attribute_list = &list; + + LocateRequestPayload lrp = {0}; + lrp.maximum_items = 1; + lrp.group_member_option = 1; + lrp.attributes = &attributes; + + int result = kmip_encode_locate_request_payload(&ctx, &lrp); + + //printf("result=%d\n", result); + //printf("observed:\n"); + //kmip_print_locate_request_payload(stderr, 1, &lrp); + //kmip_print_buffer(stdout, ctx.buffer, ctx.size); + + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + + return(result); +} + +int +test_decode_locate_request_payload_group(TestTracker *tracker) +{ + TRACK_TEST(tracker); + +/* From V1.4 15.1 + Tag: Request Payload (0x420079), Type: Structure (0x01), Data: + Tag: Maximum Items (0x42004F), Type: Integer (0x02), Data: 0x00000001 (1) + Tag: Object Group Member (0x4200AC), Type: Enumeration (0x05), Data: 0x00000001 (Group Member Fresh) + Tag: Attribute (0x420008), Type: Structure (0x01), Data: + Tag: Attribute Name (0x42000A), Type: Text String (0x07), Data: Object Group + Tag: Attribute Value (0x42000B), Type: Text String (0x07), Data: default +*/ + + uint8 encoding[] = { + 0x42, 0x00, 0x79, 0x01, 0x00, 0x00, 0x00, 0x50, + 0x42, 0x00, 0x4F, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xAC, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x28, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x0C, + 0x4F, 0x62, 0x6A, 0x65, 0x63, 0x74, 0x20, 0x47, + 0x72, 0x6F, 0x75, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x0B, 0x07, 0x00, 0x00, 0x00, 0x07, + 0x64, 0x65, 0x66, 0x61, 0x75, 0x6C, 0x74, 0x00, + }; + + struct kmip ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_4); + + Attribute a[1] = {0}; + for(int i = 0; i < 1; i++) + { + kmip_init_attribute(&a[i]); + } + + + struct text_string value = {0}; + value.value = "default"; + value.size = 7; + + a[0].type = KMIP_ATTR_OBJECT_GROUP; + a[0].value = &value; + + Attributes attributes = {0}; + LinkedList list = {0}; + LinkedListItem item_1 = {0}; + item_1.data = &a[0]; + kmip_linked_list_enqueue(&list, &item_1); + attributes.attribute_list = &list; + + LocateRequestPayload expected = {0}; + expected.maximum_items = 1; + expected.group_member_option = 1; + expected.attributes = &attributes; + + LocateRequestPayload observed = {0}; + + int result = kmip_decode_locate_request_payload(&ctx, &observed); + int comparison = kmip_compare_locate_request_payload(&expected, &observed); + result = report_decoding_test_result( + tracker, + &ctx, + comparison, + result, + __func__); + kmip_free_locate_request_payload(&ctx, &observed); + kmip_destroy(&ctx); + + return(result); +} + +int +test_encode_unique_identifiers(TestTracker *tracker) +{ + TRACK_TEST(tracker); + uint8 expected[] = { + 0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x01, // KMIP_TAG_UNIQUE_IDENTIFIER + 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x01, // KMIP_TAG_UNIQUE_IDENTIFIER + 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + + uint8 observed[8*4] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_1); + + TextString uid_1 = {0}; + uid_1.value = "1"; + uid_1.size = 1; + + TextString uid_2 = {0}; + uid_2.value = "4"; + uid_2.size = 1; + + LinkedList list_1 = {0}; + LinkedListItem item_1 = {0}; + LinkedListItem item_2 = {0}; + item_1.data = &uid_1; + item_2.data = &uid_2; + kmip_linked_list_enqueue(&list_1, &item_1); + kmip_linked_list_enqueue(&list_1, &item_2); + + UniqueIdentifiers uids = {0}; + uids.unique_identifier_list = &list_1; + + int result = kmip_encode_unique_identifiers(&ctx, &uids); + + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + + return(result); + +} + +int +test_encode_locate_response_payload(TestTracker *tracker) +{ + TRACK_TEST(tracker); + +/* + Tag: Response Payload (0x42007C), Type: Structure (0x01), Data: + Tag: Unique Identifier (0x420094), Type: Text String (0x07), Data: 49a1ca88-6bea-4fb2-b450-7e58802c3038 +*/ + + uint8 expected[] = { + 0x42, 0x00, 0x7C, 0x01, 0x00, 0x00, 0x00, 0x30, + 0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, + 0x34, 0x39, 0x61, 0x31, 0x63, 0x61, 0x38, 0x38, + 0x2D, 0x36, 0x62, 0x65, 0x61, 0x2D, 0x34, 0x66, + 0x62, 0x32, 0x2D, 0x62, 0x34, 0x35, 0x30, 0x2D, + 0x37, 0x65, 0x35, 0x38, 0x38, 0x30, 0x32, 0x63, + 0x33, 0x30, 0x33, 0x38, 0x00, 0x00, 0x00, 0x00, + }; + + uint8 observed[8*7] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_1); + + struct text_string str1 = {0}; + str1.value = "49a1ca88-6bea-4fb2-b450-7e58802c3038"; + str1.size = 36; + + LinkedList list = {0}; + LinkedListItem item_1 = {0}; + item_1.data = &str1; + kmip_linked_list_enqueue(&list, &item_1); + + UniqueIdentifiers uids; + uids.unique_identifier_list = &list; + + LocateResponsePayload lrp = {0}; + lrp.located_items = 0; + lrp.unique_ids = &uids; + + int result = kmip_encode_locate_response_payload(&ctx, &lrp); + + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + + return(result); + +} + int test_decode_query_response_payload(TestTracker *tracker) { @@ -12398,6 +12810,199 @@ test_decode_query_response_payload(TestTracker *tracker) return (result); } +int +test_decode_unique_identifiers(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[] = { + 0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x01, // KMIP_TAG_UNIQUE_IDENTIFIER + 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x01, // KMIP_TAG_UNIQUE_IDENTIFIER + 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + + struct kmip ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0); + + TextString uid_1 = {0}; + uid_1.value = "1"; + uid_1.size = 1; + + TextString uid_2 = {0}; + uid_2.value = "4"; + uid_2.size = 1; + + LinkedList list_1 = {0}; + LinkedListItem item_1 = {0}; + LinkedListItem item_2 = {0}; + item_1.data = &uid_1; + item_2.data = &uid_2; + kmip_linked_list_enqueue(&list_1, &item_1); + kmip_linked_list_enqueue(&list_1, &item_2); + + UniqueIdentifiers expected = {0}; + expected.unique_identifier_list = &list_1; + + UniqueIdentifiers observed = {0}; + + int result = kmip_decode_unique_identifiers(&ctx, &observed); + int comparison = kmip_compare_unique_identifiers(&expected, &observed); + if (!comparison) + { + printf("observed\n"); + kmip_print_unique_identifiers(stderr, 1, &observed); + printf("expected\n"); + kmip_print_unique_identifiers(stderr, 1, &expected); + } + result = report_decoding_test_result( + tracker, + &ctx, + comparison, + result, + __func__); + kmip_free_unique_identifiers(&ctx, &observed); + kmip_destroy(&ctx); + + return (result); +} + + +int +test_decode_locate_response_payload(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[] = { + 0x42, 0x00, 0x7c, 0x01, 0x00, 0x00, 0x00, 0x20, // KMIP_TAG_RESPONSE_PAYLOAD + 0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x01, // KMIP_TAG_UNIQUE_IDENTIFIER + 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x01, // KMIP_TAG_UNIQUE_IDENTIFIER + 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + + struct kmip ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0); + + TextString uid_1 = {0}; + uid_1.value = "1"; + uid_1.size = 1; + + TextString uid_2 = {0}; + uid_2.value = "4"; + uid_2.size = 1; + + UniqueIdentifiers uids = {0}; + LinkedList list_1 = {0}; + LinkedListItem item_1 = {0}; + LinkedListItem item_2 = {0}; + item_1.data = &uid_1; + item_2.data = &uid_2; + kmip_linked_list_enqueue(&list_1, &item_1); + kmip_linked_list_enqueue(&list_1, &item_2); + uids.unique_identifier_list = &list_1; + + LocateResponsePayload expected = {0}; + expected.located_items = 0; + expected.unique_ids = &uids; + + LocateResponsePayload observed = {0}; + + int result = kmip_decode_locate_response_payload(&ctx, &observed); + int comparison = kmip_compare_locate_response_payload(&expected, &observed); + if (!comparison) + { + kmip_print_locate_response_payload(stderr, 1, &observed); + kmip_print_locate_response_payload(stderr, 1, &expected); + } + result = report_decoding_test_result( + tracker, + &ctx, + comparison, + result, + __func__); + kmip_free_locate_response_payload(&ctx, &observed); + kmip_destroy(&ctx); + + return (result); +} + +int +test_decode_locate_request_payload(TestTracker *tracker) +{ + + TRACK_TEST(tracker); +/* From V1.1 3.13 */ + + uint8 encoding[] = { + 0x42, 0x00, 0x79, 0x01, 0x00, 0x00, 0x00, 0x70, + 0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x28, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x0B, + 0x4F, 0x62, 0x6A, 0x65, 0x63, 0x74, 0x20, 0x54, + 0x79, 0x70, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x0B, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x38, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x04, + 0x4E, 0x61, 0x6D, 0x65, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x0B, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x42, 0x00, 0x55, 0x07, 0x00, 0x00, 0x00, 0x04, + 0x4B, 0x65, 0x79, 0x31, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x54, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + }; + + struct kmip ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_1); + + Attribute a[4] = {0}; + for(int i = 0; i < 3; i++) + { + kmip_init_attribute(&a[i]); + } + + enum object_type t = KMIP_OBJTYPE_SYMMETRIC_KEY; + a[0].type = KMIP_ATTR_OBJECT_TYPE; + a[0].value = &t; + + struct text_string value = {0}; + value.value = "Key1"; + value.size = 4; + + struct name name = {0}; + name.value = &value; + name.type = KMIP_NAME_UNINTERPRETED_TEXT_STRING; + a[1].type = KMIP_ATTR_NAME; + a[1].value = &name; + + + Attributes attributes = {0}; + LinkedList list = {0}; + LinkedListItem item_1, item_2 = {0}; + item_1.data = &a[0]; + item_2.data = &a[1]; + kmip_linked_list_enqueue(&list, &item_1); + kmip_linked_list_enqueue(&list, &item_2); + attributes.attribute_list = &list; + + LocateRequestPayload expected = {0}; + expected.attributes = &attributes; + + LocateRequestPayload observed = {0}; + int result = kmip_decode_locate_request_payload(&ctx, &observed); + + result = report_decoding_test_result( + tracker, + &ctx, + kmip_compare_locate_request_payload(&expected,&observed), + result, + __func__); + + kmip_free_locate_request_payload(&ctx, &observed); + kmip_destroy(&ctx); + return(result); +} + /* The following tests are taken verbatim from the KMIP 1.1 Test Cases documentation, available here: @@ -13031,7 +13636,11 @@ run_tests(void) test_decode_object_types(&tracker); test_compare_query_functions(&tracker); test_decode_query_response_payload(&tracker); - + test_decode_unique_identifiers(&tracker); + test_decode_locate_response_payload(&tracker); + test_decode_locate_request_payload(&tracker); + test_decode_locate_request_payload_group(&tracker); + printf("\n"); test_encode_integer(&tracker); test_encode_long(&tracker); @@ -13094,7 +13703,12 @@ run_tests(void) test_encode_template_attribute(&tracker); test_encode_query_functions(&tracker); test_encode_query_request_payload(&tracker); - + test_encode_unique_identifiers(&tracker); + test_encode_locate_request_payload_1(&tracker); + test_encode_locate_request_payload_2(&tracker); + test_encode_locate_response_payload(&tracker); + test_encode_locate_request_payload_group(&tracker); + printf("\nKMIP 1.1 Feature Tests\n"); printf("----------------------\n"); test_decode_device_credential(&tracker); From 1183c33918941ec9e050a5956f23c721920c407b Mon Sep 17 00:00:00 2001 From: rjewell Date: Thu, 10 Feb 2022 09:21:54 -0500 Subject: [PATCH 4/5] rj - local changes needed for running demos --- Makefile | 3 +- demos/demo_create.c | 89 +++++++++++++++++++++++++++++++++++++++----- demos/demo_destroy.c | 5 +++ demos/demo_get.c | 5 +++ demos/demo_query.c | 9 +++++ src/kmip_bio.c | 2 - 6 files changed, 101 insertions(+), 12 deletions(-) diff --git a/Makefile b/Makefile index 9f7057a..d29bb63 100644 --- a/Makefile +++ b/Makefile @@ -42,7 +42,8 @@ CFLAGS = -std=c11 -pedantic -g3 -Wall -Wextra LOFLAGS = -fPIC SOFLAGS = -shared -Wl,-soname,$(SO_NAME) SOCOREFLAGS = -shared -Wl,-soname,$(SO_CORE_NAME) -LDFLAGS = -L/usr/local/lib64 -L/usr/local/lib +#LDFLAGS = -L/usr/local/lib64 -L/usr/local/lib +LDFLAGS = -L/usr/local/lib LDLIBS = -lssl -lcrypto INC_FLAGS = -I$(INC_DIR) diff --git a/demos/demo_create.c b/demos/demo_create.c index ec45107..e093643 100644 --- a/demos/demo_create.c +++ b/demos/demo_create.c @@ -28,12 +28,16 @@ print_help(const char *app) printf("-k path : path to client key file\n"); printf("-p port : the port number of the KMIP server\n"); printf("-r path : path to CA certificate file\n"); + printf("-n name : name of new key\n"); + printf("-g group : name of object group\n"); } int parse_arguments(int argc, char **argv, char **server_address, char **server_port, char **client_certificate, char **client_key, char **ca_certificate, + char** key_name, + char **group, int *print_usage) { if(argc <= 1) @@ -56,6 +60,10 @@ parse_arguments(int argc, char **argv, *server_port = argv[++i]; else if(strncmp(argv[i], "-r", 2) == 0) *ca_certificate = argv[++i]; + else if(strncmp(argv[i], "-n", 2) == 0) + *key_name = argv[++i]; + else if(strncmp(argv[i], "-g", 2) == 0) + *group = argv[++i]; else { printf("Invalid option: '%s'\n", argv[i]); @@ -72,13 +80,20 @@ use_low_level_api(const char *server_address, const char *server_port, const char *client_certificate, const char *client_key, - const char *ca_certificate) + const char *ca_certificate, + const char *key_name, + const char * group) { /* Set up the TLS connection to the KMIP server. */ SSL_CTX *ctx = NULL; SSL *ssl = NULL; + #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) OPENSSL_init_ssl(0, NULL); ctx = SSL_CTX_new(TLS_client_method()); + #else + SSL_library_init(); + ctx = SSL_CTX_new(SSLv23_client_method()); + #endif printf("\n"); printf("Loading the client certificate: %s\n", client_certificate); @@ -152,8 +167,8 @@ use_low_level_api(const char *server_address, kmip_set_buffer(&kmip_context, encoding, buffer_total_size); /* Build the request message. */ - Attribute a[3] = {0}; - for(int i = 0; i < 3; i++) + Attribute a[6] = {{0}}; + for(int i = 0; i < 6; i++) kmip_init_attribute(&a[i]); enum cryptographic_algorithm algorithm = KMIP_CRYPTOALG_AES; @@ -167,10 +182,55 @@ use_low_level_api(const char *server_address, int32 mask = KMIP_CRYPTOMASK_ENCRYPT | KMIP_CRYPTOMASK_DECRYPT; a[2].type = KMIP_ATTR_CRYPTOGRAPHIC_USAGE_MASK; a[2].value = &mask; + + int idx = 3; + + // the 'activation date' is required for Vormetric DSM. the key will be left in 'preactive' state without this + int64 date_time = 1641772563; // init with a known date in case time() does not work + time_t now = time(NULL); + if(now != (time_t)(-1)) + date_time = now - 24*3600; // set activation date in the past to create the key in the Active state + + a[idx].type = KMIP_ATTR_ACTIVATION_DATE; + a[idx].value = &date_time; + + idx++; + + + + TextString g = { 0 }; + if (group) + { + g.value = (char*) group; + g.size = kmip_strnlen_s(group, 50); + + a[idx].type = KMIP_ATTR_OBJECT_GROUP; + a[idx].value = &g; + + idx++; + } + + TextString s = { 0 }; + Name n = { 0 }; + if (key_name) + { + s.value = (char*) key_name; + s.size = kmip_strnlen_s(key_name, 50); + + n.value = &s; + n.type = KMIP_NAME_UNINTERPRETED_TEXT_STRING; + + a[idx].type = KMIP_ATTR_NAME; + a[idx].value = &n; + + idx++; + } + + int attrib_count = idx; TemplateAttribute ta = {0}; ta.attributes = a; - ta.attribute_count = ARRAY_LENGTH(a); + ta.attribute_count = attrib_count; ProtocolVersion pv = {0}; kmip_init_protocol_version(&pv, kmip_context.version); @@ -322,9 +382,18 @@ use_low_level_api(const char *server_address, printf("The KMIP operation was executed with no errors.\n"); printf("Result: "); - kmip_print_result_status_enum(stdout, result); - printf(" (%d)\n\n", result); - + kmip_print_result_status_enum(stdout, result_status); + printf(" (%d)\n\n", result_status); + + if (result_status != KMIP_STATUS_SUCCESS) + { + printf("Result Reason: "); + kmip_print_result_reason_enum(stdout, req.result_reason); + printf("\n"); + + kmip_print_text_string(stdout, 0, "Result Message", req.result_message); + } + if(result == KMIP_STATUS_SUCCESS) { CreateResponsePayload *pld = (CreateResponsePayload *)req.response_payload; @@ -356,9 +425,11 @@ main(int argc, char **argv) char *client_certificate = NULL; char *client_key = NULL; char *ca_certificate = NULL; + char *key_name = NULL; + char *group = NULL; int help = 0; - int error = parse_arguments(argc, argv, &server_address, &server_port, &client_certificate, &client_key, &ca_certificate, &help); + int error = parse_arguments(argc, argv, &server_address, &server_port, &client_certificate, &client_key, &ca_certificate, &key_name, &group, &help); if(error) return(error); if(help) @@ -367,6 +438,6 @@ main(int argc, char **argv) return(0); } - use_low_level_api(server_address, server_port, client_certificate, client_key, ca_certificate); + use_low_level_api(server_address, server_port, client_certificate, client_key, ca_certificate, key_name, group); return(0); } diff --git a/demos/demo_destroy.c b/demos/demo_destroy.c index e2397f3..1a52e8c 100644 --- a/demos/demo_destroy.c +++ b/demos/demo_destroy.c @@ -95,8 +95,13 @@ use_high_level_api(const char *server_address, /* Set up the TLS connection to the KMIP server. */ SSL_CTX *ctx = NULL; SSL *ssl = NULL; + #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) OPENSSL_init_ssl(0, NULL); ctx = SSL_CTX_new(TLS_client_method()); + #else + SSL_library_init(); + ctx = SSL_CTX_new(SSLv23_client_method()); + #endif printf("\n"); printf("Loading the client certificate: %s\n", client_certificate); diff --git a/demos/demo_get.c b/demos/demo_get.c index fa08dfe..201d949 100644 --- a/demos/demo_get.c +++ b/demos/demo_get.c @@ -131,8 +131,13 @@ use_mid_level_api(char *server_address, /* Set up the TLS connection to the KMIP server. */ SSL_CTX *ctx = NULL; SSL *ssl = NULL; + #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) OPENSSL_init_ssl(0, NULL); ctx = SSL_CTX_new(TLS_client_method()); + #else + SSL_library_init(); + ctx = SSL_CTX_new(SSLv23_client_method()); + #endif printf("\n"); printf("Loading the client certificate: %s\n", client_certificate); diff --git a/demos/demo_query.c b/demos/demo_query.c index b38a7d9..c9a0e48 100644 --- a/demos/demo_query.c +++ b/demos/demo_query.c @@ -408,8 +408,17 @@ main(int argc, char **argv) /* Set up the TLS connection to the KMIP server. */ SSL_CTX *ctx = NULL; SSL *ssl = NULL; + +//------------------------------------------------------------------------------ + printf("openssl version = %08lx\n", OPENSSL_VERSION_NUMBER); + #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) OPENSSL_init_ssl(0, NULL); ctx = SSL_CTX_new(TLS_client_method()); + #else + SSL_library_init(); + ctx = SSL_CTX_new(SSLv23_client_method()); + #endif + printf("\n"); printf("Loading the client certificate: %s\n", client_certificate); diff --git a/src/kmip_bio.c b/src/kmip_bio.c index c85b732..310324b 100644 --- a/src/kmip_bio.c +++ b/src/kmip_bio.c @@ -1565,8 +1565,6 @@ int kmip_bio_query_with_context(KMIP *ctx, BIO *bio, enum query_function queries return(result); } - kmip_free_query_request_payload(ctx, &qrp); - if (response) { FILE* out = fopen( "/tmp/kmip_query.dat", "w" ); From 028b74e1705be3f6e297f6d26a71be3bf663f7e9 Mon Sep 17 00:00:00 2001 From: rjewell Date: Thu, 14 Apr 2022 12:18:31 -0400 Subject: [PATCH 5/5] Add support for KMIP Activate command --- Makefile | 7 + demos/demo_activate.c | 202 +++++++++++++++++++++ demos/demo_create.c | 47 ++--- include/kmip.h | 18 ++ include/kmip_bio.h | 2 + include/kmip_io.h | 2 + src/kmip.c | 233 +++++++++++++++++++++++- src/kmip_bio.c | 407 ++++++++++++++++++++++++++++++++++++++++++ src/kmip_io.c | 33 +++- tests/tests.c | 165 +++++++++++++++++ 10 files changed, 1094 insertions(+), 22 deletions(-) create mode 100755 demos/demo_activate.c diff --git a/Makefile b/Makefile index 4530d1e..028c832 100644 --- a/Makefile +++ b/Makefile @@ -71,6 +71,7 @@ DEMO_O_FILES = $(OBJ_DIR)/demo_get.o DEMO_O_FILES += $(OBJ_DIR)/demo_create.o DEMO_O_FILES += $(OBJ_DIR)/demo_destroy.o DEMO_O_FILES += $(OBJ_DIR)/demo_query.o +DEMO_O_FILES += $(OBJ_DIR)/demo_activate.o DEMO_O_FILES += $(OBJ_DIR)/demo_locate.o TEST_O_FILES = $(OBJ_DIR)/tests.o @@ -89,6 +90,7 @@ demos: objs \ $(BIN_DIR)/demo_create \ $(BIN_DIR)/demo_destroy \ $(BIN_DIR)/demo_query \ + $(BIN_DIR)/demo_activate \ $(BIN_DIR)/demo_locate tests: objs \ @@ -107,6 +109,8 @@ $(BIN_DIR)/demo_destroy: $(OBJ_DIR)/demo_destroy.o $(SRC_O_FILES) $(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS) $(BIN_DIR)/demo_query: $(OBJ_DIR)/demo_query.o $(SRC_O_FILES) $(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS) +$(BIN_DIR)/demo_activate: $(OBJ_DIR)/demo_activate.o $(SRC_O_FILES) + $(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS) $(BIN_DIR)/demo_locate: $(OBJ_DIR)/demo_locate.o $(SRC_O_FILES) $(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS) @@ -131,6 +135,8 @@ $(OBJ_DIR)/demo_destroy.o: $(DEMO_DIR)/demo_destroy.c $(H_FILES) $(CC) $(CFLAGS) $(INC_FLAGS) -c $< -o $@ $(OBJ_DIR)/demo_query.o: $(DEMO_DIR)/demo_query.c $(H_FILES) $(CC) $(CFLAGS) $(INC_FLAGS) -c $< -o $@ +$(OBJ_DIR)/demo_activate.o: $(DEMO_DIR)/demo_activate.c $(H_FILES) + $(CC) $(CFLAGS) $(INC_FLAGS) -c $< -o $@ $(OBJ_DIR)/demo_locate.o: $(DEMO_DIR)/demo_locate.c $(H_FILES) $(CC) $(CFLAGS) $(INC_FLAGS) -c $< -o $@ @@ -182,6 +188,7 @@ install: all cp $(BIN_DIR)/demo_get $(DEST_DIR)$(PREFIX)/bin/$(KMIP) cp $(BIN_DIR)/demo_destroy $(DEST_DIR)$(PREFIX)/bin/$(KMIP) cp $(BIN_DIR)/demo_query $(DEST_DIR)$(PREFIX)/bin/$(KMIP) + cp $(BIN_DIR)/demo_activate $(DEST_DIR)$(PREFIX)/bin/$(KMIP) cp $(BIN_DIR)/demo_locate $(DEST_DIR)$(PREFIX)/bin/$(KMIP) cp -r $(DOCS_DIR)/source/. $(DEST_DIR)$(PREFIX)/share/doc/$(KMIP)/src cp $(SRC_DIR)/*.c $(DEST_DIR)$(PREFIX)/src/$(KMIP) diff --git a/demos/demo_activate.c b/demos/demo_activate.c new file mode 100755 index 0000000..89fc9c0 --- /dev/null +++ b/demos/demo_activate.c @@ -0,0 +1,202 @@ +/* Copyright (c) 2018 The Johns Hopkins University/Applied Physics Laboratory + * All Rights Reserved. + * + * This file is dual licensed under the terms of the Apache 2.0 License and + * the BSD 3-Clause License. See the LICENSE file in the root of this + * repository for more information. + */ + +#include +#include +#include +#include +#include + +#include "kmip.h" +#include "kmip_io.h" +#include "kmip_bio.h" + +void +print_help(const char *app) +{ + printf("Usage: %s [flag value | flag] ...\n\n", app); + printf("Flags:\n"); + printf("-a addr : the IP address of the KMIP server\n"); + printf("-c path : path to client certificate file\n"); + printf("-h : print this help info\n"); + printf("-i id : the ID of the symmetric key to activate\n"); + printf("-k path : path to client key file\n"); + printf("-p port : the port number of the KMIP server\n"); + printf("-r path : path to CA certificate file\n"); +} + +int +parse_arguments(int argc, char **argv, + char **server_address, char **server_port, + char **client_certificate, char **client_key, char **ca_certificate, + char **id, + int *print_usage) +{ + if(argc <= 1) + { + print_help(argv[0]); + return(-1); + } + + for(int i = 1; i < argc; i++) + { + if(strncmp(argv[i], "-a", 2) == 0) + { + *server_address = argv[++i]; + } + else if(strncmp(argv[i], "-c", 2) == 0) + { + *client_certificate = argv[++i]; + } + else if(strncmp(argv[i], "-h", 2) == 0) + { + *print_usage = 1; + } + else if(strncmp(argv[i], "-i", 2) == 0) + { + *id = argv[++i]; + } + else if(strncmp(argv[i], "-k", 2) == 0) + { + *client_key = argv[++i]; + } + else if(strncmp(argv[i], "-p", 2) == 0) + { + *server_port = argv[++i]; + } + else if(strncmp(argv[i], "-r", 2) == 0) + { + *ca_certificate = argv[++i]; + } + else + { + printf("Invalid option: '%s'\n", argv[i]); + print_help(argv[0]); + return(-1); + } + } + + return(0); +} + +int +use_high_level_api(BIO* bio, + char *id) +{ + /* Send the request message. */ + int result = kmip_bio_activate_symmetric_key(bio, id, kmip_strnlen_s(id, 128)); + + /* Handle the response results. */ + printf("\n"); + if(result < 0) + { + printf("An error occurred while activating object: %s\n", id); + printf("Error Code: %d\n", result); + } + else + { + printf("The KMIP operation was executed with no errors.\n"); + printf("Result: "); + kmip_print_result_status_enum(stdout, result); + printf(" (%d)\n", result); + } + + return(result); +} + +int +main(int argc, char **argv) +{ + char *server_address = NULL; + char *server_port = NULL; + char *client_certificate = NULL; + char *client_key = NULL; + char *ca_certificate = NULL; + char *id = NULL; + int help = 0; + + int error = parse_arguments(argc, argv, &server_address, &server_port, &client_certificate, &client_key, &ca_certificate, &id, &help); + if(error) + { + return(error); + } + if(help) + { + print_help(argv[0]); + return(0); + } + + /* Set up the TLS connection to the KMIP server. */ + SSL_CTX *ctx = NULL; + SSL *ssl = NULL; + #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) + OPENSSL_init_ssl(0, NULL); + ctx = SSL_CTX_new(TLS_client_method()); + #else + SSL_library_init(); + ctx = SSL_CTX_new(SSLv23_client_method()); + #endif + + printf("\n"); + printf("Loading the client certificate: %s\n", client_certificate); + if(SSL_CTX_use_certificate_file(ctx, client_certificate, SSL_FILETYPE_PEM) != 1) + { + fprintf(stderr, "Loading the client certificate failed\n"); + ERR_print_errors_fp(stderr); + SSL_CTX_free(ctx); + return(-1); + } + + printf("Loading the client key: %s\n", client_key); + if(SSL_CTX_use_PrivateKey_file(ctx, client_key, SSL_FILETYPE_PEM) != 1) + { + fprintf(stderr, "Loading the client key failed\n"); + ERR_print_errors_fp(stderr); + SSL_CTX_free(ctx); + return(-1); + } + + printf("Loading the CA certificate: %s\n", ca_certificate); + if(SSL_CTX_load_verify_locations(ctx, ca_certificate, NULL) != 1) + { + fprintf(stderr, "Loading the CA file failed\n"); + ERR_print_errors_fp(stderr); + SSL_CTX_free(ctx); + return(-1); + } + + BIO *bio = NULL; + bio = BIO_new_ssl_connect(ctx); + if(bio == NULL) + { + fprintf(stderr, "BIO_new_ssl_connect failed\n"); + ERR_print_errors_fp(stderr); + SSL_CTX_free(ctx); + return(-1); + } + + BIO_get_ssl(bio, &ssl); + SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); + BIO_set_conn_hostname(bio, server_address); + BIO_set_conn_port(bio, server_port); + if(BIO_do_connect(bio) != 1) + { + fprintf(stderr, "BIO_do_connect failed\n"); + ERR_print_errors_fp(stderr); + BIO_free_all(bio); + SSL_CTX_free(ctx); + return(-1); + } + + int result = use_high_level_api(bio, id); + + BIO_free_all(bio); + SSL_CTX_free(ctx); + + return(result); +} diff --git a/demos/demo_create.c b/demos/demo_create.c index e093643..8d4067a 100644 --- a/demos/demo_create.c +++ b/demos/demo_create.c @@ -28,6 +28,7 @@ print_help(const char *app) printf("-k path : path to client key file\n"); printf("-p port : the port number of the KMIP server\n"); printf("-r path : path to CA certificate file\n"); + printf("-A : send Activation Date\n"); printf("-n name : name of new key\n"); printf("-g group : name of object group\n"); } @@ -36,6 +37,7 @@ int parse_arguments(int argc, char **argv, char **server_address, char **server_port, char **client_certificate, char **client_key, char **ca_certificate, + int* activate, char** key_name, char **group, int *print_usage) @@ -60,6 +62,8 @@ parse_arguments(int argc, char **argv, *server_port = argv[++i]; else if(strncmp(argv[i], "-r", 2) == 0) *ca_certificate = argv[++i]; + else if(strncmp(argv[i], "-A", 2) == 0) + *activate = 1; else if(strncmp(argv[i], "-n", 2) == 0) *key_name = argv[++i]; else if(strncmp(argv[i], "-g", 2) == 0) @@ -81,6 +85,7 @@ use_low_level_api(const char *server_address, const char *client_certificate, const char *client_key, const char *ca_certificate, + int activate, const char *key_name, const char * group) { @@ -94,7 +99,7 @@ use_low_level_api(const char *server_address, SSL_library_init(); ctx = SSL_CTX_new(SSLv23_client_method()); #endif - + printf("\n"); printf("Loading the client certificate: %s\n", client_certificate); if(SSL_CTX_use_certificate_file(ctx, client_certificate, SSL_FILETYPE_PEM) != 1) @@ -104,7 +109,7 @@ use_low_level_api(const char *server_address, SSL_CTX_free(ctx); return(-1); } - + printf("Loading the client key: %s\n", client_key); if(SSL_CTX_use_PrivateKey_file(ctx, client_key, SSL_FILETYPE_PEM) != 1) { @@ -113,7 +118,7 @@ use_low_level_api(const char *server_address, SSL_CTX_free(ctx); return(-1); } - + printf("Loading the CA certificate: %s\n", ca_certificate); if(SSL_CTX_load_verify_locations(ctx, ca_certificate, NULL) != 1) { @@ -122,7 +127,7 @@ use_low_level_api(const char *server_address, SSL_CTX_free(ctx); return(-1); } - + BIO *bio = NULL; bio = BIO_new_ssl_connect(ctx); if(bio == NULL) @@ -132,7 +137,7 @@ use_low_level_api(const char *server_address, SSL_CTX_free(ctx); return(-1); } - + BIO_get_ssl(bio, &ssl); SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); BIO_set_conn_hostname(bio, server_address); @@ -145,9 +150,9 @@ use_low_level_api(const char *server_address, SSL_CTX_free(ctx); return(-1); } - + printf("\n"); - + /* Set up the KMIP context and the initial encoding buffer. */ KMIP kmip_context = {0}; kmip_init(&kmip_context, NULL, 0, KMIP_1_0); @@ -185,18 +190,19 @@ use_low_level_api(const char *server_address, int idx = 3; - // the 'activation date' is required for Vormetric DSM. the key will be left in 'preactive' state without this - int64 date_time = 1641772563; // init with a known date in case time() does not work - time_t now = time(NULL); - if(now != (time_t)(-1)) - date_time = now - 24*3600; // set activation date in the past to create the key in the Active state - - a[idx].type = KMIP_ATTR_ACTIVATION_DATE; - a[idx].value = &date_time; - - idx++; + if (activate) + { + // the key will be left in 'preactive' state without this + int64 date_time = 1641772563; // init with a known date in case time() does not work + time_t now = time(NULL); + if(now != (time_t)(-1)) + date_time = now - 24*3600; // set activation date in the past to create the key in the Active state + a[idx].type = KMIP_ATTR_ACTIVATION_DATE; + a[idx].value = &date_time; + idx++; + } TextString g = { 0 }; if (group) @@ -315,7 +321,7 @@ use_low_level_api(const char *server_address, BIO_free_all(bio); SSL_CTX_free(ctx); - + printf("\n"); if(result < 0) { @@ -427,9 +433,10 @@ main(int argc, char **argv) char *ca_certificate = NULL; char *key_name = NULL; char *group = NULL; + int activate = 0; int help = 0; - int error = parse_arguments(argc, argv, &server_address, &server_port, &client_certificate, &client_key, &ca_certificate, &key_name, &group, &help); + int error = parse_arguments(argc, argv, &server_address, &server_port, &client_certificate, &client_key, &ca_certificate, &activate, &key_name, &group, &help); if(error) return(error); if(help) @@ -438,6 +445,6 @@ main(int argc, char **argv) return(0); } - use_low_level_api(server_address, server_port, client_certificate, client_key, ca_certificate, key_name, group); + use_low_level_api(server_address, server_port, client_certificate, client_key, ca_certificate, activate, key_name, group); return(0); } diff --git a/include/kmip.h b/include/kmip.h index c5d064b..187d758 100644 --- a/include/kmip.h +++ b/include/kmip.h @@ -1122,6 +1122,16 @@ typedef struct get_response_payload void *object; } GetResponsePayload; +typedef struct activate_request_payload +{ + TextString *unique_identifier; +} ActivateRequestPayload; + +typedef struct activate_response_payload +{ + TextString *unique_identifier; +} ActivateResponsePayload; + typedef struct destroy_request_payload { TextString *unique_identifier; @@ -1623,6 +1633,8 @@ void kmip_free_create_request_payload(KMIP *, CreateRequestPayload *); void kmip_free_create_response_payload(KMIP *, CreateResponsePayload *); void kmip_free_get_request_payload(KMIP *, GetRequestPayload *); void kmip_free_get_response_payload(KMIP *, GetResponsePayload *); +void kmip_free_activate_request_payload(KMIP *, ActivateRequestPayload *); +void kmip_free_activate_response_payload(KMIP *, ActivateResponsePayload *); void kmip_free_destroy_request_payload(KMIP *, DestroyRequestPayload *); void kmip_free_destroy_response_payload(KMIP *, DestroyResponsePayload *); void kmip_free_request_batch_item(KMIP *, RequestBatchItem *); @@ -1698,6 +1710,8 @@ int kmip_compare_create_request_payload(const CreateRequestPayload *, const Crea int kmip_compare_create_response_payload(const CreateResponsePayload *, const CreateResponsePayload *); int kmip_compare_get_request_payload(const GetRequestPayload *, const GetRequestPayload *); int kmip_compare_get_response_payload(const GetResponsePayload *, const GetResponsePayload *); +int kmip_compare_activate_request_payload(const ActivateRequestPayload *, const ActivateRequestPayload *); +int kmip_compare_activate_response_payload(const ActivateResponsePayload *, const ActivateResponsePayload *); int kmip_compare_destroy_request_payload(const DestroyRequestPayload *, const DestroyRequestPayload *); int kmip_compare_destroy_response_payload(const DestroyResponsePayload *, const DestroyResponsePayload *); int kmip_compare_request_batch_item(const RequestBatchItem *, const RequestBatchItem *); @@ -1771,6 +1785,8 @@ int kmip_encode_create_request_payload(KMIP *, const CreateRequestPayload *); int kmip_encode_create_response_payload(KMIP *, const CreateResponsePayload *); int kmip_encode_get_request_payload(KMIP *, const GetRequestPayload *); int kmip_encode_get_response_payload(KMIP *, const GetResponsePayload *); +int kmip_encode_activate_request_payload(KMIP *, const ActivateRequestPayload *); +int kmip_encode_activate_response_payload(KMIP *, const ActivateResponsePayload *); int kmip_encode_destroy_request_payload(KMIP *, const DestroyRequestPayload *); int kmip_encode_destroy_response_payload(KMIP *, const DestroyResponsePayload *); int kmip_encode_nonce(KMIP *, const Nonce *); @@ -1838,6 +1854,8 @@ int kmip_decode_create_request_payload(KMIP *, CreateRequestPayload *); int kmip_decode_create_response_payload(KMIP *, CreateResponsePayload *); int kmip_decode_get_request_payload(KMIP *, GetRequestPayload *); int kmip_decode_get_response_payload(KMIP *, GetResponsePayload *); +int kmip_decode_activate_request_payload(KMIP *, ActivateRequestPayload *); +int kmip_decode_activate_response_payload(KMIP *, ActivateResponsePayload *); int kmip_decode_destroy_request_payload(KMIP *, DestroyRequestPayload *); int kmip_decode_destroy_response_payload(KMIP *, DestroyResponsePayload *); int kmip_decode_request_batch_item(KMIP *, RequestBatchItem *); diff --git a/include/kmip_bio.h b/include/kmip_bio.h index 6497b85..55495b8 100644 --- a/include/kmip_bio.h +++ b/include/kmip_bio.h @@ -37,10 +37,12 @@ OpenSSH BIO API int kmip_bio_create_symmetric_key(BIO *, TemplateAttribute *, char **, int *); int kmip_bio_get_symmetric_key(BIO *, char *, int, char **, int *); int kmip_bio_destroy_symmetric_key(BIO *, char *, int); +int kmip_bio_activate_symmetric_key(BIO *, char *, int); int kmip_bio_create_symmetric_key_with_context(KMIP *, BIO *, TemplateAttribute *, char **, int *); int kmip_bio_get_symmetric_key_with_context(KMIP *, BIO *, char *, int, char **, int *); int kmip_bio_destroy_symmetric_key_with_context(KMIP *, BIO *, char *, int); +int kmip_bio_activate_symmetric_key_with_context(KMIP *, BIO *, char *, int); int kmip_bio_get_attributes_with_context(KMIP *ctx, BIO *bio, Attribute* attribs, size_t attrib_count, LocateResponse* locate_result); diff --git a/include/kmip_io.h b/include/kmip_io.h index b8f69ff..ad5bde0 100644 --- a/include/kmip_io.h +++ b/include/kmip_io.h @@ -71,6 +71,8 @@ void kmip_print_create_request_payload(FILE *, int, CreateRequestPayload *); void kmip_print_create_response_payload(FILE *, int, CreateResponsePayload *); void kmip_print_get_request_payload(FILE *, int, GetRequestPayload *); void kmip_print_get_response_payload(FILE *, int, GetResponsePayload *); +void kmip_print_activate_request_payload(FILE *, int, ActivateRequestPayload *); +void kmip_print_activate_response_payload(FILE *, int, ActivateResponsePayload *); void kmip_print_destroy_request_payload(FILE *, int, DestroyRequestPayload *); void kmip_print_destroy_response_payload(FILE *, int, DestroyResponsePayload *); void kmip_print_request_payload(FILE *, int, enum operation, void *); diff --git a/src/kmip.c b/src/kmip.c index c3d29f2..15b12a6 100644 --- a/src/kmip.c +++ b/src/kmip.c @@ -869,6 +869,7 @@ kmip_check_enum_value(enum kmip_version version, enum tag t, int value) case KMIP_OP_CREATE: case KMIP_OP_GET: case KMIP_OP_DESTROY: + case KMIP_OP_ACTIVATE: case KMIP_OP_QUERY: case KMIP_OP_LOCATE: return(KMIP_OK); @@ -2530,6 +2531,39 @@ kmip_free_get_response_payload(KMIP *ctx, GetResponsePayload *value) return; } +void +kmip_free_activate_request_payload(KMIP *ctx, ActivateRequestPayload *value) +{ + if(value != NULL) + { + if(value->unique_identifier != NULL) + { + kmip_free_text_string(ctx, value->unique_identifier); + ctx->free_func(ctx->state, value->unique_identifier); + value->unique_identifier = NULL; + } + } + + return; +} + +void +kmip_free_activate_response_payload(KMIP *ctx, ActivateResponsePayload *value) +{ + if(value != NULL) + { + if(value->unique_identifier != NULL) + { + kmip_free_text_string(ctx, value->unique_identifier); + ctx->free_func(ctx->state, value->unique_identifier); + value->unique_identifier = NULL; + } + } + + return; +} + + void kmip_free_destroy_request_payload(KMIP *ctx, DestroyRequestPayload *value) { @@ -2660,6 +2694,10 @@ kmip_free_request_batch_item(KMIP *ctx, RequestBatchItem *value) kmip_free_get_request_payload(ctx, (GetRequestPayload *)value->request_payload); break; + case KMIP_OP_ACTIVATE: + kmip_free_activate_request_payload(ctx, (ActivateRequestPayload *)value->request_payload); + break; + case KMIP_OP_DESTROY: kmip_free_destroy_request_payload(ctx, (DestroyRequestPayload *)value->request_payload); break; @@ -2733,10 +2771,14 @@ kmip_free_response_batch_item(KMIP *ctx, ResponseBatchItem *value) kmip_free_get_response_payload(ctx, (GetResponsePayload *)value->response_payload); break; + case KMIP_OP_ACTIVATE: + kmip_free_activate_response_payload(ctx, (ActivateResponsePayload *)value->response_payload); + break; + case KMIP_OP_DESTROY: kmip_free_destroy_response_payload(ctx, (DestroyResponsePayload *)value->response_payload); break; - + case KMIP_OP_QUERY: kmip_free_query_response_payload(ctx, (QueryResponsePayload *)value->response_payload); break; @@ -5053,6 +5095,60 @@ kmip_compare_get_response_payload(const GetResponsePayload *a, const GetResponse return(KMIP_TRUE); } +int +kmip_compare_activate_request_payload(const ActivateRequestPayload *a, const ActivateRequestPayload *b) +{ + if(a != b) + { + if((a == NULL) || (b == NULL)) + { + return(KMIP_FALSE); + } + + if(a->unique_identifier != b->unique_identifier) + { + if((a->unique_identifier == NULL) || (b->unique_identifier == NULL)) + { + return(KMIP_FALSE); + } + + if(kmip_compare_text_string(a->unique_identifier, b->unique_identifier) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + } + + return(KMIP_TRUE); +} + +int +kmip_compare_activate_response_payload(const ActivateResponsePayload *a, const ActivateResponsePayload *b) +{ + if(a != b) + { + if((a == NULL) || (b == NULL)) + { + return(KMIP_FALSE); + } + + if(a->unique_identifier != b->unique_identifier) + { + if((a->unique_identifier == NULL) || (b->unique_identifier == NULL)) + { + return(KMIP_FALSE); + } + + if(kmip_compare_text_string(a->unique_identifier, b->unique_identifier) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + } + + return(KMIP_TRUE); +} + int kmip_compare_destroy_request_payload(const DestroyRequestPayload *a, const DestroyRequestPayload *b) { @@ -5162,6 +5258,13 @@ kmip_compare_request_batch_item(const RequestBatchItem *a, const RequestBatchIte return(KMIP_FALSE); } break; + + case KMIP_OP_ACTIVATE: + if(kmip_compare_activate_request_payload((ActivateRequestPayload *)a->request_payload, (ActivateRequestPayload *)b->request_payload) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + break; case KMIP_OP_DESTROY: if(kmip_compare_destroy_request_payload((DestroyRequestPayload *)a->request_payload, (DestroyRequestPayload *)b->request_payload) == KMIP_FALSE) @@ -5282,6 +5385,13 @@ kmip_compare_response_batch_item(const ResponseBatchItem *a, const ResponseBatch } break; + case KMIP_OP_ACTIVATE: + if(kmip_compare_activate_response_payload((ActivateResponsePayload *)a->response_payload, (ActivateResponsePayload *)b->response_payload) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + break; + case KMIP_OP_DESTROY: if(kmip_compare_destroy_response_payload((DestroyResponsePayload *)a->response_payload, (DestroyResponsePayload *)b->response_payload) == KMIP_FALSE) { @@ -8218,6 +8328,57 @@ kmip_encode_get_response_payload(KMIP *ctx, const GetResponsePayload *value) return(KMIP_OK); } +int +kmip_encode_activate_request_payload(KMIP *ctx, const ActivateRequestPayload *value) +{ + int result = 0; + result = kmip_encode_int32_be(ctx, TAG_TYPE(KMIP_TAG_REQUEST_PAYLOAD, KMIP_TYPE_STRUCTURE)); + CHECK_RESULT(ctx, result); + + uint8 *length_index = ctx->index; + uint8 *value_index = ctx->index += 4; + + if(value->unique_identifier != NULL) + { + result = kmip_encode_text_string(ctx, KMIP_TAG_UNIQUE_IDENTIFIER, value->unique_identifier); + CHECK_RESULT(ctx, result); + } + + uint8 *curr_index = ctx->index; + ctx->index = length_index; + + result = kmip_encode_length(ctx, curr_index - value_index); + CHECK_RESULT(ctx, result); + + ctx->index = curr_index; + + return(KMIP_OK); +} + +int +kmip_encode_activate_response_payload(KMIP *ctx, const ActivateResponsePayload *value) +{ + int result = 0; + result = kmip_encode_int32_be(ctx, TAG_TYPE(KMIP_TAG_RESPONSE_PAYLOAD, KMIP_TYPE_STRUCTURE)); + CHECK_RESULT(ctx, result); + + uint8 *length_index = ctx->index; + uint8 *value_index = ctx->index += 4; + + result = kmip_encode_text_string(ctx, KMIP_TAG_UNIQUE_IDENTIFIER, value->unique_identifier); + CHECK_RESULT(ctx, result); + + uint8 *curr_index = ctx->index; + ctx->index = length_index; + + result = kmip_encode_length(ctx, curr_index - value_index); + CHECK_RESULT(ctx, result); + + ctx->index = curr_index; + + return(KMIP_OK); +} + int kmip_encode_destroy_request_payload(KMIP *ctx, const DestroyRequestPayload *value) { @@ -8769,6 +8930,10 @@ kmip_encode_request_batch_item(KMIP *ctx, const RequestBatchItem *value) result = kmip_encode_get_request_payload(ctx, (GetRequestPayload*)value->request_payload); break; + case KMIP_OP_ACTIVATE: + result = kmip_encode_activate_request_payload(ctx, (ActivateRequestPayload*)value->request_payload); + break; + case KMIP_OP_DESTROY: result = kmip_encode_destroy_request_payload(ctx, (DestroyRequestPayload*)value->request_payload); break; @@ -8848,6 +9013,10 @@ kmip_encode_response_batch_item(KMIP *ctx, const ResponseBatchItem *value) case KMIP_OP_GET: result = kmip_encode_get_response_payload(ctx, (GetResponsePayload*)value->response_payload); break; + + case KMIP_OP_ACTIVATE: + result = kmip_encode_activate_response_payload(ctx, (ActivateResponsePayload*)value->response_payload); + break; case KMIP_OP_DESTROY: result = kmip_encode_destroy_response_payload(ctx, (DestroyResponsePayload*)value->response_payload); @@ -11019,6 +11188,56 @@ kmip_decode_get_response_payload(KMIP *ctx, GetResponsePayload *value) return(KMIP_OK); } +int +kmip_decode_activate_request_payload(KMIP *ctx, ActivateRequestPayload *value) +{ + CHECK_BUFFER_FULL(ctx, 8); + + int result = 0; + int32 tag_type = 0; + uint32 length = 0; + + kmip_decode_int32_be(ctx, &tag_type); + CHECK_TAG_TYPE(ctx, tag_type, KMIP_TAG_REQUEST_PAYLOAD, KMIP_TYPE_STRUCTURE); + + kmip_decode_length(ctx, &length); + CHECK_BUFFER_FULL(ctx, length); + + if(kmip_is_tag_next(ctx, KMIP_TAG_UNIQUE_IDENTIFIER)) + { + value->unique_identifier = ctx->calloc_func(ctx->state, 1, sizeof(TextString)); + CHECK_NEW_MEMORY(ctx, value->unique_identifier, sizeof(TextString), "UniqueIdentifier text string"); + result = kmip_decode_text_string(ctx, KMIP_TAG_UNIQUE_IDENTIFIER, value->unique_identifier); + CHECK_RESULT(ctx, result); + } + + return(KMIP_OK); +} + +int +kmip_decode_activate_response_payload(KMIP *ctx, ActivateResponsePayload *value) +{ + CHECK_BUFFER_FULL(ctx, 8); + + int result = 0; + int32 tag_type = 0; + uint32 length = 0; + + kmip_decode_int32_be(ctx, &tag_type); + CHECK_TAG_TYPE(ctx, tag_type, KMIP_TAG_RESPONSE_PAYLOAD, KMIP_TYPE_STRUCTURE); + + kmip_decode_length(ctx, &length); + CHECK_BUFFER_FULL(ctx, length); + + value->unique_identifier = ctx->calloc_func(ctx->state, 1, sizeof(TextString)); + CHECK_NEW_MEMORY(ctx, value->unique_identifier, sizeof(TextString), "UniqueIdentifier text string"); + + result = kmip_decode_text_string(ctx, KMIP_TAG_UNIQUE_IDENTIFIER, value->unique_identifier); + CHECK_RESULT(ctx, result); + + return(KMIP_OK); +} + int kmip_decode_destroy_request_payload(KMIP *ctx, DestroyRequestPayload *value) { @@ -11201,6 +11420,12 @@ kmip_decode_request_batch_item(KMIP *ctx, RequestBatchItem *value) CHECK_NEW_MEMORY(ctx, value->request_payload, sizeof(GetRequestPayload), "GetRequestPayload structure"); result = kmip_decode_get_request_payload(ctx, (GetRequestPayload*)value->request_payload); break; + + case KMIP_OP_ACTIVATE: + value->request_payload = ctx->calloc_func(ctx->state, 1, sizeof(ActivateRequestPayload)); + CHECK_NEW_MEMORY(ctx, value->request_payload, sizeof(ActivateRequestPayload), "ActivateRequestPayload structure"); + result = kmip_decode_activate_request_payload(ctx, (ActivateRequestPayload*)value->request_payload); + break; case KMIP_OP_DESTROY: value->request_payload = ctx->calloc_func(ctx->state, 1, sizeof(DestroyRequestPayload)); @@ -11306,6 +11531,12 @@ kmip_decode_response_batch_item(KMIP *ctx, ResponseBatchItem *value) result = kmip_decode_get_response_payload(ctx, value->response_payload); break; + + case KMIP_OP_ACTIVATE: + value->response_payload = ctx->calloc_func(ctx->state, 1, sizeof(ActivateResponsePayload)); + CHECK_NEW_MEMORY(ctx, value->response_payload, sizeof(ActivateResponsePayload), "ActivateResponsePayload structure"); + result = kmip_decode_activate_response_payload(ctx, value->response_payload); + break; case KMIP_OP_DESTROY: value->response_payload = ctx->calloc_func(ctx->state, 1, sizeof(DestroyResponsePayload)); diff --git a/src/kmip_bio.c b/src/kmip_bio.c index 69f7cc0..7a4b9b5 100644 --- a/src/kmip_bio.c +++ b/src/kmip_bio.c @@ -437,6 +437,209 @@ int kmip_bio_destroy_symmetric_key(BIO *bio, char *uuid, int uuid_size) return(result); } +int kmip_bio_activate_symmetric_key(BIO *bio, char *uuid, int uuid_size) +{ + if(bio == NULL || uuid == NULL || uuid_size <= 0) + { + return(KMIP_ARG_INVALID); + } + + /* Set up the KMIP context and the initial encoding buffer. */ + KMIP ctx = {0}; + kmip_init(&ctx, NULL, 0, KMIP_1_0); + + size_t buffer_blocks = 1; + size_t buffer_block_size = 1024; + size_t buffer_total_size = buffer_blocks * buffer_block_size; + + uint8 *encoding = ctx.calloc_func(ctx.state, buffer_blocks, + buffer_block_size); + if(encoding == NULL) + { + kmip_destroy(&ctx); + return(KMIP_MEMORY_ALLOC_FAILED); + } + kmip_set_buffer(&ctx, encoding, buffer_total_size); + + /* Build the request message. */ + ProtocolVersion pv = {0}; + kmip_init_protocol_version(&pv, ctx.version); + + RequestHeader rh = {0}; + kmip_init_request_header(&rh); + + rh.protocol_version = &pv; + rh.maximum_response_size = ctx.max_message_size; + rh.time_stamp = time(NULL); + rh.batch_count = 1; + + TextString id = {0}; + id.value = uuid; + id.size = uuid_size; + + ActivateRequestPayload arp = {0}; + arp.unique_identifier = &id; + + RequestBatchItem rbi = {0}; + kmip_init_request_batch_item(&rbi); + rbi.operation = KMIP_OP_ACTIVATE; + rbi.request_payload = &arp; + + RequestMessage rm = {0}; + rm.request_header = &rh; + rm.batch_items = &rbi; + rm.batch_count = 1; + + /* Encode the request message. Dynamically resize the encoding buffer */ + /* if it's not big enough. Once encoding succeeds, send the request */ + /* message. */ + int encode_result = kmip_encode_request_message(&ctx, &rm); + while(encode_result == KMIP_ERROR_BUFFER_FULL) + { + kmip_reset(&ctx); + ctx.free_func(ctx.state, encoding); + + buffer_blocks += 1; + buffer_total_size = buffer_blocks * buffer_block_size; + + encoding = ctx.calloc_func(ctx.state, buffer_blocks, + buffer_block_size); + if(encoding == NULL) + { + kmip_destroy(&ctx); + return(KMIP_MEMORY_ALLOC_FAILED); + } + + kmip_set_buffer( + &ctx, + encoding, + buffer_total_size); + encode_result = kmip_encode_request_message(&ctx, &rm); + } + + if(encode_result != KMIP_OK) + { + kmip_free_buffer(&ctx, encoding, buffer_total_size); + encoding = NULL; + kmip_destroy(&ctx); + return(encode_result); + } + + int sent = BIO_write(bio, ctx.buffer, ctx.index - ctx.buffer); + if(sent != ctx.index - ctx.buffer) + { + kmip_free_buffer(&ctx, encoding, buffer_total_size); + encoding = NULL; + kmip_destroy(&ctx); + return(KMIP_IO_FAILURE); + } + + kmip_free_buffer(&ctx, encoding, buffer_total_size); + encoding = NULL; + + /* Read the response message. Dynamically resize the encoding buffer */ + /* to align with the message size advertised by the message encoding. */ + /* Reject the message if the message size is too large. */ + buffer_blocks = 1; + buffer_block_size = 8; + buffer_total_size = buffer_blocks * buffer_block_size; + + encoding = ctx.calloc_func(ctx.state, buffer_blocks, buffer_block_size); + if(encoding == NULL) + { + kmip_destroy(&ctx); + return(KMIP_MEMORY_ALLOC_FAILED); + } + + int recv = BIO_read(bio, encoding, buffer_total_size); + if((size_t)recv != buffer_total_size) + { + kmip_free_buffer(&ctx, encoding, buffer_total_size); + encoding = NULL; + kmip_destroy(&ctx); + return(KMIP_IO_FAILURE); + } + + kmip_set_buffer(&ctx, encoding, buffer_total_size); + ctx.index += 4; + int length = 0; + + kmip_decode_int32_be(&ctx, &length); + kmip_rewind(&ctx); + if(length > ctx.max_message_size) + { + kmip_free_buffer(&ctx, encoding, buffer_total_size); + encoding = NULL; + kmip_destroy(&ctx); + return(KMIP_EXCEED_MAX_MESSAGE_SIZE); + } + + kmip_set_buffer(&ctx, NULL, 0); + uint8 *extended = ctx.realloc_func(ctx.state, encoding, buffer_total_size + length); + if(extended == NULL) + { + kmip_free_buffer(&ctx, encoding, buffer_total_size); + encoding = NULL; + kmip_destroy(&ctx); + return(KMIP_MEMORY_ALLOC_FAILED); + } + else + { + encoding = extended; + extended = NULL; + } + + ctx.memset_func(encoding + buffer_total_size, 0, length); + + buffer_block_size += length; + buffer_total_size = buffer_blocks * buffer_block_size; + + recv = BIO_read(bio, encoding + 8, length); + if(recv != length) + { + kmip_free_buffer(&ctx, encoding, buffer_total_size); + encoding = NULL; + kmip_destroy(&ctx); + return(KMIP_IO_FAILURE); + } + + kmip_set_buffer(&ctx, encoding, buffer_block_size); + + /* Decode the response message and retrieve the operation result status. */ + ResponseMessage resp_m = {0}; + int decode_result = kmip_decode_response_message(&ctx, &resp_m); + if(decode_result != KMIP_OK) + { + kmip_free_response_message(&ctx, &resp_m); + kmip_free_buffer(&ctx, encoding, buffer_total_size); + encoding = NULL; + kmip_destroy(&ctx); + return(decode_result); + } + + if(resp_m.batch_count != 1 || resp_m.batch_items == NULL) + { + kmip_free_response_message(&ctx, &resp_m); + kmip_free_buffer(&ctx, encoding, buffer_total_size); + encoding = NULL; + kmip_destroy(&ctx); + return(KMIP_MALFORMED_RESPONSE); + } + + ResponseBatchItem resp_item = resp_m.batch_items[0]; + enum result_status result = resp_item.result_status; + + /* Clean up the response message, the encoding buffer, and the KMIP */ + /* context. */ + kmip_free_response_message(&ctx, &resp_m); + kmip_free_buffer(&ctx, encoding, buffer_total_size); + encoding = NULL; + kmip_set_buffer(&ctx, NULL, 0); + kmip_destroy(&ctx); + + return(result); +} + int kmip_bio_get_symmetric_key(BIO *bio, char *id, int id_size, char **key, int *key_size) @@ -1386,6 +1589,210 @@ int kmip_bio_destroy_symmetric_key_with_context(KMIP *ctx, BIO *bio, return(result); } +int kmip_bio_activate_symmetric_key_with_context(KMIP *ctx, BIO *bio, + char *uuid, int uuid_size) +{ + if(ctx == NULL || bio == NULL || uuid == NULL || uuid_size <= 0) + { + return(KMIP_ARG_INVALID); + } + + /* Set up the initial encoding buffer. */ + size_t buffer_blocks = 1; + size_t buffer_block_size = 1024; + size_t buffer_total_size = buffer_blocks * buffer_block_size; + + uint8 *encoding = ctx->calloc_func(ctx->state, buffer_blocks, + buffer_block_size); + if(encoding == NULL) + { + return(KMIP_MEMORY_ALLOC_FAILED); + } + kmip_set_buffer(ctx, encoding, buffer_total_size); + + /* Build the request message. */ + ProtocolVersion pv = {0}; + kmip_init_protocol_version(&pv, ctx->version); + + RequestHeader rh = {0}; + kmip_init_request_header(&rh); + + rh.protocol_version = &pv; + rh.maximum_response_size = ctx->max_message_size; + rh.time_stamp = time(NULL); + rh.batch_count = 1; + + TextString id = {0}; + id.value = uuid; + id.size = uuid_size; + + ActivateRequestPayload arp = {0}; + arp.unique_identifier = &id; + + RequestBatchItem rbi = {0}; + kmip_init_request_batch_item(&rbi); + rbi.operation = KMIP_OP_ACTIVATE; + rbi.request_payload = &arp; + + RequestMessage rm = {0}; + rm.request_header = &rh; + rm.batch_items = &rbi; + rm.batch_count = 1; + + /* Add the context credential to the request message if it exists. */ + /* TODO (ph) Update this to add multiple credentials. */ + Authentication auth = {0}; + if(ctx->credential_list != NULL) + { + LinkedListItem *item = ctx->credential_list->head; + if(item != NULL) + { + auth.credential = (Credential *)item->data; + rh.authentication = &auth; + } + } + + /* Encode the request message. Dynamically resize the encoding buffer */ + /* if it's not big enough. Once encoding succeeds, send the request */ + /* message. */ + int encode_result = kmip_encode_request_message(ctx, &rm); + while(encode_result == KMIP_ERROR_BUFFER_FULL) + { + kmip_reset(ctx); + ctx->free_func(ctx->state, encoding); + + buffer_blocks += 1; + buffer_total_size = buffer_blocks * buffer_block_size; + + encoding = ctx->calloc_func(ctx->state, buffer_blocks, + buffer_block_size); + if(encoding == NULL) + { + kmip_set_buffer(ctx, NULL, 0); + return(KMIP_MEMORY_ALLOC_FAILED); + } + + kmip_set_buffer( + ctx, + encoding, + buffer_total_size); + encode_result = kmip_encode_request_message(ctx, &rm); + } + + if(encode_result != KMIP_OK) + { + kmip_free_buffer(ctx, encoding, buffer_total_size); + encoding = NULL; + kmip_set_buffer(ctx, NULL, 0); + return(encode_result); + } + + int sent = BIO_write(bio, ctx->buffer, ctx->index - ctx->buffer); + if(sent != ctx->index - ctx->buffer) + { + kmip_free_buffer(ctx, encoding, buffer_total_size); + encoding = NULL; + kmip_set_buffer(ctx, NULL, 0); + return(KMIP_IO_FAILURE); + } + + kmip_free_buffer(ctx, encoding, buffer_total_size); + encoding = NULL; + kmip_set_buffer(ctx, NULL, 0); + + /* Read the response message. Dynamically resize the encoding buffer */ + /* to align with the message size advertised by the message encoding. */ + /* Reject the message if the message size is too large. */ + buffer_blocks = 1; + buffer_block_size = 8; + buffer_total_size = buffer_blocks * buffer_block_size; + + encoding = ctx->calloc_func(ctx->state, buffer_blocks, buffer_block_size); + if(encoding == NULL) + { + return(KMIP_MEMORY_ALLOC_FAILED); + } + + int recv = BIO_read(bio, encoding, buffer_total_size); + if((size_t)recv != buffer_total_size) + { + kmip_free_buffer(ctx, encoding, buffer_total_size); + encoding = NULL; + kmip_set_buffer(ctx, NULL, 0); + return(KMIP_IO_FAILURE); + } + + kmip_set_buffer(ctx, encoding, buffer_total_size); + ctx->index += 4; + int length = 0; + + kmip_decode_int32_be(ctx, &length); + kmip_rewind(ctx); + if(length > ctx->max_message_size) + { + kmip_free_buffer(ctx, encoding, buffer_total_size); + encoding = NULL; + kmip_set_buffer(ctx, NULL, 0); + return(KMIP_EXCEED_MAX_MESSAGE_SIZE); + } + + kmip_set_buffer(ctx, NULL, 0); + uint8 *extended = ctx->realloc_func(ctx->state, encoding, + buffer_total_size + length); + if(encoding != extended) + { + encoding = extended; + } + ctx->memset_func(encoding + buffer_total_size, 0, length); + + buffer_block_size += length; + buffer_total_size = buffer_blocks * buffer_block_size; + + recv = BIO_read(bio, encoding + 8, length); + if(recv != length) + { + kmip_free_buffer(ctx, encoding, buffer_total_size); + encoding = NULL; + kmip_set_buffer(ctx, NULL, 0); + return(KMIP_IO_FAILURE); + } + + kmip_set_buffer(ctx, encoding, buffer_block_size); + + /* Decode the response message and retrieve the operation result status. */ + ResponseMessage resp_m = {0}; + int decode_result = kmip_decode_response_message(ctx, &resp_m); + + kmip_set_buffer(ctx, NULL, 0); + + if(decode_result != KMIP_OK) + { + kmip_free_response_message(ctx, &resp_m); + kmip_free_buffer(ctx, encoding, buffer_total_size); + encoding = NULL; + return(decode_result); + } + + if(resp_m.batch_count != 1 || resp_m.batch_items == NULL) + { + kmip_free_response_message(ctx, &resp_m); + kmip_free_buffer(ctx, encoding, buffer_total_size); + encoding = NULL; + return(KMIP_MALFORMED_RESPONSE); + } + + ResponseBatchItem resp_item = resp_m.batch_items[0]; + enum result_status result = resp_item.result_status; + + /* Clean up the response message and the encoding buffer. */ + kmip_free_response_message(ctx, &resp_m); + kmip_free_buffer(ctx, encoding, buffer_total_size); + encoding = NULL; + kmip_set_buffer(ctx, NULL, 0); + + return(result); +} + int kmip_bio_send_request_encoding(KMIP *ctx, BIO *bio, char *request, int request_size, char **response, int *response_size) diff --git a/src/kmip_io.c b/src/kmip_io.c index d49bad4..d2d6676 100644 --- a/src/kmip_io.c +++ b/src/kmip_io.c @@ -2806,6 +2806,29 @@ kmip_print_get_response_payload(FILE *f, int indent, GetResponsePayload *value) } return; + +} + +void +kmip_print_activate_request_payload(FILE *f, int indent, ActivateRequestPayload *value) +{ + fprintf(f, "%*sActivate Request Payload @ %p\n", indent, "", (void *)value); + + if(value != NULL) + { + kmip_print_text_string(f, indent + 2, "Unique Identifier", value->unique_identifier); + } +} + +void +kmip_print_activate_response_payload(FILE *f, int indent, ActivateResponsePayload *value) +{ + fprintf(f, "%*sActivate Response Payload @ %p\n", indent, "", (void *)value); + + if(value != NULL) + { + kmip_print_text_string(f, indent + 2, "Unique Identifier", value->unique_identifier); + } } void @@ -2843,10 +2866,14 @@ kmip_print_request_payload(FILE *f, int indent, enum operation type, void *value kmip_print_get_request_payload(f, indent, (GetRequestPayload *)value); break; + case KMIP_OP_ACTIVATE: + kmip_print_activate_request_payload(f, indent, value); + break; + case KMIP_OP_DESTROY: kmip_print_destroy_request_payload(f, indent, value); break; - + case KMIP_OP_QUERY: kmip_print_query_request_payload(f, indent, value); break; @@ -2874,6 +2901,10 @@ kmip_print_response_payload(FILE *f, int indent, enum operation type, void *valu kmip_print_get_response_payload(f, indent, (GetResponsePayload *)value); break; + case KMIP_OP_ACTIVATE: + kmip_print_activate_response_payload(f, indent, value); + break; + case KMIP_OP_DESTROY: kmip_print_destroy_response_payload(f, indent, value); break; diff --git a/tests/tests.c b/tests/tests.c index d402531..256e16c 100644 --- a/tests/tests.c +++ b/tests/tests.c @@ -7287,6 +7287,167 @@ test_decode_destroy_response_payload(TestTracker *tracker) return(result); } +int +test_encode_activate_request_payload(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + // Tag: Request Payload (0x420079), Type: Structure (0x01), Data: + // Tag: Unique Identifier (0x420094), Type: Text String (0x07), Data: 668eff89-3010-4258-bc0e-8c402309c746 + + uint8 expected[56] = { + 0x42, 0x00, 0x79, 0x01, 0x00, 0x00, 0x00, 0x30, + 0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, + 0x36, 0x36, 0x38, 0x65, 0x66, 0x66, 0x38, 0x39, + 0x2D, 0x33, 0x30, 0x31, 0x30, 0x2D, 0x34, 0x32, + 0x35, 0x38, 0x2D, 0x62, 0x63, 0x30, 0x65, 0x2D, + 0x38, 0x63, 0x34, 0x30, 0x32, 0x33, 0x30, 0x39, + 0x63, 0x37, 0x34, 0x36, 0x00, 0x00, 0x00, 0x00, + }; + + uint8 observed[56] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0); + + struct text_string uuid = {0}; + uuid.value = "668eff89-3010-4258-bc0e-8c402309c746"; + uuid.size = 36; + + struct activate_request_payload arp = {0}; + arp.unique_identifier = &uuid; + + int result = kmip_encode_activate_request_payload(&ctx, &arp); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_decode_activate_request_payload(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[56] = { + 0x42, 0x00, 0x79, 0x01, 0x00, 0x00, 0x00, 0x30, + 0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, + 0x36, 0x36, 0x38, 0x65, 0x66, 0x66, 0x38, 0x39, + 0x2D, 0x33, 0x30, 0x31, 0x30, 0x2D, 0x34, 0x32, + 0x35, 0x38, 0x2D, 0x62, 0x63, 0x30, 0x65, 0x2D, + 0x38, 0x63, 0x34, 0x30, 0x32, 0x33, 0x30, 0x39, + 0x63, 0x37, 0x34, 0x36, 0x00, 0x00, 0x00, 0x00, + }; + + struct kmip ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0); + + struct text_string uuid = {0}; + uuid.value = "668eff89-3010-4258-bc0e-8c402309c746"; + uuid.size = 36; + + struct activate_request_payload expected = {0}; + expected.unique_identifier = &uuid; + + struct activate_request_payload observed = {0}; + + int result = kmip_decode_activate_request_payload(&ctx, &observed); + result = report_decoding_test_result( + tracker, + &ctx, + kmip_compare_activate_request_payload(&expected, &observed), + result, + __func__); + kmip_free_activate_request_payload(&ctx, &observed); + kmip_destroy(&ctx); + return(result); +} + +int +test_encode_activate_response_payload(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + // Tag: Response Payload (0x42007C), Type: Structure (0x01), Data: + // Tag: Unique Identifier (0x420094), Type: Text String (0x07), Data: 668eff89-3010-4258-bc0e-8c402309c746 + + uint8 expected[56] = { + 0x42, 0x00, 0x7C, 0x01, 0x00, 0x00, 0x00, 0x30, + 0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, + 0x36, 0x36, 0x38, 0x65, 0x66, 0x66, 0x38, 0x39, + 0x2D, 0x33, 0x30, 0x31, 0x30, 0x2D, 0x34, 0x32, + 0x35, 0x38, 0x2D, 0x62, 0x63, 0x30, 0x65, 0x2D, + 0x38, 0x63, 0x34, 0x30, 0x32, 0x33, 0x30, 0x39, + 0x63, 0x37, 0x34, 0x36, 0x00, 0x00, 0x00, 0x00, + }; + + uint8 observed[56] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0); + + struct text_string uuid = {0}; + uuid.value = "668eff89-3010-4258-bc0e-8c402309c746"; + uuid.size = 36; + + struct activate_response_payload drp = {0}; + drp.unique_identifier = &uuid; + + int result = kmip_encode_activate_response_payload(&ctx, &drp); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_decode_activate_response_payload(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[56] = { + 0x42, 0x00, 0x7C, 0x01, 0x00, 0x00, 0x00, 0x30, + 0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, + 0x36, 0x36, 0x38, 0x65, 0x66, 0x66, 0x38, 0x39, + 0x2D, 0x33, 0x30, 0x31, 0x30, 0x2D, 0x34, 0x32, + 0x35, 0x38, 0x2D, 0x62, 0x63, 0x30, 0x65, 0x2D, + 0x38, 0x63, 0x34, 0x30, 0x32, 0x33, 0x30, 0x39, + 0x63, 0x37, 0x34, 0x36, 0x00, 0x00, 0x00, 0x00, + }; + + struct kmip ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0); + + struct text_string uuid = {0}; + uuid.value = "668eff89-3010-4258-bc0e-8c402309c746"; + uuid.size = 36; + + struct activate_response_payload expected = {0}; + expected.unique_identifier = &uuid; + + struct activate_response_payload observed = {0}; + + int result = kmip_decode_activate_response_payload(&ctx, &observed); + result = report_decoding_test_result( + tracker, + &ctx, + kmip_compare_activate_response_payload(&expected, &observed), + result, + __func__); + kmip_free_activate_response_payload(&ctx, &observed); + kmip_destroy(&ctx); + return(result); +} + + int test_encode_username_password_credential(TestTracker *tracker) { @@ -14232,6 +14393,8 @@ run_tests(void) test_decode_create_response_payload_with_template_attribute(&tracker); test_decode_get_request_payload(&tracker); test_decode_get_response_payload(&tracker); + test_decode_activate_request_payload(&tracker); + test_decode_activate_response_payload(&tracker); test_decode_destroy_request_payload(&tracker); test_decode_destroy_response_payload(&tracker); test_decode_response_batch_item_get_payload(&tracker); @@ -14304,6 +14467,8 @@ run_tests(void) test_encode_get_request_payload_with_format_compression(&tracker); test_encode_get_request_payload_with_wrapping_spec(&tracker); test_encode_get_response_payload(&tracker); + test_encode_activate_response_payload(&tracker); + test_encode_activate_request_payload(&tracker); test_encode_destroy_request_payload(&tracker); test_encode_destroy_response_payload(&tracker); test_encode_username_password_credential(&tracker);