diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:45:59 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:45:59 +0000 |
commit | 19fcec84d8d7d21e796c7624e521b60d28ee21ed (patch) | |
tree | 42d26aa27d1e3f7c0b8bd3fd14e7d7082f5008dc /src/libkmip | |
parent | Initial commit. (diff) | |
download | ceph-upstream.tar.xz ceph-upstream.zip |
Adding upstream version 16.2.11+ds.upstream/16.2.11+dsupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/libkmip')
32 files changed, 34150 insertions, 0 deletions
diff --git a/src/libkmip/.gitignore b/src/libkmip/.gitignore new file mode 100644 index 000000000..801c00a68 --- /dev/null +++ b/src/libkmip/.gitignore @@ -0,0 +1,8 @@ +*.o +*.lo +*.a +*.so.* +demo_create +demo_destroy +demo_get +tests diff --git a/src/libkmip/.travis.yml b/src/libkmip/.travis.yml new file mode 100644 index 000000000..399e2808c --- /dev/null +++ b/src/libkmip/.travis.yml @@ -0,0 +1,23 @@ +sudo: true + +language: c + +compiler: + - clang + - gcc + +os: linux +dist: xenial + +before_install: + - mkdir -p ~/build/openssl + - curl -s https://www.openssl.org/source/openssl-1.1.0i.tar.gz | tar -C ~/build/openssl -xzf - + - pushd ~/build/openssl/openssl-1.1.0i + - ./Configure enable-crypto-mdebug enable-crypto-mdebug-backtrace linux-x86_64 + - make &> ~/build/openssl/openssl-1.1.0i-make.log + - sudo make install &> ~/build/openssl/openssl-1.1.0i-make-install.log + - popd + +script: + - make && sudo make install + - make test diff --git a/src/libkmip/CHANGELOG.rst b/src/libkmip/CHANGELOG.rst new file mode 100644 index 000000000..841fc843a --- /dev/null +++ b/src/libkmip/CHANGELOG.rst @@ -0,0 +1,36 @@ +========= +Changelog +========= + +.. _v0.2: + +0.2 - July 12, 2019 +~~~~~~~~~~~~~~~~~~~ + +* Add the BSD 3-clause license to the library +* Add KMIP 2.0 attributes +* Add deep copy utilities for all attribute types +* Upgrade Create support to enable KMIP 2.0 encodings +* Upgrade the unit test suite to use intelligent test tracking +* Upgrade the linked list to support enqueue and double linkage +* Fix an implicit infinite loop in the test suite application +* Fix a usage issue when passing no args to the demo applications +* Fix Travis CI config to redirect OpenSSL install logs to a file + +.. _v0.1: + +0.1 - November 15, 2018 +~~~~~~~~~~~~~~~~~~~~~~~ + +* Initial release +* Add encoding/decoding support for Symmetric/Public/Private Keys +* Add encoding/decoding support for Create/Get/Destroy operations +* Add KMIP 1.0 - 1.4 support for all supported KMIP structures +* Add an OpenSSL BIO client to securely connect to KMIP servers +* Add demo applications that show how to use the client API +* Add a unit test suite that covers the encoding/decoding library +* Add library documentation built and managed by Sphinx +* Add a Makefile that can build/install static/shared libraries + +.. _`master`: https://github.com/OpenKMIP/libkmip/ + diff --git a/src/libkmip/CMakeLists.txt b/src/libkmip/CMakeLists.txt new file mode 100644 index 000000000..af24fba3b --- /dev/null +++ b/src/libkmip/CMakeLists.txt @@ -0,0 +1,10 @@ +set(libkmip_srcs + kmip.c + kmip_memset.c + kmip_bio.c) + +add_library(kmip STATIC ${libkmip_srcs}) + +IF (CMAKE_SYSTEM_NAME STREQUAL "Linux") + LIST (APPEND SYSFLAGS -D_POSIX_C_SOURCE=1) +ENDIF () diff --git a/src/libkmip/LICENSE b/src/libkmip/LICENSE new file mode 100644 index 000000000..55de2da79 --- /dev/null +++ b/src/libkmip/LICENSE @@ -0,0 +1,3 @@ +libkmip is made available under the terms of either license found in +LICENSE.APACHE or LICENSE.BSD. Contributions to libkmip are made under the +terms of both licenses. diff --git a/src/libkmip/LICENSE.APACHE b/src/libkmip/LICENSE.APACHE new file mode 100644 index 000000000..261eeb9e9 --- /dev/null +++ b/src/libkmip/LICENSE.APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/src/libkmip/LICENSE.BSD b/src/libkmip/LICENSE.BSD new file mode 100644 index 000000000..0d183e08e --- /dev/null +++ b/src/libkmip/LICENSE.BSD @@ -0,0 +1,27 @@ +Copyright (c) 2019 The Johns Hopkins University/Applied Physics Laboratory +All Rights Reserved + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors +may be used to endorse or promote products derived from this software without +specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/src/libkmip/Makefile b/src/libkmip/Makefile new file mode 100644 index 000000000..7da1d84ba --- /dev/null +++ b/src/libkmip/Makefile @@ -0,0 +1,117 @@ +## +## Makefile for libkmip +## +.POSIX: +.SUFFIXES: + +SRCDIR = . +BINDIR = $(SRCDIR)/bin + +MAJOR = 0 +MINOR = 2 +MICRO = 0 +VERSION = $(MAJOR).$(MINOR) +ARCNAME = libkmip.a +LINKNAME = libkmip.so +SONAME = $(LINKNAME).$(MAJOR) +LIBNAME = $(LINKNAME).$(VERSION) +LIBS = $(LIBNAME) $(ARCNAME) + +CC = cc +#CFLAGS = -std=c11 -pedantic -g3 -Og -Wall -Wextra -D_POSIX_C_SOURCE +CFLAGS = -std=c11 -pedantic -g3 -Wall -Wextra -D_POSIX_C_SOURCE +LOFLAGS = -fPIC +SOFLAGS = -shared -Wl,-soname,$(SONAME) +LDFLAGS = -L/usr/local/lib +LDLIBS = -lssl -lcrypto +AR = ar csrv +DESTDIR = +PREFIX = /usr/local +KMIP = kmip + +OFILES = kmip.o kmip_memset.o kmip_bio.o +LOFILES = kmip.lo kmip_memset.lo kmip_bio.lo + +all: demos tests $(LIBS) + +test: tests + $(SRCDIR)/tests + +install: all + mkdir -p $(DESTDIR)$(PREFIX)/bin/$(KMIP) + mkdir -p $(DESTDIR)$(PREFIX)/include/$(KMIP) + mkdir -p $(DESTDIR)$(PREFIX)/lib + mkdir -p $(DESTDIR)$(PREFIX)/src/$(KMIP) + mkdir -p $(DESTDIR)$(PREFIX)/share/doc/$(KMIP)/src + cp demo_create $(DESTDIR)$(PREFIX)/bin/$(KMIP) + cp demo_get $(DESTDIR)$(PREFIX)/bin/$(KMIP) + cp demo_destroy $(DESTDIR)$(PREFIX)/bin/$(KMIP) + cp tests $(DESTDIR)$(PREFIX)/bin/$(KMIP) + cp -r $(SRCDIR)/docs/source/. $(DESTDIR)$(PREFIX)/share/doc/$(KMIP)/src + cp $(SRCDIR)/*.c $(DESTDIR)$(PREFIX)/src/$(KMIP) + cp $(SRCDIR)/*.h $(DESTDIR)$(PREFIX)/include/$(KMIP) + cp $(SRCDIR)/$(LIBNAME) $(DESTDIR)$(PREFIX)/lib + cp $(SRCDIR)/$(ARCNAME) $(DESTDIR)$(PREFIX)/lib + cd $(DESTDIR)$(PREFIX)/lib && ln -sf $(LIBNAME) $(LINKNAME) && cd - + +install_html_docs: html_docs + mkdir -p $(DESTDIR)$(PREFIX)/share/doc/$(KMIP)/html + cp -r $(SRCDIR)/docs/build/html/. $(DESTDIR)$(PREFIX)/share/doc/$(KMIP)/html + +uninstall: + rm -rf $(DESTDIR)$(PREFIX)/bin/$(KMIP) + rm -rf $(DESTDIR)$(PREFIX)/include/$(KMIP) + rm -rf $(DESTDIR)$(PREFIX)/src/$(KMIP) + rm -rf $(DESTDIR)$(PREFIX)/share/doc/$(KMIP) + rm -r $(DESTDIR)$(PREFIX)/lib/$(LINKNAME)* + rm -r $(DESTDIR)$(PREFIX)/lib/$(ARCNAME) + +uninstall_html_docs: + rm -rf $(DESTDIR)$(PREFIX)/share/doc/$(KMIP)/html + +docs: html_docs +html_docs: + cd $(SRCDIR)/docs && make html && cd - +demos: demo_create demo_get demo_destroy +demo_get: demo_get.o $(OFILES) + $(CC) $(LDFLAGS) -o demo_get demo_get.o $(OFILES) $(LDLIBS) +demo_create: demo_create.o $(OFILES) + $(CC) $(LDFLAGS) -o demo_create demo_create.o $(OFILES) $(LDLIBS) +demo_destroy: demo_destroy.o $(OFILES) + $(CC) $(LDFLAGS) -o demo_destroy demo_destroy.o $(OFILES) $(LDLIBS) +tests: tests.o kmip.o kmip_memset.o + $(CC) $(LDFLAGS) -o tests tests.o kmip.o kmip_memset.o + +demo_get.o: demo_get.c kmip_memset.h kmip.h +demo_create.o: demo_create.c kmip_memset.h kmip.h +demo_destroy.o: demo_destroy.c kmip_memset.h kmip.h +tests.o: tests.c kmip_memset.h kmip.h +$(LIBNAME): $(LOFILES) + $(CC) $(CFLAGS) $(SOFLAGS) -o $@ $(LOFILES) +$(ARCNAME): $(OFILES) + $(AR) $@ $(OFILES) + +kmip.o: kmip.c kmip.h kmip_memset.h +kmip.lo: kmip.c kmip.h kmip_memset.h + +kmip_memset.o: kmip_memset.c kmip_memset.h +kmip_memset.lo: kmip_memset.c kmip_memset.h + +kmip_bio.o: kmip_bio.c kmip_bio.h +kmip_bio.lo: kmip_bio.c kmip_bio.h + +clean: + rm -f *.o *.lo +clean_html_docs: + cd docs && make clean && cd .. +cleanest: + rm -f demo_create demo_get demo_destroy tests *.o $(LOFILES) $(LIBS) + cd docs && make clean && cd .. + +.SUFFIXES: .c .o .lo .so +.c.o: + $(CC) $(CFLAGS) -c $< +.c.lo: + $(CC) $(CFLAGS) $(LOFLAGS) -c $< -o $@ +#.lo.so: +# $(CC) $(CFLAGS) $(SOFLAGS) -o $@ $? diff --git a/src/libkmip/README.md b/src/libkmip/README.md new file mode 100644 index 000000000..af882d960 --- /dev/null +++ b/src/libkmip/README.md @@ -0,0 +1,35 @@ +# libkmip + +libkmip is an ISO C11 implementation of the Key Management Interoperability +Protocol (KMIP), an [OASIS][oasis] communication standard for the management +of objects stored and maintained by key management systems. KMIP defines how +key management operations and operation data should be encoded and +communicated, between client and server applications. Supported operations +include creating, retrieving, and destroying keys. Supported object types +include: + +* symmetric and asymmetric encryption keys + +For more information on KMIP, check out the +[OASIS KMIP Technical Committee][kmip] and the +[OASIS KMIP Documentation][spec]. + +For more information on libkmip, check out the project [Documentation][docs]. + +## Installation + +You can install libkmip from source using `make`: + +``` +$ cd libkmip +$ make +$ make install +``` + +See [Installation][install] for more information. + +[docs]: https://libkmip.readthedocs.io/en/latest/index.html +[install]: https://libkmip.readthedocs.io/en/latest/installation.html +[kmip]: https://www.oasis-open.org/committees/tc_home.php?wg_abbrev=kmip +[oasis]: https://www.oasis-open.org +[spec]: https://docs.oasis-open.org/kmip/spec diff --git a/src/libkmip/demo_create.c b/src/libkmip/demo_create.c new file mode 100644 index 000000000..dabb36ebb --- /dev/null +++ b/src/libkmip/demo_create.c @@ -0,0 +1,371 @@ +/* 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 <openssl/err.h> +#include <openssl/ssl.h> +#include <stdio.h> +#include <string.h> +#include <time.h> + +#include "kmip.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"); +} + +int +parse_arguments(int argc, char **argv, + char **server_address, char **server_port, + char **client_certificate, char **client_key, char **ca_certificate, + 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 + { + printf("Invalid option: '%s'\n", argv[i]); + print_help(argv[0]); + return(-1); + } + } + + return(0); +} + +int +use_low_level_api(const char *server_address, + const char *server_port, + const char *client_certificate, + const char *client_key, + const char *ca_certificate) +{ + /* 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 certificate 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); + } + + 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); + + size_t buffer_blocks = 1; + size_t buffer_block_size = 1024; + size_t buffer_total_size = buffer_blocks * buffer_block_size; + + uint8 *encoding = kmip_context.calloc_func(kmip_context.state, buffer_blocks, buffer_block_size); + if(encoding == NULL) + { + kmip_destroy(&kmip_context); + BIO_free_all(bio); + SSL_CTX_free(ctx); + return(KMIP_MEMORY_ALLOC_FAILED); + } + kmip_set_buffer(&kmip_context, encoding, buffer_total_size); + + /* Build the request message. */ + Attribute a[3] = {0}; + for(int i = 0; i < 3; i++) + kmip_init_attribute(&a[i]); + + enum cryptographic_algorithm algorithm = KMIP_CRYPTOALG_AES; + a[0].type = KMIP_ATTR_CRYPTOGRAPHIC_ALGORITHM; + a[0].value = &algorithm; + + int32 length = 256; + a[1].type = KMIP_ATTR_CRYPTOGRAPHIC_LENGTH; + a[1].value = &length; + + int32 mask = KMIP_CRYPTOMASK_ENCRYPT | KMIP_CRYPTOMASK_DECRYPT; + a[2].type = KMIP_ATTR_CRYPTOGRAPHIC_USAGE_MASK; + a[2].value = &mask; + + TemplateAttribute ta = {0}; + ta.attributes = a; + ta.attribute_count = ARRAY_LENGTH(a); + + ProtocolVersion pv = {0}; + kmip_init_protocol_version(&pv, kmip_context.version); + + RequestHeader rh = {0}; + kmip_init_request_header(&rh); + + rh.protocol_version = &pv; + rh.maximum_response_size = kmip_context.max_message_size; + rh.time_stamp = time(NULL); + rh.batch_count = 1; + + CreateRequestPayload crp = {0}; + crp.object_type = KMIP_OBJTYPE_SYMMETRIC_KEY; + crp.template_attribute = &ta; + + RequestBatchItem rbi = {0}; + kmip_init_request_batch_item(&rbi); + rbi.operation = KMIP_OP_CREATE; + rbi.request_payload = &crp; + + 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(&kmip_context, &rm); + while(encode_result == KMIP_ERROR_BUFFER_FULL) + { + kmip_reset(&kmip_context); + kmip_context.free_func(kmip_context.state, encoding); + + buffer_blocks += 1; + buffer_total_size = buffer_blocks * buffer_block_size; + + encoding = kmip_context.calloc_func(kmip_context.state, buffer_blocks, buffer_block_size); + if(encoding == NULL) + { + printf("Failure: Could not automatically enlarge the encoding "); + printf("buffer for the Create request.\n"); + + kmip_destroy(&kmip_context); + BIO_free_all(bio); + SSL_CTX_free(ctx); + return(KMIP_MEMORY_ALLOC_FAILED); + } + + kmip_set_buffer(&kmip_context, encoding, buffer_total_size); + encode_result = kmip_encode_request_message(&kmip_context, &rm); + } + + if(encode_result != KMIP_OK) + { + printf("An error occurred while encoding the Create request.\n"); + printf("Error Code: %d\n", encode_result); + printf("Error Name: "); + kmip_print_error_string(encode_result); + printf("\n"); + printf("Context Error: %s\n", kmip_context.error_message); + printf("Stack trace:\n"); + kmip_print_stack_trace(&kmip_context); + + kmip_free_buffer(&kmip_context, encoding, buffer_total_size); + encoding = NULL; + kmip_set_buffer(&kmip_context, NULL, 0); + kmip_destroy(&kmip_context); + BIO_free_all(bio); + SSL_CTX_free(ctx); + return(encode_result); + } + + kmip_print_request_message(&rm); + printf("\n"); + + char *response = NULL; + int response_size = 0; + + int result = kmip_bio_send_request_encoding(&kmip_context, bio, (char *)encoding, kmip_context.index - kmip_context.buffer, &response, &response_size); + + BIO_free_all(bio); + SSL_CTX_free(ctx); + + printf("\n"); + if(result < 0) + { + printf("An error occurred while creating the symmetric key.\n"); + printf("Error Code: %d\n", result); + printf("Error Name: "); + kmip_print_error_string(result); + printf("\n"); + printf("Context Error: %s\n", kmip_context.error_message); + printf("Stack trace:\n"); + kmip_print_stack_trace(&kmip_context); + + kmip_free_buffer(&kmip_context, encoding, buffer_total_size); + kmip_free_buffer(&kmip_context, response, response_size); + encoding = NULL; + response = NULL; + kmip_set_buffer(&kmip_context, NULL, 0); + kmip_destroy(&kmip_context); + return(result); + } + + kmip_free_buffer(&kmip_context, encoding, buffer_total_size); + encoding = NULL; + kmip_set_buffer(&kmip_context, response, response_size); + + /* Decode the response message and retrieve the operation results. */ + ResponseMessage resp_m = {0}; + int decode_result = kmip_decode_response_message(&kmip_context, &resp_m); + if(decode_result != KMIP_OK) + { + printf("An error occurred while decoding the Create response.\n"); + printf("Error Code: %d\n", decode_result); + printf("Error Name: "); + kmip_print_error_string(decode_result); + printf("\n"); + printf("Context Error: %s\n", kmip_context.error_message); + printf("Stack trace:\n"); + kmip_print_stack_trace(&kmip_context); + + kmip_free_response_message(&kmip_context, &resp_m); + kmip_free_buffer(&kmip_context, response, response_size); + response = NULL; + kmip_set_buffer(&kmip_context, NULL, 0); + kmip_destroy(&kmip_context); + return(decode_result); + } + + kmip_print_response_message(&resp_m); + printf("\n"); + + if(resp_m.batch_count != 1 || resp_m.batch_items == NULL) + { + printf("Expected to find one batch item in the Create response.\n"); + kmip_free_response_message(&kmip_context, &resp_m); + kmip_free_buffer(&kmip_context, response, response_size); + response = NULL; + kmip_set_buffer(&kmip_context, NULL, 0); + kmip_destroy(&kmip_context); + 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(result); + printf(" (%d)\n\n", result); + + if(result == KMIP_STATUS_SUCCESS) + { + CreateResponsePayload *pld = (CreateResponsePayload *)req.response_payload; + if(pld != NULL) + { + TextString *uuid = pld->unique_identifier; + + if(uuid != NULL) + printf("Symmetric Key ID: %.*s\n", (int)uuid->size, uuid->value); + } + } + + /* Clean up the response message, the response buffer, and the KMIP */ + /* context. */ + kmip_free_response_message(&kmip_context, &resp_m); + kmip_free_buffer(&kmip_context, response, response_size); + response = NULL; + kmip_set_buffer(&kmip_context, NULL, 0); + kmip_destroy(&kmip_context); + + return(result_status); +} + +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; + int help = 0; + + int error = parse_arguments(argc, argv, &server_address, &server_port, &client_certificate, &client_key, &ca_certificate, &help); + if(error) + return(error); + if(help) + { + print_help(argv[0]); + return(0); + } + + use_low_level_api(server_address, server_port, client_certificate, client_key, ca_certificate); + return(0); +} diff --git a/src/libkmip/demo_destroy.c b/src/libkmip/demo_destroy.c new file mode 100644 index 000000000..f97f5e6ae --- /dev/null +++ b/src/libkmip/demo_destroy.c @@ -0,0 +1,199 @@ +/* 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 <openssl/err.h> +#include <openssl/ssl.h> +#include <stdio.h> +#include <string.h> +#include <time.h> + +#include "kmip.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 destroy\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(const char *server_address, + const char *server_port, + const char *client_certificate, + const char *client_key, + const char *ca_certificate, + char *id) +{ + /* 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); + } + + /* Send the request message. */ + int result = kmip_bio_destroy_symmetric_key(bio, id, kmip_strnlen_s(id, 50)); + + BIO_free_all(bio); + SSL_CTX_free(ctx); + + /* Handle the response results. */ + printf("\n"); + if(result < 0) + { + printf("An error occurred while deleting 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(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); + } + + int result = use_high_level_api(server_address, server_port, client_certificate, client_key, ca_certificate, id); + return(result); +} diff --git a/src/libkmip/demo_get.c b/src/libkmip/demo_get.c new file mode 100644 index 000000000..16f8afef8 --- /dev/null +++ b/src/libkmip/demo_get.c @@ -0,0 +1,303 @@ +/* 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 <openssl/err.h> +#include <openssl/ssl.h> +#include <stdio.h> +#include <string.h> +#include <time.h> + +#include "kmip.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("-i id : the ID of the symmetric key to retrieve\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("-s pass : the password for KMIP server authentication\n"); + printf("-u user : the username for KMIP server authentication\n"); +} + +int +parse_arguments(int argc, char **argv, + char **server_address, char **server_port, + char **client_certificate, char **client_key, char **ca_certificate, + char **username, char **password, + 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 if(strncmp(argv[i], "-s", 2) == 0) + { + *password = argv[++i]; + } + else if(strncmp(argv[i], "-u", 2) == 0) + { + *username = 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) +{ + printf("demo_calloc called: state = %p, num = %zu, size = %zu\n", state, num, size); + return(calloc(num, size)); +} + +void * +demo_realloc(void *state, void *ptr, size_t size) +{ + printf("demo_realloc called: state = %p, ptr = %p, size = %zu\n", state, ptr, size); + return(realloc(ptr, size)); +} + +void +demo_free(void *state, void *ptr) +{ + printf("demo_free called: state = %p, ptr = %p\n", state, ptr); + free(ptr); + return; +} + +int +use_mid_level_api(char *server_address, + char *server_port, + char *client_certificate, + char *client_key, + char *ca_certificate, + char *username, + char *password, + char *id) +{ + /* 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) + { + printf("BIO_new_ssl_connect failed\n"); + 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); + } + + printf("\n"); + + char *key = NULL; + int key_size = 0; + size_t id_size = kmip_strnlen_s(id, 50); + + /* Set up the KMIP context and send the request message. */ + KMIP kmip_context = {0}; + + kmip_context.calloc_func = &demo_calloc; + kmip_context.realloc_func = &demo_realloc; + kmip_context.free_func = &demo_free; + + kmip_init(&kmip_context, NULL, 0, KMIP_1_0); + + TextString u = {0}; + u.value = username; + u.size = kmip_strnlen_s(username, 50); + + TextString p = {0}; + p.value = password; + p.size = kmip_strnlen_s(password, 50); + + UsernamePasswordCredential upc = {0}; + upc.username = &u; + upc.password = &p; + + Credential credential = {0}; + credential.credential_type = KMIP_CRED_USERNAME_AND_PASSWORD; + credential.credential_value = &upc; + + int result = kmip_add_credential(&kmip_context, &credential); + + if(result != KMIP_OK) + { + printf("Failed to add credential to the KMIP context.\n"); + BIO_free_all(bio); + SSL_CTX_free(ctx); + kmip_destroy(&kmip_context); + return(result); + } + + result = kmip_bio_get_symmetric_key_with_context(&kmip_context, bio, id, id_size, &key, &key_size); + + BIO_free_all(bio); + SSL_CTX_free(ctx); + + /* Handle the response results. */ + printf("\n"); + if(result < 0) + { + printf("An error occurred while creating the symmetric key."); + printf("Error Code: %d\n", result); + printf("Error Name: "); + kmip_print_error_string(result); + printf("\n"); + printf("Context Error: %s\n", kmip_context.error_message); + printf("Stack trace:\n"); + kmip_print_stack_trace(&kmip_context); + } + else if(result >= 0) + { + printf("The KMIP operation was executed with no errors.\n"); + printf("Result: "); + kmip_print_result_status_enum(result); + printf(" (%d)\n", result); + + if(result == KMIP_STATUS_SUCCESS) + { + printf("Symmetric Key ID: %s\n", id); + printf("Symmetric Key Size: %d bits\n", key_size * 8); + printf("Symmetric Key:"); + kmip_print_buffer(key, key_size); + printf("\n"); + } + } + + printf("\n"); + + if(key != NULL) + { + kmip_memset(key, 0, key_size); + kmip_free(NULL, key); + } + + /* Clean up the KMIP context and return the results. */ + 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 *username = NULL; + char *password = NULL; + char *id = NULL; + int help = 0; + + int error = parse_arguments(argc, argv, &server_address, &server_port, &client_certificate, &client_key, &ca_certificate, &username, &password, &id, &help); + if(error) + { + return(error); + } + if(help) + { + print_help(argv[0]); + return(0); + } + + int result = use_mid_level_api(server_address, server_port, client_certificate, client_key, ca_certificate, username, password, id); + return(result); +} diff --git a/src/libkmip/doc-requirements.txt b/src/libkmip/doc-requirements.txt new file mode 100644 index 000000000..9cf821c49 --- /dev/null +++ b/src/libkmip/doc-requirements.txt @@ -0,0 +1,4 @@ +sphinx>=1.6.4 +sphinx_rtd_theme>=0.2.4 + + diff --git a/src/libkmip/docs/Makefile b/src/libkmip/docs/Makefile new file mode 100644 index 000000000..e6e3d88a4 --- /dev/null +++ b/src/libkmip/docs/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = python -msphinx +SPHINXPROJ = libkmip +SOURCEDIR = source +BUILDDIR = build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
\ No newline at end of file diff --git a/src/libkmip/docs/source/_static/.keep b/src/libkmip/docs/source/_static/.keep new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/src/libkmip/docs/source/_static/.keep diff --git a/src/libkmip/docs/source/api.rst b/src/libkmip/docs/source/api.rst new file mode 100644 index 000000000..c97e9281e --- /dev/null +++ b/src/libkmip/docs/source/api.rst @@ -0,0 +1,1187 @@ +API +=== +libkmip is composed of several components: + +* an encoding/decoding library +* a client library +* a utilities library + +The encoding library transforms KMIP message structures to and from the KMIP +binary TTLV encoding format. The client library uses the `OpenSSL BIO library`_ +to create secure connections with a KMIP server, sending and receiving +TTLV-encoded messages. Finally, the utilities library is used to create and +manage the library context and its associated structures which are used by the +client library. Together, these components can be used to conduct secure key +management operations. + +.. _client-api: + +Client API +---------- +The libkmip Client API supports varying levels of granularity, allowing parent +applications access to everything from the low-level encoded message buffer +up to high-level KMIP operation functions that handle all of the message +building and encoding details automatically. + +The following function signatures define the client API and can be found in +``kmip_bio.h``: + +.. code-block:: c + + /* High-level 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); + + /* Mid-level API */ + 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 *, size_t); + + /* Low-level API */ + int kmip_bio_send_request_encoding(KMIP *, BIO *, char *, int, char **, int *); + +.. _high-level-api: + +High-level API +~~~~~~~~~~~~~~ +The high-level client API contains KMIP operation functions that simply +require the inputs for a specific KMIP operation. Using these functions, the +library will automatically: + +* create the libkmip library context (see :ref:`the-libkmip-context`) +* create the request message structure +* encode the request message structure into a request encoding +* send the request encoding to the BIO-connected KMIP server +* receive the response encoding back from the BIO-connected KMIP server +* decode the response encoding into the response message structure +* extract the relevant output from the response message structure +* clean up the library context and the encoding buffers +* handle any errors that occur throughout the request/response process + +Because the library context and encoding processes are handled internally, the +parent application has no access to additional debugging or error information +when the KMIP operation fails. There is also no way to control or manage the +dynamic memory allocation process required for the encoding buffers and the +decoding process. If this information and/or capability is needed by the +parent application, consider switching to use the :ref:`mid-level-api` or +:ref:`low-level-api` which provide these capabilities. + +The function header details for each of the high-level API functions are +provided below. + +.. c:function:: int kmip_bio_create_symmetric_key(BIO *, TemplateAttribute *, char **, int *) + + Create a symmetric key with the attributes provided in the + ``TemplateAttribute`` structure. + + :param BIO*: An OpenSSL ``BIO`` structure containing a connection to the + KMIP server that will create the symmetric key. + :param TemplateAttribute*: A libkmip ``TemplateAttribute`` structure + containing the attributes for the symmetric key (e.g., cryptographic + algorithm, cryptographic length). + :param char**: A double pointer that can be used to access the UUID of the + newly created symmetric key. + + .. note:: + This pointer will point to a newly allocated block of memory. The + parent application is responsible for clearing and freeing this + memory once it is done using the UUID. + + :param int*: A pointer that can be used to access the length of the UUID + string pointed to by the above double pointer. + + :return: A status code indicating success or failure of the operation. A + negative status code indicates a libkmip error occurred while + processing the request. A positive status code indicates a KMIP error + occurred while the KMIP server processed the request. A status code + of 0 indicates the operation succeeded. + + The following codes are returned explicitly by this function. If the + code returned is negative and is not listed here, it is the result of + the request encoding or response decoding process. See + :ref:`status-codes` for all possible status code values. + + * ``KMIP_ARG_INVALID`` + One or more of the function arguments are invalid or unset and no + work can be done. This failure can occur if any of the following + are true: + + * the OpenSSL ``BIO`` pointer is set to ``NULL`` + * the ``TemplateAttribute`` pointer is set to ``NULL`` + * the ``char **`` UUID double pointer is set to ``NULL`` + * the ``int *`` UUID size pointer is set to ``NULL`` + + * ``KMIP_MEMORY_ALLOC_FAILED`` + Memory allocation failed during the key creation call. This + failure can occur during any of the following steps: + + * creation/resizing of the encoding buffer + * creation of the decoding buffer + + * ``KMIP_IO_FAILURE`` + A ``BIO`` error occurred during the key creation call. This + failure can occur during any of the following steps: + + * sending the encoded request message to the KMIP server + * receiving the encoded response message from the KMIP server + + * ``KMIP_EXCEED_MAX_MESSAGE_SIZE`` + The received response message from the KMIP server exceeds the + maximum allowed message size defined in the default libkmip + library context. Switching to the :ref:`mid-level-api` will + allow the parent application to set the max message size in the + library context directly. + + * ``KMIP_MALFORMED_RESPONSE`` + The received response message from the KMIP server is malformed + and does not contain valid operation result information. + +.. c:function:: int kmip_bio_get_symmetric_key(BIO *, char *, int, char **, int *) + + Retrieve a symmetric key identified by a specific UUID. + + :param BIO*: An OpenSSL ``BIO`` structure containing a connection to + the KMIP server that stores the symmetric key. + :param char*: A string containing the UUID of the symmetric key to retrieve. + :param int: The length of the above UUID string. + :param char**: A double pointer that can be used to access the bytes of + the retrieved symmetric key. + + .. note:: + This pointer will point to a newly allocated block of memory. The + parent application is responsible for clearing and freeing this + memory once it is done using the symmetric key. + + :param int*: A pointer that can be used to access the length of the + symmetric key pointed to by the above double pointer. + + :return: A status code indicating success or failure of the operation. A + negative status code indicates a libkmip error occurred while + processing the request. A positive status code indicates a KMIP error + occurred while the KMIP server processed the request. A status code + of 0 indicates the operation succeeded. + + The following codes are returned explicitly by this function. If the + code returned is negative and is not listed here, it is the result of + the request encoding or response decoding process. See + :ref:`status-codes` for all possible status code values. + + * ``KMIP_ARG_INVALID`` + One or more of the function arguments are invalid or unset and no + work can be done. This failure can occur if any of the following + are true: + + * the OpenSSL ``BIO`` pointer is set to ``NULL`` + * the ``char *`` UUID pointer is set to ``NULL`` + * the ``int`` UUID size argument is set to a non-positive integer + * the ``char **`` bytes double pointer is set to ``NULL`` + * the ``int *`` bytes size pointer is set to ``NULL`` + + * ``KMIP_MEMORY_ALLOC_FAILED`` + Memory allocation failed during the key retrieval call. This + failure can occur during any of the following steps: + + * creation/resizing of the encoding buffer + * creation of the decoding buffer + + * ``KMIP_IO_FAILURE`` + A ``BIO`` error occurred during the key retrieval call. This + failure can occur during any of the following steps: + + * sending the encoded request message to the KMIP server + * receiving the encoded response message from the KMIP server + + * ``KMIP_EXCEED_MAX_MESSAGE_SIZE`` + The received response message from the KMIP server exceeds the + maximum allowed message size defined in the default libkmip + library context. Switching to the :ref:`mid-level-api` will + allow the parent application to set the max message size in the + library context directly. + + * ``KMIP_MALFORMED_RESPONSE`` + The received response message from the KMIP server is malformed + and does not contain valid operation result information. + +.. c:function:: int kmip_bio_destroy_symmetric_key(BIO *, char *, int) + + Destroy a symmetric key identified by a specific UUID. + + :param BIO*: An OpenSSL ``BIO`` structure containing a connection to + the KMIP server that stores the symmetric key. + :param char*: A string containing the UUID of the symmetric key to destroy. + :param int: The length of the above UUID string. + + :return: A status code indicating success or failure of the operation. A + negative status code indicates a libkmip error occurred while + processing the request. A positive status code indicates a KMIP error + occurred while the KMIP server processed the request. A status code + of 0 indicates the operation succeeded. + + The following codes are returned explicitly by this function. If the + code returned is negative and is not listed here, it is the result of + the request encoding or response decoding process. See + :ref:`status-codes` for all possible status code values. + + * ``KMIP_ARG_INVALID`` + One or more of the function arguments are invalid or unset and no + work can be done. This failure can occur if any of the following + are true: + + * the OpenSSL ``BIO`` pointer is set to ``NULL`` + * the ``char *`` UUID pointer is set to ``NULL`` + * the ``int`` UUID size argument is set to a non-positive integer + + * ``KMIP_MEMORY_ALLOC_FAILED`` + Memory allocation failed during the key destruction call. This + failure can occur during any of the following steps: + + * creation/resizing of the encoding buffer + * creation of the decoding buffer + + * ``KMIP_IO_FAILURE`` + A ``BIO`` error occurred during the key destruction call. This + failure can occur during any of the following steps: + + * sending the encoded request message to the KMIP server + * receiving the encoded response message from the KMIP server + + * ``KMIP_EXCEED_MAX_MESSAGE_SIZE`` + The received response message from the KMIP server exceeds the + maximum allowed message size defined in the default libkmip + library context. Switching to the :ref:`mid-level-api` will + allow the parent application to set the max message size in the + library context directly. + + * ``KMIP_MALFORMED_RESPONSE`` + The received response message from the KMIP server is malformed + and does not contain valid operation result information. + +.. _mid-level-api: + +Mid-level API +~~~~~~~~~~~~~ +The mid-level client API is similar to the high-level API except that it +allows the parent application to create and supply the library context to +each KMIP operation function. This allows the parent application to set the +KMIP message settings relevant to its own use case, including the KMIP version +to use for message encoding, the maximum message size to accept from the KMIP +server, and the list of credentials to use when sending a KMIP request +message. The application can also substitute its own memory management system +using the standard memory function hooks provided in the context. + +Should an error occur during the request encoding or response decoding +process, error information, including an error message and a stack trace +detailing the function call path triggering the error, can be obtained from +the library context. For more information on the context, see +:ref:`the-libkmip-context`. + +Using these functions, the library will automatically: + +* create the request message structure +* encode the request message structure into a request encoding +* send the request encoding to the BIO-connected KMIP server +* receive the response encoding back from the BIO-connected KMIP server +* decode the response encoding into the response message structure +* extract the relevant output from the response message structure +* clean up the encoding buffers +* handle any errors that occur throughout the request/response process + +The function header details for each of the mid-level API functions are +provided below. + +.. c:function:: int kmip_bio_create_symmetric_key_with_context(KMIP *, BIO *, TemplateAttribute *, char **, int *) + + Create a symmetric key with the attributes provided in the + ``TemplateAttribute`` structure. + + :param KMIP*: A libkmip ``KMIP`` structure containing the context + information needed to encode and decode message structures. + + .. note:: + This structure should be properly destroyed by the parent + application once it is done conducting KMIP operations. See + :ref:`the-libkmip-context` and :ref:`context-functions` for more + information. + + :param BIO*: An OpenSSL ``BIO`` structure containing a connection to the + KMIP server that will create the symmetric key. + :param TemplateAttribute*: A libkmip :class:`TemplateAttribute` structure + containing the attributes for the symmetric key (e.g., cryptographic + algorithm, cryptographic length). + :param char**: A double pointer that can be used to access the UUID of the + newly created symmetric key. + + .. note:: + This pointer will point to a newly allocated block of memory. The + parent application is responsible for clearing and freeing this + memory once it is done using the UUID. + + :param int*: A pointer that can be used to access the length of the UUID + string pointed to by the above double pointer. + + :return: A status code indicating success or failure of the operation. A + negative status code indicates a libkmip error occurred while + processing the request. A positive status code indicates a KMIP error + occurred while the KMIP server processed the request. A status code + of 0 indicates the operation succeeded. + + The following codes are returned explicitly by this function. If the + code returned is negative and is not listed here, it is the result of + the request encoding or response decoding process. See + :ref:`status-codes` for all possible status code values. + + * ``KMIP_ARG_INVALID`` + One or more of the function arguments are invalid or unset and no + work can be done. This failure can occur if any of the following + are true: + + * the libkmip ``KMIP`` pointer is set to ``NULL`` + * the OpenSSL ``BIO`` pointer is set to ``NULL`` + * the ``TemplateAttribute`` pointer is set to ``NULL`` + * the ``char **`` UUID double pointer is set to ``NULL`` + * the ``int *`` UUID size pointer is set to ``NULL`` + + * ``KMIP_MEMORY_ALLOC_FAILED`` + Memory allocation failed during the key creation call. This + failure can occur during any of the following steps: + + * creation/resizing of the encoding buffer + * creation of the decoding buffer + + * ``KMIP_IO_FAILURE`` + A ``BIO`` error occurred during the key creation call. This + failure can occur during any of the following steps: + + * sending the encoded request message to the KMIP server + * receiving the encoded response message from the KMIP server + + * ``KMIP_EXCEED_MAX_MESSAGE_SIZE`` + The received response message from the KMIP server exceeds the + maximum allowed message size defined in the provided libkmip + library context. + + * ``KMIP_MALFORMED_RESPONSE`` + The received response message from the KMIP server is malformed + and does not contain valid operation result information. + +.. c:function:: int kmip_bio_get_symmetric_key_with_context(KMIP *, BIO *, char *, int, char **, int *) + + Retrieve a symmetric key identified by a specific UUID. + + :param KMIP*: A libkmip ``KMIP`` structure containing the context + information needed to encode and decode message structures. + + .. note:: + This structure should be properly destroyed by the parent + application once it is done conducting KMIP operations. See + :ref:`the-libkmip-context` and :ref:`context-functions` for more + information. + + :param BIO*: An OpenSSL ``BIO`` structure containing a connection to + the KMIP server that stores the symmetric key. + :param char*: A string containing the UUID of the symmetric key to retrieve. + :param int: The length of the above UUID string. + :param char**: A double pointer that can be used to access the bytes of + the retrieved symmetric key. + + .. note:: + This pointer will point to a newly allocated block of memory. The + parent application is responsible for clearing and freeing this + memory once it is done using the symmetric key. + + :param int*: A pointer that can be used to access the length of the + symmetric key pointed to by the above double pointer. + + :return: A status code indicating success or failure of the operation. A + negative status code indicates a libkmip error occurred while + processing the request. A positive status code indicates a KMIP error + occurred while the KMIP server processed the request. A status code + of 0 indicates the operation succeeded. + + The following codes are returned explicitly by this function. If the + code returned is negative and is not listed here, it is the result of + the request encoding or response decoding process. See + :ref:`status-codes` for all possible status code values. + + * ``KMIP_ARG_INVALID`` + One or more of the function arguments are invalid or unset and no + work can be done. This failure can occur if any of the following + are true: + + * the libkmip ``KMIP`` pointer is set to ``NULL`` + * the OpenSSL ``BIO`` pointer is set to ``NULL`` + * the ``char *`` UUID pointer is set to ``NULL`` + * the ``int`` UUID size argument is set to a non-positive integer + * the ``char **`` bytes double pointer is set to ``NULL`` + * the ``int *`` bytes size pointer is set to ``NULL`` + + * ``KMIP_MEMORY_ALLOC_FAILED`` + Memory allocation failed during the key retrieval call. This + failure can occur during any of the following steps: + + * creation/resizing of the encoding buffer + * creation of the decoding buffer + + * ``KMIP_IO_FAILURE`` + A ``BIO`` error occurred during the key retrieval call. This + failure can occur during any of the following steps: + + * sending the encoded request message to the KMIP server + * receiving the encoded response message from the KMIP server + + * ``KMIP_EXCEED_MAX_MESSAGE_SIZE`` + The received response message from the KMIP server exceeds the + maximum allowed message size defined in the provided libkmip + library context. + + * ``KMIP_MALFORMED_RESPONSE`` + The received response message from the KMIP server is malformed + and does not contain valid operation result information. + +.. c:function:: int kmip_bio_destroy_symmetric_key_with_context(KMIP *, BIO *, char *, int) + + Destroy a symmetric key identified by a specific UUID. + + :param KMIP*: A libkmip ``KMIP`` structure containing the context + information needed to encode and decode message structures. + + .. note:: + This structure should be properly destroyed by the parent + application once it is done conducting KMIP operations. See + :ref:`the-libkmip-context` and :ref:`context-functions` for more + information. + + :param BIO*: An OpenSSL ``BIO`` structure containing a connection to + the KMIP server that stores the KMIP managed object. + :param char*: A string containing the UUID of the KMIP managed object to + destroy. + :param int: The length of the above UUID string. + + :return: A status code indicating success or failure of the operation. A + negative status code indicates a libkmip error occurred while + processing the request. A positive status code indicates a KMIP error + occurred while the KMIP server processed the request. A status code + of 0 indicates the operation succeeded. + + The following codes are returned explicitly by this function. If the + code returned is negative and is not listed here, it is the result of + the request encoding or response decoding process. See + :ref:`status-codes` for all possible status code values. + + * ``KMIP_ARG_INVALID`` + One or more of the function arguments are invalid or unset and no + work can be done. This failure can occur if any of the following + are true: + + * the libkmip ``KMIP`` pointer is set to ``NULL`` + * the OpenSSL ``BIO`` pointer is set to ``NULL`` + * the ``char *`` UUID pointer is set to ``NULL`` + * the ``int`` UUID size argument is set to a non-positive integer + + * ``KMIP_MEMORY_ALLOC_FAILED`` + Memory allocation failed during the key destruction call. This + failure can occur during any of the following steps: + + * creation/resizing of the encoding buffer + * creation of the decoding buffer + + * ``KMIP_IO_FAILURE`` + A ``BIO`` error occurred during the key destruction call. This + failure can occur during any of the following steps: + + * sending the encoded request message to the KMIP server + * receiving the encoded response message from the KMIP server + + * ``KMIP_EXCEED_MAX_MESSAGE_SIZE`` + The received response message from the KMIP server exceeds the + maximum allowed message size defined in the provided libkmip + library context. + + * ``KMIP_MALFORMED_RESPONSE`` + The received response message from the KMIP server is malformed + and does not contain valid operation result information. + +.. _low-level-api: + +Low-level API +~~~~~~~~~~~~~ +The low-level client API differs from the mid and high-level APIs. It provides +a single function that is used to send and receive encoded KMIP messages. The +request message structure construction and encoding, along with the response +message structure decoding, is left up to the parent application. This provides +the parent application complete control over KMIP message processing. + +Using this function, the library will automatically: + +* send the request encoding to the BIO-connected KMIP server +* receive the response encoding back from the BIO-connected KMIP server +* handle any errors that occur throughout the send/receive process + +The function header details for the low-level API function is provided below. + +.. c:function:: int kmip_bio_send_request_encoding(KMIP *, BIO *, char *, int, char **, int *) + + Send a KMIP encoded request message to the KMIP server. + + :param KMIP*: A libkmip ``KMIP`` structure containing the context + information needed to encode and decode message structures. Primarily + used here to control the maximum response message size. + + .. note:: + This structure should be properly destroyed by the parent + application once it is done conducting KMIP operations. See + :ref:`the-libkmip-context` and :ref:`context-functions` for more + information. + + :param BIO*: An OpenSSL ``BIO`` structure containing a connection to + the KMIP server. + :param char*: A string containing the KMIP encoded request message bytes. + :param int: The length of the above encoded request message. + :param char**: A double pointer that can be used to access the bytes of + the received KMIP encoded response message. + + .. note:: + This pointer will point to a newly allocated block of memory. The + parent application is responsible for clearing and freeing this + memory once it is done processing the encoded response message. + + :param int*: A pointer that can be used to access the length of the + encoded response message pointed to by the above double pointer. + + :return: A status code indicating success or failure of the operation. A + negative status code indicates a libkmip error occurred while + processing the request. A positive status code indicates a KMIP error + occurred while the KMIP server processed the operation. A status code + of 0 indicates the operation succeeded. The following codes are + returned explicitly by this function. + + * ``KMIP_ARG_INVALID`` + One or more of the function arguments are invalid or unset and no + work can be done. This failure can occur if any of the following + are true: + + * the libkmip ``KMIP`` pointer is set to ``NULL`` + * the OpenSSL ``BIO`` pointer is set to ``NULL`` + * the ``char *`` encoded request message bytes pointer is set to + ``NULL`` + * the ``int`` encoded request message bytes size argument is set + to a non-positive integer + * the ``char **`` encoded response message bytes double pointer is + set to ``NULL`` + * the ``int *`` encoded response message bytes size pointer is set + to ``NULL`` + + * ``KMIP_MEMORY_ALLOC_FAILED`` + Memory allocation failed during message handling. This failure can + occur during the following step: + + * creation of the decoding buffer + + * ``KMIP_IO_FAILURE`` + A ``BIO`` error occurred during message handling. This failure can + occur during any of the following steps: + + * sending the encoded request message to the KMIP server + * receiving the encoded response message from the KMIP server + + * ``KMIP_EXCEED_MAX_MESSAGE_SIZE`` + The received response message from the KMIP server exceeds the + maximum allowed message size defined in the provided libkmip + library context. + +.. _status-codes: + +Status Codes +~~~~~~~~~~~~ +The following tables list the status codes that can be returned by the client +API functions. The first table lists the status codes related to the +functioning of libkmip. + +============================ ===== +Status Code Value +============================ ===== +KMIP_OK 0 +KMIP_NOT_IMPLEMENTED -1 +KMIP_ERROR_BUFFER_FULL -2 +KMIP_ERROR_ATTR_UNSUPPORTED -3 +KMIP_TAG_MISMATCH -4 +KMIP_TYPE_MISMATCH -5 +KMIP_LENGTH_MISMATCH -6 +KMIP_PADDING_MISMATCH -7 +KMIP_BOOLEAN_MISMATCH -8 +KMIP_ENUM_MISMATCH -9 +KMIP_ENUM_UNSUPPORTED -10 +KMIP_INVALID_FOR_VERSION -11 +KMIP_MEMORY_ALLOC_FAILED -12 +KMIP_IO_FAILURE -13 +KMIP_EXCEED_MAX_MESSAGE_SIZE -14 +KMIP_MALFORMED_RESPONSE -15 +KMIP_OBJECT_MISMATCH -16 +============================ ===== + +The second table lists the operation result status codes that can be returned +by a KMIP server as the result of a successful or unsuccessful operation. + +============================= ===== +Status Code Value +============================= ===== +KMIP_STATUS_SUCCESS 0 +KMIP_STATUS_OPERATION_FAILED 1 +KMIP_STATUS_OPERATION_PENDING 2 +KMIP_STATUS_OPERATION_UNDONE 3 +============================= ===== + +.. _encoding-api: + +Encoding API +------------ +The libkmip Encoding API supports encoding and decoding a variety of message +structures and substructures to and from the KMIP TTLV encoding format. The +:ref:`client-api` functions use the resulting encoded messages to communicate +KMIP operation instructions to the KMIP server. While each substructure +contained in a request or response message structure has its own corresponding +set of encoding and decoding functions, parent applications using libkmip +should only need to use the encoding and decoding functions for request and +response messages respectively. + +The following function signatures define the encoding API and can be found in +``kmip.h``: + +.. code-block:: c + + int kmip_encode_request_message(KMIP *, const RequestMessage *); + int kmip_decode_response_message(KMIP *, ResponseMessage *); + +The function header details for each of the encoding API functions are +provided below. + +.. c:function:: int kmip_encode_request_message(KMIP *, const RequestMessage *) + + Encode the request message and store the encoding in the library context. + + :param KMIP*: A libkmip ``KMIP`` structure containing the context + information needed to encode and decode message structures. + :param RequestMessage*: A libkmip ``RequestMessage`` structure containing + the request message information that will be encoded. The structure + will not be modified during the encoding process. + + :return: A status code indicating success or failure of the encoding + process. See :ref:`status-codes` for all possible status code values. + If ``KMIP_OK`` is returned, the encoding succeeded. + +.. c:function:: int kmip_decode_response_message(KMIP *, ResponseMessage *) + + Decode the encoding in the library context into the response message. + + :param KMIP*: A libkmip ``KMIP`` structure containing the context + information needed to encode and decode message structures. + :param ResponseMessage*: A libkmip ``ResponseMessage`` structure + that will be filled out by the decoding process. + + .. note:: + This structure will contain pointers to newly allocated + substructures created during the decoding process. The calling + function is responsible for clearing and freeing these + substructures once it is done processing the response message. + See (ref here) for more information. + + .. warning:: + Any attributes set in the structure before it is passed in to this + decoding function will be overwritten and lost during the decoding + process. Best practice is to pass in a pointer to a freshly + initialized, empty structure to ensure this does not cause + application errors. + + :return: A status code indicating success or failure of the decoding + process. See :ref:`status-codes` for all possible status code values. + If ``KMIP_OK`` is returned, the decoding succeeded. + +.. _utilities-api: + +Utilities API +------------- +The libkmip Utilities API supports a wide variety of helper functions and +structures that are used throughout libkmip, ranging from the core library +context structure that is used for all encoding and decoding operations to +structure initializers, deallocators, and debugging aides. + +.. warning:: + Additional capabilities are included in libkmip that may not be discussed + here. These capabilities are generally for internal library use only and + are subject to change in any release. Parent applications that use these + undocumented features should not expect API stability. + +.. _the-libkmip-context: + +The libkmip Context +~~~~~~~~~~~~~~~~~~~ +The libkmip library context is a structure that contains all of the settings +and controls needed to create KMIP message encodings. It is defined in +``kmip.h``: + +.. code-block:: c + + typedef struct kmip + { + /* Encoding buffer */ + uint8 *buffer; + uint8 *index; + size_t size; + + /* KMIP message settings */ + enum kmip_version version; + int max_message_size; + LinkedList *credentials; + + /* Error handling information */ + char *error_message; + size_t error_message_size; + LinkedList *error_frames; + + /* Memory management function pointers */ + void *(*calloc_func)(void *state, size_t num, size_t size); + void *(*realloc_func)(void *state, void *ptr, size_t size); + void (*free_func)(void *state, void *ptr); + void *(*memset_func)(void *ptr, int value, size_t size); + void *state; + } KMIP; + +The structure includes the encoding/decoding buffer, KMIP message settings, +error information, and memory management hooks. + +The Encoding/Decoding Buffer +```````````````````````````` +The library context contains a pointer to the main target buffer, ``buffer``, +used for both encoding and decoding KMIP messages. This buffer should only +be set and accessed using the defined context utility functions defined below. +It should never be accessed or manipulated directly. + +KMIP Message Settings +````````````````````` +The library context contains several attributes that are used throughout the +encoding and decoding process. + +The ``version`` enum attribute is used to control what KMIP structures are +included in operation request and response messages. It should be set by the +parent application to the desired KMIP version: + +.. code-block:: c + + enum kmip_version + { + KMIP_1_0 = 0, + KMIP_1_1 = 1, + KMIP_1_2 = 2, + KMIP_1_3 = 3, + KMIP_1_4 = 4 + }; + +The ``max_message_size`` attribute defines the maximum size allowed for +incoming response messages. Since KMIP message encodings define the total size +of the message at the beginning of the encoding, it is important for the +parent application to set this attribute to a reasonable default suitable for +its operation. + +The ``credentials`` list is intended to store a set of authentication +credentials that should be included in any request message created with the +library context. This is primarily intended for use with the +:ref:`mid-level-api`. + +Each of these attributes will be set to reasonable defaults by the +``kmip_init`` context utility and can be overridden as needed. + +Error Information +````````````````` +The library context contains several attributes that are used to track and +store error information. These are only used when errors occur during the +encoding or decoding process. Once an error is detected, a libkmip stack +trace will be constructed, with each frame in the stack containing the +function name and source line number where the error occurred to facilitate +debugging. + +.. code-block:: c + + typedef struct error_frame + { + char *function; + int line; + } ErrorFrame; + +The original error message will be captured in the ``error_message`` +attribute for use in logging or user-facing status messages. + +See the context functions below for using and accessing this error +information. + +Memory Management +````````````````` +The library context contains several function pointers that can be used to +wrap or substitute common memory management utilities. All memory management +done by libkmip is done through these function pointers, allowing the calling +application to easily substitute its own memory management system. Note +specifically the ``void *state`` attribute in the library context; it is +intended to contain a reference to the parent application's custom memory +management system, if one exists. This attribute is passed to every call made +through the context's memory management hooks, allowing the parent application +complete control of the memory allocation process. By default, the ``state`` +attribute is ignored in the default memory management hooks. The ``kmip_init`` +utility function will automatically set these hooks to the default memory +management functions if any of them are unset. + +.. _context-functions: + +Utility Functions +~~~~~~~~~~~~~~~~~ +The following function signatures define the Utilities API and can be found +in ``kmip.h``: + +.. code-block:: c + + /* Library context utilities */ + void kmip_clear_errors(KMIP *); + void kmip_init(KMIP *, void *, size_t, enum kmip_version); + void kmip_init_error_message(KMIP *); + int kmip_add_credential(KMIP *, Credential *); + void kmip_remove_credentials(KMIP *); + void kmip_reset(KMIP *); + void kmip_rewind(KMIP *); + void kmip_set_buffer(KMIP *, void *, size_t); + void kmip_destroy(KMIP *); + void kmip_push_error_frame(KMIP *, const char *, const int); + + /* Message structure initializers */ + void kmip_init_protocol_version(ProtocolVersion *, enum kmip_version); + void kmip_init_attribute(Attribute *); + void kmip_init_request_header(RequestHeader *); + void kmip_init_response_header(ResponseHeader *); + + /* Message structure deallocators */ + void kmip_free_request_message(KMIP *, RequestMessage *); + void kmip_free_response_message(KMIP *, ResponseMessage *); + + /* Message structure debugging utilities */ + void kmip_print_request_message(RequestMessage *); + void kmip_print_response_message(ResponseMessage *); + +Library Context Utilities +````````````````````````` +The libkmip context contains various fields and attributes used in various +ways throughout the encoding and decoding process. In general, the context +fields should not be modified directly. All modifications should be done +using one of the context utility functions described below. + +The function header details for each of the relevant context utility functions +are provided below. + +.. c:function:: void kmip_init(KMIP *, void *, size_t, enum kmip_version) + + Initialize the ``KMIP`` context. + + This function initializes the different fields and attributes used by the + context to encode and decode KMIP messages. Reasonable defaults are chosen + for certain fields, like the maximum message size and the error message + size. If any of the memory allocation function hooks are ``NULL``, they + will be set to system defaults. + + :param KMIP*: The libkmip ``KMIP`` context to be initialized. If ``NULL``, + the function does nothing and returns. + :param void*: A ``void`` pointer to a buffer to be used for encoding and + decoding KMIP messages. If setting up the context for use with the + :ref:`mid-level-api` it is fine to use ``NULL`` here. + :param size_t: The size of the above buffer. If setting up the context for + use with the :ref:`mid-level-api` it is fine to use 0 here. + :param enum kmip_version: A KMIP version enumeration that will be used by + the context to decide how to encode and decode messages. + + :return: None + +.. c:function:: void kmip_clear_errors(KMIP *) + + Clean up any error-related information stored in the ``KMIP`` context. + + This function clears and frees any error-related information or structures + contained in the context, should any exist. It is intended to be used + between encoding or decoding operations so that repeated use of the + context is possible without causing errors. It is often used by other + context handling utilities. See the utility source code for more details. + + :param KMIP*: The libkmip ``KMIP`` context containing error-related + information to be cleared. + + :return: None + +.. c:function:: void kmip_init_error_message(KMIP *) + + Initialize the error message field of the ``KMIP`` context. + + This function allocates memory required to store the error message string + in the library context. If an error message string already exists, nothing + is done. Primarily used internally by other utility functions. + + :param KMIP*: The libkmip ``KMIP`` context whose error message memory + should be allocated. + + :return: None + +.. c:function:: int kmip_add_credential(KMIP *, Credential *) + + Add a ``Credential`` structure to the list of credentials used by the + ``KMIP`` context. + + This function dynamically adds a node to the ``LinkedList`` of + ``Credential`` structures stored by the context. These credentials are + used automatically by the :ref:`mid-level-api` when creating KMIP + operation requests. + + :param KMIP*: The libkmip ``KMIP`` context to add a credential to. + :param Credential*: The libkmip ``Credential`` structure to add to the + list of credentials stored by the context. + + :return: A status code indicating if the credential was added to the + context. The code will be one of the following: + + * ``KMIP_OK`` + The credential was added successfully. + * ``KMIP_UNSET`` + The credential was not added successfully. + +.. c:function:: void kmip_remove_credentials(KMIP *) + + Remove all ``Credential`` structures stored by the ``KMIP`` context. + + This function clears and frees all of the ``LinkedList`` nodes used to + store the ``Credential`` structures associated with the context. + + .. note:: + If the underlying ``Credential`` structures were themselves + dynamically allocatted, they must be freed separately by the parent + application. + + :param KMIP*: The libkmip ``KMIP`` context containing credentials to + be removed. + + :return: None + +.. c:function:: void kmip_reset(KMIP *) + + Reset the ``KMIP`` context buffer so that encoding can be reattempted. + + This function resets the context buffer to its initial empty starting + state, allowing the context to be used for another encoding attempt if + the prior attempt failed. The buffer will be overwritten with zeros to + ensure that no information leaks across encoding attempts. This function + also calls ``kmip_clear_errors`` to clear out any error information that + was generated by the encoding failure. + + :param KMIP*: The libkmip ``KMIP`` context that contains the buffer + needing to be reset. + + :return: None + +.. c:function:: void kmip_rewind(KMIP *) + + Rewind the ``KMIP`` context buffer so that decoding can be reattempted. + + This function rewinds the context buffer to its initial starting state, + allowing the context to be used for another decoding attempt if the + prior attempt failed. This function also calls ``kmip_clear_errors`` to + clear out any error information that was generated by the decoding + failure. + + :param KMIP*: The libkmip ``KMIP`` context that contains the buffer + needing to be rewound. + + :return: None + +.. c:function:: void kmip_set_buffer(KMIP *, void *, size_t) + + Set the encoding buffer used by the ``KMIP`` context. + + :param KMIP*: The libkmip ``KMIP`` context that will contain the buffer. + :param void*: A ``void`` pointer to a buffer to be used for encoding and + decoding KMIP messages. + :param size_t: The size of the above buffer. + + :return: None + +.. c:function:: void kmip_destroy(KMIP *) + + Deallocate the content of the ``KMIP`` context. + + This function resets and deallocates all of the fields contained in the + context. It calls ``kmip_reset`` and ``kmip_set_buffer`` to clear the + buffer and overwrite any leftover pointers to it. It calls + ``kmip_clear_credentials`` to clear out any referenced credential + information. It also unsets all of the memory allocation function hooks. + + .. note:: + The buffer memory itself will not be deallocated by this function, nor + will any of the ``Credential`` structures if they are dynamically + allocatted. The parent application is responsible for clearing and + deallocating those segments of memory. + +.. c:function:: void kmip_push_error_frame(KMIP *, const char *, const int) + + Add an error frame to the stack trace contained in the ``KMIP`` context. + + This function dynamically adds a new error frame to the context stack + trace, using the information provided to record where an error occurred. + + :param KMIP*: The libkmip ``KMIP`` context containing the stack trace. + :param char*: The string containing the function name for the new + stack trace error frame. + :param int: The line number for the new stack trace error frame. + + :return: None + +Message Structure Initializers +`````````````````````````````` +There are many different KMIP message structures and substructures that are +defined and supported by libkmip. In general, the parent application should +zero initialize any libkmip structures before using them, like so: + +.. code-block:: c + + RequestMessage message = {0}; + +In most cases, optional fields in KMIP substructures are excluded from the +encoding process when set to 0. However, in some cases 0 is a valid value +for a specific optional field. In these cases, we set these values to +``KMIP_UNSET``. The parent application should never need to worry about +manually initialize these types of fields. Instead, the following initializer +functions should be used for the associated structures to handle properly +setting default field values. + +The function header details for each of the relevant initializer functions +are provided below. + +.. c:function:: void kmip_init_protocol_version(ProtocolVersion *, enum kmip_version) + + Initialize a ``ProtocolVersion`` structure with a KMIP version + enumeration. + + :param ProtocolVersion*: A libkmip ``ProtocolVersion`` structure to be + initialized. + :param enum kmip_version: A KMIP version enumeration whose value will be + used to initialize the ProtocolVersion structure. + + :return: None + +.. c:function:: void kmip_init_attribute(Attribute *) + + Initialize an ``Attribute`` structure. + + :param Attribute*: A libkmip ``Attribute`` structure to be initialized. + + :return: None + +.. c:function:: void kmip_init_request_header(RequestHeader *) + + Initialize a ``RequestHeader`` structure. + + :param RequestHeader*: A libkmip ``RequestHeader`` structure to be + initialized. + + :return: None + +.. c:function:: void kmip_init_response_header(ResponseHeader *) + + Initialize a ``ResponseHeader`` structure. + + :param ResponseHeader*: A libkmip ``ResponseHeader`` structure to be + initialized. + + :return: None + +Message Structure Deallocators +`````````````````````````````` +Along with structure initializers, there are corresponding structure +deallocators for every supported KMIP structure. The deallocator behaves +like the initializer; it takes in a pointer to a specific libkmip structure +and will set all structure fields to safe, initial defaults. If a structure +field is a non ``NULL`` pointer, the deallocator will attempt to clear and +free the associated memory. + +.. note:: + A deallocator will not free the actual structure passed to it. It will + only attempt to free memory referenced by the structure fields. The parent + application is responsible for freeing the structure memory if it was + dynamically allocated and should set any pointers to the structure to + ``NULL`` once it is done with the structure. + +Given how deallocators handle memory, they should only ever be used on +structures that are created from the decoding process (i.e., structures +created on the heap). The decoding process dynamically allocates memory to +build out the message structure in the target encoding and it is beyond the +capabilities of the client API or the parent application to manually free +all of this memory directly. + +.. warning:: + If you use a deallocator on a structure allocated fully or in part on the + stack, the deallocator will attempt to free stack memory and will trigger + undefined behavior. This can lead to program instability and may cause + the application to crash. + +While there are deallocators for every supported structure, parent +applications should only need to use the deallocators for request and response +messages. Given these are the root KMIP structures, using these will free +all associated substructures used to represent the message. + +The function header details for each of the deallocator functions are provided +below. + +.. c:function:: void kmip_free_request_message(KMIP *, RequestMessage *) + + Deallocate the content of a ``RequestMessage`` structure. + + :param KMIP*: A libkmip ``KMIP`` structure containing the context + information needed to encode and decode message structures. Primarily + used here for memory handlers. + :param RequestMessage*: A libkmip ``RequestMessage`` structure whose + content should be reset and/or freed. + + :return: None + +.. c:function:: void kmip_free_response_message(KMIP *, ResponseMessage *) + + Deallocate the content of a ``ResponseMessage`` structure. + + :param KMIP*: A libkmip ``KMIP`` structure containing the context + information needed to encode and decode message structures. Primarily + used here for memory handlers. + :param ResponseMessage*: A libkmip ``ResponseMessage`` structure whose + content should be reset and/or freed. + + :return: None + +Message Structure Debugging Utilities +````````````````````````````````````` +If the parent application is using the :ref:`low-level-api`, it will have +access to the ``RequestMessage`` and ``ResponseMessage`` structures used to +generate the KMIP operation encodings. These structures can be used with +basic printing utilities to display the content of these structures in an +easy to view and debug format. + +The function header details for each of the printing utilities are provided +below. + +.. c:function:: void kmip_print_request_message(RequestMessage *) + + Print the contents of a ``RequestMessage`` structure. + + :param RequestMessage*: A libkmip ``RequestMessage`` structure to be + displayed. + + :return: None + +.. c:function:: void kmip_print_response_message(ResponseMessage *) + + Print the contents of a ``ResponseMessage`` structure. + + :param ResponseMessage*: A libkmip ``ResponseMessage`` structure to be + displayed. + + :return: None + +.. _`OpenSSL BIO library`: https://www.openssl.org/docs/man1.1.0/crypto/bio.html
\ No newline at end of file diff --git a/src/libkmip/docs/source/changelog.rst b/src/libkmip/docs/source/changelog.rst new file mode 100644 index 000000000..09929fe43 --- /dev/null +++ b/src/libkmip/docs/source/changelog.rst @@ -0,0 +1 @@ +.. include:: ../../CHANGELOG.rst diff --git a/src/libkmip/docs/source/conf.py b/src/libkmip/docs/source/conf.py new file mode 100644 index 000000000..1d8b97c9e --- /dev/null +++ b/src/libkmip/docs/source/conf.py @@ -0,0 +1,173 @@ +# -*- coding: utf-8 -*- +# +# libkmip documentation build configuration file. +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +# import os +# import sys +import sphinx_rtd_theme +# sys.path.insert(0, os.path.abspath('.')) + + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +# +# needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = ['sphinx.ext.autodoc'] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +# source_suffix = ['.rst', '.md'] +source_suffix = '.rst' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'libkmip' +copyright = u'2018, Peter Hamilton' +author = u'Peter Hamilton' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = u'0.1' +# The full version, including alpha/beta/rc tags. +release = u'0.1.rel' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This patterns also effect to html_static_path and html_extra_path +exclude_patterns = [] + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = False + + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +#html_theme = 'alabaster' +html_theme = "sphinx_rtd_theme" +html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +# +# html_theme_options = {} + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# Custom sidebar templates, must be a dictionary that maps document names +# to template names. +# +# This is required for the alabaster theme +# refs: http://alabaster.readthedocs.io/en/latest/installation.html#sidebars +html_sidebars = { + '**': [ + 'about.html', + 'navigation.html', + 'relations.html', # needs 'show_related': True theme option to display + 'searchbox.html', + 'donate.html', + ] +} + + +# -- Options for HTMLHelp output ------------------------------------------ + +# Output file base name for HTML help builder. +htmlhelp_basename = 'libkmipdoc' + + +# -- Options for LaTeX output --------------------------------------------- + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', + + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + (master_doc, 'libkmip.tex', u'libkmip Documentation', + u'Peter Hamilton', 'manual'), +] + + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + (master_doc, 'libkmip', u'libkmip Documentation', + [author], 1) +] + + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + (master_doc, 'libkmip', u'libkmip Documentation', + author, 'libkmip', 'One line description of project.', + 'Miscellaneous'), +] + + + diff --git a/src/libkmip/docs/source/development.rst b/src/libkmip/docs/source/development.rst new file mode 100644 index 000000000..0168ef11a --- /dev/null +++ b/src/libkmip/docs/source/development.rst @@ -0,0 +1,105 @@ +Development +=========== +Development for libkmip is open to all contributors. Use the information +provided here to inform your contributions and help the project maintainers +review and accept your work. + +Getting Started +--------------- +File a new issue on the project `issue tracker`_ on GitHub describing the +work you intend on doing. This is especially recommended for any sizable +contributions, like adding support for a new KMIP operation or object type. +Provide as much information on your feature request as possible, using +information from the KMIP specifications or existing feature support in +libkmip where applicable. + +The issue number for your new issue should be included at the end of the +commit message of each patch related to that issue. + +If you simply want to request a new feature but do not intend on working on +it, file your issue as normal and the project maintainers will triage it for +future work. + +.. _writing-code: + +Writing Code +------------ +New code should be written in its own ``git`` branch, ideally branched from +``HEAD`` on ``master``. If other commits are merged into ``master`` after your +branch was created, be sure to rebase your work on the current state of +``master`` before submitting a pull request to GitHub. + +New code should generally follow the style used in the surrounding libkmip +codebase. + +.. _writing-docs: + +Writing Documentation +--------------------- +Like new code, new documentation should be written in its own ``git`` branch. +All libkmip documentation is written in `RST`_ format and managed using +``sphinx``. It can be found under ``docs/source``. + +If you are interested in contributing to the project documentation, install +the project documentation requirements: + +.. code:: console + + $ pip install -r doc-requirements.txt + +To build the documentation, navigate into the ``docs`` directory and run: + +.. code:: console + + $ make html + +This will build the libkmip documentation as HTML and place it under the new +``docs/build/html`` directory. View it using your preferred web browser. + +Commit Messages +--------------- +Commit messages should include a single line title (75 characters max) followed +by a blank line and a description of the change, including feature details, +testing and documentation updates, feature limitations, known issues, etc. + +The issue number for the issue associated with the commit should be included +at the end of the commit message, if it exists. If the commit is the final one +for a specific issue, use ``Closes #XXX`` or ``Fixes #XXX`` to link the issue +and close it simultaneously. + +Bug Fixes +--------- +If you have found a bug in libkmip, file a new issue and use the title format +``Bug: <brief description here>``. In the body of the issue please provide as +much information as you can, including platform, compiler version, dependency +version, and any stacktraces or error information produced by libkmip related +to the bug. See `What to put in your bug report`_ for a breakdown of bug +reporting best practices. + +If you are working on a bug fix for a bug in ``master``, follow the general +guidelines above for branching and code development (see :ref:`writing-code`). + +If you are working on a bug fix for an older version of libkmip, your branch +should be based on the latest commit of the repository branch for the version +of libkmip the bug applies to (e.g., branch ``release-0.1.0`` for libkmip 0.1). +The pull request for your bug fix should also target the version branch in +question. If appliable, it will be pulled forward to newer versions of libkmip, +up to and including ``master``. + +.. running-tests: + +Running Tests +------------- +libkmip comes with its own testing application that primarily covers the +encoding/decoding functionality of the library. It is built with the default +``make`` target and can be run locally by invoking the ``tests`` binary: + +.. code-block:: console + + $ cd libkmip + $ make + $ ./tests + +.. _`issue tracker`: https://github.com/openkmip/libkmip/issues +.. _`RST`: http://docutils.sourceforge.net/rst.html +.. _`What to put in your bug report`: http://www.contribution-guide.org/#What-to-put-in-your-bug-report diff --git a/src/libkmip/docs/source/docs.txt b/src/libkmip/docs/source/docs.txt new file mode 100644 index 000000000..a58d1a32e --- /dev/null +++ b/src/libkmip/docs/source/docs.txt @@ -0,0 +1,9 @@ +Welcome to libkmip + +1. Installation +2. Changelog +3. FAQ +4. Development +5. Client +6. Community +7. Glossary
\ No newline at end of file diff --git a/src/libkmip/docs/source/examples.rst b/src/libkmip/docs/source/examples.rst new file mode 100644 index 000000000..89cbac45d --- /dev/null +++ b/src/libkmip/docs/source/examples.rst @@ -0,0 +1,76 @@ +Examples +======== +To demonstrate how to use libkmip, several example applications are built +and deployed with the library to get developers started. + +Demos +----- +Three demo applications are included with libkmip, one for each of the +following KMIP operations: + +* ``Create`` +* ``Get`` +* ``Destroy`` + +If libkmip is built, the demo applications can be found in the local build +directory. If libkmip is installed, the demo applications can also be found +in the bin directory, by default located at ``/usr/local/bin/kmip``. + +Run any of the demo applications with the ``-h`` flag to see usage +information. + +Create Demo +~~~~~~~~~~~ +The ``Create`` demo, ``demo_create.c``, uses the :ref:`low-level-api` to issue +a KMIP request to the KMIP server to create a symmetric key. The application +manually creates the library context and initalizes it. It then manually +builds the request message structure, creating the following attributes for +the symmetric key: + +* cryptographic algorithm (AES) +* cryptographic length (256 bits) +* cryptographic usage mask (Encrypt and Decrypt usage) + +The demo application encodes the request and then sends it through the +low-level API to retrieve the response encoding. It decodes the response +encoding into the response message structure and then extracts the UUID of +the newly created symmetric key. + +Get Demo +~~~~~~~~ +The ``Get`` demo, ``demo_get.c``, uses the :ref:`mid-level-api` to issue a +KMIP request to the KMIP server to retrieve a symmetric key. The application +manually creates the library context and initializes it. It sets its own +custom memory handlers to override the default ones supplied by libkmip and +then invokes the mid-level API with the UUID of the symmetric key it wants +to retrieve. + +The client API internally builds the corresponding request message, encodes +it, sends it via BIO to the KMIP server, retrieves the response encoding, and +then decodes the response into the corresponding response message structure. +Finally, it extracts the symmetric key bytes and copies them to a separate +block of memory that will be handed back to the demo application. Finally, it +cleans up the buffers used for the encoding and decoding process and cleans +up the response message structure. + +Destroy Demo +~~~~~~~~~~~~ +The ``Destroy`` demo, ``demo_destroy.c``, use the :ref:`high-level-api` to +issue a KMIP request to the KMIP server to destroy a symmetric key. The +application invokes the high-level API with the UUID of the symmetric key it +wants to destroy. + +The client API internally builds the library context along with the +corresponding request message. It encodes the request, sends it via BIO to +the KMIP server, retrieves the response encoding, and then decodes the +response into the corresponding response message structure. Finally, it +extracts the result of the KMIP operation from the response message structure +and returns it. + +Tests +----- +A test application is also included with libkmip to exercise the encoding and +decoding capabilities for all support KMIP features. The source code for this +application, ``tests.c``, contains numerous examples of how to build and use +different libkmip structures. + diff --git a/src/libkmip/docs/source/faq.rst b/src/libkmip/docs/source/faq.rst new file mode 100644 index 000000000..fc18bf483 --- /dev/null +++ b/src/libkmip/docs/source/faq.rst @@ -0,0 +1,19 @@ +Frequently Asked Questions +========================== + +.. contents:: Table of Contents + +There are no results when I run ``man libkmip``. Why not? +--------------------------------------------------------- +The current build and install process does not generate ``man`` compatible +documentation output. + +The libkmip documentation is written in `RST`_ and is built as HTML by +``sphinx``. It is typically installed under ``/usr/local/share/doc/kmip``. +It is available online on `ReadTheDocs`_. + +For more information, see :ref:`writing-docs` and +:ref:`building-libkmip-on-linux`. + +.. _`RST`: http://docutils.sourceforge.net/rst.html +.. _`ReadTheDocs`: https://libkmip.readthedocs.io/
\ No newline at end of file diff --git a/src/libkmip/docs/source/index.rst b/src/libkmip/docs/source/index.rst new file mode 100644 index 000000000..d55e3e196 --- /dev/null +++ b/src/libkmip/docs/source/index.rst @@ -0,0 +1,46 @@ +Welcome to libkmip +================== +libkmip is an ISO C11 implementation of the Key Management Interoperability +Protocol (KMIP), an `OASIS`_ communication standard for the management of +objects stored and maintained by key management systems. KMIP defines how key +management operations and operation data should be encoded and communicated +between client and server applications. Supported operations include creating, +retrieving, and destroying keys. Supported object types include: + +* symmetric/asymmetric encryption keys + +For more information on KMIP, check out the `OASIS KMIP Technical Committee`_ +and the `OASIS KMIP Documentation`_. + +Installation +------------ +You can install libkmip from source using ``make``: + +.. code-block:: console + + $ cd libkmip + $ make + $ make install + +See :doc:`Installation <installation>` for more information. + +Layout +------ +libkmip provides client functionality, allowing developers to integrate the +key management lifecycle into their projects. For more information, check +out the various articles below: + +.. toctree:: + :maxdepth: 2 + + installation + changelog + faq + development + security + api + examples + +.. _`OASIS`: https://www.oasis-open.org +.. _`OASIS KMIP Technical Committee`: https://www.oasis-open.org/committees/tc_home.php?wg_abbrev=kmip +.. _`OASIS KMIP Documentation`: https://docs.oasis-open.org/kmip/spec diff --git a/src/libkmip/docs/source/installation.rst b/src/libkmip/docs/source/installation.rst new file mode 100644 index 000000000..e3e0720ee --- /dev/null +++ b/src/libkmip/docs/source/installation.rst @@ -0,0 +1,101 @@ +Installation +============ + +Dependencies +------------ +Building libkmip requires the following dependencies: + +* `OpenSSL 1.1.0`_ + +These may come installed by default on your target system or they may require +separate installation procedures. See each individual dependency's +documentation for more details. + +.. _building-libkmip-on-linux: + +Building libkmip on Linux +------------------------- +You can install libkmip from source via ``git``: + +.. code-block:: console + + $ git clone https://github.com/openkmip/libkmip.git + $ cd libkmip + $ make + $ make install + +The default build settings will direct ``make`` to install libkmip under +``/usr/local``, which may require ``sudo`` access. There are several different +libkmip components that will be installed, including the documentation, the +source code and header files, the shared library, and the example demo +applications. The following list defines the default install directories and +the files that can be found in them: + +* ``/usr/local/bin/kmip`` + Contains demo libkmip applications showing how to use the supported KMIP + operations. +* ``/usr/local/include/kmip`` + Contains the libkmip header files for use in third-party applications. +* ``/usr/local/lib/kmip`` + Contains the libkmip shared library, ``libkmip.so``. +* ``/usr/local/src/kmip`` + Contains the libkmip source files. +* ``/usr/local/share/doc/kmip/src`` + Contains the libkmip documentation source files. +* ``/usr/local/share/doc/kmip/html`` + Contains the libkmip documentation HTML files `if they have have already + been built`. + +You can override the build defaults when invoking ``make install``. The +following list defines the build variables used by ``make`` and what their +default values are: + +* ``PREFIX`` + Defines where libkmip will be installed. Defaults to ``/usr/local``. +* ``KMIP`` + Defines the common name of the libkmip subdirectories that will be created + under ``PREFIX``. Defaults to ``kmip``. +* ``DESTDIR`` + Defines an alternative root of the file system where libkmip will be + installed. Used primarily to test the installation process without needing + to modify the default values of ``PREFIX`` or ``KMIP``. Defaults to the + empty string. + +For example, to install libkmip under your home directory, you could use the +following command: + +.. code-block:: console + + $ make PREFIX=$HOME/.local install + +This would create all of the normal installation directories (e.g., ``bin``, +``include``, ``lib``) under ``$HOME/.local`` instead of ``/usr/local``. + +To ensure that your system is up-to-date after you install libkmip, make sure +to run ``ldconfig`` to update the dynamic linker's run-time bindings. + +.. code-block:: console + + $ ldconfig + +For more information see the project Makefile (insert link here). + +Uninstalling libkmip +-------------------- +You can uninstall libkmip using the provided ``make uninstall`` target: + +.. code-block:: console + + $ cd libkmip + $ make uninstall + +This will simply remove all of the installation directories and files created +during the above installation process. Like with ``make install``, the default +build settings will direct ``make`` to remove libkmip from under +``/usr/local``, which may require ``sudo`` access. If you customize the +installation settings, be sure to use those same settings when uninstalling. + +Like the installation process, run ``ldconfig`` again after uninstall to make +the dynamic linker is up-to-date. + +.. _`OpenSSL 1.1.0`: https://www.openssl.org/docs/man1.1.0/
\ No newline at end of file diff --git a/src/libkmip/docs/source/security.rst b/src/libkmip/docs/source/security.rst new file mode 100644 index 000000000..16aa465a5 --- /dev/null +++ b/src/libkmip/docs/source/security.rst @@ -0,0 +1,44 @@ +Security +======== +The security of libkmip is the top priority for the project. Use the +information provided below to inform your security posture. + +Handling Sensitive Data +----------------------- +Given that libkmip is an ISO C11 implementation of a key management protocol, +the most sensitive aspect of the library is its handling of memory containing +cryptographic material. All memory allocation and deallocation routines +explicitly zero memory to prevent inadvertent leaks of sensitive data. This +approach relies on the use of the standard ``memset_s`` function +(see `memset_s`_) included in C11 Annex K. If ``memset_s`` is unavailable at +build time, memory clearing is done through a volatile function pointer to +prevent the optimizer from optimizing away the clearing operation. + +.. warning:: + Despite the precautions taken here, it is possible that your build system + will still optimize away the memory clearing operation. If this occurs, + sensitive cryptographic material will be left behind in memory during and + after application execution. Examine your application binary directly to + determine if this is true for your setup. + +Other security concerns, such as locking memory pages, are left up to the +parent application and are not the domain of libkmip. + +Reporting a Security Issue +-------------------------- +Please do not report security issues to the normal GitHub project issue +tracker. Contact the project maintainers directly via email to report +and discuss security issues. + +When reporting a security issue, please include as much detail as possible. +This includes a high-level description of the issue, information on how to +cause or reproduce the issue, and any details on specific portions of the +project code base related to the issue. + +Once you have submitted an issue, you should receive an acknowledgement. +Depending upon the severity of the issue, the project maintainers will +respond to collect additional information and work with you to address the +security issue. If applicable, a new library subrelease will be produced +across all actively supported releases to address and fix the issue. + +.. _`memset_s`: https://en.cppreference.com/w/c/string/byte/memset
\ No newline at end of file diff --git a/src/libkmip/kmip.c b/src/libkmip/kmip.c new file mode 100644 index 000000000..2173dd3f5 --- /dev/null +++ b/src/libkmip/kmip.c @@ -0,0 +1,15958 @@ +/* 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 <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <time.h> + +#include "kmip.h" +#include "kmip_memset.h" + +/* +Miscellaneous Utilities +*/ + +size_t +kmip_strnlen_s(const char *str, size_t strsz) +{ + if(str == NULL) + { + return(0); + } + + size_t length = 0; + for(const char *i = str; *i != 0; i++) + { + length++; + if(length >= strsz) + { + return(strsz); + } + } + return(length); +} + +LinkedListItem * +kmip_linked_list_pop(LinkedList *list) +{ + if(list == NULL) + { + return(NULL); + } + + LinkedListItem *popped = list->head; + + if(popped != NULL) + { + list->head = popped->next; + popped->next = NULL; + popped->prev = NULL; + + if(list->head != NULL) + { + list->head->prev = NULL; + } + + if(popped == list->tail) + { + list->tail = NULL; + } + + if(list->size > 0) + { + list->size -= 1; + } + } + else + { + if(list->size != 0) + { + list->size = 0; + } + } + + return(popped); +} + +void +kmip_linked_list_push(LinkedList *list, LinkedListItem *item) +{ + if(list != NULL && item != NULL) + { + LinkedListItem *head = list->head; + list->head = item; + item->next = head; + item->prev = NULL; + list->size += 1; + + if(head != NULL) + { + head->prev = item; + } + + if(list->tail == NULL) + { + list->tail = list->head; + } + } +} + +void +kmip_linked_list_enqueue(LinkedList *list, LinkedListItem *item) +{ + if(list != NULL && item != NULL) + { + LinkedListItem *tail = list->tail; + list->tail = item; + item->next = NULL; + item->prev = tail; + list->size += 1; + + if(tail != NULL) + { + tail->next = item; + } + + if(list->head == NULL) + { + list->head = list->tail; + } + } +} + +/* +Memory Handlers +*/ + +void * +kmip_calloc(void *state, size_t num, size_t size) +{ + (void)state; + return(calloc(num, size)); +} + +void * +kmip_realloc(void *state, void *ptr, size_t size) +{ + (void)state; + return(realloc(ptr, size)); +} + +void +kmip_free(void *state, void *ptr) +{ + (void)state; + free(ptr); + return; +} + +/* TODO (ph) Consider replacing this with memcpy_s, ala memset_s. */ +void * +kmip_memcpy(void *state, void *destination, const void *source, size_t size) +{ + (void)state; + return(memcpy(destination, source, size)); +} + +/* +Enumeration Utilities +*/ + +static const char *kmip_attribute_names[] = { + "Unique Identifier", + "Name", + "Object Type", + "Cryptographic Algorithm", + "Cryptographic Length", + "Cryptographic Parameters", + "Cryptographic Domain Parameters", + "Certificate Type", + "Certificate Length", + "X.509 Certificate Identifier", + "X.509 Certificate Subject", + "X.509 Certificate Issuer", + "Certificate Identifier", + "Certificate Subject", + "Certificate Issuer", + "Digital Signature Algorithm", + "Digest", + "Operation Policy Name", + "Cryptographic Usage Mask", + "Lease Time", + "Usage Limits", + "State", + "Initial Date", + "Activation Date", + "Process Start Date", + "Protect Stop Date", + "Deactivation Date", + "Destroy Date", + "Compromise Occurrence Date", + "Compromise Date", + "Revocation Reason", + "Archive Date", + "Object Group", + "Fresh", + "Link", + "Application Specific Information", + "Contact Information", + "Last Change Date", + "Alternative Name", + "Key Value Present", + "Key Value Location", + "Original Creation Date", + "Random Number Generator", + "PKCS#12 Friendly Name", + "Description", + "Comment", + "Sensitive", + "Always Sensitive", + "Extractable", + "Never Extractable", + "Key Format Type", + "Unknown" /* Catch all for unsupported enumerations */ +}; + +int +kmip_get_enum_string_index(enum tag t) +{ + switch(t) + { + case KMIP_TAG_UNIQUE_IDENTIFIER: + return(0); + break; + + case KMIP_TAG_NAME: + return(1); + break; + + case KMIP_TAG_OBJECT_TYPE: + return(2); + break; + + case KMIP_TAG_CRYPTOGRAPHIC_ALGORITHM: + return(3); + break; + + case KMIP_TAG_CRYPTOGRAPHIC_LENGTH: + return(4); + break; + + case KMIP_TAG_CRYPTOGRAPHIC_PARAMETERS: + return(5); + break; + + case KMIP_TAG_CRYPTOGRAPHIC_DOMAIN_PARAMETERS: + return(6); + break; + + case KMIP_TAG_CERTIFICATE_TYPE: + return(7); + break; + + case KMIP_TAG_CERTIFICATE_LENGTH: + return(8); + break; + + case KMIP_TAG_X509_CERTIFICATE_IDENTIFIER: + return(9); + break; + + case KMIP_TAG_X509_CERTIFICATE_SUBJECT: + return(10); + break; + + case KMIP_TAG_X509_CERTIFICATE_ISSUER: + return(11); + break; + + case KMIP_TAG_CERTIFICATE_IDENTIFIER: + return(12); + break; + + case KMIP_TAG_CERTIFICATE_SUBJECT: + return(13); + break; + + case KMIP_TAG_CERTIFICATE_ISSUER: + return(14); + break; + + case KMIP_TAG_DIGITAL_SIGNATURE_ALGORITHM: + return(15); + break; + + case KMIP_TAG_DIGEST: + return(16); + break; + + case KMIP_TAG_OPERATION_POLICY_NAME: + return(17); + break; + + case KMIP_TAG_CRYPTOGRAPHIC_USAGE_MASK: + return(18); + break; + + case KMIP_TAG_LEASE_TIME: + return(19); + break; + + case KMIP_TAG_USAGE_LIMITS: + return(20); + break; + + case KMIP_TAG_STATE: + return(21); + break; + + case KMIP_TAG_INITIAL_DATE: + return(22); + break; + + case KMIP_TAG_ACTIVATION_DATE: + return(23); + break; + + case KMIP_TAG_PROCESS_START_DATE: + return(24); + break; + + case KMIP_TAG_PROTECT_STOP_DATE: + return(25); + break; + + case KMIP_TAG_DEACTIVATION_DATE: + return(26); + break; + + case KMIP_TAG_DESTROY_DATE: + return(27); + break; + + case KMIP_TAG_COMPROMISE_OCCURRENCE_DATE: + return(28); + break; + + case KMIP_TAG_COMPROMISE_DATE: + return(29); + break; + + case KMIP_TAG_REVOCATION_REASON: + return(30); + break; + + case KMIP_TAG_ARCHIVE_DATE: + return(31); + break; + + case KMIP_TAG_OBJECT_GROUP: + return(32); + break; + + case KMIP_TAG_FRESH: + return(33); + break; + + case KMIP_TAG_LINK: + return(34); + break; + + case KMIP_TAG_APPLICATION_SPECIFIC_INFORMATION: + return(35); + break; + + case KMIP_TAG_CONTACT_INFORMATION: + return(36); + break; + + case KMIP_TAG_LAST_CHANGE_DATE: + return(37); + break; + + case KMIP_TAG_ALTERNATIVE_NAME: + return(38); + break; + + case KMIP_TAG_KEY_VALUE_PRESENT: + return(39); + break; + + case KMIP_TAG_KEY_VALUE_LOCATION: + return(40); + break; + + case KMIP_TAG_ORIGINAL_CREATION_DATE: + return(41); + break; + + case KMIP_TAG_RANDOM_NUMBER_GENERATOR: + return(42); + break; + + case KMIP_TAG_PKCS_12_FRIENDLY_NAME: + return(43); + break; + + case KMIP_TAG_DESCRIPTION: + return(44); + break; + + case KMIP_TAG_COMMENT: + return(45); + break; + + case KMIP_TAG_SENSITIVE: + return(46); + break; + + case KMIP_TAG_ALWAYS_SENSITIVE: + return(47); + break; + + case KMIP_TAG_EXTRACTABLE: + return(48); + break; + + case KMIP_TAG_NEVER_EXTRACTABLE: + return(49); + break; + + case KMIP_TAG_KEY_FORMAT_TYPE: + return(50); + break; + + default: + return(51); + break; + }; +} + +int +kmip_check_enum_value(enum kmip_version version, enum tag t, int value) +{ + int m; + switch(t) + { + case KMIP_TAG_ATTESTATION_TYPE: + switch(value) + { + case KMIP_ATTEST_TPM_QUOTE: + case KMIP_ATTEST_TCG_INTEGRITY_REPORT: + case KMIP_ATTEST_SAML_ASSERTION: + if(version >= KMIP_1_2) + return(KMIP_OK); + else + return(KMIP_INVALID_FOR_VERSION); + break; + + default: + return(KMIP_ENUM_MISMATCH); + break; + }; + break; + + case KMIP_TAG_BATCH_ERROR_CONTINUATION_OPTION: + switch(value) + { + case KMIP_BATCH_CONTINUE: + case KMIP_BATCH_STOP: + case KMIP_BATCH_UNDO: + return(KMIP_OK); + break; + + default: + return(KMIP_ENUM_MISMATCH); + break; + }; + break; + + case KMIP_TAG_BLOCK_CIPHER_MODE: + switch(value) + { + case KMIP_BLOCK_CBC: + case KMIP_BLOCK_ECB: + case KMIP_BLOCK_PCBC: + case KMIP_BLOCK_CFB: + case KMIP_BLOCK_OFB: + case KMIP_BLOCK_CTR: + case KMIP_BLOCK_CMAC: + case KMIP_BLOCK_CCM: + case KMIP_BLOCK_GCM: + case KMIP_BLOCK_CBC_MAC: + case KMIP_BLOCK_XTS: + case KMIP_BLOCK_AES_KEY_WRAP_PADDING: + case KMIP_BLOCK_NIST_KEY_WRAP: + case KMIP_BLOCK_X9102_AESKW: + case KMIP_BLOCK_X9102_TDKW: + case KMIP_BLOCK_X9102_AKW1: + case KMIP_BLOCK_X9102_AKW2: + return(KMIP_OK); + break; + + case KMIP_BLOCK_AEAD: + if(version >= KMIP_1_4) + return(KMIP_OK); + else + return(KMIP_INVALID_FOR_VERSION); + break; + + default: + return(KMIP_ENUM_MISMATCH); + break; + }; + break; + + case KMIP_TAG_CREDENTIAL_TYPE: + switch(value) + { + case KMIP_CRED_USERNAME_AND_PASSWORD: + return(KMIP_OK); + break; + + case KMIP_CRED_DEVICE: + if(version >= KMIP_1_1) + return(KMIP_OK); + else + return(KMIP_INVALID_FOR_VERSION); + break; + + case KMIP_CRED_ATTESTATION: + if(version >= KMIP_1_2) + return(KMIP_OK); + else + return(KMIP_INVALID_FOR_VERSION); + break; + + /* KMIP 2.0 */ + case KMIP_CRED_ONE_TIME_PASSWORD: + case KMIP_CRED_HASHED_PASSWORD: + case KMIP_CRED_TICKET: + if(version >= KMIP_2_0) + return(KMIP_OK); + else + return(KMIP_INVALID_FOR_VERSION); + break; + + default: + return(KMIP_ENUM_MISMATCH); + break; + }; + break; + + case KMIP_TAG_CRYPTOGRAPHIC_ALGORITHM: + switch(value) + { + case KMIP_CRYPTOALG_DES: + case KMIP_CRYPTOALG_TRIPLE_DES: + case KMIP_CRYPTOALG_AES: + case KMIP_CRYPTOALG_RSA: + case KMIP_CRYPTOALG_DSA: + case KMIP_CRYPTOALG_ECDSA: + case KMIP_CRYPTOALG_HMAC_SHA1: + case KMIP_CRYPTOALG_HMAC_SHA224: + case KMIP_CRYPTOALG_HMAC_SHA256: + case KMIP_CRYPTOALG_HMAC_SHA384: + case KMIP_CRYPTOALG_HMAC_SHA512: + case KMIP_CRYPTOALG_HMAC_MD5: + case KMIP_CRYPTOALG_DH: + case KMIP_CRYPTOALG_ECDH: + case KMIP_CRYPTOALG_ECMQV: + case KMIP_CRYPTOALG_BLOWFISH: + case KMIP_CRYPTOALG_CAMELLIA: + case KMIP_CRYPTOALG_CAST5: + case KMIP_CRYPTOALG_IDEA: + case KMIP_CRYPTOALG_MARS: + case KMIP_CRYPTOALG_RC2: + case KMIP_CRYPTOALG_RC4: + case KMIP_CRYPTOALG_RC5: + case KMIP_CRYPTOALG_SKIPJACK: + case KMIP_CRYPTOALG_TWOFISH: + return(KMIP_OK); + break; + + case KMIP_CRYPTOALG_EC: + if(version >= KMIP_1_2) + return(KMIP_OK); + else + return(KMIP_INVALID_FOR_VERSION); + break; + + case KMIP_CRYPTOALG_ONE_TIME_PAD: + if(version >= KMIP_1_3) + return(KMIP_OK); + else + return(KMIP_INVALID_FOR_VERSION); + break; + + case KMIP_CRYPTOALG_CHACHA20: + case KMIP_CRYPTOALG_POLY1305: + case KMIP_CRYPTOALG_CHACHA20_POLY1305: + case KMIP_CRYPTOALG_SHA3_224: + case KMIP_CRYPTOALG_SHA3_256: + case KMIP_CRYPTOALG_SHA3_384: + case KMIP_CRYPTOALG_SHA3_512: + case KMIP_CRYPTOALG_HMAC_SHA3_224: + case KMIP_CRYPTOALG_HMAC_SHA3_256: + case KMIP_CRYPTOALG_HMAC_SHA3_384: + case KMIP_CRYPTOALG_HMAC_SHA3_512: + case KMIP_CRYPTOALG_SHAKE_128: + case KMIP_CRYPTOALG_SHAKE_256: + if(version >= KMIP_1_4) + return(KMIP_OK); + else + return(KMIP_INVALID_FOR_VERSION); + break; + + /* KMIP 2.0 */ + case KMIP_CRYPTOALG_ARIA: + case KMIP_CRYPTOALG_SEED: + case KMIP_CRYPTOALG_SM2: + case KMIP_CRYPTOALG_SM3: + case KMIP_CRYPTOALG_SM4: + case KMIP_CRYPTOALG_GOST_R_34_10_2012: + case KMIP_CRYPTOALG_GOST_R_34_11_2012: + case KMIP_CRYPTOALG_GOST_R_34_13_2015: + case KMIP_CRYPTOALG_GOST_28147_89: + case KMIP_CRYPTOALG_XMSS: + case KMIP_CRYPTOALG_SPHINCS_256: + case KMIP_CRYPTOALG_MCELIECE: + case KMIP_CRYPTOALG_MCELIECE_6960119: + case KMIP_CRYPTOALG_MCELIECE_8192128: + case KMIP_CRYPTOALG_ED25519: + case KMIP_CRYPTOALG_ED448: + if(version >= KMIP_2_0) + return(KMIP_OK); + else + return(KMIP_INVALID_FOR_VERSION); + break; + + default: + return(KMIP_ENUM_MISMATCH); + break; + }; + break; + + case KMIP_TAG_CRYPTOGRAPHIC_USAGE_MASK: + switch(value) + { + case KMIP_CRYPTOMASK_SIGN: + case KMIP_CRYPTOMASK_VERIFY: + case KMIP_CRYPTOMASK_ENCRYPT: + case KMIP_CRYPTOMASK_DECRYPT: + case KMIP_CRYPTOMASK_WRAP_KEY: + case KMIP_CRYPTOMASK_UNWRAP_KEY: + case KMIP_CRYPTOMASK_EXPORT: + case KMIP_CRYPTOMASK_MAC_GENERATE: + case KMIP_CRYPTOMASK_MAC_VERIFY: + case KMIP_CRYPTOMASK_DERIVE_KEY: + case KMIP_CRYPTOMASK_CONTENT_COMMITMENT: + case KMIP_CRYPTOMASK_KEY_AGREEMENT: + case KMIP_CRYPTOMASK_CERTIFICATE_SIGN: + case KMIP_CRYPTOMASK_CRL_SIGN: + case KMIP_CRYPTOMASK_GENERATE_CRYPTOGRAM: + case KMIP_CRYPTOMASK_VALIDATE_CRYPTOGRAM: + case KMIP_CRYPTOMASK_TRANSLATE_ENCRYPT: + case KMIP_CRYPTOMASK_TRANSLATE_DECRYPT: + case KMIP_CRYPTOMASK_TRANSLATE_WRAP: + case KMIP_CRYPTOMASK_TRANSLATE_UNWRAP: + return(KMIP_OK); + break; + + /* KMIP 2.0 */ + case KMIP_CRYPTOMASK_AUTHENTICATE: + case KMIP_CRYPTOMASK_UNRESTRICTED: + case KMIP_CRYPTOMASK_FPE_ENCRYPT: + case KMIP_CRYPTOMASK_FPE_DECRYPT: + if(version >= KMIP_2_0) + return(KMIP_OK); + else + return(KMIP_INVALID_FOR_VERSION); + break; + + default: + return(KMIP_ENUM_MISMATCH); + break; + }; + break; + + case KMIP_TAG_DIGITAL_SIGNATURE_ALGORITHM: + switch(value) + { + case KMIP_DIGITAL_MD2_WITH_RSA: + case KMIP_DIGITAL_MD5_WITH_RSA: + case KMIP_DIGITAL_SHA1_WITH_RSA: + case KMIP_DIGITAL_SHA224_WITH_RSA: + case KMIP_DIGITAL_SHA256_WITH_RSA: + case KMIP_DIGITAL_SHA384_WITH_RSA: + case KMIP_DIGITAL_SHA512_WITH_RSA: + case KMIP_DIGITAL_RSASSA_PSS: + case KMIP_DIGITAL_DSA_WITH_SHA1: + case KMIP_DIGITAL_DSA_WITH_SHA224: + case KMIP_DIGITAL_DSA_WITH_SHA256: + case KMIP_DIGITAL_ECDSA_WITH_SHA1: + case KMIP_DIGITAL_ECDSA_WITH_SHA224: + case KMIP_DIGITAL_ECDSA_WITH_SHA256: + case KMIP_DIGITAL_ECDSA_WITH_SHA384: + case KMIP_DIGITAL_ECDSA_WITH_SHA512: + if(version >= KMIP_1_1) + return(KMIP_OK); + else + return(KMIP_INVALID_FOR_VERSION); + break; + + case KMIP_DIGITAL_SHA3_256_WITH_RSA: + case KMIP_DIGITAL_SHA3_384_WITH_RSA: + case KMIP_DIGITAL_SHA3_512_WITH_RSA: + if(version >= KMIP_1_4) + return(KMIP_OK); + else + return(KMIP_INVALID_FOR_VERSION); + break; + + default: + return(KMIP_ENUM_MISMATCH); + break; + }; + break; + + case KMIP_TAG_ENCODING_OPTION: + switch(value) + { + case KMIP_ENCODE_NO_ENCODING: + case KMIP_ENCODE_TTLV_ENCODING: + if(version >= KMIP_1_1) + return(KMIP_OK); + else + return(KMIP_INVALID_FOR_VERSION); + break; + + default: + return(KMIP_ENUM_MISMATCH); + break; + }; + break; + + case KMIP_TAG_HASHING_ALGORITHM: + switch(value) + { + case KMIP_HASH_MD2: + case KMIP_HASH_MD4: + case KMIP_HASH_MD5: + case KMIP_HASH_SHA1: + case KMIP_HASH_SHA224: + case KMIP_HASH_SHA256: + case KMIP_HASH_SHA384: + case KMIP_HASH_SHA512: + case KMIP_HASH_RIPEMD160: + case KMIP_HASH_TIGER: + case KMIP_HASH_WHIRLPOOL: + return(KMIP_OK); + break; + + case KMIP_HASH_SHA512_224: + case KMIP_HASH_SHA512_256: + if(version >= KMIP_1_2) + return(KMIP_OK); + else + return(KMIP_INVALID_FOR_VERSION); + break; + + case KMIP_HASH_SHA3_224: + case KMIP_HASH_SHA3_256: + case KMIP_HASH_SHA3_384: + case KMIP_HASH_SHA3_512: + if(version >= KMIP_1_4) + return(KMIP_OK); + else + return(KMIP_INVALID_FOR_VERSION); + break; + + default: + return(KMIP_ENUM_MISMATCH); + break; + }; + break; + + case KMIP_TAG_KEY_COMPRESSION_TYPE: + switch(value) + { + case KMIP_KEYCOMP_EC_PUB_UNCOMPRESSED: + case KMIP_KEYCOMP_EC_PUB_X962_COMPRESSED_PRIME: + case KMIP_KEYCOMP_EC_PUB_X962_COMPRESSED_CHAR2: + case KMIP_KEYCOMP_EC_PUB_X962_HYBRID: + return(KMIP_OK); + break; + + default: + return(KMIP_ENUM_MISMATCH); + break; + }; + break; + + case KMIP_TAG_KEY_FORMAT_TYPE: + switch(value) + { + case KMIP_KEYFORMAT_RAW: + case KMIP_KEYFORMAT_OPAQUE: + case KMIP_KEYFORMAT_PKCS1: + case KMIP_KEYFORMAT_PKCS8: + case KMIP_KEYFORMAT_X509: + case KMIP_KEYFORMAT_EC_PRIVATE_KEY: + case KMIP_KEYFORMAT_TRANS_SYMMETRIC_KEY: + case KMIP_KEYFORMAT_TRANS_DSA_PRIVATE_KEY: + case KMIP_KEYFORMAT_TRANS_DSA_PUBLIC_KEY: + case KMIP_KEYFORMAT_TRANS_RSA_PRIVATE_KEY: + case KMIP_KEYFORMAT_TRANS_RSA_PUBLIC_KEY: + case KMIP_KEYFORMAT_TRANS_DH_PRIVATE_KEY: + case KMIP_KEYFORMAT_TRANS_DH_PUBLIC_KEY: + return(KMIP_OK); + break; + + /* The following set is deprecated as of KMIP 1.3 */ + case KMIP_KEYFORMAT_TRANS_ECDSA_PRIVATE_KEY: + case KMIP_KEYFORMAT_TRANS_ECDSA_PUBLIC_KEY: + case KMIP_KEYFORMAT_TRANS_ECDH_PRIVATE_KEY: + case KMIP_KEYFORMAT_TRANS_ECDH_PUBLIC_KEY: + case KMIP_KEYFORMAT_TRANS_ECMQV_PRIVATE_KEY: + case KMIP_KEYFORMAT_TRANS_ECMQV_PUBLIC_KEY: + /* TODO (ph) What should happen if version >= 1.3? */ + return(KMIP_OK); + break; + + case KMIP_KEYFORMAT_TRANS_EC_PRIVATE_KEY: + case KMIP_KEYFORMAT_TRANS_EC_PUBLIC_KEY: + if(version >= KMIP_1_3) + return(KMIP_OK); + else + return(KMIP_INVALID_FOR_VERSION); + break; + + case KMIP_KEYFORMAT_PKCS12: + if(version >= KMIP_1_4) + return(KMIP_OK); + else + return(KMIP_INVALID_FOR_VERSION); + break; + + /* KMIP 2.0 */ + case KMIP_KEYFORMAT_PKCS10: + if(version >= KMIP_2_0) + return(KMIP_OK); + else + return(KMIP_INVALID_FOR_VERSION); + break; + + default: + return(KMIP_ENUM_MISMATCH); + break; + }; + break; + + case KMIP_TAG_KEY_ROLE_TYPE: + switch(value) + { + /* KMIP 1.0 */ + case KMIP_ROLE_BDK: + case KMIP_ROLE_CVK: + case KMIP_ROLE_DEK: + case KMIP_ROLE_MKAC: + case KMIP_ROLE_MKSMC: + case KMIP_ROLE_MKSMI: + case KMIP_ROLE_MKDAC: + case KMIP_ROLE_MKDN: + case KMIP_ROLE_MKCP: + case KMIP_ROLE_MKOTH: + case KMIP_ROLE_KEK: + case KMIP_ROLE_MAC16609: + case KMIP_ROLE_MAC97971: + case KMIP_ROLE_MAC97972: + case KMIP_ROLE_MAC97973: + case KMIP_ROLE_MAC97974: + case KMIP_ROLE_MAC97975: + case KMIP_ROLE_ZPK: + case KMIP_ROLE_PVKIBM: + case KMIP_ROLE_PVKPVV: + case KMIP_ROLE_PVKOTH: + return(KMIP_OK); + break; + + /* KMIP 1.4 */ + case KMIP_ROLE_DUKPT: + case KMIP_ROLE_IV: + case KMIP_ROLE_TRKBK: + if(version >= KMIP_1_4) + return(KMIP_OK); + else + return(KMIP_INVALID_FOR_VERSION); + break; + + default: + return(KMIP_ENUM_MISMATCH); + break; + }; + break; + + case KMIP_TAG_KEY_WRAP_TYPE: + switch(value) + { + /* KMIP 1.4 */ + case KMIP_WRAPTYPE_NOT_WRAPPED: + case KMIP_WRAPTYPE_AS_REGISTERED: + if(version >= KMIP_1_4) + return(KMIP_OK); + else + return(KMIP_INVALID_FOR_VERSION); + break; + + default: + return(KMIP_ENUM_MISMATCH); + break; + }; + break; + + case KMIP_TAG_MASK_GENERATOR: + switch(value) + { + /* KMIP 1.4 */ + case KMIP_MASKGEN_MGF1: + if(version >= KMIP_1_4) + return(KMIP_OK); + else + return(KMIP_INVALID_FOR_VERSION); + break; + + default: + return(KMIP_ENUM_MISMATCH); + break; + }; + break; + + case KMIP_TAG_NAME_TYPE: + switch(value) + { + /* KMIP 1.0 */ + case KMIP_NAME_UNINTERPRETED_TEXT_STRING: + case KMIP_NAME_URI: + return(KMIP_OK); + break; + + default: + return(KMIP_ENUM_MISMATCH); + break; + }; + break; + + case KMIP_TAG_OBJECT_TYPE: + switch(value) + { + /* KMIP 1.0 */ + case KMIP_OBJTYPE_CERTIFICATE: + case KMIP_OBJTYPE_SYMMETRIC_KEY: + case KMIP_OBJTYPE_PUBLIC_KEY: + case KMIP_OBJTYPE_PRIVATE_KEY: + case KMIP_OBJTYPE_SPLIT_KEY: + case KMIP_OBJTYPE_SECRET_DATA: + case KMIP_OBJTYPE_OPAQUE_OBJECT: + return(KMIP_OK); + break; + + /* The following set is deprecated as of KMIP 1.3 */ + case KMIP_OBJTYPE_TEMPLATE: + /* TODO (ph) What should happen if version >= 1.3? */ + return(KMIP_OK); + break; + + /* KMIP 1.2 */ + case KMIP_OBJTYPE_PGP_KEY: + if(version >= KMIP_1_2) + return(KMIP_OK); + else + return(KMIP_INVALID_FOR_VERSION); + break; + + /* KMIP 2.0 */ + case KMIP_OBJTYPE_CERTIFICATE_REQUEST: + if(version >= KMIP_2_0) + return(KMIP_OK); + else + return(KMIP_INVALID_FOR_VERSION); + break; + + default: + return(KMIP_ENUM_MISMATCH); + break; + }; + break; + + case KMIP_TAG_OPERATION: + switch(value) + { + case KMIP_OP_EXPORT: + case KMIP_OP_IMPORT: + if(version < KMIP_1_4) + return(KMIP_INVALID_FOR_VERSION); + else return(KMIP_OK); + + case KMIP_OP_JOIN_SPLIT_KEY: + case KMIP_OP_CREATE_SPLIT_KEY: + case KMIP_OP_HASH: + case KMIP_OP_RNG_SEED: + case KMIP_OP_RNG_RETRIEVE: + case KMIP_OP_MAC_VERIFY: + case KMIP_OP_MAC: + case KMIP_OP_SIGNATURE_VERIFY: + case KMIP_OP_SIGN: + case KMIP_OP_DECRYPT: + case KMIP_OP_ENCRYPT: + if(version < KMIP_1_2) + return(KMIP_INVALID_FOR_VERSION); + else return(KMIP_OK); + + case KMIP_OP_DISCOVER_VERSIONS: + case KMIP_OP_REKEY_KEY_PAIR: + if(version < KMIP_1_1) + return(KMIP_INVALID_FOR_VERSION); + else return(KMIP_OK); + + /* KMIP 1.0 */ + case KMIP_OP_PUT: + case KMIP_OP_NOTIFY: + case KMIP_OP_POLL: + case KMIP_OP_CANCEL: + case KMIP_OP_QUERY: + case KMIP_OP_VALIDATE: + case KMIP_OP_RECOVER: + case KMIP_OP_ARCHIVE: + case KMIP_OP_DESTROY: + case KMIP_OP_REVOKE: + case KMIP_OP_ACTIVATE: + case KMIP_OP_GET_USAGE_ALLOCATION: + case KMIP_OP_OBTAIN_LEASE: + case KMIP_OP_DELETE_ATTRIBUTE: + case KMIP_OP_MODIFY_ATTRIBUTE: + case KMIP_OP_ADD_ATTRIBUTE: + case KMIP_OP_GET_ATTRIBUTE_LIST: + case KMIP_OP_GET_ATTRIBUTES: + case KMIP_OP_GET: + case KMIP_OP_CHECK: + case KMIP_OP_LOCATE: + case KMIP_OP_RECERTIFY: + case KMIP_OP_CERTIFY: + case KMIP_OP_DERIVE_KEY: + case KMIP_OP_REKEY: + case KMIP_OP_REGISTER: + case KMIP_OP_CREATE_KEY_PAIR: + case KMIP_OP_CREATE: + return(KMIP_OK); + + default: + return(KMIP_ENUM_MISMATCH); + }; + break; + + case KMIP_TAG_PADDING_METHOD: + switch(value) + { + /* KMIP 1.0 */ + case KMIP_PAD_NONE: + case KMIP_PAD_OAEP: + case KMIP_PAD_PKCS5: + case KMIP_PAD_SSL3: + case KMIP_PAD_ZEROS: + case KMIP_PAD_ANSI_X923: + case KMIP_PAD_ISO_10126: + case KMIP_PAD_PKCS1v15: + case KMIP_PAD_X931: + case KMIP_PAD_PSS: + return(KMIP_OK); + break; + + default: + return(KMIP_ENUM_MISMATCH); + break; + }; + break; + + case KMIP_TAG_PROTECTION_STORAGE_MASK: + { + switch(value) + { + /* KMIP 2.0 */ + case KMIP_PROTECT_SOFTWARE: + case KMIP_PROTECT_HARDWARE: + case KMIP_PROTECT_ON_PROCESSOR: + case KMIP_PROTECT_ON_SYSTEM: + case KMIP_PROTECT_OFF_SYSTEM: + case KMIP_PROTECT_HYPERVISOR: + case KMIP_PROTECT_OPERATING_SYSTEM: + case KMIP_PROTECT_CONTAINER: + case KMIP_PROTECT_ON_PREMISES: + case KMIP_PROTECT_OFF_PREMISES: + case KMIP_PROTECT_SELF_MANAGED: + case KMIP_PROTECT_OUTSOURCED: + case KMIP_PROTECT_VALIDATED: + case KMIP_PROTECT_SAME_JURISDICTION: + if(version >= KMIP_2_0) + return(KMIP_OK); + else + return(KMIP_INVALID_FOR_VERSION); + break; + + default: + return(KMIP_ENUM_MISMATCH); + break; + }; + }; + break; + + case KMIP_TAG_RESULT_REASON: + switch(value) + { + /* KMIP 1.0 */ + case KMIP_REASON_GENERAL_FAILURE: + case KMIP_REASON_ITEM_NOT_FOUND: + case KMIP_REASON_RESPONSE_TOO_LARGE: + case KMIP_REASON_AUTHENTICATION_NOT_SUCCESSFUL: + case KMIP_REASON_INVALID_MESSAGE: + case KMIP_REASON_OPERATION_NOT_SUPPORTED: + case KMIP_REASON_MISSING_DATA: + case KMIP_REASON_INVALID_FIELD: + case KMIP_REASON_FEATURE_NOT_SUPPORTED: + case KMIP_REASON_OPERATION_CANCELED_BY_REQUESTER: + case KMIP_REASON_CRYPTOGRAPHIC_FAILURE: + case KMIP_REASON_ILLEGAL_OPERATION: + case KMIP_REASON_PERMISSION_DENIED: + case KMIP_REASON_OBJECT_ARCHIVED: + case KMIP_REASON_INDEX_OUT_OF_BOUNDS: + case KMIP_REASON_APPLICATION_NAMESPACE_NOT_SUPPORTED: + case KMIP_REASON_KEY_FORMAT_TYPE_NOT_SUPPORTED: + case KMIP_REASON_KEY_COMPRESSION_TYPE_NOT_SUPPORTED: + return(KMIP_OK); + break; + + /* KMIP 1.1 */ + case KMIP_REASON_ENCODING_OPTION_FAILURE: + if(version >= KMIP_1_1) + return(KMIP_OK); + else + return(KMIP_INVALID_FOR_VERSION); + break; + + /* KMIP 1.2 */ + case KMIP_REASON_KEY_VALUE_NOT_PRESENT: + case KMIP_REASON_ATTESTATION_REQUIRED: + case KMIP_REASON_ATTESTATION_FAILED: + if(version >= KMIP_1_2) + return(KMIP_OK); + else + return(KMIP_INVALID_FOR_VERSION); + break; + + /* KMIP 1.4 */ + case KMIP_REASON_SENSITIVE: + case KMIP_REASON_NOT_EXTRACTABLE: + case KMIP_REASON_OBJECT_ALREADY_EXISTS: + if(version >= KMIP_1_4) + return(KMIP_OK); + else + return(KMIP_INVALID_FOR_VERSION); + break; + + /* KMIP 2.0 */ + case KMIP_REASON_INVALID_TICKET: + case KMIP_REASON_USAGE_LIMIT_EXCEEDED: + case KMIP_REASON_NUMERIC_RANGE: + case KMIP_REASON_INVALID_DATA_TYPE: + case KMIP_REASON_READ_ONLY_ATTRIBUTE: + case KMIP_REASON_MULTI_VALUED_ATTRIBUTE: + case KMIP_REASON_UNSUPPORTED_ATTRIBUTE: + case KMIP_REASON_ATTRIBUTE_INSTANCE_NOT_FOUND: + case KMIP_REASON_ATTRIBUTE_NOT_FOUND: + case KMIP_REASON_ATTRIBUTE_READ_ONLY: + case KMIP_REASON_ATTRIBUTE_SINGLE_VALUED: + case KMIP_REASON_BAD_CRYPTOGRAPHIC_PARAMETERS: + case KMIP_REASON_BAD_PASSWORD: + case KMIP_REASON_CODEC_ERROR: + case KMIP_REASON_ILLEGAL_OBJECT_TYPE: + case KMIP_REASON_INCOMPATIBLE_CRYPTOGRAPHIC_USAGE_MASK: + case KMIP_REASON_INTERNAL_SERVER_ERROR: + case KMIP_REASON_INVALID_ASYNCHRONOUS_CORRELATION_VALUE: + case KMIP_REASON_INVALID_ATTRIBUTE: + case KMIP_REASON_INVALID_ATTRIBUTE_VALUE: + case KMIP_REASON_INVALID_CORRELATION_VALUE: + case KMIP_REASON_INVALID_CSR: + case KMIP_REASON_INVALID_OBJECT_TYPE: + case KMIP_REASON_KEY_WRAP_TYPE_NOT_SUPPORTED: + case KMIP_REASON_MISSING_INITIALIZATION_VECTOR: + case KMIP_REASON_NON_UNIQUE_NAME_ATTRIBUTE: + case KMIP_REASON_OBJECT_DESTROYED: + case KMIP_REASON_OBJECT_NOT_FOUND: + case KMIP_REASON_NOT_AUTHORISED: + case KMIP_REASON_SERVER_LIMIT_EXCEEDED: + case KMIP_REASON_UNKNOWN_ENUMERATION: + case KMIP_REASON_UNKNOWN_MESSAGE_EXTENSION: + case KMIP_REASON_UNKNOWN_TAG: + case KMIP_REASON_UNSUPPORTED_CRYPTOGRAPHIC_PARAMETERS: + case KMIP_REASON_UNSUPPORTED_PROTOCOL_VERSION: + case KMIP_REASON_WRAPPING_OBJECT_ARCHIVED: + case KMIP_REASON_WRAPPING_OBJECT_DESTROYED: + case KMIP_REASON_WRAPPING_OBJECT_NOT_FOUND: + case KMIP_REASON_WRONG_KEY_LIFECYCLE_STATE: + case KMIP_REASON_PROTECTION_STORAGE_UNAVAILABLE: + case KMIP_REASON_PKCS11_CODEC_ERROR: + case KMIP_REASON_PKCS11_INVALID_FUNCTION: + case KMIP_REASON_PKCS11_INVALID_INTERFACE: + case KMIP_REASON_PRIVATE_PROTECTION_STORAGE_UNAVAILABLE: + case KMIP_REASON_PUBLIC_PROTECTION_STORAGE_UNAVAILABLE: + if(version >= KMIP_2_0) + return(KMIP_OK); + else + return(KMIP_INVALID_FOR_VERSION); + break; + + default: + return(KMIP_ENUM_MISMATCH); + break; + }; + break; + + case KMIP_TAG_RESULT_STATUS: + switch(value) + { + /* KMIP 1.0 */ + case KMIP_STATUS_SUCCESS: + case KMIP_STATUS_OPERATION_FAILED: + case KMIP_STATUS_OPERATION_PENDING: + case KMIP_STATUS_OPERATION_UNDONE: + return(KMIP_OK); + break; + + default: + return(KMIP_ENUM_MISMATCH); + break; + }; + break; + + case KMIP_TAG_STATE: + switch(value) + { + /* KMIP 1.0 */ + case KMIP_STATE_PRE_ACTIVE: + case KMIP_STATE_ACTIVE: + case KMIP_STATE_DEACTIVATED: + case KMIP_STATE_COMPROMISED: + case KMIP_STATE_DESTROYED: + case KMIP_STATE_DESTROYED_COMPROMISED: + return(KMIP_OK); + break; + + default: + return(KMIP_ENUM_MISMATCH); + break; + }; + break; + + case KMIP_TAG_TAG: + return(KMIP_OK); + break; + + case KMIP_TAG_TYPE: + switch(value) + { + /* KMIP 1.0 */ + case KMIP_TYPE_STRUCTURE: + case KMIP_TYPE_INTEGER: + case KMIP_TYPE_LONG_INTEGER: + case KMIP_TYPE_BIG_INTEGER: + case KMIP_TYPE_ENUMERATION: + case KMIP_TYPE_BOOLEAN: + case KMIP_TYPE_TEXT_STRING: + case KMIP_TYPE_BYTE_STRING: + case KMIP_TYPE_DATE_TIME: + case KMIP_TYPE_INTERVAL: + return(KMIP_OK); + break; + + /* KMIP 2.0 */ + case KMIP_TYPE_DATE_TIME_EXTENDED: + if(version >= KMIP_2_0) + return(KMIP_OK); + else + return(KMIP_INVALID_FOR_VERSION); + break; + + default: + return(KMIP_ENUM_MISMATCH); + break; + }; + break; + + case KMIP_TAG_WRAPPING_METHOD: + switch(value) + { + /* KMIP 1.0 */ + case KMIP_WRAP_ENCRYPT: + case KMIP_WRAP_MAC_SIGN: + case KMIP_WRAP_ENCRYPT_MAC_SIGN: + case KMIP_WRAP_MAC_SIGN_ENCRYPT: + case KMIP_WRAP_TR31: + return(KMIP_OK); + break; + + default: + return(KMIP_ENUM_MISMATCH); + break; + }; + break; + + case KMIP_TAG_STORAGE_STATUS_MASK: + if ((value & ~(KMIP_OGM_GROUP_MEMBER_FRESH|KMIP_OGM_GROUP_MEMBER_DEFAULT))) + return KMIP_ENUM_MISMATCH; + return KMIP_OK; + + case KMIP_TAG_OBJECT_GROUP_MEMBER: + m = KMIP_SSM_ONLINE_STORAGE | KMIP_SSM_ARCHIVAL_STORAGE; + if(version >= KMIP_2_0) { + m |= KMIP_SSM_DESTROYED_STORAGE; + } + if (value & ~m) + return KMIP_ENUM_MISMATCH; + return KMIP_OK; + break; + + default: + return(KMIP_ENUM_UNSUPPORTED); + break; + }; +} + +/* +Context Utilities +*/ + +void +kmip_clear_errors(KMIP *ctx) +{ + if(ctx == NULL) + { + return; + } + + for(size_t i = 0; i < ARRAY_LENGTH(ctx->errors); i++) + { + ctx->errors[i] = (ErrorFrame){0}; + } + ctx->frame_index = ctx->errors; + + if(ctx->error_message != NULL) + { + ctx->free_func(ctx->state, ctx->error_message); + ctx->error_message = NULL; + } +} + +void +kmip_init(KMIP *ctx, void *buffer, size_t buffer_size, enum kmip_version v) +{ + if(ctx == NULL) + { + return; + } + + ctx->buffer = (uint8 *)buffer; + ctx->index = ctx->buffer; + ctx->size = buffer_size; + ctx->version = v; + + if(ctx->calloc_func == NULL) + { + ctx->calloc_func = &kmip_calloc; + } + if(ctx->realloc_func == NULL) + { + ctx->realloc_func = &kmip_realloc; + } + if(ctx->memset_func == NULL) + { + ctx->memset_func = &kmip_memset; + } + if(ctx->free_func == NULL) + { + ctx->free_func = &kmip_free; + } + if(ctx->memcpy_func == NULL) + ctx->memcpy_func = &kmip_memcpy; + + ctx->max_message_size = 8192; + ctx->error_message_size = 200; + ctx->error_message = NULL; + + ctx->error_frame_count = 20; + + ctx->credential_list = ctx->calloc_func(ctx->state, 1, sizeof(LinkedList)); + + kmip_clear_errors(ctx); +} + +void +kmip_init_error_message(KMIP *ctx) +{ + if(ctx == NULL) + { + return; + } + + if(ctx->error_message == NULL) + { + ctx->error_message = ctx->calloc_func(ctx->state, ctx->error_message_size, sizeof(char)); + } +} + +int +kmip_add_credential(KMIP *ctx, Credential *cred) +{ + if(ctx == NULL || cred == NULL) + { + return(KMIP_UNSET); + } + + LinkedListItem *item = ctx->calloc_func(ctx->state, 1, sizeof(LinkedListItem)); + if(item != NULL) + { + item->data = cred; + kmip_linked_list_push(ctx->credential_list, item); + return(KMIP_OK); + } + + return(KMIP_UNSET); +} + +void +kmip_remove_credentials(KMIP *ctx) +{ + if(ctx == NULL) + { + return; + } + + LinkedListItem *item = kmip_linked_list_pop(ctx->credential_list); + while(item != NULL) + { + ctx->memset_func(item, 0, sizeof(LinkedListItem)); + ctx->free_func(ctx->state, item); + + item = kmip_linked_list_pop(ctx->credential_list); + } +} + +void +kmip_reset(KMIP *ctx) +{ + if(ctx == NULL) + { + return; + } + + if(ctx->buffer != NULL) + { + kmip_memset(ctx->buffer, 0, ctx->size); + } + ctx->index = ctx->buffer; + + kmip_clear_errors(ctx); +} + +void +kmip_rewind(KMIP *ctx) +{ + if(ctx == NULL) + { + return; + } + + ctx->index = ctx->buffer; + + kmip_clear_errors(ctx); +} + +void +kmip_set_buffer(KMIP *ctx, void *buffer, size_t buffer_size) +{ + if(ctx == NULL) + { + return; + } + + /* TODO (ph) Add own_buffer if buffer == NULL? */ + ctx->buffer = (uint8 *)buffer; + ctx->index = ctx->buffer; + ctx->size = buffer_size; +} + +void +kmip_destroy(KMIP *ctx) +{ + if(ctx == NULL) + { + return; + } + + kmip_reset(ctx); + kmip_set_buffer(ctx, NULL, 0); + + kmip_remove_credentials(ctx); + ctx->memset_func(ctx->credential_list, 0, sizeof(LinkedList)); + ctx->free_func(ctx->state, ctx->credential_list); + + ctx->calloc_func = NULL; + ctx->realloc_func = NULL; + ctx->memset_func = NULL; + ctx->free_func = NULL; + ctx->memcpy_func = NULL; + ctx->state = NULL; +} + +void +kmip_push_error_frame(KMIP *ctx, const char *function, const int line) +{ + if(ctx == NULL) + { + return; + } + + for(size_t i = 0; i < 20; i++) + { + ErrorFrame *frame = &ctx->errors[i]; + if(frame->line == 0) + { + ctx->frame_index = frame; + strncpy(frame->function, function, sizeof(frame->function) - 1); + frame->line = line; + break; + } + } +} + +void +kmip_set_enum_error_message(KMIP *ctx, enum tag t, int value, int result) +{ + if(ctx == NULL) + { + return; + } + + switch(result) + { + /* TODO (ph) Update error message for KMIP version 2.0+ */ + case KMIP_INVALID_FOR_VERSION: + kmip_init_error_message(ctx); + snprintf(ctx->error_message, ctx->error_message_size, "KMIP 1.%d does not support %s enumeration value (%d)", ctx->version, kmip_attribute_names[kmip_get_enum_string_index(t)], value); + break; + + default: /* KMIP_ENUM_MISMATCH */ + kmip_init_error_message(ctx); + snprintf(ctx->error_message, ctx->error_message_size, "Invalid %s enumeration value (%d)", kmip_attribute_names[kmip_get_enum_string_index(t)], value); + break; + }; +} + +void +kmip_set_alloc_error_message(KMIP *ctx, size_t size, const char *type) +{ + if(ctx == NULL) + { + return; + } + + kmip_init_error_message(ctx); + snprintf(ctx->error_message, ctx->error_message_size, "Could not allocate %zd bytes for a %s", size, type); +} + +void +kmip_set_error_message(KMIP *ctx, const char *message) +{ + if(ctx == NULL) + { + return; + } + + kmip_init_error_message(ctx); + snprintf(ctx->error_message, ctx->error_message_size, "%s", message); +} + +int +kmip_is_tag_next(const KMIP *ctx, enum tag t) +{ + if(ctx == NULL) + { + return(KMIP_FALSE); + } + + uint8 *index = ctx->index; + + if((ctx->size - (index - ctx->buffer)) < 3) + { + return(KMIP_FALSE); + } + + uint32 tag = 0; + + tag |= ((uint32)*index++ << 16); + tag |= ((uint32)*index++ << 8); + tag |= ((uint32)*index++ << 0); + + if(tag != t) + { + return(KMIP_FALSE); + } + + return(KMIP_TRUE); +} + +int +kmip_is_tag_type_next(const KMIP *ctx, enum tag t, enum type s) +{ + if(ctx == NULL) + { + return(KMIP_FALSE); + } + + uint8 *index = ctx->index; + + if((ctx->size - (index - ctx->buffer)) < 4) + { + return(KMIP_FALSE); + } + + uint32 tag_type = 0; + + tag_type |= ((uint32)*index++ << 24); + tag_type |= ((uint32)*index++ << 16); + tag_type |= ((uint32)*index++ << 8); + tag_type |= ((uint32)*index++ << 0); + + if(tag_type != TAG_TYPE(t, s)) + { + return(KMIP_FALSE); + } + + return(KMIP_TRUE); +} + +int +kmip_get_num_items_next(KMIP *ctx, enum tag t) +{ + if(ctx == NULL) + { + return(0); + } + + int count = 0; + + uint8 *index = ctx->index; + uint32 length = 0; + + while((ctx->size - (ctx->index - ctx->buffer)) > 8) + { + if(kmip_is_tag_next(ctx, t)) + { + ctx->index += 4; + + length = 0; + length |= ((int32)*ctx->index++ << 24); + length |= ((int32)*ctx->index++ << 16); + length |= ((int32)*ctx->index++ << 8); + length |= ((int32)*ctx->index++ << 0); + length += CALCULATE_PADDING(length); + + if((ctx->size - (ctx->index - ctx->buffer)) >= length) + { + ctx->index += length; + count++; + } + else + { + break; + } + } + else + { + break; + } + } + + ctx->index = index; + return(count); +} + +uint32 +kmip_peek_tag(KMIP *ctx) +{ + if(BUFFER_BYTES_LEFT(ctx) < 3) + { + return(0); + } + + uint8 *index = ctx->index; + uint32 tag = 0; + + tag |= ((int32)*index++ << 16); + tag |= ((int32)*index++ << 8); + tag |= ((int32)*index++ << 0); + + return(tag); +} + +int +kmip_is_attribute_tag(uint32 value) +{ + enum tag attribute_tags[] = { + KMIP_TAG_UNIQUE_IDENTIFIER, + KMIP_TAG_NAME, + KMIP_TAG_OBJECT_TYPE, + KMIP_TAG_CRYPTOGRAPHIC_ALGORITHM, + KMIP_TAG_CRYPTOGRAPHIC_LENGTH, + KMIP_TAG_CRYPTOGRAPHIC_PARAMETERS, + KMIP_TAG_CRYPTOGRAPHIC_DOMAIN_PARAMETERS, + KMIP_TAG_CERTIFICATE_TYPE, + KMIP_TAG_CERTIFICATE_LENGTH, + KMIP_TAG_X509_CERTIFICATE_IDENTIFIER, + KMIP_TAG_X509_CERTIFICATE_SUBJECT, + KMIP_TAG_X509_CERTIFICATE_ISSUER, + KMIP_TAG_CERTIFICATE_IDENTIFIER, + KMIP_TAG_CERTIFICATE_SUBJECT, + KMIP_TAG_CERTIFICATE_ISSUER, + KMIP_TAG_DIGITAL_SIGNATURE_ALGORITHM, + KMIP_TAG_DIGEST, + KMIP_TAG_OPERATION_POLICY_NAME, + KMIP_TAG_CRYPTOGRAPHIC_USAGE_MASK, + KMIP_TAG_LEASE_TIME, + KMIP_TAG_USAGE_LIMITS, + KMIP_TAG_STATE, + KMIP_TAG_INITIAL_DATE, + KMIP_TAG_ACTIVATION_DATE, + KMIP_TAG_PROCESS_START_DATE, + KMIP_TAG_PROTECT_STOP_DATE, + KMIP_TAG_DEACTIVATION_DATE, + KMIP_TAG_DESTROY_DATE, + KMIP_TAG_COMPROMISE_OCCURRENCE_DATE, + KMIP_TAG_COMPROMISE_DATE, + KMIP_TAG_REVOCATION_REASON, + KMIP_TAG_ARCHIVE_DATE, + KMIP_TAG_OBJECT_GROUP, + KMIP_TAG_FRESH, + KMIP_TAG_LINK, + KMIP_TAG_APPLICATION_SPECIFIC_INFORMATION, + KMIP_TAG_CONTACT_INFORMATION, + KMIP_TAG_LAST_CHANGE_DATE, + KMIP_TAG_ALTERNATIVE_NAME, + KMIP_TAG_KEY_VALUE_PRESENT, + KMIP_TAG_KEY_VALUE_LOCATION, + KMIP_TAG_ORIGINAL_CREATION_DATE, + KMIP_TAG_RANDOM_NUMBER_GENERATOR, + KMIP_TAG_PKCS_12_FRIENDLY_NAME, + KMIP_TAG_DESCRIPTION, + KMIP_TAG_COMMENT, + KMIP_TAG_SENSITIVE, + KMIP_TAG_ALWAYS_SENSITIVE, + KMIP_TAG_EXTRACTABLE, + KMIP_TAG_NEVER_EXTRACTABLE, + KMIP_TAG_KEY_FORMAT_TYPE + }; + + for(size_t i = 0; i < ARRAY_LENGTH(attribute_tags); i++) + { + if(attribute_tags[i] == value) + { + return(KMIP_TRUE); + } + } + + return(KMIP_FALSE); +} + +/* +Initialization Functions +*/ + +void +kmip_init_protocol_version(ProtocolVersion *value, enum kmip_version kmip_version) +{ + if(value == NULL) + { + return; + } + + switch(kmip_version) + { + case KMIP_2_0: + { + value->major = 2; + value->minor = 0; + }; + break; + + case KMIP_1_4: + { + value->major = 1; + value->minor = 4; + }; + break; + + case KMIP_1_3: + { + value->major = 1; + value->minor = 3; + }; + break; + + case KMIP_1_2: + { + value->major = 1; + value->minor = 2; + }; + break; + + case KMIP_1_1: + { + value->major = 1; + value->minor = 1; + }; + break; + + case KMIP_1_0: + default: + { + value->major = 1; + value->minor = 0; + }; + break; + }; +} + +void +kmip_init_attribute(Attribute *value) +{ + if(value == NULL) + { + return; + } + + value->type = 0; + value->index = KMIP_UNSET; + value->value = NULL; +} + +void +kmip_init_cryptographic_parameters(CryptographicParameters *value) +{ + if(value == NULL) + { + return; + } + + value->block_cipher_mode = 0; + value->padding_method = 0; + value->hashing_algorithm = 0; + value->key_role_type = 0; + + value->digital_signature_algorithm = 0; + value->cryptographic_algorithm = 0; + value->random_iv = KMIP_UNSET; + value->iv_length = KMIP_UNSET; + value->tag_length = KMIP_UNSET; + value->fixed_field_length = KMIP_UNSET; + value->invocation_field_length = KMIP_UNSET; + value->counter_length = KMIP_UNSET; + value->initial_counter_value = KMIP_UNSET; + + value->salt_length = KMIP_UNSET; + value->mask_generator = 0; + value->mask_generator_hashing_algorithm = 0; + value->p_source = NULL; + value->trailer_field = KMIP_UNSET; +} + +void +kmip_init_key_block(KeyBlock *value) +{ + if(value == NULL) + { + return; + } + + value->key_format_type = 0; + value->key_compression_type = 0; + value->key_value = NULL; + value->key_value_type = 0; + value->cryptographic_algorithm = 0; + value->cryptographic_length = KMIP_UNSET; + value->key_wrapping_data = NULL; +} + +void +kmip_init_request_header(RequestHeader *value) +{ + if(value == NULL) + { + return; + } + + value->protocol_version = NULL; + value->maximum_response_size = KMIP_UNSET; + value->asynchronous_indicator = KMIP_UNSET; + value->authentication = NULL; + value->batch_error_continuation_option = 0; + value->batch_order_option = KMIP_UNSET; + value->time_stamp = 0; + value->batch_count = KMIP_UNSET; + + value->attestation_capable_indicator = KMIP_UNSET; + value->attestation_types = NULL; + value->attestation_type_count = 0; + + value->client_correlation_value = NULL; + value->server_correlation_value = NULL; +} + +void +kmip_init_response_header(ResponseHeader *value) +{ + if(value == NULL) + { + return; + } + + value->protocol_version = NULL; + value->time_stamp = 0; + value->batch_count = KMIP_UNSET; + + value->nonce = NULL; + value->attestation_types = NULL; + value->attestation_type_count = 0; + + value->client_correlation_value = NULL; + value->server_correlation_value = NULL; + + value->server_hashed_password = NULL; +} + +void +kmip_init_request_batch_item(RequestBatchItem *value) +{ + if(value == NULL) + { + return; + } + + value->operation = 0; + value->unique_batch_item_id = NULL; + value->request_payload = NULL; + + value->ephemeral = KMIP_UNSET; +} + +/* +Printing Functions +*/ + +void +kmip_print_buffer(void *buffer, int size) +{ + if(buffer == NULL) + { + return; + } + + uint8 *index = (uint8 *)buffer; + for(int i = 0; i < size; i++) + { + if(i % 16 == 0) + { + printf("\n0x"); + } + printf("%02X", index[i]); + } +} + +void +kmip_print_stack_trace(KMIP *ctx) +{ + if(ctx == NULL) + { + return; + } + + ErrorFrame *index = ctx->frame_index; + do + { + printf("- %s @ line: %d\n", index->function, index->line); + } while(index-- != ctx->errors); +} + +void +kmip_print_error_string(int value) +{ + /* TODO (ph) Move this to a static string array. */ + switch(value) + { + case 0: + { + printf("KMIP_OK"); + } break; + + case -1: + { + printf("KMIP_NOT_IMPLEMENTED"); + } break; + + case -2: + { + printf("KMIP_ERROR_BUFFER_FULL"); + } break; + + case -3: + { + printf("KMIP_ERROR_ATTR_UNSUPPORTED"); + } break; + + case -4: + { + printf("KMIP_TAG_MISMATCH"); + } break; + + case -5: + { + printf("KMIP_TYPE_MISMATCH"); + } break; + + case -6: + { + printf("KMIP_LENGTH_MISMATCH"); + } break; + + case -7: + { + printf("KMIP_PADDING_MISMATCH"); + } break; + + case -8: + { + printf("KMIP_BOOLEAN_MISMATCH"); + } break; + + case -9: + { + printf("KMIP_ENUM_MISMATCH"); + } break; + + case -10: + { + printf("KMIP_ENUM_UNSUPPORTED"); + } break; + + case -11: + { + printf("KMIP_INVALID_FOR_VERSION"); + } break; + + case -12: + { + printf("KMIP_MEMORY_ALLOC_FAILED"); + } break; + + case -13: + { + printf("KMIP_IO_FAILURE"); + } break; + + case -14: + { + printf("KMIP_EXCEED_MAX_MESSAGE_SIZE"); + } break; + + case -15: + { + printf("KMIP_MALFORMED_RESPONSE"); + } break; + + case -16: + { + printf("KMIP_OBJECT_MISMATCH"); + } break; + + case -17: + { + printf("KMIP_ARG_INVALID"); + } break; + + case -18: + { + printf("KMIP_ERROR_BUFFER_UNDERFULL"); + } break; + + default: + { + printf("Unrecognized Error Code"); + } break; + }; + + return; +} + +void +kmip_print_attestation_type_enum(enum attestation_type value) +{ + if(value == 0) + { + printf("-"); + return; + } + + switch(value) + { + case KMIP_ATTEST_TPM_QUOTE: + printf("TPM Quote"); + break; + + case KMIP_ATTEST_TCG_INTEGRITY_REPORT: + printf("TCG Integrity Report"); + break; + + case KMIP_ATTEST_SAML_ASSERTION: + printf("SAML Assertion"); + break; + + default: + printf("Unknown"); + break; + }; +} + +void +kmip_print_batch_error_continuation_option(enum batch_error_continuation_option value) +{ + if(value == 0) + { + printf("-"); + return; + } + + switch(value) + { + case KMIP_BATCH_CONTINUE: + printf("Continue"); + break; + + case KMIP_BATCH_STOP: + printf("Stop"); + break; + + case KMIP_BATCH_UNDO: + printf("Undo"); + break; + + default: + printf("Unknown"); + break; + }; +} + +void +kmip_print_operation_enum(enum operation value) +{ + if(value == 0) + { + printf("-"); + return; + } + + switch(value) + { + case KMIP_OP_CREATE: + printf("Create"); + break; + + case KMIP_OP_GET: + printf("Get"); + break; + + case KMIP_OP_DESTROY: + printf("Destroy"); + break; + + case KMIP_OP_CREATE_KEY_PAIR: printf ("Create Key Pair"); break; + case KMIP_OP_REGISTER: printf ("Register"); break; + case KMIP_OP_REKEY: printf ("Re-key"); break; + case KMIP_OP_DERIVE_KEY: printf ("Derive Key"); break; + case KMIP_OP_CERTIFY: printf ("Certify"); break; + case KMIP_OP_RECERTIFY: printf ("Recertify"); break; + case KMIP_OP_LOCATE: printf ("Locate"); break; + case KMIP_OP_CHECK: printf ("Check"); break; + case KMIP_OP_GET_ATTRIBUTES: printf ("Get Attributes"); break; + case KMIP_OP_GET_ATTRIBUTE_LIST: printf ("Get Attribute List"); break; + case KMIP_OP_ADD_ATTRIBUTE: printf ("Add Attribute"); break; + case KMIP_OP_MODIFY_ATTRIBUTE: printf ("Modify Attribute"); break; + case KMIP_OP_DELETE_ATTRIBUTE: printf ("Delete Attribute"); break; + case KMIP_OP_OBTAIN_LEASE: printf ("Obtain Lease"); break; + case KMIP_OP_GET_USAGE_ALLOCATION: printf ("Get Usage Allocation"); break; + case KMIP_OP_ACTIVATE: printf ("Activate"); break; + case KMIP_OP_REVOKE: printf ("Revoke"); break; + case KMIP_OP_ARCHIVE: printf ("Archive"); break; + case KMIP_OP_RECOVER: printf ("Recover"); break; + case KMIP_OP_VALIDATE: printf ("Validate"); break; + case KMIP_OP_QUERY: printf ("Query"); break; + case KMIP_OP_CANCEL: printf ("Cancel"); break; + case KMIP_OP_POLL: printf ("Poll"); break; + case KMIP_OP_NOTIFY: printf ("Notify"); break; + case KMIP_OP_PUT: printf ("Put"); break; + case KMIP_OP_REKEY_KEY_PAIR: printf ("Rekey Key Pair"); break; + case KMIP_OP_DISCOVER_VERSIONS: printf ("Discover Versions"); break; + case KMIP_OP_ENCRYPT: printf ("Encrypt"); break; + case KMIP_OP_DECRYPT: printf ("Decrypt"); break; + case KMIP_OP_SIGN: printf ("Sign"); break; + case KMIP_OP_SIGNATURE_VERIFY: printf ("Signature Verify"); break; + case KMIP_OP_MAC: printf ("MAC"); break; + case KMIP_OP_MAC_VERIFY: printf ("MAC Verify"); break; + case KMIP_OP_RNG_RETRIEVE: printf ("RNG Retrieve"); break; + case KMIP_OP_RNG_SEED: printf ("RNG Seed"); break; + case KMIP_OP_HASH: printf ("Hash"); break; + case KMIP_OP_CREATE_SPLIT_KEY: printf ("Create Split Key"); break; + case KMIP_OP_JOIN_SPLIT_KEY: printf ("Join Split Key"); break; + case KMIP_OP_IMPORT: printf ("Import"); break; + case KMIP_OP_EXPORT: printf ("Export"); break; + + default: + printf("Unknown"); + break; + }; +} + +void +kmip_print_result_status_enum(enum result_status value) +{ + switch(value) + { + case KMIP_STATUS_SUCCESS: + printf("Success"); + break; + + case KMIP_STATUS_OPERATION_FAILED: + printf("Operation Failed"); + break; + + case KMIP_STATUS_OPERATION_PENDING: + printf("Operation Pending"); + break; + + case KMIP_STATUS_OPERATION_UNDONE: + printf("Operation Undone"); + break; + + default: + printf("Unknown"); + break; + }; +} + +void +kmip_print_result_reason_enum(enum result_reason value) +{ + if(value == 0) + { + printf("-"); + return; + } + + switch(value) + { + case KMIP_REASON_GENERAL_FAILURE: + printf("General Failure"); + break; + + case KMIP_REASON_ITEM_NOT_FOUND: + printf("Item Not Found"); + break; + + case KMIP_REASON_RESPONSE_TOO_LARGE: + printf("Response Too Large"); + break; + + case KMIP_REASON_AUTHENTICATION_NOT_SUCCESSFUL: + printf("Authentication Not Successful"); + break; + + case KMIP_REASON_INVALID_MESSAGE: + printf("Invalid Message"); + break; + + case KMIP_REASON_OPERATION_NOT_SUPPORTED: + printf("Operation Not Supported"); + break; + + case KMIP_REASON_MISSING_DATA: + printf("Missing Data"); + break; + + case KMIP_REASON_INVALID_FIELD: + printf("Invalid Field"); + break; + + case KMIP_REASON_FEATURE_NOT_SUPPORTED: + printf("Feature Not Supported"); + break; + + case KMIP_REASON_OPERATION_CANCELED_BY_REQUESTER: + printf("Operation Canceled By Requester"); + break; + + case KMIP_REASON_CRYPTOGRAPHIC_FAILURE: + printf("Cryptographic Failure"); + break; + + case KMIP_REASON_ILLEGAL_OPERATION: + printf("Illegal Operation"); + break; + + case KMIP_REASON_PERMISSION_DENIED: + printf("Permission Denied"); + break; + + case KMIP_REASON_OBJECT_ARCHIVED: + printf("Object Archived"); + break; + + case KMIP_REASON_INDEX_OUT_OF_BOUNDS: + printf("Index Out Of Bounds"); + break; + + case KMIP_REASON_APPLICATION_NAMESPACE_NOT_SUPPORTED: + printf("Application Namespace Not Supported"); + break; + + case KMIP_REASON_KEY_FORMAT_TYPE_NOT_SUPPORTED: + printf("Key Format Type Not Supported"); + break; + + case KMIP_REASON_KEY_COMPRESSION_TYPE_NOT_SUPPORTED: + printf("Key Compression Type Not Supported"); + break; + + case KMIP_REASON_ENCODING_OPTION_FAILURE: + printf("Encoding Option Failure"); + break; + + case KMIP_REASON_KEY_VALUE_NOT_PRESENT: + printf("Key Value Not Present"); + break; + + case KMIP_REASON_ATTESTATION_REQUIRED: + printf("Attestation Required"); + break; + + case KMIP_REASON_ATTESTATION_FAILED: + printf("Attestation Failed"); + break; + + case KMIP_REASON_SENSITIVE: + printf("Sensitive"); + break; + + case KMIP_REASON_NOT_EXTRACTABLE: + printf("Not Extractable"); + break; + + case KMIP_REASON_OBJECT_ALREADY_EXISTS: + printf("Object Already Exists"); + break; + + case KMIP_REASON_INVALID_TICKET: + printf("Invalid Ticket"); + break; + + case KMIP_REASON_USAGE_LIMIT_EXCEEDED: + printf("Usage Limit Exceeded"); + break; + + case KMIP_REASON_NUMERIC_RANGE: + printf("Numeric Range"); + break; + + case KMIP_REASON_INVALID_DATA_TYPE: + printf("Invalid Data Type"); + break; + + case KMIP_REASON_READ_ONLY_ATTRIBUTE: + printf("Read Only Attribute"); + break; + + case KMIP_REASON_MULTI_VALUED_ATTRIBUTE: + printf("Multi Valued Attribute"); + break; + + case KMIP_REASON_UNSUPPORTED_ATTRIBUTE: + printf("Unsupported Attribute"); + break; + + case KMIP_REASON_ATTRIBUTE_INSTANCE_NOT_FOUND: + printf("Attribute Instance Not Found"); + break; + + case KMIP_REASON_ATTRIBUTE_NOT_FOUND: + printf("Attribute Not Found"); + break; + + case KMIP_REASON_ATTRIBUTE_READ_ONLY: + printf("Attribute Read Only"); + break; + + case KMIP_REASON_ATTRIBUTE_SINGLE_VALUED: + printf("Attribute Single Valued"); + break; + + case KMIP_REASON_BAD_CRYPTOGRAPHIC_PARAMETERS: + printf("Bad Cryptographic Parameters"); + break; + + case KMIP_REASON_BAD_PASSWORD: + printf("Bad Password"); + break; + + case KMIP_REASON_CODEC_ERROR: + printf("Codec Error"); + break; + + case KMIP_REASON_ILLEGAL_OBJECT_TYPE: + printf("Illegal Object Type"); + break; + + case KMIP_REASON_INCOMPATIBLE_CRYPTOGRAPHIC_USAGE_MASK: + printf("Incompatible Cryptographic Usage Mask"); + break; + + case KMIP_REASON_INTERNAL_SERVER_ERROR: + printf("Internal Server Error"); + break; + + case KMIP_REASON_INVALID_ASYNCHRONOUS_CORRELATION_VALUE: + printf("Invalid Asynchronous Correlation Value"); + break; + + case KMIP_REASON_INVALID_ATTRIBUTE: + printf("Invalid Attribute"); + break; + + case KMIP_REASON_INVALID_ATTRIBUTE_VALUE: + printf("Invalid Attribute Value"); + break; + + case KMIP_REASON_INVALID_CORRELATION_VALUE: + printf("Invalid Correlation Value"); + break; + + case KMIP_REASON_INVALID_CSR: + printf("Invalid CSR"); + break; + + case KMIP_REASON_INVALID_OBJECT_TYPE: + printf("Invalid Object Type"); + break; + + case KMIP_REASON_KEY_WRAP_TYPE_NOT_SUPPORTED: + printf("Key Wrap Type Not Supported"); + break; + + case KMIP_REASON_MISSING_INITIALIZATION_VECTOR: + printf("Missing Initialization Vector"); + break; + + case KMIP_REASON_NON_UNIQUE_NAME_ATTRIBUTE: + printf("Non Unique Name Attribute"); + break; + + case KMIP_REASON_OBJECT_DESTROYED: + printf("Object Destroyed"); + break; + + case KMIP_REASON_OBJECT_NOT_FOUND: + printf("Object Not Found"); + break; + + case KMIP_REASON_NOT_AUTHORISED: + printf("Not Authorised"); + break; + + case KMIP_REASON_SERVER_LIMIT_EXCEEDED: + printf("Server Limit Exceeded"); + break; + + case KMIP_REASON_UNKNOWN_ENUMERATION: + printf("Unknown Enumeration"); + break; + + case KMIP_REASON_UNKNOWN_MESSAGE_EXTENSION: + printf("Unknown Message Extension"); + break; + + case KMIP_REASON_UNKNOWN_TAG: + printf("Unknown Tag"); + break; + + case KMIP_REASON_UNSUPPORTED_CRYPTOGRAPHIC_PARAMETERS: + printf("Unsupported Cryptographic Parameters"); + break; + + case KMIP_REASON_UNSUPPORTED_PROTOCOL_VERSION: + printf("Unsupported Protocol Version"); + break; + + case KMIP_REASON_WRAPPING_OBJECT_ARCHIVED: + printf("Wrapping Object Archived"); + break; + + case KMIP_REASON_WRAPPING_OBJECT_DESTROYED: + printf("Wrapping Object Destroyed"); + break; + + case KMIP_REASON_WRAPPING_OBJECT_NOT_FOUND: + printf("Wrapping Object Not Found"); + break; + + case KMIP_REASON_WRONG_KEY_LIFECYCLE_STATE: + printf("Wrong Key Lifecycle State"); + break; + + case KMIP_REASON_PROTECTION_STORAGE_UNAVAILABLE: + printf("Protection Storage Unavailable"); + break; + + case KMIP_REASON_PKCS11_CODEC_ERROR: + printf("PKCS#11 Codec Error"); + break; + + case KMIP_REASON_PKCS11_INVALID_FUNCTION: + printf("PKCS#11 Invalid Function"); + break; + + case KMIP_REASON_PKCS11_INVALID_INTERFACE: + printf("PKCS#11 Invalid Interface"); + break; + + case KMIP_REASON_PRIVATE_PROTECTION_STORAGE_UNAVAILABLE: + printf("Private Protection Storage Unavailable"); + break; + + case KMIP_REASON_PUBLIC_PROTECTION_STORAGE_UNAVAILABLE: + printf("Public Protection Storage Unavailable"); + break; + + default: + printf("Unknown"); + break; + }; +} + +void +kmip_print_object_type_enum(enum object_type value) +{ + if(value == 0) + { + printf("-"); + return; + } + + switch(value) + { + case KMIP_OBJTYPE_CERTIFICATE: + printf("Certificate"); + break; + + case KMIP_OBJTYPE_SYMMETRIC_KEY: + printf("Symmetric Key"); + break; + + case KMIP_OBJTYPE_PUBLIC_KEY: + printf("Public Key"); + break; + + case KMIP_OBJTYPE_PRIVATE_KEY: + printf("Private Key"); + break; + + case KMIP_OBJTYPE_SPLIT_KEY: + printf("Split Key"); + break; + + case KMIP_OBJTYPE_TEMPLATE: + printf("Template"); + break; + + case KMIP_OBJTYPE_SECRET_DATA: + printf("Secret Data"); + break; + + case KMIP_OBJTYPE_OPAQUE_OBJECT: + printf("Opaque Object"); + break; + + case KMIP_OBJTYPE_PGP_KEY: + printf("PGP Key"); + break; + + case KMIP_OBJTYPE_CERTIFICATE_REQUEST: + printf("Certificate Request"); + break; + + default: + printf("Unknown"); + break; + }; +} + +void +kmip_print_key_format_type_enum(enum key_format_type value) +{ + if(value == 0) + { + printf("-"); + return; + } + + switch(value) + { + case KMIP_KEYFORMAT_RAW: + printf("Raw"); + break; + + case KMIP_KEYFORMAT_OPAQUE: + printf("Opaque"); + break; + + case KMIP_KEYFORMAT_PKCS1: + printf("PKCS1"); + break; + + case KMIP_KEYFORMAT_PKCS8: + printf("PKCS8"); + break; + + case KMIP_KEYFORMAT_X509: + printf("X509"); + break; + + case KMIP_KEYFORMAT_EC_PRIVATE_KEY: + printf("EC Private Key"); + break; + + case KMIP_KEYFORMAT_TRANS_SYMMETRIC_KEY: + printf("Transparent Symmetric Key"); + break; + + case KMIP_KEYFORMAT_TRANS_DSA_PRIVATE_KEY: + printf("Transparent DSA Private Key"); + break; + + case KMIP_KEYFORMAT_TRANS_DSA_PUBLIC_KEY: + printf("Transparent DSA Public Key"); + break; + + case KMIP_KEYFORMAT_TRANS_RSA_PRIVATE_KEY: + printf("Transparent RSA Private Key"); + break; + + case KMIP_KEYFORMAT_TRANS_RSA_PUBLIC_KEY: + printf("Transparent RSA Public Key"); + break; + + case KMIP_KEYFORMAT_TRANS_DH_PRIVATE_KEY: + printf("Transparent DH Private Key"); + break; + + case KMIP_KEYFORMAT_TRANS_DH_PUBLIC_KEY: + printf("Transparent DH Public Key"); + break; + + case KMIP_KEYFORMAT_TRANS_ECDSA_PRIVATE_KEY: + printf("Transparent ECDSA Private Key"); + break; + + case KMIP_KEYFORMAT_TRANS_ECDSA_PUBLIC_KEY: + printf("Transparent ECDSA Public Key"); + break; + + case KMIP_KEYFORMAT_TRANS_ECDH_PRIVATE_KEY: + printf("Transparent ECDH Private Key"); + break; + + case KMIP_KEYFORMAT_TRANS_ECDH_PUBLIC_KEY: + printf("Transparent ECDH Public Key"); + break; + + case KMIP_KEYFORMAT_TRANS_ECMQV_PRIVATE_KEY: + printf("Transparent ECMQV Private Key"); + break; + + case KMIP_KEYFORMAT_TRANS_ECMQV_PUBLIC_KEY: + printf("Transparent ECMQV Public Key"); + break; + + case KMIP_KEYFORMAT_TRANS_EC_PRIVATE_KEY: + printf("Transparent EC Private Key"); + break; + + case KMIP_KEYFORMAT_TRANS_EC_PUBLIC_KEY: + printf("Transparent EC Public Key"); + break; + + case KMIP_KEYFORMAT_PKCS12: + printf("PKCS#12"); + break; + + case KMIP_KEYFORMAT_PKCS10: + printf("PKCS#10"); + break; + + default: + printf("Unknown"); + break; + }; +} + +void +kmip_print_key_compression_type_enum(enum key_compression_type value) +{ + if(value == 0) + { + printf("-"); + return; + } + + switch(value) + { + case KMIP_KEYCOMP_EC_PUB_UNCOMPRESSED: + printf("EC Public Key Type Uncompressed"); + break; + + case KMIP_KEYCOMP_EC_PUB_X962_COMPRESSED_PRIME: + printf("EC Public Key Type X9.62 Compressed Prime"); + break; + + case KMIP_KEYCOMP_EC_PUB_X962_COMPRESSED_CHAR2: + printf("EC Public Key Type X9.62 Compressed Char2"); + break; + + case KMIP_KEYCOMP_EC_PUB_X962_HYBRID: + printf("EC Public Key Type X9.62 Hybrid"); + break; + + default: + printf("Unknown"); + break; + }; +} + +void +kmip_print_cryptographic_algorithm_enum(enum cryptographic_algorithm value) +{ + if(value == 0) + { + printf("-"); + return; + } + + switch(value) + { + case KMIP_CRYPTOALG_DES: + printf("DES"); + break; + + case KMIP_CRYPTOALG_TRIPLE_DES: + printf("3DES"); + break; + + case KMIP_CRYPTOALG_AES: + printf("AES"); + break; + + case KMIP_CRYPTOALG_RSA: + printf("RSA"); + break; + + case KMIP_CRYPTOALG_DSA: + printf("DSA"); + break; + + case KMIP_CRYPTOALG_ECDSA: + printf("ECDSA"); + break; + + case KMIP_CRYPTOALG_HMAC_SHA1: + printf("SHA1"); + break; + + case KMIP_CRYPTOALG_HMAC_SHA224: + printf("SHA224"); + break; + + case KMIP_CRYPTOALG_HMAC_SHA256: + printf("SHA256"); + break; + + case KMIP_CRYPTOALG_HMAC_SHA384: + printf("SHA384"); + break; + + case KMIP_CRYPTOALG_HMAC_SHA512: + printf("SHA512"); + break; + + case KMIP_CRYPTOALG_HMAC_MD5: + printf("MD5"); + break; + + case KMIP_CRYPTOALG_DH: + printf("DH"); + break; + + case KMIP_CRYPTOALG_ECDH: + printf("ECDH"); + break; + + case KMIP_CRYPTOALG_ECMQV: + printf("ECMQV"); + break; + + case KMIP_CRYPTOALG_BLOWFISH: + printf("Blowfish"); + break; + + case KMIP_CRYPTOALG_CAMELLIA: + printf("Camellia"); + break; + + case KMIP_CRYPTOALG_CAST5: + printf("CAST5"); + break; + + case KMIP_CRYPTOALG_IDEA: + printf("IDEA"); + break; + + case KMIP_CRYPTOALG_MARS: + printf("MARS"); + break; + + case KMIP_CRYPTOALG_RC2: + printf("RC2"); + break; + + case KMIP_CRYPTOALG_RC4: + printf("RC4"); + break; + + case KMIP_CRYPTOALG_RC5: + printf("RC5"); + break; + + case KMIP_CRYPTOALG_SKIPJACK: + printf("Skipjack"); + break; + + case KMIP_CRYPTOALG_TWOFISH: + printf("Twofish"); + break; + + case KMIP_CRYPTOALG_EC: + printf("EC"); + break; + + case KMIP_CRYPTOALG_ONE_TIME_PAD: + printf("One Time Pad"); + break; + + case KMIP_CRYPTOALG_CHACHA20: + printf("ChaCha20"); + break; + + case KMIP_CRYPTOALG_POLY1305: + printf("Poly1305"); + break; + + case KMIP_CRYPTOALG_CHACHA20_POLY1305: + printf("ChaCha20 Poly1305"); + break; + + case KMIP_CRYPTOALG_SHA3_224: + printf("SHA3-224"); + break; + + case KMIP_CRYPTOALG_SHA3_256: + printf("SHA3-256"); + break; + + case KMIP_CRYPTOALG_SHA3_384: + printf("SHA3-384"); + break; + + case KMIP_CRYPTOALG_SHA3_512: + printf("SHA3-512"); + break; + + case KMIP_CRYPTOALG_HMAC_SHA3_224: + printf("HMAC SHA3-224"); + break; + + case KMIP_CRYPTOALG_HMAC_SHA3_256: + printf("HMAC SHA3-256"); + break; + + case KMIP_CRYPTOALG_HMAC_SHA3_384: + printf("HMAC SHA3-384"); + break; + + case KMIP_CRYPTOALG_HMAC_SHA3_512: + printf("HMAC SHA3-512"); + break; + + case KMIP_CRYPTOALG_SHAKE_128: + printf("SHAKE-128"); + break; + + case KMIP_CRYPTOALG_SHAKE_256: + printf("SHAKE-256"); + break; + + case KMIP_CRYPTOALG_ARIA: + printf("ARIA"); + break; + + case KMIP_CRYPTOALG_SEED: + printf("SEED"); + break; + + case KMIP_CRYPTOALG_SM2: + printf("SM2"); + break; + + case KMIP_CRYPTOALG_SM3: + printf("SM3"); + break; + + case KMIP_CRYPTOALG_SM4: + printf("SM4"); + break; + + case KMIP_CRYPTOALG_GOST_R_34_10_2012: + printf("GOST R 34.10-2012"); + break; + + case KMIP_CRYPTOALG_GOST_R_34_11_2012: + printf("GOST R 34.11-2012"); + break; + + case KMIP_CRYPTOALG_GOST_R_34_13_2015: + printf("GOST R 34.13-2015"); + break; + + case KMIP_CRYPTOALG_GOST_28147_89: + printf("GOST 28147-89"); + break; + + case KMIP_CRYPTOALG_XMSS: + printf("XMSS"); + break; + + case KMIP_CRYPTOALG_SPHINCS_256: + printf("SPHINCS-256"); + break; + + case KMIP_CRYPTOALG_MCELIECE: + printf("McEliece"); + break; + + case KMIP_CRYPTOALG_MCELIECE_6960119: + printf("McEliece 6960119"); + break; + + case KMIP_CRYPTOALG_MCELIECE_8192128: + printf("McEliece 8192128"); + break; + + case KMIP_CRYPTOALG_ED25519: + printf("Ed25519"); + break; + + case KMIP_CRYPTOALG_ED448: + printf("Ed448"); + break; + + default: + printf("Unknown"); + break; + }; +} + +void +kmip_print_name_type_enum(enum name_type value) +{ + if(value == 0) + { + printf("-"); + return; + } + + switch(value) + { + case KMIP_NAME_UNINTERPRETED_TEXT_STRING: + printf("Uninterpreted Text String"); + break; + + case KMIP_NAME_URI: + printf("URI"); + break; + + default: + printf("Unknown"); + break; + }; +} + +void +kmip_print_attribute_type_enum(enum attribute_type value) +{ + if((int)value == KMIP_UNSET) + { + printf("-"); + return; + } + + switch(value) + { + case KMIP_ATTR_UNIQUE_IDENTIFIER: + printf("Unique Identifier"); + break; + + case KMIP_ATTR_NAME: + printf("Name"); + break; + + case KMIP_ATTR_OBJECT_TYPE: + printf("Object Type"); + break; + + case KMIP_ATTR_CRYPTOGRAPHIC_ALGORITHM: + printf("Cryptographic Algorithm"); + break; + + case KMIP_ATTR_CRYPTOGRAPHIC_LENGTH: + printf("Cryptographic Length"); + break; + + case KMIP_ATTR_CRYPTOGRAPHIC_PARAMETERS: + printf("Cryptographic Parameters"); + break; + + case KMIP_ATTR_CRYPTOGRAPHIC_DOMAIN_PARAMETERS: + printf("Cryptographic Domain Parameters"); + break; + + case KMIP_ATTR_CERTIFICATE_TYPE: + printf("Certificate Type"); + break; + + case KMIP_ATTR_CERTIFICATE_LENGTH: + printf("Certificate Length"); + break; + + case KMIP_ATTR_X509_CERTIFICATE_IDENTIFIER: + printf("X.509 Certificate Identifier"); + break; + + case KMIP_ATTR_X509_CERTIFICATE_SUBJECT: + printf("X.509 Certificate Subject"); + break; + + case KMIP_ATTR_X509_CERTIFICATE_ISSUER: + printf("X.509 Certificate Issuer"); + break; + + case KMIP_ATTR_CERTIFICATE_IDENTIFIER: + printf("Certificate Identifier"); + break; + + case KMIP_ATTR_CERTIFICATE_SUBJECT: + printf("Certificate Subject"); + break; + + case KMIP_ATTR_CERTIFICATE_ISSUER: + printf("Certificate Issuer"); + break; + + case KMIP_ATTR_DIGITAL_SIGNATURE_ALGORITHM: + printf("Digital Signature Algorithm"); + break; + + case KMIP_ATTR_DIGEST: + printf("Digest"); + break; + + case KMIP_ATTR_OPERATION_POLICY_NAME: + printf("Operation Policy Name"); + break; + + case KMIP_ATTR_CRYPTOGRAPHIC_USAGE_MASK: + printf("Cryptographic Usage Mask"); + break; + + case KMIP_ATTR_LEASE_TIME: + printf("Lease Time"); + break; + + case KMIP_ATTR_USAGE_LIMITS: + printf("Usage Limits"); + break; + + case KMIP_ATTR_STATE: + printf("State"); + break; + + case KMIP_ATTR_INITIAL_DATE: + printf("Initial Date"); + break; + + case KMIP_ATTR_ACTIVATION_DATE: + printf("Activation Date"); + break; + + case KMIP_ATTR_PROCESS_START_DATE: + printf("Process Start Date"); + break; + + case KMIP_ATTR_PROTECT_STOP_DATE: + printf("Protect Stop Date"); + break; + + case KMIP_ATTR_DEACTIVATION_DATE: + printf("Deactivation Date"); + break; + + case KMIP_ATTR_DESTROY_DATE: + printf("Destroy Date"); + break; + + case KMIP_ATTR_COMPROMISE_OCCURRENCE_DATE: + printf("Compromise Occurrence Date"); + break; + + case KMIP_ATTR_COMPROMISE_DATE: + printf("Compromise Date"); + break; + + case KMIP_ATTR_REVOCATION_REASON: + printf("Revocation Reason"); + break; + + case KMIP_ATTR_ARCHIVE_DATE: + printf("Archive Date"); + break; + + case KMIP_ATTR_OBJECT_GROUP: + printf("Object Group"); + break; + + case KMIP_ATTR_FRESH: + printf("Fresh"); + break; + + case KMIP_ATTR_LINK: + printf("Link"); + break; + + case KMIP_ATTR_APPLICATION_SPECIFIC_INFORMATION: + printf("Application Specific Information"); + break; + + case KMIP_ATTR_CONTACT_INFORMATION: + printf("Contact Information"); + break; + + case KMIP_ATTR_LAST_CHANGE_DATE: + printf("Last Change Date"); + break; + + case KMIP_ATTR_CUSTOM_ATTRIBUTE: + printf("* X-* Y-* Custom Attribute"); + break; + + case KMIP_ATTR_ALTERNATIVE_NAME: + printf("Alternative Name"); + break; + + case KMIP_ATTR_KEY_VALUE_PRESENT: + printf("Key Value Present"); + break; + + case KMIP_ATTR_KEY_VALUE_LOCATION: + printf("Key Value Location"); + break; + + case KMIP_ATTR_ORIGINAL_CREATION_DATE: + printf("Original Creation Date"); + break; + + case KMIP_ATTR_RANDOM_NUMBER_GENERATOR: + printf("Random Number Generator"); + break; + + case KMIP_ATTR_PKCS_12_FRIENDLY_NAME: + printf("PKCS#12 Friendly Name"); + break; + + case KMIP_ATTR_DESCRIPTION: + printf("Description"); + break; + + case KMIP_ATTR_COMMENT: + printf("Comment"); + break; + + case KMIP_ATTR_SENSITIVE: + printf("Sensitive"); + break; + + case KMIP_ATTR_ALWAYS_SENSITIVE: + printf("Always Sensitive"); + break; + + case KMIP_ATTR_EXTRACTABLE: + printf("Extractable"); + break; + + case KMIP_ATTR_NEVER_EXTRACTABLE: + printf("Never Extractable"); + break; + + case KMIP_ATTR_KEY_FORMAT_TYPE: + printf("Key Format Type"); + break; + + default: + printf("Unknown"); + break; + }; +} + +void +kmip_print_state_enum(enum state value) +{ + if(value == 0) + { + printf("-"); + return; + } + + switch(value) + { + case KMIP_STATE_PRE_ACTIVE: + printf("Pre-Active"); + break; + + case KMIP_STATE_ACTIVE: + printf("Active"); + break; + + case KMIP_STATE_DEACTIVATED: + printf("Deactivated"); + break; + + case KMIP_STATE_COMPROMISED: + printf("Compromised"); + break; + + case KMIP_STATE_DESTROYED: + printf("Destroyed"); + break; + + case KMIP_STATE_DESTROYED_COMPROMISED: + printf("Destroyed Compromised"); + break; + + default: + printf("Unknown"); + break; + }; +} + +void +kmip_print_block_cipher_mode_enum(enum block_cipher_mode value) +{ + if(value == 0) + { + printf("-"); + return; + } + + switch(value) + { + case KMIP_BLOCK_CBC: + printf("CBC"); + break; + + case KMIP_BLOCK_ECB: + printf("ECB"); + break; + + case KMIP_BLOCK_PCBC: + printf("PCBC"); + break; + + case KMIP_BLOCK_CFB: + printf("CFB"); + break; + + case KMIP_BLOCK_OFB: + printf("OFB"); + break; + + case KMIP_BLOCK_CTR: + printf("CTR"); + break; + + case KMIP_BLOCK_CMAC: + printf("CMAC"); + break; + + case KMIP_BLOCK_CCM: + printf("CCM"); + break; + + case KMIP_BLOCK_GCM: + printf("GCM"); + break; + + case KMIP_BLOCK_CBC_MAC: + printf("CBC-MAC"); + break; + + case KMIP_BLOCK_XTS: + printf("XTS"); + break; + + case KMIP_BLOCK_AES_KEY_WRAP_PADDING: + printf("AESKeyWrapPadding"); + break; + + case KMIP_BLOCK_NIST_KEY_WRAP: + printf("NISTKeyWrap"); + break; + + case KMIP_BLOCK_X9102_AESKW: + printf("X9.102 AESKW"); + break; + + case KMIP_BLOCK_X9102_TDKW: + printf("X9.102 TDKW"); + break; + + case KMIP_BLOCK_X9102_AKW1: + printf("X9.102 AKW1"); + break; + + case KMIP_BLOCK_X9102_AKW2: + printf("X9.102 AKW2"); + break; + + case KMIP_BLOCK_AEAD: + printf("AEAD"); + break; + + default: + printf("Unknown"); + break; + }; +} + +void +kmip_print_certificate_type_enum(enum certificate_type value) +{ + if(value == 0) + { + printf("-"); + return; + } + + switch(value) + { + case KMIP_CERT_X509: + printf("X.509"); + break; + + case KMIP_CERT_PGP: + printf("PGP"); + break; + + default: + printf("Unknown"); + break; + }; +} + +void +kmip_print_padding_method_enum(enum padding_method value) +{ + if(value == 0) + { + printf("-"); + return; + } + + switch(value) + { + case KMIP_PAD_NONE: + printf("None"); + break; + + case KMIP_PAD_OAEP: + printf("OAEP"); + break; + + case KMIP_PAD_PKCS5: + printf("PKCS5"); + break; + + case KMIP_PAD_SSL3: + printf("SSL3"); + break; + + case KMIP_PAD_ZEROS: + printf("Zeros"); + break; + + case KMIP_PAD_ANSI_X923: + printf("ANSI X9.23"); + break; + + case KMIP_PAD_ISO_10126: + printf("ISO 10126"); + break; + + case KMIP_PAD_PKCS1v15: + printf("PKCS1 v1.5"); + break; + + case KMIP_PAD_X931: + printf("X9.31"); + break; + + case KMIP_PAD_PSS: + printf("PSS"); + break; + + default: + printf("Unknown"); + break; + }; +} + +void +kmip_print_hashing_algorithm_enum(enum hashing_algorithm value) +{ + if(value == 0) + { + printf("-"); + return; + } + + switch(value) + { + case KMIP_HASH_MD2: + printf("MD2"); + break; + + case KMIP_HASH_MD4: + printf("MD4"); + break; + + case KMIP_HASH_MD5: + printf("MD5"); + break; + + case KMIP_HASH_SHA1: + printf("SHA-1"); + break; + + case KMIP_HASH_SHA224: + printf("SHA-224"); + break; + + case KMIP_HASH_SHA256: + printf("SHA-256"); + break; + + case KMIP_HASH_SHA384: + printf("SHA-384"); + break; + + case KMIP_HASH_SHA512: + printf("SHA-512"); + break; + + case KMIP_HASH_RIPEMD160: + printf("RIPEMD-160"); + break; + + case KMIP_HASH_TIGER: + printf("Tiger"); + break; + + case KMIP_HASH_WHIRLPOOL: + printf("Whirlpool"); + break; + + case KMIP_HASH_SHA512_224: + printf("SHA-512/224"); + break; + + case KMIP_HASH_SHA512_256: + printf("SHA-512/256"); + break; + + case KMIP_HASH_SHA3_224: + printf("SHA-3-224"); + break; + + case KMIP_HASH_SHA3_256: + printf("SHA-3-256"); + break; + + case KMIP_HASH_SHA3_384: + printf("SHA-3-384"); + break; + + case KMIP_HASH_SHA3_512: + printf("SHA-3-512"); + break; + + default: + printf("Unknown"); + break; + }; +} + +void +kmip_print_key_role_type_enum(enum key_role_type value) +{ + if(value == 0) + { + printf("-"); + return; + } + + switch(value) + { + case KMIP_ROLE_BDK: + printf("BDK"); + break; + + case KMIP_ROLE_CVK: + printf("CVK"); + break; + + case KMIP_ROLE_DEK: + printf("DEK"); + break; + + case KMIP_ROLE_MKAC: + printf("MKAC"); + break; + + case KMIP_ROLE_MKSMC: + printf("MKSMC"); + break; + + case KMIP_ROLE_MKSMI: + printf("MKSMI"); + break; + + case KMIP_ROLE_MKDAC: + printf("MKDAC"); + break; + + case KMIP_ROLE_MKDN: + printf("MKDN"); + break; + + case KMIP_ROLE_MKCP: + printf("MKCP"); + break; + + case KMIP_ROLE_MKOTH: + printf("MKOTH"); + break; + + case KMIP_ROLE_KEK: + printf("KEK"); + break; + + case KMIP_ROLE_MAC16609: + printf("MAC16609"); + break; + + case KMIP_ROLE_MAC97971: + printf("MAC97971"); + break; + + case KMIP_ROLE_MAC97972: + printf("MAC97972"); + break; + + case KMIP_ROLE_MAC97973: + printf("MAC97973"); + break; + + case KMIP_ROLE_MAC97974: + printf("MAC97974"); + break; + + case KMIP_ROLE_MAC97975: + printf("MAC97975"); + break; + + case KMIP_ROLE_ZPK: + printf("ZPK"); + break; + + case KMIP_ROLE_PVKIBM: + printf("PVKIBM"); + break; + + case KMIP_ROLE_PVKPVV: + printf("PVKPVV"); + break; + + case KMIP_ROLE_PVKOTH: + printf("PVKOTH"); + break; + + case KMIP_ROLE_DUKPT: + printf("DUKPT"); + break; + + case KMIP_ROLE_IV: + printf("IV"); + break; + + case KMIP_ROLE_TRKBK: + printf("TRKBK"); + break; + + default: + printf("Unknown"); + break; + }; +} + +void +kmip_print_digital_signature_algorithm_enum(enum digital_signature_algorithm value) +{ + if(value == 0) + { + printf("-"); + return; + } + + switch(value) + { + case KMIP_DIGITAL_MD2_WITH_RSA: + printf("MD2 with RSA Encryption (PKCS#1 v1.5)"); + break; + + case KMIP_DIGITAL_MD5_WITH_RSA: + printf("MD5 with RSA Encryption (PKCS#1 v1.5)"); + break; + + case KMIP_DIGITAL_SHA1_WITH_RSA: + printf("SHA-1 with RSA Encryption (PKCS#1 v1.5)"); + break; + + case KMIP_DIGITAL_SHA224_WITH_RSA: + printf("SHA-224 with RSA Encryption (PKCS#1 v1.5)"); + break; + + case KMIP_DIGITAL_SHA256_WITH_RSA: + printf("SHA-256 with RSA Encryption (PKCS#1 v1.5)"); + break; + + case KMIP_DIGITAL_SHA384_WITH_RSA: + printf("SHA-384 with RSA Encryption (PKCS#1 v1.5)"); + break; + + case KMIP_DIGITAL_SHA512_WITH_RSA: + printf("SHA-512 with RSA Encryption (PKCS#1 v1.5)"); + break; + + case KMIP_DIGITAL_RSASSA_PSS: + printf("RSASSA-PSS (PKCS#1 v2.1)"); + break; + + case KMIP_DIGITAL_DSA_WITH_SHA1: + printf("DSA with SHA-1"); + break; + + case KMIP_DIGITAL_DSA_WITH_SHA224: + printf("DSA with SHA224"); + break; + + case KMIP_DIGITAL_DSA_WITH_SHA256: + printf("DSA with SHA256"); + break; + + case KMIP_DIGITAL_ECDSA_WITH_SHA1: + printf("ECDSA with SHA-1"); + break; + + case KMIP_DIGITAL_ECDSA_WITH_SHA224: + printf("ECDSA with SHA224"); + break; + + case KMIP_DIGITAL_ECDSA_WITH_SHA256: + printf("ECDSA with SHA256"); + break; + + case KMIP_DIGITAL_ECDSA_WITH_SHA384: + printf("ECDSA with SHA384"); + break; + + case KMIP_DIGITAL_ECDSA_WITH_SHA512: + printf("ECDSA with SHA512"); + break; + + case KMIP_DIGITAL_SHA3_256_WITH_RSA: + printf("SHA3-256 with RSA Encryption"); + break; + + case KMIP_DIGITAL_SHA3_384_WITH_RSA: + printf("SHA3-384 with RSA Encryption"); + break; + + case KMIP_DIGITAL_SHA3_512_WITH_RSA: + printf("SHA3-512 with RSA Encryption"); + break; + + default: + printf("Unknown"); + break; + }; +} + +void +kmip_print_date_time(int64 value) +{ + time_t t = value; + struct tm tm[1]; + char decoded_time[64]; + gmtime_r(&t, tm); + strftime(decoded_time, sizeof decoded_time, "%F %T", tm); + printf ("%s (%ld)", decoded_time, value); +} + +void +kmip_print_mask_generator_enum(enum mask_generator value) +{ + if(value == 0) + { + printf("-"); + return; + } + + switch(value) + { + case KMIP_MASKGEN_MGF1: + printf("MGF1"); + break; + + default: + printf("Unknown"); + break; + }; +} + +void +kmip_print_wrapping_method_enum(enum wrapping_method value) +{ + if(value == 0) + { + printf("-"); + return; + } + + switch(value) + { + case KMIP_WRAP_ENCRYPT: + printf("Encrypt"); + break; + + case KMIP_WRAP_MAC_SIGN: + printf("MAC/sign"); + break; + + case KMIP_WRAP_ENCRYPT_MAC_SIGN: + printf("Encrypt then MAC/sign"); + break; + + case KMIP_WRAP_MAC_SIGN_ENCRYPT: + printf("MAC/sign then encrypt"); + break; + + case KMIP_WRAP_TR31: + printf("TR-31"); + break; + + default: + printf("Unknown"); + break; + }; +} + +void +kmip_print_encoding_option_enum(enum encoding_option value) +{ + if(value == 0) + { + printf("-"); + return; + } + + switch(value) + { + case KMIP_ENCODE_NO_ENCODING: + printf("No Encoding"); + break; + + case KMIP_ENCODE_TTLV_ENCODING: + printf("TTLV Encoding"); + break; + + default: + printf("Unknown"); + break; + }; +} + +void +kmip_print_key_wrap_type_enum(enum key_wrap_type value) +{ + if(value == 0) + { + printf("-"); + return; + } + + switch(value) + { + case KMIP_WRAPTYPE_NOT_WRAPPED: + printf("Not Wrapped"); + break; + + case KMIP_WRAPTYPE_AS_REGISTERED: + printf("As Registered"); + break; + + default: + printf("Unknown"); + break; + }; +} + +void +kmip_print_credential_type_enum(enum credential_type value) +{ + if(value == 0) + { + printf("-"); + return; + } + + switch(value) + { + case KMIP_CRED_USERNAME_AND_PASSWORD: + printf("Username and Password"); + break; + + case KMIP_CRED_DEVICE: + printf("Device"); + break; + + case KMIP_CRED_ATTESTATION: + printf("Attestation"); + break; + + case KMIP_CRED_ONE_TIME_PASSWORD: + printf("One Time Password"); + break; + + case KMIP_CRED_HASHED_PASSWORD: + printf("Hashed Password"); + break; + + case KMIP_CRED_TICKET: + printf("Ticket"); + break; + + default: + printf("Unknown"); + break; + }; +} + +void +kmip_print_cryptographic_usage_mask_enums(int indent, int32 value) +{ + printf("\n"); + + if((value & KMIP_CRYPTOMASK_SIGN) == KMIP_CRYPTOMASK_SIGN) + { + printf("%*sSign\n", indent, ""); + } + + if((value & KMIP_CRYPTOMASK_VERIFY) == KMIP_CRYPTOMASK_VERIFY) + { + printf("%*sVerify\n", indent, ""); + } + + if((value & KMIP_CRYPTOMASK_ENCRYPT) == KMIP_CRYPTOMASK_ENCRYPT) + { + printf("%*sEncrypt\n", indent, ""); + } + + if((value & KMIP_CRYPTOMASK_DECRYPT) == KMIP_CRYPTOMASK_DECRYPT) + { + printf("%*sDecrypt\n", indent, ""); + } + + if((value & KMIP_CRYPTOMASK_WRAP_KEY) == KMIP_CRYPTOMASK_WRAP_KEY) + { + printf("%*sWrap Key\n", indent, ""); + } + + if((value & KMIP_CRYPTOMASK_UNWRAP_KEY) == KMIP_CRYPTOMASK_UNWRAP_KEY) + { + printf("%*sUnwrap Key\n", indent, ""); + } + + if((value & KMIP_CRYPTOMASK_EXPORT) == KMIP_CRYPTOMASK_EXPORT) + { + printf("%*sExport\n", indent, ""); + } + + if((value & KMIP_CRYPTOMASK_MAC_GENERATE) == KMIP_CRYPTOMASK_MAC_GENERATE) + { + printf("%*sMAC Generate\n", indent, ""); + } + + if((value & KMIP_CRYPTOMASK_MAC_VERIFY) == KMIP_CRYPTOMASK_MAC_VERIFY) + { + printf("%*sMAC Verify\n", indent, ""); + } + + if((value & KMIP_CRYPTOMASK_DERIVE_KEY) == KMIP_CRYPTOMASK_DERIVE_KEY) + { + printf("%*sDerive Key\n", indent, ""); + } + + if((value & KMIP_CRYPTOMASK_CONTENT_COMMITMENT) == KMIP_CRYPTOMASK_CONTENT_COMMITMENT) + { + printf("%*sContent Commitment\n", indent, ""); + } + + if((value & KMIP_CRYPTOMASK_KEY_AGREEMENT) == KMIP_CRYPTOMASK_KEY_AGREEMENT) + { + printf("%*sKey Agreement\n", indent, ""); + } + + if((value & KMIP_CRYPTOMASK_CERTIFICATE_SIGN) == KMIP_CRYPTOMASK_CERTIFICATE_SIGN) + { + printf("%*sCertificate Sign\n", indent, ""); + } + + if((value & KMIP_CRYPTOMASK_CRL_SIGN) == KMIP_CRYPTOMASK_CRL_SIGN) + { + printf("%*sCRL Sign\n", indent, ""); + } + + if((value & KMIP_CRYPTOMASK_GENERATE_CRYPTOGRAM) == KMIP_CRYPTOMASK_GENERATE_CRYPTOGRAM) + { + printf("%*sGenerate Cryptogram\n", indent, ""); + } + + if((value & KMIP_CRYPTOMASK_VALIDATE_CRYPTOGRAM) == KMIP_CRYPTOMASK_VALIDATE_CRYPTOGRAM) + { + printf("%*sValidate Cryptogram\n", indent, ""); + } + + if((value & KMIP_CRYPTOMASK_TRANSLATE_ENCRYPT) == KMIP_CRYPTOMASK_TRANSLATE_ENCRYPT) + { + printf("%*sTranslate Encrypt\n", indent, ""); + } + + if((value & KMIP_CRYPTOMASK_TRANSLATE_DECRYPT) == KMIP_CRYPTOMASK_TRANSLATE_DECRYPT) + { + printf("%*sTranslate Decrypt\n", indent, ""); + } + + if((value & KMIP_CRYPTOMASK_TRANSLATE_WRAP) == KMIP_CRYPTOMASK_TRANSLATE_WRAP) + { + printf("%*sTranslate Wrap\n", indent, ""); + } + + if((value & KMIP_CRYPTOMASK_TRANSLATE_UNWRAP) == KMIP_CRYPTOMASK_TRANSLATE_UNWRAP) + { + printf("%*sTranslate Unwrap\n", indent, ""); + } + + if((value & KMIP_CRYPTOMASK_AUTHENTICATE) == KMIP_CRYPTOMASK_AUTHENTICATE) + { + printf("%*sAuthenticate\n", indent, ""); + } + + if((value & KMIP_CRYPTOMASK_UNRESTRICTED) == KMIP_CRYPTOMASK_UNRESTRICTED) + { + printf("%*sUnrestricted\n", indent, ""); + } + + if((value & KMIP_CRYPTOMASK_FPE_ENCRYPT) == KMIP_CRYPTOMASK_FPE_ENCRYPT) + { + printf("%*sFPE Encrypt\n", indent, ""); + } + + if((value & KMIP_CRYPTOMASK_FPE_DECRYPT) == KMIP_CRYPTOMASK_FPE_DECRYPT) + { + printf("%*sFPE Decrypt\n", indent, ""); + } +} + +void +kmip_print_protection_storage_mask_enum(int indent, int32 value) +{ + printf("\n"); + + if((value & KMIP_PROTECT_SOFTWARE) == KMIP_PROTECT_SOFTWARE) + { + printf("%*sSoftware\n", indent, ""); + } + + if((value & KMIP_PROTECT_HARDWARE) == KMIP_PROTECT_HARDWARE) + { + printf("%*sHardware\n", indent, ""); + } + + if((value & KMIP_PROTECT_ON_PROCESSOR) == KMIP_PROTECT_ON_PROCESSOR) + { + printf("%*sOn Processor\n", indent, ""); + } + + if((value & KMIP_PROTECT_ON_SYSTEM) == KMIP_PROTECT_ON_SYSTEM) + { + printf("%*sOn System\n", indent, ""); + } + + if((value & KMIP_PROTECT_OFF_SYSTEM) == KMIP_PROTECT_OFF_SYSTEM) + { + printf("%*sOff System\n", indent, ""); + } + + if((value & KMIP_PROTECT_HYPERVISOR) == KMIP_PROTECT_HYPERVISOR) + { + printf("%*sHypervisor\n", indent, ""); + } + + if((value & KMIP_PROTECT_OPERATING_SYSTEM) == KMIP_PROTECT_OPERATING_SYSTEM) + { + printf("%*sOperating System\n", indent, ""); + } + + if((value & KMIP_PROTECT_CONTAINER) == KMIP_PROTECT_CONTAINER) + { + printf("%*sContainer\n", indent, ""); + } + + if((value & KMIP_PROTECT_ON_PREMISES) == KMIP_PROTECT_ON_PREMISES) + { + printf("%*sOn Premises\n", indent, ""); + } + + if((value & KMIP_PROTECT_OFF_PREMISES) == KMIP_PROTECT_OFF_PREMISES) + { + printf("%*sOff Premises\n", indent, ""); + } + + if((value & KMIP_PROTECT_SELF_MANAGED) == KMIP_PROTECT_SELF_MANAGED) + { + printf("%*sSelf Managed\n", indent, ""); + } + + if((value & KMIP_PROTECT_OUTSOURCED) == KMIP_PROTECT_OUTSOURCED) + { + printf("%*sOutsourced\n", indent, ""); + } + + if((value & KMIP_PROTECT_VALIDATED) == KMIP_PROTECT_VALIDATED) + { + printf("%*sValidated\n", indent, ""); + } + + if((value & KMIP_PROTECT_SAME_JURISDICTION) == KMIP_PROTECT_SAME_JURISDICTION) + { + printf("%*sSame Jurisdiction\n", indent, ""); + } +} + +void +kmip_print_storage_status_mask_enum(enum storage_status_mask value) +{ + char *sep = ""; + if((value & KMIP_SSM_ONLINE_STORAGE)) + { + printf("%sonline", sep); sep = " "; + } + if((value & KMIP_SSM_ARCHIVAL_STORAGE)) + { + printf("%sarchived", sep); sep = " "; + } + if((value & KMIP_SSM_DESTROYED_STORAGE)) + { + printf("%sdestroyed", sep); sep = " "; + } +} + +void +kmip_print_object_group_member_enum(enum object_group_member value) +{ + char *sep = ""; + if((value & KMIP_OGM_GROUP_MEMBER_FRESH)) + { + printf("%sfresh", sep); sep = " "; + } + if((value & KMIP_OGM_GROUP_MEMBER_DEFAULT)) + { + printf("%sdefault", sep); sep = " "; + } +} + +void +kmip_print_protection_storage_masks(int indent, ProtectionStorageMasks *value) +{ + printf("%*sProtection Storage Masks @ %p\n", indent, "", (void *)value); + + if(value != NULL) + { + printf("%*sMasks: %zu\n", indent + 2, "", value->masks->size); + LinkedListItem *curr = value->masks->head; + size_t count = 1; + while(curr != NULL) + { + printf("%*sMask: %zu", indent + 4, "", count); + int32 mask = *(int32 *)curr->data; + kmip_print_protection_storage_mask_enum(indent + 6, mask); + + curr = curr->next; + count++; + } + } +} + +void +kmip_print_integer(int32 value) +{ + switch(value) + { + case KMIP_UNSET: + printf("-"); + break; + + default: + printf("%d", value); + break; + }; +} + +void +kmip_print_bool(int32 value) +{ + switch(value) + { + case KMIP_TRUE: + printf("True"); + break; + + case KMIP_FALSE: + printf("False"); + break; + + default: + printf("-"); + break; + }; +} + +void +kmip_print_text_string(int indent, const char *name, TextString *value) +{ + printf("%*s%s @ %p\n", indent, "", name, (void *)value); + + if(value != NULL) + { + printf("%*sValue: %.*s\n", indent + 2, "", (int)value->size, value->value); + } + + return; +} + +void +kmip_print_byte_string(int indent, const char *name, ByteString *value) +{ + printf("%*s%s @ %p\n", indent, "", name, (void *)value); + + if(value != NULL) + { + printf("%*sValue:", indent + 2, ""); + for(size_t i = 0; i < value->size; i++) + { + if(i % 16 == 0) + { + printf("\n%*s0x", indent + 4, ""); + } + printf("%02X", value->value[i]); + } + printf("\n"); + } + + return; +} + +void +kmip_print_protocol_version(int indent, ProtocolVersion *value) +{ + printf("%*sProtocol Version @ %p\n", indent, "", (void *)value); + + if(value != NULL) + { + printf("%*sMajor: %d\n", indent + 2, "", value->major); + printf("%*sMinor: %d\n", indent + 2, "", value->minor); + } + + return; +} + +void +kmip_print_name(int indent, Name *value) +{ + printf("%*sName @ %p\n", indent, "", (void *)value); + + if(value != NULL) + { + kmip_print_text_string(indent + 2, "Name Value", value->value); + + printf("%*sName Type: ", indent + 2, ""); + kmip_print_name_type_enum(value->type); + printf("\n"); + } +} + +void +kmip_print_nonce(int indent, Nonce *value) +{ + printf("%*sNonce @ %p\n", indent, "", (void *)value); + + if(value != NULL) + { + kmip_print_byte_string(indent + 2, "Nonce ID", value->nonce_id); + kmip_print_byte_string(indent + 2, "Nonce Value", value->nonce_value); + } + + return; +} + +void +kmip_print_cryptographic_parameters(int indent, CryptographicParameters *value) +{ + printf("%*sCryptographic Parameters @ %p\n", indent, "", (void *)value); + + if(value != NULL) + { + printf("%*sBlock Cipher Mode: ", indent + 2, ""); + kmip_print_block_cipher_mode_enum(value->block_cipher_mode); + printf("\n"); + + printf("%*sPadding Method: ", indent + 2, ""); + kmip_print_padding_method_enum(value->padding_method); + printf("\n"); + + printf("%*sHashing Algorithm: ", indent + 2, ""); + kmip_print_hashing_algorithm_enum(value->hashing_algorithm); + printf("\n"); + + printf("%*sKey Role Type: ", indent + 2, ""); + kmip_print_key_role_type_enum(value->key_role_type); + printf("\n"); + + printf("%*sDigital Signature Algorithm: ", indent + 2, ""); + kmip_print_digital_signature_algorithm_enum(value->digital_signature_algorithm); + printf("\n"); + + printf("%*sCryptographic Algorithm: ", indent + 2, ""); + kmip_print_cryptographic_algorithm_enum(value->cryptographic_algorithm); + printf("\n"); + + printf("%*sRandom IV: ", indent + 2, ""); + kmip_print_bool(value->random_iv); + printf("\n"); + + printf("%*sIV Length: ", indent + 2, ""); + kmip_print_integer(value->iv_length); + printf("\n"); + + printf("%*sTag Length: ", indent + 2, ""); + kmip_print_integer(value->tag_length); + printf("\n"); + + printf("%*sFixed Field Length: ", indent + 2, ""); + kmip_print_integer(value->fixed_field_length); + printf("\n"); + + printf("%*sInvocation Field Length: ", indent + 2, ""); + kmip_print_integer(value->invocation_field_length); + printf("\n"); + + printf("%*sCounter Length: ", indent + 2, ""); + kmip_print_integer(value->counter_length); + printf("\n"); + + printf("%*sInitial Counter Value: ", indent + 2, ""); + kmip_print_integer(value->initial_counter_value); + printf("\n"); + + printf("%*sSalt Length: ", indent + 2, ""); + kmip_print_integer(value->salt_length); + printf("\n"); + + printf("%*sMask Generator: ", indent + 2, ""); + kmip_print_mask_generator_enum(value->mask_generator); + printf("\n"); + + printf("%*sMask Generator Hashing Algorithm: ", indent + 2, ""); + kmip_print_hashing_algorithm_enum(value->mask_generator_hashing_algorithm); + printf("\n"); + + kmip_print_byte_string(indent + 2, "P Source", value->p_source); + + printf("%*sTrailer Field: ", indent + 2, ""); + kmip_print_integer(value->trailer_field); + printf("\n"); + } +} + +void +kmip_print_encryption_key_information(int indent, EncryptionKeyInformation *value) +{ + printf("%*sEncryption Key Information @ %p\n", indent, "", (void *)value); + + if(value != NULL) + { + kmip_print_text_string(indent + 2, "Unique Identifier", value->unique_identifier); + + kmip_print_cryptographic_parameters(indent + 2, value->cryptographic_parameters); + } +} + +void +kmip_print_mac_signature_key_information(int indent, MACSignatureKeyInformation *value) +{ + printf("%*sMAC/Signature Key Information @ %p\n", indent, "", (void *)value); + + if(value != NULL) + { + kmip_print_text_string(indent + 2, "Unique Identifier", value->unique_identifier); + + kmip_print_cryptographic_parameters(indent + 2, value->cryptographic_parameters); + } +} + +void +kmip_print_key_wrapping_data(int indent, KeyWrappingData *value) +{ + printf("%*sKey Wrapping Data @ %p\n", indent, "", (void *)value); + + if(value != NULL) + { + printf("%*sWrapping Method: ", indent + 2, ""); + kmip_print_wrapping_method_enum(value->wrapping_method); + printf("\n"); + + kmip_print_encryption_key_information(indent + 2, value->encryption_key_info); + + kmip_print_mac_signature_key_information(indent + 2, value->mac_signature_key_info); + + kmip_print_byte_string(indent + 2, "MAC/Signature", value->mac_signature); + + kmip_print_byte_string(indent + 2, "IV/Counter/Nonce", value->iv_counter_nonce); + + printf("%*sEncoding Option: ", indent + 2, ""); + kmip_print_encoding_option_enum(value->encoding_option); + printf("\n"); + } + + return; +} + +void +kmip_print_attribute_value(int indent, enum attribute_type type, void *value) +{ + printf("%*sAttribute Value: ", indent, ""); + + switch(type) + { + case KMIP_ATTR_UNIQUE_IDENTIFIER: + printf("\n"); + kmip_print_text_string(indent + 2, "Unique Identifier", value); + break; + + case KMIP_ATTR_NAME: + printf("\n"); + kmip_print_name(indent + 2, value); + break; + + case KMIP_ATTR_OBJECT_TYPE: + kmip_print_object_type_enum(*(enum object_type *)value); + printf("\n"); + break; + + case KMIP_ATTR_CRYPTOGRAPHIC_ALGORITHM: + kmip_print_cryptographic_algorithm_enum(*(enum cryptographic_algorithm *)value); + printf("\n"); + break; + + case KMIP_ATTR_CRYPTOGRAPHIC_LENGTH: + printf("%d\n", *(int32 *)value); + break; + + // case KMIP_ATTR_CRYPTOGRAPHIC_PARAMETERS: XXX how to hack struct? + // case KMIP_ATTR_CRYPTOGRAPHIC_DOMAIN_PARAMETERS: XXX how to hack struct? + + case KMIP_ATTR_CERTIFICATE_TYPE: + kmip_print_certificate_type_enum(*(enum certificate_type *)value); + printf("\n"); + break; + + case KMIP_ATTR_CERTIFICATE_LENGTH: + printf("%d\n", *(int32 *)value); + break; + + // case KMIP_ATTR_X509_CERTIFICATE_IDENTIFIER: XXX how to hack struct? + // case KMIP_ATTR_X509_CERTIFICATE_SUBJECT: XXX how to hack struct? + // case KMIP_ATTR_X509_CERTIFICATE_ISSUER: XXX how to hack struct? + // case KMIP_ATTR_CERTIFICATE_IDENTIFIER: XXX how to hack struct? + // case KMIP_ATTR_CERTIFICATE_SUBJECT: XXX how to hack struct? + // case KMIP_ATTR_CERTIFICATE_ISSUER: XXX how to hack struct? + + case KMIP_ATTR_DIGITAL_SIGNATURE_ALGORITHM: + kmip_print_digital_signature_algorithm_enum(*(enum digital_signature_algorithm *)value); + printf("\n"); + break; + + // case KMIP_ATTR_DIGEST: XXX how to hack struct? + + case KMIP_ATTR_OPERATION_POLICY_NAME: + printf("\n"); + kmip_print_text_string(indent + 2, "Operation Policy Name", value); + break; + + case KMIP_ATTR_CRYPTOGRAPHIC_USAGE_MASK: + kmip_print_cryptographic_usage_mask_enums(indent + 2, *(int32 *)value); + break; + + case KMIP_ATTR_LEASE_TIME: + printf("%u\n", *(uint32 *)value); + break; + + // case KMIP_ATTR_USAGE_LIMITS: XXX how to hack struct? + + case KMIP_ATTR_STATE: + kmip_print_state_enum(*(enum state *)value); + printf("\n"); + break; + + case KMIP_ATTR_INITIAL_DATE: + kmip_print_date_time(*(int64*)value); + break; + + case KMIP_ATTR_ACTIVATION_DATE: + kmip_print_date_time(*(int64*)value); + break; + + case KMIP_ATTR_PROCESS_START_DATE: + kmip_print_date_time(*(int64*)value); + break; + + case KMIP_ATTR_PROTECT_STOP_DATE: + kmip_print_date_time(*(int64*)value); + break; + + case KMIP_ATTR_DEACTIVATION_DATE: + kmip_print_date_time(*(int64*)value); + break; + + case KMIP_ATTR_DESTROY_DATE: + kmip_print_date_time(*(int64*)value); + break; + + case KMIP_ATTR_COMPROMISE_OCCURRENCE_DATE: + kmip_print_date_time(*(int64*)value); + break; + + case KMIP_ATTR_COMPROMISE_DATE: + kmip_print_date_time(*(int64*)value); + break; + + // case KMIP_ATTR_REVOCATION_REASON: XXX how to hack struct? + + case KMIP_ATTR_ARCHIVE_DATE: + kmip_print_date_time(*(int64*)value); + break; + + case KMIP_ATTR_OBJECT_GROUP: + printf("\n"); + kmip_print_text_string(indent + 2, "Object Group", value); + break; + + case KMIP_ATTR_FRESH: + printf("%d\n", *(bool32 *)value); + break; + + // case KMIP_ATTR_LINK: XXX how to hack struct? + // case KMIP_ATTR_APPLICATION_SPECIFIC_INFORMATION: XXX how to hack struct? + // case KMIP_ATTR_CONTACT_INFORMATION: XXX how to hack struct? + + case KMIP_ATTR_LAST_CHANGE_DATE: + kmip_print_date_time(*(int64*)value); + break; + + // case KMIP_ATTR_CUSTOM_ATTRIBUTE: XXX how to hack custom? + // case KMIP_ATTR_ALTERNATIVE_NAME: XXX how to hack struct? + + case KMIP_ATTR_KEY_VALUE_PRESENT: + printf("%d\n", *(bool32 *)value); + break; + + // case KMIP_ATTR_KEY_VALUE_LOCATION: XXX how to hack struct? + + case KMIP_ATTR_ORIGINAL_CREATION_DATE: + kmip_print_date_time(*(int64*)value); + break; + + case KMIP_ATTR_RANDOM_NUMBER_GENERATOR: + printf("\n"); + kmip_print_text_string(indent + 2, "Random Number Generator", value); + break; + + case KMIP_ATTR_PKCS_12_FRIENDLY_NAME: + printf("\n"); + kmip_print_text_string(indent + 2, "PKCS#12 Friendly Name", value); + break; + + case KMIP_ATTR_DESCRIPTION: + printf("\n"); + kmip_print_text_string(indent + 2, "Description", value); + break; + + case KMIP_ATTR_COMMENT: + printf("\n"); + kmip_print_text_string(indent + 2, "Comment", value); + break; + + + case KMIP_ATTR_SENSITIVE: + printf("%d\n", *(bool32 *)value); + break; + + case KMIP_ATTR_ALWAYS_SENSITIVE: + printf("%d\n", *(bool32 *)value); + break; + + case KMIP_ATTR_EXTRACTABLE: + printf("%d\n", *(bool32 *)value); + break; + + case KMIP_ATTR_NEVER_EXTRACTABLE: + printf("%d\n", *(bool32 *)value); + break; + + case KMIP_ATTR_KEY_FORMAT_TYPE: + kmip_print_key_format_type_enum(*(enum key_format_type *)value); + printf("\n"); + break; + + default: + printf("Unknown\n"); + break; + }; +} + +void +kmip_print_attribute(int indent, Attribute *value) +{ + printf("%*sAttribute @ %p\n", indent, "", (void *)value); + + if(value != NULL) + { + printf("%*sAttribute Name: ", indent + 2, ""); + kmip_print_attribute_type_enum(value->type); + printf("\n"); + + printf("%*sAttribute Index: ", indent + 2, ""); + kmip_print_integer(value->index); + printf("\n"); + + kmip_print_attribute_value(indent + 2, value->type, value->value); + } + + return; +} + +void +kmip_print_key_material(int indent, enum key_format_type format, void *value) +{ + switch(format) + { + case KMIP_KEYFORMAT_RAW: + case KMIP_KEYFORMAT_OPAQUE: + case KMIP_KEYFORMAT_PKCS1: + case KMIP_KEYFORMAT_PKCS8: + case KMIP_KEYFORMAT_X509: + case KMIP_KEYFORMAT_EC_PRIVATE_KEY: + kmip_print_byte_string(indent, "Key Material", (ByteString *)value); + break; + + default: + printf("%*sUnknown Key Material @ %p\n", indent, "", value); + break; + }; +} + +void +kmip_print_key_value(int indent, enum type type, enum key_format_type format, void *value) +{ + switch(type) + { + case KMIP_TYPE_BYTE_STRING: + kmip_print_byte_string(indent, "Key Value", (ByteString *)value); + break; + + case KMIP_TYPE_STRUCTURE: + printf("%*sKey Value @ %p\n", indent, "", value); + + if(value != NULL) + { + KeyValue key_value = *(KeyValue *)value; + kmip_print_key_material(indent + 2, format, key_value.key_material); + printf("%*sAttributes: %zu\n", indent + 2, "", key_value.attribute_count); + for(size_t i = 0; i < key_value.attribute_count; i++) + { + kmip_print_attribute(indent + 2, &key_value.attributes[i]); + } + } + break; + + default: + printf("%*sUnknown Key Value @ %p\n", indent, "", value); + break; + }; +} + +void +kmip_print_key_block(int indent, KeyBlock *value) +{ + printf("%*sKey Block @ %p\n", indent, "", (void *)value); + + if(value != NULL) + { + printf("%*sKey Format Type: ", indent + 2, ""); + kmip_print_key_format_type_enum(value->key_format_type); + printf("\n"); + + printf("%*sKey Compression Type: ", indent + 2, ""); + kmip_print_key_compression_type_enum(value->key_compression_type); + printf("\n"); + + kmip_print_key_value(indent + 2, value->key_value_type, value->key_format_type, value->key_value); + + printf("%*sCryptographic Algorithm: ", indent + 2, ""); + kmip_print_cryptographic_algorithm_enum(value->cryptographic_algorithm); + printf("\n"); + + printf("%*sCryptographic Length: %d\n", indent + 2, "", value->cryptographic_length); + + kmip_print_key_wrapping_data(indent + 2, value->key_wrapping_data); + } + + return; +} + +void +kmip_print_symmetric_key(int indent, SymmetricKey *value) +{ + printf("%*sSymmetric Key @ %p\n", indent, "", (void *)value); + + if(value != NULL) + { + kmip_print_key_block(indent + 2, value->key_block); + } + + return; +} + +void +kmip_print_object(int indent, enum object_type type, void *value) +{ + switch(type) + { + case KMIP_OBJTYPE_SYMMETRIC_KEY: + kmip_print_symmetric_key(indent, (SymmetricKey *)value); + break; + + default: + printf("%*sUnknown Object @ %p\n", indent, "", value); + break; + }; +} + +void +kmip_print_key_wrapping_specification(int indent, KeyWrappingSpecification *value) +{ + printf("%*sKey Wrapping Specification @ %p\n", indent, "", (void *)value); +} + +void +kmip_print_attributes(int indent, Attributes *value) +{ + printf("%*sAttributes @ %p\n", indent, "", (void *)value); + + if(value != NULL) + { + printf("%*sAttributes: %zu\n", indent + 2, "", value->attribute_list->size); + LinkedListItem *curr = value->attribute_list->head; + while(curr != NULL) + { + Attribute *attribute = (Attribute *)curr->data; + kmip_print_attribute(indent + 4, attribute); + + curr = curr->next; + } + } +} + +void +kmip_print_template_attribute(int indent, TemplateAttribute *value) +{ + printf("%*sTemplate Attribute @ %p\n", indent, "", (void *)value); + + if(value != NULL) + { + printf("%*sNames: %zu\n", indent + 2, "", value->name_count); + for(size_t i = 0; i < value->name_count; i++) + { + kmip_print_name(indent + 4, &value->names[i]); + } + + printf("%*sAttributes: %zu\n", indent + 2, "", value->attribute_count); + for(size_t i = 0; i< value->attribute_count; i++) + { + kmip_print_attribute(indent + 4, &value->attributes[i]); + } + } +} + +void +kmip_print_create_request_payload(int indent, CreateRequestPayload *value) +{ + printf("%*sCreate Request Payload @ %p\n", indent, "", (void *)value); + + if(value != NULL) + { + printf("%*sObject Type: ", indent + 2, ""); + kmip_print_object_type_enum(value->object_type); + printf("\n"); + + kmip_print_template_attribute(indent + 2, value->template_attribute); + kmip_print_attributes(indent + 2, value->attributes); + kmip_print_protection_storage_masks(indent + 2, value->protection_storage_masks); + } +} + +void +kmip_print_create_response_payload(int indent, CreateResponsePayload *value) +{ + printf("%*sCreate Response Payload @ %p\n", indent, "", (void *)value); + + if(value != NULL) + { + printf("%*sObject Type: ", indent + 2, ""); + kmip_print_object_type_enum(value->object_type); + printf("\n"); + + kmip_print_text_string( + indent + 2, + "Unique Identifier", + value->unique_identifier); + + kmip_print_template_attribute(indent + 2, value->template_attribute); + } +} + +void +kmip_print_locate_request_payload(int indent, LocateRequestPayload *value) +{ + printf("%*sLocate Request Payload @ %p\n", indent, "", (void *)value); + + if(value != NULL) + { + printf("%*sMaximum Items: ", indent + 2, ""); + kmip_print_integer(value->maximum_items); + printf("\n"); + + printf("%*sOffset Items: ", indent + 2, ""); + kmip_print_integer(value->offset_items); + printf("\n"); + + printf("%*sStorage Status Mask: ", indent + 2, ""); + kmip_print_storage_status_mask_enum(value->storage_status_mask); + printf("\n"); + + printf("%*sObject Group Member: ", indent + 2, ""); + kmip_print_object_group_member_enum(value->object_group_member); + printf("\n"); + + printf("%*sAttributes: %d\n", indent + 2, "", value->attribute_count); + for(int i = 0; i < value->attribute_count; ++i) + { + kmip_print_attribute(indent + 4, value->attributes + i); + } + } +} + +void +kmip_print_locate_response_payload(int indent, LocateResponsePayload *value) +{ + printf("%*sLocate Response Payload @ %p\n", indent, "", (void *)value); + + if(value != NULL) + { + printf("%*sLocated Items: ", indent + 2, ""); + kmip_print_integer(value->located_items); + printf("\n"); + + printf("%*sUnique Identifiers: %d\n", indent + 2, "", value->unique_identifiers_count); + for(int i = 0; i < value->unique_identifiers_count; ++i) + { + printf("%*s%.*s\n", indent + 4, "", + (int)value->unique_identifiers[i].size, + value->unique_identifiers[i].value); + } + } +} + +void +kmip_print_get_request_payload(int indent, GetRequestPayload *value) +{ + printf("%*sGet Request Payload @ %p\n", indent, "", (void *)value); + + if(value != NULL) + { + kmip_print_text_string( + indent + 2, + "Unique Identifier", + value->unique_identifier); + + printf("%*sKey Format Type: ", indent + 2, ""); + kmip_print_key_format_type_enum(value->key_format_type); + printf("\n"); + + printf("%*sKey Wrap Type: ", indent + 2, ""); + kmip_print_key_wrap_type_enum(value->key_wrap_type); + printf("\n"); + + printf("%*sKey Compression Type: ", indent + 2, ""); + kmip_print_key_compression_type_enum(value->key_compression_type); + printf("\n"); + + kmip_print_key_wrapping_specification(indent + 2, value->key_wrapping_spec); + } +} + +void +kmip_print_get_response_payload(int indent, GetResponsePayload *value) +{ + printf("%*sGet Response Payload @ %p\n", indent, "", (void *)value); + + if(value != NULL) + { + printf("%*sObject Type: ", indent + 2, ""); + kmip_print_object_type_enum(value->object_type); + printf("\n"); + + kmip_print_text_string(indent + 2, "Unique Identifier", value->unique_identifier); + kmip_print_object(indent + 2, value->object_type, value->object); + } + + return; +} + +void +kmip_print_get_attributes_request_payload(int indent, GetAttributesRequestPayload *value) +{ + printf("%*sGet Attributes Request Payload @ %p\n", indent, "", (void *)value); + + if(value != NULL) + { + kmip_print_text_string( + indent + 2, + "Unique Identifier", + value->unique_identifier); + + printf("%*sAttribute Names: %d\n", indent + 2, "", value->attribute_count); + for(int i = 0; i < value->attribute_count; ++i) + { + printf("%*s", indent + 4, ""); + kmip_print_attribute_type_enum(value->attribute_names[i]); + printf ("\n"); + } + } +} + +void +kmip_print_get_attributes_response_payload(int indent, GetAttributesResponsePayload *value) +{ + printf("%*sGet Attributes Response Payload @ %p\n", indent, "", (void *)value); + + if(value != NULL) + { + kmip_print_text_string( + indent + 2, + "Unique Identifier", + value->unique_identifier); + + printf("%*sAttributes: %d\n", indent + 2, "", value->attribute_count); + for(int i = 0; i < value->attribute_count; ++i) + { + kmip_print_attribute(indent + 4, value->attributes + i); + } + } + + return; +} + +void +kmip_print_get_attribute_list_request_payload(int indent, GetAttributeListRequestPayload *value) +{ + printf("%*sGet Attribute List Request Payload @ %p\n", indent, "", (void *)value); + + if(value != NULL) + { + kmip_print_text_string( + indent + 2, + "Unique Identifier", + value->unique_identifier); + } +} + +void +kmip_print_get_attribute_list_response_payload(int indent, GetAttributeListResponsePayload *value) +{ + printf("%*sGet Attribute List Response Payload @ %p\n", indent, "", (void *)value); + + if(value != NULL) + { + kmip_print_text_string( + indent + 2, + "Unique Identifier", + value->unique_identifier); + + printf("%*sAttribute Names: %d\n", indent + 2, "", value->attribute_names_count); + for(int i = 0; i < value->attribute_names_count; ++i) + { + printf("%*s", indent + 4, ""); + kmip_print_attribute_type_enum(value->attribute_names[i]); + printf ("\n"); + } + } + + return; +} + +void +kmip_print_destroy_request_payload(int indent, DestroyRequestPayload *value) +{ + printf("%*sDestroy Request Payload @ %p\n", indent, "", (void *)value); + + if(value != NULL) + { + kmip_print_text_string( + indent + 2, + "Unique Identifier", + value->unique_identifier); + } +} + +void +kmip_print_destroy_response_payload(int indent, DestroyResponsePayload *value) +{ + printf("%*sDestroy Response Payload @ %p\n", indent, "", (void *)value); + + if(value != NULL) + { + kmip_print_text_string( + indent + 2, + "Unique Identifier", + value->unique_identifier); + } +} + +void +kmip_print_request_payload(int indent, enum operation type, void *value) +{ + switch(type) + { + case KMIP_OP_CREATE: + kmip_print_create_request_payload(indent, value); + break; + + case KMIP_OP_LOCATE: + kmip_print_locate_request_payload(indent, (LocateRequestPayload *)value); + break; + + case KMIP_OP_GET: + kmip_print_get_request_payload(indent, (GetRequestPayload *)value); + break; + + case KMIP_OP_GET_ATTRIBUTES: + kmip_print_get_attributes_request_payload(indent, (GetAttributesRequestPayload *)value); + break; + + case KMIP_OP_GET_ATTRIBUTE_LIST: + kmip_print_get_attribute_list_request_payload(indent, (GetAttributeListRequestPayload *)value); + break; + + case KMIP_OP_DESTROY: + kmip_print_destroy_request_payload(indent, value); + break; + + default: + printf("%*sUnknown Payload @ %p\n", indent, "", value); + break; + }; +} + +void +kmip_print_response_payload(int indent, enum operation type, void *value) +{ + switch(type) + { + case KMIP_OP_CREATE: + kmip_print_create_response_payload(indent, value); + break; + + case KMIP_OP_LOCATE: + kmip_print_locate_response_payload(indent, (LocateResponsePayload *)value); + break; + + case KMIP_OP_GET: + kmip_print_get_response_payload(indent, (GetResponsePayload *)value); + break; + + case KMIP_OP_GET_ATTRIBUTES: + kmip_print_get_attributes_response_payload(indent, (GetAttributesResponsePayload *)value); + break; + + case KMIP_OP_GET_ATTRIBUTE_LIST: + kmip_print_get_attribute_list_response_payload(indent, (GetAttributeListResponsePayload *)value); + break; + + case KMIP_OP_DESTROY: + kmip_print_destroy_response_payload(indent, value); + break; + + default: + printf("%*sUnknown Payload @ %p\n", indent, "", value); + break; + }; +} + +void +kmip_print_username_password_credential(int indent, UsernamePasswordCredential *value) +{ + printf("%*sUsername/Password Credential @ %p\n", indent, "", (void *)value); + + if(value != NULL) + { + kmip_print_text_string(indent + 2, "Username", value->username); + kmip_print_text_string(indent + 2, "Password", value->password); + } +} + +void +kmip_print_device_credential(int indent, DeviceCredential *value) +{ + printf("%*sDevice Credential @ %p\n", indent, "", (void *)value); + + if(value != NULL) + { + kmip_print_text_string(indent + 2, "Device Serial Number", value->device_serial_number); + kmip_print_text_string(indent + 2, "Password", value->password); + kmip_print_text_string(indent + 2, "Device Identifier", value->device_identifier); + kmip_print_text_string(indent + 2, "Network Identifier", value->network_identifier); + kmip_print_text_string(indent + 2, "Machine Identifier", value->machine_identifier); + kmip_print_text_string(indent + 2, "Media Identifier", value->media_identifier); + } +} + +void +kmip_print_attestation_credential(int indent, AttestationCredential *value) +{ + printf("%*sAttestation Credential @ %p\n", indent, "", (void *)value); + + if(value != NULL) + { + kmip_print_nonce(indent + 2, value->nonce); + printf("%*sAttestation Type: ", indent + 2, ""); + kmip_print_attestation_type_enum(value->attestation_type); + printf("\n"); + kmip_print_byte_string(indent + 2, "Attestation Measurement", value->attestation_measurement); + kmip_print_byte_string(indent + 2, "Attestation Assertion", value->attestation_assertion); + } +} + +void +kmip_print_credential_value(int indent, enum credential_type type, void *value) +{ + printf("%*sCredential Value @ %p\n", indent, "", value); + + if(value != NULL) + { + switch(type) + { + case KMIP_CRED_USERNAME_AND_PASSWORD: + kmip_print_username_password_credential(indent + 2, value); + break; + + case KMIP_CRED_DEVICE: + kmip_print_device_credential(indent + 2, value); + break; + + case KMIP_CRED_ATTESTATION: + kmip_print_attestation_credential(indent + 2, value); + break; + + default: + printf("%*sUnknown Credential @ %p\n", indent + 2, "", value); + break; + }; + } +} + +void +kmip_print_credential(int indent, Credential *value) +{ + printf("%*sCredential @ %p\n", indent, "", (void *)value); + + if(value != NULL) + { + printf("%*sCredential Type: ", indent + 2, ""); + kmip_print_credential_type_enum(value->credential_type); + printf("\n"); + + kmip_print_credential_value( + indent + 2, + value->credential_type, + value->credential_value); + } +} + +void +kmip_print_authentication(int indent, Authentication *value) +{ + printf("%*sAuthentication @ %p\n", indent, "", (void *)value); + + if(value != NULL) + { + kmip_print_credential(indent + 2, value->credential); + } +} + +void +kmip_print_request_batch_item(int indent, RequestBatchItem *value) +{ + printf("%*sRequest Batch Item @ %p\n", indent, "", (void *)value); + + if(value != NULL) + { + printf("%*sOperation: ", indent + 2, ""); + kmip_print_operation_enum(value->operation); + printf("\n"); + + printf("%*sEphemeral: ", indent + 2, ""); + kmip_print_bool(value->ephemeral); + printf("\n"); + + kmip_print_byte_string( + indent + 2, + "Unique Batch Item ID", + value->unique_batch_item_id); + + kmip_print_request_payload( + indent + 2, + value->operation, + value->request_payload); + } +} + +void +kmip_print_response_batch_item(int indent, ResponseBatchItem *value) +{ + printf("%*sResponse Batch Item @ %p\n", indent, "", (void *)value); + + if(value != NULL) + { + printf("%*sOperation: ", indent + 2, ""); + kmip_print_operation_enum(value->operation); + printf("\n"); + + kmip_print_byte_string( + indent + 2, + "Unique Batch Item ID", + value->unique_batch_item_id); + + printf("%*sResult Status: ", indent + 2, ""); + kmip_print_result_status_enum(value->result_status); + printf("\n"); + + printf("%*sResult Reason: ", indent + 2, ""); + kmip_print_result_reason_enum(value->result_reason); + printf("\n"); + + kmip_print_text_string(indent + 2, "Result Message", value->result_message); + kmip_print_byte_string( + indent + 2, + "Asynchronous Correlation Value", + value->asynchronous_correlation_value); + + kmip_print_response_payload( + indent + 2, + value->operation, + value->response_payload); + } + + return; +} + +void +kmip_print_request_header(int indent, RequestHeader *value) +{ + printf("%*sRequest Header @ %p\n", indent, "", (void *)value); + + if(value != NULL) + { + kmip_print_protocol_version(indent + 2, value->protocol_version); + + printf("%*sMaximum Response Size: ", indent + 2, ""); + kmip_print_integer(value->maximum_response_size); + printf("\n"); + + kmip_print_text_string( + indent + 2, + "Client Correlation Value", + value->client_correlation_value); + kmip_print_text_string( + indent + 2, + "Server Correlation Value", + value->server_correlation_value); + printf("%*sAsynchronous Indicator: ", indent + 2, ""); + kmip_print_bool(value->asynchronous_indicator); + printf("\n"); + printf("%*sAttestation Capable Indicator: ", indent + 2, ""); + kmip_print_bool(value->attestation_capable_indicator); + printf("\n"); + printf( + "%*sAttestation Types: %zu\n", + indent + 2, + "", + value->attestation_type_count); + for(size_t i = 0; i < value->attestation_type_count; i++) + { + /* TODO (ph) Add enum value -> string functionality. */ + printf("%*sAttestation Type: %s\n", indent + 4, "", "???"); + } + kmip_print_authentication(indent + 2, value->authentication); + printf("%*sBatch Error Continuation Option: ", indent + 2, ""); + kmip_print_batch_error_continuation_option( + value->batch_error_continuation_option); + printf("\n"); + printf("%*sBatch Order Option: ", indent + 2, ""); + kmip_print_bool(value->batch_order_option); + printf("\n"); + printf("%*sTime Stamp: %lu\n", indent + 2, "", value->time_stamp); + printf("%*sBatch Count: %d\n", indent + 2, "", value->batch_count); + } +} + +void +kmip_print_response_header(int indent, ResponseHeader *value) +{ + printf("%*sResponse Header @ %p\n", indent, "", (void *)value); + + if(value != NULL) + { + kmip_print_protocol_version(indent + 2, value->protocol_version); + printf("%*sTime Stamp: %lu\n", indent + 2, "", value->time_stamp); + kmip_print_nonce(indent + 2, value->nonce); + + kmip_print_byte_string(indent + 2, "Server Hashed Password", value->server_hashed_password); + + printf( + "%*sAttestation Types: %zu\n", + indent + 2, + "", + value->attestation_type_count); + for(size_t i = 0; i < value->attestation_type_count; i++) + { + /* TODO (ph) Add enum value -> string functionality. */ + printf("%*sAttestation Type: %s\n", indent + 4, "", "???"); + } + kmip_print_text_string( + indent + 2, + "Client Correlation Value", + value->client_correlation_value); + kmip_print_text_string( + indent + 2, + "Server Correlation Value", + value->server_correlation_value); + printf("%*sBatch Count: %d\n", indent + 2, "", value->batch_count); + } +} + +void +kmip_print_request_message(RequestMessage *value) +{ + printf("Request Message @ %p\n", (void *)value); + + if(value != NULL) + { + kmip_print_request_header(2, value->request_header); + printf("%*sBatch Items: %zu\n", 2, "", value->batch_count); + + for(size_t i = 0; i < value->batch_count; i++) + { + kmip_print_request_batch_item(4, &value->batch_items[i]); + } + } + + return; +} + +void +kmip_print_response_message(ResponseMessage *value) +{ + printf("Response Message @ %p\n", (void *)value); + + if(value != NULL) + { + kmip_print_response_header(2, value->response_header); + printf(" Batch Items: %zu\n", value->batch_count); + + for(size_t i = 0; i < value->batch_count; i++) + { + kmip_print_response_batch_item(4, &value->batch_items[i]); + } + } + + return; +} + +/* +Freeing Functions +*/ + +void +kmip_free_buffer(KMIP *ctx, void *buffer, size_t size) +{ + if(ctx == NULL) + { + return; + } + + ctx->memset_func(buffer, 0, size); + ctx->free_func(ctx->state, buffer); +} + +void +kmip_free_text_string(KMIP *ctx, TextString *value) +{ + if(ctx == NULL) + { + return; + } + + if(value != NULL) + { + if(value->value != NULL) + { + ctx->memset_func(value->value, 0, value->size); + ctx->free_func(ctx->state, value->value); + + value->value = NULL; + } + + value->size = 0; + } + + return; +} + +void +kmip_free_byte_string(KMIP *ctx, ByteString *value) +{ + if(value != NULL) + { + if(value->value != NULL) + { + ctx->memset_func(value->value, 0, value->size); + ctx->free_func(ctx->state, value->value); + + value->value = NULL; + } + + value->size = 0; + } + + return; +} + +void +kmip_free_name(KMIP *ctx, Name *value) +{ + if(value != NULL) + { + if(value->value != NULL) + { + kmip_free_text_string(ctx, value->value); + ctx->free_func(ctx->state, value->value); + + value->value = NULL; + } + + value->type = 0; + } + + return; +} + +void +kmip_free_protection_storage_masks(KMIP *ctx, ProtectionStorageMasks *value) +{ + if(value != NULL) + { + if(value->masks != NULL) + { + LinkedListItem *curr = kmip_linked_list_pop(value->masks); + while(curr != NULL) + { + ctx->free_func(ctx->state, curr->data); + curr->data = NULL; + ctx->free_func(ctx->state, curr); + curr = kmip_linked_list_pop(value->masks); + } + ctx->free_func(ctx->state, value->masks); + value->masks = NULL; + } + } + + return; +} + +void +kmip_free_digest(KMIP *ctx, Digest *value) +{ + if(value != NULL) + { + if(value->digest_value != NULL) + { + kmip_free_byte_string(ctx, value->digest_value); + value->digest_value = NULL; + } + value->hashing_algorithm = 0; + value->key_format_type = 0; + } + + return; +} + +void +kmip_free_attribute(KMIP *ctx, Attribute *value) +{ + if(value != NULL) + { + if(value->value != NULL) + { + switch(value->type) + { + case KMIP_ATTR_UNIQUE_IDENTIFIER: + kmip_free_text_string(ctx, value->value); + break; + + case KMIP_ATTR_NAME: + kmip_free_name(ctx, value->value); + break; + + case KMIP_ATTR_OBJECT_TYPE: + *(int32*)value->value = 0; + break; + + case KMIP_ATTR_CRYPTOGRAPHIC_ALGORITHM: + *(int32*)value->value = 0; + break; + + case KMIP_ATTR_CRYPTOGRAPHIC_LENGTH: + *(int32 *)value->value = KMIP_UNSET; + break; + + // case KMIP_ATTR_CRYPTOGRAPHIC_PARAMETERS: XXX how to hack struct? + // case KMIP_ATTR_CRYPTOGRAPHIC_DOMAIN_PARAMETERS: XXX how to hack struct? + + case KMIP_ATTR_CERTIFICATE_TYPE: + *(int32*)value->value = 0; + break; + + case KMIP_ATTR_CERTIFICATE_LENGTH: + *(int32 *)value->value = 0; + break; + + // case KMIP_ATTR_X509_CERTIFICATE_IDENTIFIER: XXX how to hack struct? + // case KMIP_ATTR_X509_CERTIFICATE_SUBJECT: XXX how to hack struct? + // case KMIP_ATTR_X509_CERTIFICATE_ISSUER: XXX how to hack struct? + // case KMIP_ATTR_CERTIFICATE_IDENTIFIER: XXX how to hack struct? + // case KMIP_ATTR_CERTIFICATE_SUBJECT: XXX how to hack struct? + // case KMIP_ATTR_CERTIFICATE_ISSUER: XXX how to hack struct? + + case KMIP_ATTR_DIGITAL_SIGNATURE_ALGORITHM: + *(int32*)value->value = 0; + break; + + case KMIP_ATTR_DIGEST: + kmip_free_digest(ctx, value->value); + break; + + case KMIP_ATTR_OPERATION_POLICY_NAME: + kmip_free_text_string(ctx, value->value); + break; + + case KMIP_ATTR_CRYPTOGRAPHIC_USAGE_MASK: + *(int32 *)value->value = KMIP_UNSET; + break; + + case KMIP_ATTR_LEASE_TIME: + *(uint32 *)value->value = 0; + break; + + // case KMIP_ATTR_USAGE_LIMITS: XXX how to hack struct? + + case KMIP_ATTR_STATE: + *(uint32*)value->value = 0; + break; + + case KMIP_ATTR_INITIAL_DATE: + *(int64*)value->value = 0; + break; + + case KMIP_ATTR_ACTIVATION_DATE: + *(int64*)value->value = 0; + break; + + case KMIP_ATTR_PROCESS_START_DATE: + *(int64*)value->value = 0; + break; + + case KMIP_ATTR_PROTECT_STOP_DATE: + *(int64*)value->value = 0; + break; + + case KMIP_ATTR_DEACTIVATION_DATE: + *(int64*)value->value = 0; + break; + + case KMIP_ATTR_DESTROY_DATE: + *(int64*)value->value = 0; + break; + + case KMIP_ATTR_COMPROMISE_OCCURRENCE_DATE: + *(int64*)value->value = 0; + break; + + case KMIP_ATTR_COMPROMISE_DATE: + *(int64*)value->value = 0; + break; + + // case KMIP_ATTR_REVOCATION_REASON: XXX how to hack struct? + + case KMIP_ATTR_ARCHIVE_DATE: + *(int64*)value->value = 0; + break; + + case KMIP_ATTR_OBJECT_GROUP: + kmip_free_text_string(ctx, value->value); + break; + + case KMIP_ATTR_FRESH: + *(bool32 *)value->value = 0; + break; + + // case KMIP_ATTR_LINK: XXX how to hack struct? + // case KMIP_ATTR_APPLICATION_SPECIFIC_INFORMATION: XXX how to hack struct? + // case KMIP_ATTR_CONTACT_INFORMATION: XXX how to hack struct? + + case KMIP_ATTR_LAST_CHANGE_DATE: + *(int64*)value->value = 0; + break; + + // case KMIP_ATTR_CUSTOM_ATTRIBUTE: XXX how to hack custom? + // case KMIP_ATTR_ALTERNATIVE_NAME: XXX how to hack struct? + + case KMIP_ATTR_KEY_VALUE_PRESENT: + *(bool32 *)value->value = 0; + break; + + // case KMIP_ATTR_KEY_VALUE_LOCATION: XXX how to hack struct? + + case KMIP_ATTR_ORIGINAL_CREATION_DATE: + *(int64*)value->value = 0; + break; + + case KMIP_ATTR_RANDOM_NUMBER_GENERATOR: + kmip_free_text_string(ctx, value->value); + break; + + case KMIP_ATTR_PKCS_12_FRIENDLY_NAME: + kmip_free_text_string(ctx, value->value); + break; + + case KMIP_ATTR_DESCRIPTION: + kmip_free_text_string(ctx, value->value); + break; + + case KMIP_ATTR_COMMENT: + kmip_free_text_string(ctx, value->value); + break; + + case KMIP_ATTR_SENSITIVE: + *(bool32 *)value->value = 0; + break; + + case KMIP_ATTR_ALWAYS_SENSITIVE: + *(bool32 *)value->value = 0; + break; + + case KMIP_ATTR_EXTRACTABLE: + *(bool32 *)value->value = 0; + break; + + case KMIP_ATTR_NEVER_EXTRACTABLE: + *(bool32 *)value->value = 0; + break; + + case KMIP_ATTR_KEY_FORMAT_TYPE: + *(int32*)value->value = 0; + break; + + default: + /* NOTE (ph) Hitting this case means that we don't know what the */ + /* actual type, size, or value of value->value is. We can */ + /* still free it but we cannot securely zero the memory. We */ + /* also do not know how to free any possible substructures */ + /* pointed to within value->value. */ + /* */ + /* Avoid hitting this case at all costs. */ + break; + }; + + ctx->free_func(ctx->state, value->value); + value->value = NULL; + } + + value->type = 0; + value->index = KMIP_UNSET; + } + + return; +} + +void +kmip_free_attributes(KMIP *ctx, Attributes *value) +{ + if(value != NULL) + { + if(value->attribute_list != NULL) + { + LinkedListItem *curr = kmip_linked_list_pop(value->attribute_list); + while(curr != NULL) + { + Attribute *attribute = (Attribute *)curr->data; + kmip_free_attribute(ctx, attribute); + ctx->free_func(ctx->state, attribute); + ctx->free_func(ctx->state, curr); + curr = kmip_linked_list_pop(value->attribute_list); + } + ctx->free_func(ctx->state, value->attribute_list); + + value->attribute_list = NULL; + } + } + + return; +} + +void +kmip_free_attributes_2(KMIP *ctx, Attribute *value, int count) +{ + if(value != NULL) + { + for(int i = 0; i < count; i++) + { + kmip_free_attribute(ctx, &value[i]); + } + ctx->free_func(ctx->state, value); + } + + return; +} + +void +kmip_free_template_attribute(KMIP *ctx, TemplateAttribute *value) +{ + if(value != NULL) + { + if(value->names != NULL) + { + for(size_t i = 0; i < value->name_count; i++) + { + kmip_free_name(ctx, &value->names[i]); + } + ctx->free_func(ctx->state, value->names); + + value->names = NULL; + } + + value->name_count = 0; + + if(value->attributes != NULL) + { + for(size_t i = 0; i < value->attribute_count; i++) + { + kmip_free_attribute(ctx, &value->attributes[i]); + } + ctx->free_func(ctx->state, value->attributes); + + value->attributes = NULL; + } + + value->attribute_count = 0; + } + + return; +} + +void +kmip_free_transparent_symmetric_key(KMIP *ctx, TransparentSymmetricKey *value) +{ + if(value != NULL) + { + if(value->key != NULL) + { + kmip_free_byte_string(ctx, value->key); + + ctx->free_func(ctx->state, value->key); + value->key = NULL; + } + } + + return; +} + +void +kmip_free_key_material(KMIP *ctx, enum key_format_type format, void **value) +{ + if(value != NULL) + { + if(*value != NULL) + { + switch(format) + { + case KMIP_KEYFORMAT_RAW: + case KMIP_KEYFORMAT_OPAQUE: + case KMIP_KEYFORMAT_PKCS1: + case KMIP_KEYFORMAT_PKCS8: + case KMIP_KEYFORMAT_X509: + case KMIP_KEYFORMAT_EC_PRIVATE_KEY: + kmip_free_byte_string(ctx, *value); + break; + + case KMIP_KEYFORMAT_TRANS_SYMMETRIC_KEY: + kmip_free_transparent_symmetric_key(ctx, *value); + break; + + default: + /* NOTE (ph) Hitting this case means that we don't know */ + /* what the actual type, size, or value of value is. */ + /* We can still free it but we cannot securely zero */ + /* the memory. We also do not know how to free any */ + /* possible substructures pointed to within value. */ + /* */ + /* Avoid hitting this case at all costs. */ + break; + }; + + ctx->free_func(ctx->state, *value); + *value = NULL; + } + } + + return; +} + +void +kmip_free_key_value(KMIP *ctx, enum key_format_type format, KeyValue *value) +{ + if(value != NULL) + { + if(value->key_material != NULL) + { + kmip_free_key_material(ctx, format, &value->key_material); + value->key_material = NULL; + } + + if(value->attributes != NULL) + { + for(size_t i = 0; i < value->attribute_count; i++) + { + kmip_free_attribute(ctx, &value->attributes[i]); + } + ctx->free_func(ctx->state, value->attributes); + + value->attributes = NULL; + } + + value->attribute_count = 0; + } + + return; +} + +void +kmip_free_cryptographic_parameters(KMIP *ctx, CryptographicParameters *value) +{ + if(value != NULL) + { + if(value->p_source != NULL) + { + kmip_free_byte_string(ctx, value->p_source); + + ctx->free_func(ctx->state, value->p_source); + value->p_source = NULL; + } + + kmip_init_cryptographic_parameters(value); + } + + return; +} + +void +kmip_free_encryption_key_information(KMIP *ctx, EncryptionKeyInformation *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->cryptographic_parameters != NULL) + { + kmip_free_cryptographic_parameters(ctx, value->cryptographic_parameters); + + ctx->free_func(ctx->state, value->cryptographic_parameters); + value->cryptographic_parameters = NULL; + } + } + + return; +} + +void +kmip_free_mac_signature_key_information(KMIP *ctx, MACSignatureKeyInformation *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->cryptographic_parameters != NULL) + { + kmip_free_cryptographic_parameters(ctx, value->cryptographic_parameters); + + ctx->free_func(ctx->state, value->cryptographic_parameters); + value->cryptographic_parameters = NULL; + } + } + + return; +} + +void +kmip_free_key_wrapping_data(KMIP *ctx, KeyWrappingData *value) +{ + if(value != NULL) + { + if(value->encryption_key_info != NULL) + { + kmip_free_encryption_key_information(ctx, value->encryption_key_info); + + ctx->free_func(ctx->state, value->encryption_key_info); + value->encryption_key_info = NULL; + } + + if(value->mac_signature_key_info != NULL) + { + kmip_free_mac_signature_key_information(ctx, value->mac_signature_key_info); + + ctx->free_func(ctx->state, value->mac_signature_key_info); + value->mac_signature_key_info = NULL; + } + + if(value->mac_signature != NULL) + { + kmip_free_byte_string(ctx, value->mac_signature); + + ctx->free_func(ctx->state, value->mac_signature); + value->mac_signature = NULL; + } + + if(value->iv_counter_nonce != NULL) + { + kmip_free_byte_string(ctx, value->iv_counter_nonce); + + ctx->free_func(ctx->state, value->iv_counter_nonce); + value->iv_counter_nonce = NULL; + } + + value->wrapping_method = 0; + value->encoding_option = 0; + } + + return; +} + +void +kmip_free_key_block(KMIP *ctx, KeyBlock *value) +{ + if(value != NULL) + { + if(value->key_value != NULL) + { + if(value->key_value_type == KMIP_TYPE_BYTE_STRING) + { + kmip_free_byte_string(ctx, value->key_value); + ctx->free_func(ctx->state, value->key_value); + } + else + { + kmip_free_key_value(ctx, value->key_format_type, value->key_value); + ctx->free_func(ctx->state, value->key_value); + } + value->key_value = NULL; + } + + if(value->key_wrapping_data != NULL) + { + kmip_free_key_wrapping_data(ctx, value->key_wrapping_data); + ctx->free_func(ctx->state, value->key_wrapping_data); + value->key_wrapping_data = NULL; + } + + kmip_init_key_block(value); + } + + return; +} + +void +kmip_free_symmetric_key(KMIP *ctx, SymmetricKey *value) +{ + if(value != NULL) + { + if(value->key_block != NULL) + { + kmip_free_key_block(ctx, value->key_block); + ctx->free_func(ctx->state, value->key_block); + value->key_block = NULL; + } + } + + return; +} + +void +kmip_free_public_key(KMIP *ctx, PublicKey *value) +{ + if(value != NULL) + { + if(value->key_block != NULL) + { + kmip_free_key_block(ctx, value->key_block); + ctx->free_func(ctx->state, value->key_block); + value->key_block = NULL; + } + } + + return; +} + +void +kmip_free_private_key(KMIP *ctx, PrivateKey *value) +{ + if(value != NULL) + { + if(value->key_block != NULL) + { + kmip_free_key_block(ctx, value->key_block); + ctx->free_func(ctx->state, value->key_block); + value->key_block = NULL; + } + } + + return; +} + +void +kmip_free_key_wrapping_specification(KMIP *ctx, KeyWrappingSpecification *value) +{ + if(value != NULL) + { + if(value->encryption_key_info != NULL) + { + kmip_free_encryption_key_information(ctx, value->encryption_key_info); + ctx->free_func(ctx->state, value->encryption_key_info); + value->encryption_key_info = NULL; + } + + if(value->mac_signature_key_info != NULL) + { + kmip_free_mac_signature_key_information(ctx, value->mac_signature_key_info); + ctx->free_func(ctx->state, value->mac_signature_key_info); + value->mac_signature_key_info = NULL; + } + + if(value->attribute_names != NULL) + { + for(size_t i = 0; i < value->attribute_name_count; i++) + { + kmip_free_text_string(ctx, &value->attribute_names[i]); + } + ctx->free_func(ctx->state, value->attribute_names); + value->attribute_names = NULL; + } + value->attribute_name_count = 0; + + value->wrapping_method = 0; + value->encoding_option = 0; + } + + return; +} + +void +kmip_free_create_request_payload(KMIP *ctx, CreateRequestPayload *value) +{ + if(value != NULL) + { + if(value->template_attribute != NULL) + { + kmip_free_template_attribute(ctx, value->template_attribute); + ctx->free_func(ctx->state, value->template_attribute); + value->template_attribute = NULL; + } + + if(value->attributes != NULL) + { + kmip_free_attributes(ctx, value->attributes); + ctx->free_func(ctx->state, value->attributes); + value->attributes = NULL; + } + + if(value->protection_storage_masks != NULL) + { + kmip_free_protection_storage_masks(ctx, value->protection_storage_masks); + ctx->free_func(ctx->state, value->protection_storage_masks); + value->protection_storage_masks = NULL; + } + + value->object_type = 0; + } + + return; +} + +void +kmip_free_create_response_payload(KMIP *ctx, CreateResponsePayload *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->template_attribute != NULL) + { + kmip_free_template_attribute(ctx, value->template_attribute); + ctx->free_func(ctx->state, value->template_attribute); + value->template_attribute = NULL; + } + + value->object_type = 0; + } + + return; +} + +void +kmip_free_locate_request_payload(KMIP *ctx, LocateRequestPayload *value) +{ + if(value != NULL) + { + kmip_free_attributes_2(ctx, value->attributes, value->attribute_count); + memset(value, 0, sizeof *value); + } + + return; +} + +void +kmip_free_locate_response_payload(KMIP *ctx, LocateResponsePayload *value) +{ + if(value != NULL) + { + if(value->unique_identifiers != NULL) + { + for(int i = 0; i < value->unique_identifiers_count; i++) + { + kmip_free_text_string(ctx, &value->unique_identifiers[i]); + } + ctx->free_func(ctx->state, value->unique_identifiers); + } + memset(value, 0, sizeof *value); + } + + return; +} + +void +kmip_free_get_request_payload(KMIP *ctx, GetRequestPayload *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->key_wrapping_spec != NULL) + { + kmip_free_key_wrapping_specification(ctx, value->key_wrapping_spec); + ctx->free_func(ctx->state, value->key_wrapping_spec); + value->key_wrapping_spec = NULL; + } + + value->key_format_type = 0; + value->key_compression_type = 0; + value->key_wrap_type = 0; + } + + return; +} + +void +kmip_free_get_response_payload(KMIP *ctx, GetResponsePayload *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->object != NULL) + { + switch(value->object_type) + { + case KMIP_OBJTYPE_SYMMETRIC_KEY: + kmip_free_symmetric_key(ctx, (SymmetricKey *)value->object); + break; + + case KMIP_OBJTYPE_PUBLIC_KEY: + kmip_free_public_key(ctx, (PublicKey *)value->object); + break; + + case KMIP_OBJTYPE_PRIVATE_KEY: + kmip_free_private_key(ctx, (PrivateKey *)value->object); + break; + + default: + /* NOTE (ph) Hitting this case means that we don't know */ + /* what the actual type, size, or value of */ + /* value->object is. We can still free it but we */ + /* cannot securely zero the memory. We also do not */ + /* know how to free any possible substructures */ + /* pointed to within value->object. */ + /* */ + /* Avoid hitting this case at all costs. */ + break; + }; + + ctx->free_func(ctx->state, value->object); + value->object = NULL; + } + + value->object_type = 0; + } + + 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) + { + 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; + } + kmip_free_attributes_2(ctx, value->attributes, value->attribute_count); + } + + return; +} + +void +kmip_free_get_attribute_list_request_payload(KMIP *ctx, GetAttributeListRequestPayload *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_get_attribute_list_response_payload(KMIP *ctx, GetAttributeListResponsePayload *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) + { + ctx->free_func(ctx->state, value->attribute_names); + value->attribute_names = NULL; + } + } + + return; +} + +void +kmip_free_destroy_request_payload(KMIP *ctx, DestroyRequestPayload *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_response_payload(KMIP *ctx, DestroyResponsePayload *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_request_batch_item(KMIP *ctx, RequestBatchItem *value) +{ + if(value != NULL) + { + if(value->unique_batch_item_id != NULL) + { + kmip_free_byte_string(ctx, value->unique_batch_item_id); + ctx->free_func(ctx->state, value->unique_batch_item_id); + value->unique_batch_item_id = NULL; + } + + if(value->request_payload != NULL) + { + switch(value->operation) + { + case KMIP_OP_CREATE: + kmip_free_create_request_payload(ctx, (CreateRequestPayload *)value->request_payload); + break; + + case KMIP_OP_LOCATE: + kmip_free_locate_request_payload(ctx, (LocateRequestPayload *)value->request_payload); + break; + + case KMIP_OP_GET: + kmip_free_get_request_payload(ctx, (GetRequestPayload *)value->request_payload); + break; + + case KMIP_OP_GET_ATTRIBUTES: + kmip_free_get_attributes_request_payload(ctx, (GetAttributesRequestPayload *)value->request_payload); + break; + + case KMIP_OP_GET_ATTRIBUTE_LIST: + kmip_free_get_attribute_list_request_payload(ctx, (GetAttributeListRequestPayload *)value->request_payload); + break; + + case KMIP_OP_DESTROY: + kmip_free_destroy_request_payload(ctx, (DestroyRequestPayload *)value->request_payload); + break; + + default: + /* NOTE (ph) Hitting this case means that we don't know */ + /* what the actual type, size, or value of */ + /* value->request_payload is. We can still free it */ + /* but we cannot securely zero the memory. We also */ + /* do not know how to free any possible substructures */ + /* pointed to within value->request_payload. */ + /* */ + /* Avoid hitting this case at all costs. */ + break; + }; + + ctx->free_func(ctx->state, value->request_payload); + value->request_payload = NULL; + } + + value->operation = 0; + value->ephemeral = 0; + } + + return; +} + +void +kmip_free_response_batch_item(KMIP *ctx, ResponseBatchItem *value) +{ + if(value != NULL) + { + if(value->unique_batch_item_id != NULL) + { + kmip_free_byte_string(ctx, value->unique_batch_item_id); + ctx->free_func(ctx->state, value->unique_batch_item_id); + value->unique_batch_item_id = NULL; + } + + if(value->result_message != NULL) + { + kmip_free_text_string(ctx, value->result_message); + ctx->free_func(ctx->state, value->result_message); + value->result_message = NULL; + } + + if(value->asynchronous_correlation_value != NULL) + { + kmip_free_byte_string(ctx, value->asynchronous_correlation_value); + ctx->free_func(ctx->state, value->asynchronous_correlation_value); + value->asynchronous_correlation_value = NULL; + } + + if(value->response_payload != NULL) + { + switch(value->operation) + { + case KMIP_OP_CREATE: + kmip_free_create_response_payload(ctx, (CreateResponsePayload *)value->response_payload); + break; + + case KMIP_OP_LOCATE: + kmip_free_locate_response_payload(ctx, (LocateResponsePayload *)value->response_payload); + break; + + case KMIP_OP_GET: + kmip_free_get_response_payload(ctx, (GetResponsePayload *)value->response_payload); + break; + + case KMIP_OP_GET_ATTRIBUTES: + kmip_free_get_attributes_response_payload(ctx, (GetAttributesResponsePayload *)value->response_payload); + break; + + case KMIP_OP_GET_ATTRIBUTE_LIST: + kmip_free_get_attribute_list_response_payload(ctx, (GetAttributeListResponsePayload *)value->response_payload); + break; + + case KMIP_OP_DESTROY: + kmip_free_destroy_response_payload(ctx, (DestroyResponsePayload *)value->response_payload); + break; + + default: + /* NOTE (ph) Hitting this case means that we don't know */ + /* what the actual type, size, or value of */ + /* value->response_payload is. We can still free it */ + /* but we cannot securely zero the memory. We also */ + /* do not know how to free any possible substructures */ + /* pointed to within value->response_payload. */ + /* */ + /* Avoid hitting this case at all costs. */ + break; + }; + + ctx->free_func(ctx->state, value->response_payload); + value->response_payload = NULL; + } + + value->operation = 0; + value->result_status = 0; + value->result_reason = 0; + } + + return; +} + +void +kmip_free_nonce(KMIP *ctx, Nonce *value) +{ + if(value != NULL) + { + if(value->nonce_id != NULL) + { + kmip_free_byte_string(ctx, value->nonce_id); + ctx->free_func(ctx->state, value->nonce_id); + value->nonce_id = NULL; + } + + if(value->nonce_value != NULL) + { + kmip_free_byte_string(ctx, value->nonce_value); + ctx->free_func(ctx->state, value->nonce_value); + value->nonce_value = NULL; + } + } + + return; +} + +void +kmip_free_username_password_credential(KMIP *ctx, UsernamePasswordCredential *value) +{ + if(value != NULL) + { + if(value->username != NULL) + { + kmip_free_text_string(ctx, value->username); + ctx->free_func(ctx->state, value->username); + value->username = NULL; + } + + if(value->password != NULL) + { + kmip_free_text_string(ctx, value->password); + ctx->free_func(ctx->state, value->password); + value->password = NULL; + } + } + + return; +} + +void +kmip_free_device_credential(KMIP *ctx, DeviceCredential *value) +{ + if(value != NULL) + { + if(value->device_serial_number != NULL) + { + kmip_free_text_string(ctx, value->device_serial_number); + ctx->free_func(ctx->state, value->device_serial_number); + value->device_serial_number = NULL; + } + + if(value->password != NULL) + { + kmip_free_text_string(ctx, value->password); + ctx->free_func(ctx->state, value->password); + value->password = NULL; + } + + if(value->device_identifier != NULL) + { + kmip_free_text_string(ctx, value->device_identifier); + ctx->free_func(ctx->state, value->device_identifier); + value->device_identifier = NULL; + } + + if(value->network_identifier != NULL) + { + kmip_free_text_string(ctx, value->network_identifier); + ctx->free_func(ctx->state, value->network_identifier); + value->network_identifier = NULL; + } + + if(value->machine_identifier != NULL) + { + kmip_free_text_string(ctx, value->machine_identifier); + ctx->free_func(ctx->state, value->machine_identifier); + value->machine_identifier = NULL; + } + + if(value->media_identifier != NULL) + { + kmip_free_text_string(ctx, value->media_identifier); + ctx->free_func(ctx->state, value->media_identifier); + value->media_identifier = NULL; + } + } + + return; +} + +void +kmip_free_attestation_credential(KMIP *ctx, AttestationCredential *value) +{ + if(value != NULL) + { + if(value->nonce != NULL) + { + kmip_free_nonce(ctx, value->nonce); + ctx->free_func(ctx->state, value->nonce); + value->nonce = NULL; + } + + if(value->attestation_measurement != NULL) + { + kmip_free_byte_string(ctx, value->attestation_measurement); + ctx->free_func(ctx->state, value->attestation_measurement); + value->attestation_measurement = NULL; + } + + if(value->attestation_assertion != NULL) + { + kmip_free_byte_string(ctx, value->attestation_assertion); + ctx->free_func(ctx->state, value->attestation_assertion); + value->attestation_assertion = NULL; + } + + value->attestation_type = 0; + } + + return; +} + +void +kmip_free_credential_value(KMIP *ctx, enum credential_type type, void **value) +{ + if(value != NULL) + { + if(*value != NULL) + { + switch(type) + { + case KMIP_CRED_USERNAME_AND_PASSWORD: + kmip_free_username_password_credential(ctx, (UsernamePasswordCredential *)*value); + break; + + case KMIP_CRED_DEVICE: + kmip_free_device_credential(ctx, (DeviceCredential *)*value); + break; + + case KMIP_CRED_ATTESTATION: + kmip_free_attestation_credential(ctx, (AttestationCredential *)*value); + break; + + default: + /* NOTE (ph) Hitting this case means that we don't know */ + /* what the actual type, size, or value of value is. */ + /* We can still free it but we cannot securely zero */ + /* the memory. We also do not know how to free any */ + /* possible substructures pointed to within value. */ + /* */ + /* Avoid hitting this case at all costs. */ + break; + }; + + ctx->free_func(ctx->state, *value); + *value = NULL; + } + } + + return; +} + +void +kmip_free_credential(KMIP *ctx, Credential *value) +{ + if(value != NULL) + { + if(value->credential_value != NULL) + { + kmip_free_credential_value(ctx, value->credential_type, &value->credential_value); + value->credential_value = NULL; + } + + value->credential_type = 0; + } + + return; +} + +void +kmip_free_authentication(KMIP *ctx, Authentication *value) +{ + if(value != NULL) + { + if(value->credential != NULL) + { + kmip_free_credential(ctx, value->credential); + ctx->free_func(ctx->state, value->credential); + value->credential = NULL; + } + } + + return; +} + +void +kmip_free_request_header(KMIP *ctx, RequestHeader *value) +{ + if(value != NULL) + { + if(value->protocol_version != NULL) + { + ctx->memset_func( + value->protocol_version, + 0, + sizeof(ProtocolVersion)); + ctx->free_func(ctx->state, value->protocol_version); + value->protocol_version = NULL; + } + + if(value->authentication != NULL) + { + kmip_free_authentication(ctx, value->authentication); + ctx->free_func(ctx->state, value->authentication); + value->authentication = NULL; + } + + if(value->attestation_types != NULL) + { + ctx->memset_func( + value->attestation_types, + 0, + value->attestation_type_count * sizeof(enum attestation_type)); + ctx->free_func(ctx->state, value->attestation_types); + value->attestation_types = NULL; + value->attestation_type_count = 0; + } + + if(value->client_correlation_value != NULL) + { + kmip_free_text_string(ctx, value->client_correlation_value); + ctx->free_func(ctx->state, value->client_correlation_value); + value->client_correlation_value = NULL; + } + + if(value->server_correlation_value != NULL) + { + kmip_free_text_string(ctx, value->server_correlation_value); + ctx->free_func(ctx->state, value->server_correlation_value); + value->server_correlation_value = NULL; + } + + kmip_init_request_header(value); + } + + return; +} + +void +kmip_free_response_header(KMIP *ctx, ResponseHeader *value) +{ + if(value != NULL) + { + if(value->protocol_version != NULL) + { + ctx->memset_func( + value->protocol_version, + 0, + sizeof(ProtocolVersion)); + ctx->free_func(ctx->state, value->protocol_version); + value->protocol_version = NULL; + } + + if(value->nonce != NULL) + { + kmip_free_nonce(ctx, value->nonce); + ctx->free_func(ctx->state, value->nonce); + value->nonce = NULL; + } + + if(value->server_hashed_password != NULL) + { + kmip_free_byte_string(ctx, value->server_hashed_password); + ctx->free_func(ctx->state, value->server_hashed_password); + value->server_hashed_password = NULL; + } + + if(value->attestation_types != NULL) + { + ctx->memset_func( + value->attestation_types, + 0, + value->attestation_type_count * sizeof(enum attestation_type)); + ctx->free_func(ctx->state, value->attestation_types); + value->attestation_types = NULL; + } + + value->attestation_type_count = 0; + + if(value->client_correlation_value != NULL) + { + kmip_free_text_string(ctx, value->client_correlation_value); + ctx->free_func(ctx->state, value->client_correlation_value); + value->client_correlation_value = NULL; + } + + if(value->server_correlation_value != NULL) + { + kmip_free_text_string(ctx, value->server_correlation_value); + ctx->free_func(ctx->state, value->server_correlation_value); + value->server_correlation_value = NULL; + } + + kmip_init_response_header(value); + } + + return; +} + +void +kmip_free_request_message(KMIP *ctx, RequestMessage *value) +{ + if(value != NULL) + { + if(value->request_header != NULL) + { + kmip_free_request_header(ctx, value->request_header); + ctx->free_func(ctx->state, value->request_header); + value->request_header = NULL; + } + + if(value->batch_items != NULL) + { + for(size_t i = 0; i < value->batch_count; i++) + { + kmip_free_request_batch_item(ctx, &value->batch_items[i]); + } + ctx->free_func(ctx, value->batch_items); + value->batch_items = NULL; + } + + value->batch_count = 0; + } + + return; +} + +void +kmip_free_response_message(KMIP *ctx, ResponseMessage *value) +{ + if(value != NULL) + { + if(value->response_header != NULL) + { + kmip_free_response_header(ctx, value->response_header); + ctx->free_func(ctx->state, value->response_header); + value->response_header = NULL; + } + + if(value->batch_items != NULL) + { + for(size_t i = 0; i < value->batch_count; i++) + { + kmip_free_response_batch_item(ctx, &value->batch_items[i]); + } + ctx->free_func(ctx, value->batch_items); + value->batch_items = NULL; + } + + value->batch_count = 0; + } + + return; +} + +/* +Copying Functions +*/ + +int32 * +kmip_deep_copy_int32(KMIP *ctx, const int32 *value) +{ + if(ctx == NULL || value == NULL) + return(NULL); + + int32 *copy = ctx->calloc_func(ctx, 1, sizeof(int32)); + if(copy == NULL) + return(NULL); + + copy = ctx->memcpy_func(ctx->state, copy, value, sizeof(int32)); + + return(copy); +} + +int64 * +kmip_deep_copy_int64(KMIP *ctx, const int64 *value) +{ + if(ctx == NULL || value == NULL) + return(NULL); + + int64 *copy = ctx->calloc_func(ctx, 1, sizeof(int64)); + if(copy == NULL) + return(NULL); + + copy = ctx->memcpy_func(ctx->state, copy, value, sizeof(int64)); + + return(copy); +} + +TextString * +kmip_deep_copy_text_string(KMIP *ctx, const TextString *value) +{ + if(ctx == NULL || value == NULL) + return(NULL); + + TextString *copy = ctx->calloc_func(ctx->state, 1, sizeof(TextString)); + if(copy == NULL) + return(NULL); + + copy->size = value->size; + if(value->value != NULL) + { + copy->value = ctx->calloc_func(ctx->state, 1, value->size); + if(copy->value == NULL && value->value != NULL) + { + ctx->free_func(ctx->state, copy); + return(NULL); + } + copy->value = ctx->memcpy_func(ctx->state, copy->value, value->value, value->size); + } + else + copy->value = NULL; + + return(copy); +} + +Name * +kmip_deep_copy_name(KMIP *ctx, const Name *value) +{ + if(ctx == NULL || value == NULL) + return(NULL); + + Name *copy = ctx->calloc_func(ctx->state, 1, sizeof(Name)); + if(copy == NULL) + return(NULL); + + copy->type = value->type; + if(value->value != NULL) + { + copy->value = kmip_deep_copy_text_string(ctx, value->value); + if(copy->value == NULL) + { + ctx->free_func(ctx->state, copy); + return(NULL); + } + } + else + copy->value = NULL; + + return(copy); +} + +Attribute * +kmip_deep_copy_attribute(KMIP *ctx, const Attribute *value) +{ + if(ctx == NULL || value == NULL) + return(NULL); + + Attribute *copy = ctx->calloc_func(ctx->state, 1, sizeof(Attribute)); + if(copy == NULL) + return(NULL); + + copy->type = value->type; + copy->index = value->index; + + if(value->value == NULL) + { + copy->value = NULL; + return(copy); + } + + switch(value->type) + { + case KMIP_ATTR_UNIQUE_IDENTIFIER: + case KMIP_ATTR_OPERATION_POLICY_NAME: + case KMIP_ATTR_OBJECT_GROUP: + case KMIP_ATTR_RANDOM_NUMBER_GENERATOR: + case KMIP_ATTR_PKCS_12_FRIENDLY_NAME: + case KMIP_ATTR_DESCRIPTION: + case KMIP_ATTR_COMMENT: + { + copy->value = kmip_deep_copy_text_string(ctx, (TextString *)value->value); + if(copy->value == NULL) + { + ctx->free_func(ctx->state, copy); + return(NULL); + } + } break; + + case KMIP_ATTR_NAME: + { + copy->value = kmip_deep_copy_name(ctx, (Name *)value->value); + if(copy->value == NULL) + { + ctx->free_func(ctx->state, copy); + return(NULL); + } + } break; + + case KMIP_ATTR_OBJECT_TYPE: + case KMIP_ATTR_CRYPTOGRAPHIC_ALGORITHM: + case KMIP_ATTR_CRYPTOGRAPHIC_LENGTH: + case KMIP_ATTR_CERTIFICATE_TYPE: + case KMIP_ATTR_CERTIFICATE_LENGTH: + case KMIP_ATTR_DIGITAL_SIGNATURE_ALGORITHM: + case KMIP_ATTR_CRYPTOGRAPHIC_USAGE_MASK: + case KMIP_ATTR_LEASE_TIME: + case KMIP_ATTR_STATE: + case KMIP_ATTR_FRESH: + case KMIP_ATTR_KEY_VALUE_PRESENT: + case KMIP_ATTR_SENSITIVE: + case KMIP_ATTR_ALWAYS_SENSITIVE: + case KMIP_ATTR_EXTRACTABLE: + case KMIP_ATTR_NEVER_EXTRACTABLE: + case KMIP_ATTR_KEY_FORMAT_TYPE: + { + copy->value = kmip_deep_copy_int32(ctx, (int32 *)value->value); + if(copy->value == NULL) + { + ctx->free_func(ctx->state, copy); + return(NULL); + } + } break; + + case KMIP_ATTR_INITIAL_DATE: + case KMIP_ATTR_ACTIVATION_DATE: + case KMIP_ATTR_PROCESS_START_DATE: + case KMIP_ATTR_PROTECT_STOP_DATE: + case KMIP_ATTR_DEACTIVATION_DATE: + case KMIP_ATTR_DESTROY_DATE: + case KMIP_ATTR_COMPROMISE_OCCURRENCE_DATE: + case KMIP_ATTR_COMPROMISE_DATE: + case KMIP_ATTR_ARCHIVE_DATE: + case KMIP_ATTR_LAST_CHANGE_DATE: + case KMIP_ATTR_ORIGINAL_CREATION_DATE: + { + copy->value = kmip_deep_copy_int64(ctx, (int64 *)value->value); + if(copy->value == NULL) + { + ctx->free_func(ctx->state, copy); + return(NULL); + } + } break; + + // case KMIP_ATTR_CRYPTOGRAPHIC_PARAMETERS: + // case KMIP_ATTR_CRYPTOGRAPHIC_DOMAIN_PARAMETERS: + // case KMIP_ATTR_X509_CERTIFICATE_IDENTIFIER: + // case KMIP_ATTR_X509_CERTIFICATE_SUBJECT: + // case KMIP_ATTR_X509_CERTIFICATE_ISSUER: + // case KMIP_ATTR_CERTIFICATE_IDENTIFIER: + // case KMIP_ATTR_CERTIFICATE_SUBJECT: + // case KMIP_ATTR_CERTIFICATE_ISSUER: + // case KMIP_ATTR_DIGEST: + // case KMIP_ATTR_USAGE_LIMITS: + // case KMIP_ATTR_REVOCATION_REASON: + // case KMIP_ATTR_LINK: + // case KMIP_ATTR_APPLICATION_SPECIFIC_INFORMATION: + // case KMIP_ATTR_CONTACT_INFORMATION: + // case KMIP_ATTR_CUSTOM_ATTRIBUTE: + // case KMIP_ATTR_ALTERNATIVE_NAME: + // case KMIP_ATTR_KEY_VALUE_LOCATION: + + default: + { + ctx->free_func(ctx->state, copy); + return(NULL); + } break; + }; + + return(copy); +} + +/* +Comparison Functions +*/ + +int +kmip_compare_text_string(const TextString *a, const TextString *b) +{ + if(a != b) + { + if((a == NULL) || (b == NULL)) + { + return(KMIP_FALSE); + } + + if(a->size != b->size) + { + return(KMIP_FALSE); + } + + if(a->value != b->value) + { + if((a->value == NULL) || (b->value == NULL)) + { + return(KMIP_FALSE); + } + + for(size_t i = 0; i < a->size; i++) + { + if(a->value[i] != b->value[i]) + { + return(KMIP_FALSE); + } + } + } + } + + return(KMIP_TRUE); +} + +int +kmip_compare_byte_string(const ByteString *a, const ByteString *b) +{ + if(a != b) + { + if((a == NULL) || (b == NULL)) + { + return(KMIP_FALSE); + } + + if(a->size != b->size) + { + return(KMIP_FALSE); + } + + if(a->value != b->value) + { + if((a->value == NULL) || (b->value == NULL)) + { + return(KMIP_FALSE); + } + + for(size_t i = 0; i < a->size; i++) + { + if(a->value[i] != b->value[i]) + { + return(KMIP_FALSE); + } + } + } + } + + return(KMIP_TRUE); +} + +int +kmip_compare_name(const Name *a, const Name *b) +{ + if(a != b) + { + if((a == NULL) || (b == NULL)) + { + return(KMIP_FALSE); + } + + if(a->type != b->type) + { + return(KMIP_FALSE); + } + + if(a->value != b->value) + { + if((a->value == NULL) || (b->value == NULL)) + { + return(KMIP_FALSE); + } + + if(kmip_compare_text_string(a->value, b->value) != KMIP_TRUE) + { + return(KMIP_FALSE); + } + } + } + + return(KMIP_TRUE); +} + +int +kmip_compare_protection_storage_masks(const ProtectionStorageMasks *a, const ProtectionStorageMasks *b) +{ + if(a != b) + { + if((a == NULL) || (b == NULL)) + { + return(KMIP_FALSE); + } + + if((a->masks != b->masks)) + { + if((a->masks == NULL) || (b->masks == NULL)) + { + return(KMIP_FALSE); + } + + if((a->masks->size != b->masks->size)) + { + return(KMIP_FALSE); + } + + LinkedListItem *a_item = a->masks->head; + LinkedListItem *b_item = b->masks->head; + while((a_item != NULL) || (b_item != NULL)) + { + if(a_item != b_item) + { + int32 a_data = *(int32 *)a_item->data; + int32 b_data = *(int32 *)b_item->data; + if(a_data != b_data) + { + return(KMIP_FALSE); + } + } + + a_item = a_item->next; + b_item = b_item->next; + } + + if(a_item != b_item) + { + return(KMIP_FALSE); + } + } + } + + return(KMIP_TRUE); +} + +int +kmip_compare_attribute(const Attribute *a, const Attribute *b) +{ + if(a != b) + { + if((a == NULL) || (b == NULL)) + { + return(KMIP_FALSE); + } + + if(a->type != b->type) + { + return(KMIP_FALSE); + } + + if(a->index != b->index) + { + return(KMIP_FALSE); + } + + if(a->value != b->value) + { + if((a->value == NULL) || (b->value == NULL)) + { + return(KMIP_FALSE); + } + + switch(a->type) + { + case KMIP_ATTR_UNIQUE_IDENTIFIER: + case KMIP_ATTR_OPERATION_POLICY_NAME: + case KMIP_ATTR_OBJECT_GROUP: + case KMIP_ATTR_RANDOM_NUMBER_GENERATOR: + case KMIP_ATTR_PKCS_12_FRIENDLY_NAME: + case KMIP_ATTR_DESCRIPTION: + case KMIP_ATTR_COMMENT: + return(kmip_compare_text_string((TextString *)a->value, (TextString *)b->value)); + break; + + case KMIP_ATTR_NAME: + return(kmip_compare_name((Name *)a->value, (Name *)b->value)); + break; + + case KMIP_ATTR_OBJECT_TYPE: + case KMIP_ATTR_CRYPTOGRAPHIC_ALGORITHM: + case KMIP_ATTR_CRYPTOGRAPHIC_LENGTH: + case KMIP_ATTR_CERTIFICATE_TYPE: + case KMIP_ATTR_CERTIFICATE_LENGTH: + case KMIP_ATTR_DIGITAL_SIGNATURE_ALGORITHM: + case KMIP_ATTR_CRYPTOGRAPHIC_USAGE_MASK: + case KMIP_ATTR_LEASE_TIME: + case KMIP_ATTR_STATE: + case KMIP_ATTR_FRESH: + case KMIP_ATTR_KEY_VALUE_PRESENT: + case KMIP_ATTR_SENSITIVE: + case KMIP_ATTR_ALWAYS_SENSITIVE: + case KMIP_ATTR_EXTRACTABLE: + case KMIP_ATTR_NEVER_EXTRACTABLE: + case KMIP_ATTR_KEY_FORMAT_TYPE: + if(*(int32*)a->value != *(int32*)b->value) + { + return(KMIP_FALSE); + } + break; + + case KMIP_ATTR_INITIAL_DATE: + case KMIP_ATTR_ACTIVATION_DATE: + case KMIP_ATTR_PROCESS_START_DATE: + case KMIP_ATTR_PROTECT_STOP_DATE: + case KMIP_ATTR_DEACTIVATION_DATE: + case KMIP_ATTR_DESTROY_DATE: + case KMIP_ATTR_COMPROMISE_OCCURRENCE_DATE: + case KMIP_ATTR_COMPROMISE_DATE: + case KMIP_ATTR_ARCHIVE_DATE: + case KMIP_ATTR_LAST_CHANGE_DATE: + case KMIP_ATTR_ORIGINAL_CREATION_DATE: + if(*(int64*)a->value != *(int64*)b->value) + { + return(KMIP_FALSE); + } + break; + + // case KMIP_ATTR_CRYPTOGRAPHIC_PARAMETERS: + // case KMIP_ATTR_CRYPTOGRAPHIC_DOMAIN_PARAMETERS: + // case KMIP_ATTR_X509_CERTIFICATE_IDENTIFIER: + // case KMIP_ATTR_X509_CERTIFICATE_SUBJECT: + // case KMIP_ATTR_X509_CERTIFICATE_ISSUER: + // case KMIP_ATTR_CERTIFICATE_IDENTIFIER: + // case KMIP_ATTR_CERTIFICATE_SUBJECT: + // case KMIP_ATTR_CERTIFICATE_ISSUER: + // case KMIP_ATTR_DIGEST: + // case KMIP_ATTR_USAGE_LIMITS: + // case KMIP_ATTR_REVOCATION_REASON: + // case KMIP_ATTR_LINK: + // case KMIP_ATTR_APPLICATION_SPECIFIC_INFORMATION: + // case KMIP_ATTR_CONTACT_INFORMATION: + // case KMIP_ATTR_CUSTOM_ATTRIBUTE: + // case KMIP_ATTR_ALTERNATIVE_NAME: + // case KMIP_ATTR_KEY_VALUE_LOCATION: + + default: + /* NOTE (ph) Unsupported types can't be compared. */ + return(KMIP_FALSE); + break; + }; + } + } + + return(KMIP_TRUE); +} + +int +kmip_compare_attributes(const Attributes *a, const Attributes *b) +{ + if(a != b) + { + if((a == NULL) || (b == NULL)) + { + return(KMIP_FALSE); + } + + if((a->attribute_list != b->attribute_list)) + { + if((a->attribute_list == NULL) || (b->attribute_list == NULL)) + { + return(KMIP_FALSE); + } + + if((a->attribute_list->size != b->attribute_list->size)) + { + return(KMIP_FALSE); + } + + LinkedListItem *a_item = a->attribute_list->head; + LinkedListItem *b_item = b->attribute_list->head; + while((a_item != NULL) || (b_item != NULL)) + { + if(a_item != b_item) + { + Attribute *a_data = (Attribute *)a_item->data; + Attribute *b_data = (Attribute *)b_item->data; + if(kmip_compare_attribute(a_data, b_data) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + + a_item = a_item->next; + b_item = b_item->next; + } + + if(a_item != b_item) + { + return(KMIP_FALSE); + } + } + } + + return(KMIP_TRUE); +} + +int +kmip_compare_template_attribute(const TemplateAttribute *a, const TemplateAttribute *b) +{ + if(a != b) + { + if((a == NULL) || (b == NULL)) + { + return(KMIP_FALSE); + } + + if(a->name_count != b->name_count) + { + return(KMIP_FALSE); + } + + if(a->attribute_count != b->attribute_count) + { + return(KMIP_FALSE); + } + + if(a->names != b->names) + { + if((a->names == NULL) || (b->names == NULL)) + { + return(KMIP_FALSE); + } + + for(size_t i = 0; i < a->name_count; i++) + { + if(kmip_compare_name(&a->names[i], &b->names[i]) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + } + + if(a->attributes != b->attributes) + { + if((a->attributes == NULL) || (b->attributes == NULL)) + { + return(KMIP_FALSE); + } + + for(size_t i = 0; i < a->attribute_count; i++) + { + if(kmip_compare_attribute(&a->attributes[i], &b->attributes[i]) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + } + } + + return(KMIP_TRUE); +} + +int +kmip_compare_protocol_version(const ProtocolVersion *a, const ProtocolVersion *b) +{ + if(a != b) + { + if((a == NULL) || (b == NULL)) + { + return(KMIP_FALSE); + } + + if(a->major != b->major) + { + return(KMIP_FALSE); + } + + if(a->minor != b->minor) + { + return(KMIP_FALSE); + } + } + + return(KMIP_TRUE); +} + +int +kmip_compare_transparent_symmetric_key(const TransparentSymmetricKey *a, const TransparentSymmetricKey *b) +{ + if(a != b) + { + if((a == NULL) || (b == NULL)) + { + return(KMIP_FALSE); + } + + if(a->key != b->key) + { + if((a->key == NULL) || (b->key == NULL)) + { + return(KMIP_FALSE); + } + + if(kmip_compare_byte_string(a->key, b->key) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + } + + return(KMIP_TRUE); +} + +int +kmip_compare_key_material(enum key_format_type format, void **a, void **b) +{ + if(a != b) + { + if((a == NULL) || (b == NULL)) + { + return(KMIP_FALSE); + } + + if(*a != *b) + { + if((*a == NULL) || (*b == NULL)) + { + return(KMIP_FALSE); + } + + switch(format) + { + case KMIP_KEYFORMAT_RAW: + case KMIP_KEYFORMAT_OPAQUE: + case KMIP_KEYFORMAT_PKCS1: + case KMIP_KEYFORMAT_PKCS8: + case KMIP_KEYFORMAT_X509: + case KMIP_KEYFORMAT_EC_PRIVATE_KEY: + if(kmip_compare_byte_string(*a, *b) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + break; + + case KMIP_KEYFORMAT_TRANS_SYMMETRIC_KEY: + if(kmip_compare_transparent_symmetric_key(*a, *b) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + break; + + default: + /* NOTE (ph) Unsupported types cannot be compared. */ + return(KMIP_FALSE); + break; + }; + } + } + + return(KMIP_TRUE); +} + +int +kmip_compare_key_value(enum key_format_type format, const KeyValue *a, const KeyValue *b) +{ + if(a != b) + { + if((a == NULL) || (b == NULL)) + { + return(KMIP_FALSE); + } + + if(a->key_material != b->key_material) + { + if((a->key_material == NULL) || (b->key_material == NULL)) + { + return(KMIP_FALSE); + } + + if(kmip_compare_key_material(format, (void**)&a->key_material, (void**)&b->key_material) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + + if(a->attributes != b->attributes) + { + if((a->attributes == NULL) || (b->attributes == NULL)) + { + return(KMIP_FALSE); + } + + for(size_t i = 0; i < a->attribute_count; i++) + { + if(kmip_compare_attribute(&a->attributes[i], &b->attributes[i]) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + } + } + + return(KMIP_TRUE); +} + +int +kmip_compare_cryptographic_parameters(const CryptographicParameters *a, const CryptographicParameters *b) +{ + if(a != b) + { + if((a == NULL) || (b == NULL)) + { + return(KMIP_FALSE); + } + + if(a->block_cipher_mode != b->block_cipher_mode) + { + return(KMIP_FALSE); + } + + if(a->padding_method != b->padding_method) + { + return(KMIP_FALSE); + } + + if(a->hashing_algorithm != b->hashing_algorithm) + { + return(KMIP_FALSE); + } + + if(a->key_role_type != b->key_role_type) + { + return(KMIP_FALSE); + } + + if(a->digital_signature_algorithm != b->digital_signature_algorithm) + { + return(KMIP_FALSE); + } + + if(a->cryptographic_algorithm != b->cryptographic_algorithm) + { + return(KMIP_FALSE); + } + + if(a->random_iv != b->random_iv) + { + return(KMIP_FALSE); + } + + if(a->iv_length != b->iv_length) + { + return(KMIP_FALSE); + } + + if(a->tag_length != b->tag_length) + { + return(KMIP_FALSE); + } + + if(a->fixed_field_length != b->fixed_field_length) + { + return(KMIP_FALSE); + } + + if(a->invocation_field_length != b->invocation_field_length) + { + return(KMIP_FALSE); + } + + if(a->counter_length != b->counter_length) + { + return(KMIP_FALSE); + } + + if(a->initial_counter_value != b->initial_counter_value) + { + return(KMIP_FALSE); + } + + if(a->salt_length != b->salt_length) + { + return(KMIP_FALSE); + } + + if(a->mask_generator != b->mask_generator) + { + return(KMIP_FALSE); + } + + if(a->mask_generator_hashing_algorithm != + b->mask_generator_hashing_algorithm) + { + return(KMIP_FALSE); + } + + if(a->trailer_field != b->trailer_field) + { + return(KMIP_FALSE); + } + + if(a->p_source != b->p_source) + { + if((a->p_source == NULL) || (b->p_source == NULL)) + { + return(KMIP_FALSE); + } + + if(kmip_compare_byte_string(a->p_source, b->p_source) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + } + + return(KMIP_TRUE); +} + +int +kmip_compare_encryption_key_information(const EncryptionKeyInformation *a, const EncryptionKeyInformation *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->cryptographic_parameters != b->cryptographic_parameters) + { + if((a->cryptographic_parameters == NULL) || + (b->cryptographic_parameters == NULL)) + { + return(KMIP_FALSE); + } + + if(kmip_compare_cryptographic_parameters(a->cryptographic_parameters, b->cryptographic_parameters) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + } + + return(KMIP_TRUE); +} + +int +kmip_compare_mac_signature_key_information(const MACSignatureKeyInformation *a, const MACSignatureKeyInformation *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->cryptographic_parameters != b->cryptographic_parameters) + { + if((a->cryptographic_parameters == NULL) || (b->cryptographic_parameters == NULL)) + { + return(KMIP_FALSE); + } + + if(kmip_compare_cryptographic_parameters(a->cryptographic_parameters, b->cryptographic_parameters) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + } + + return(KMIP_TRUE); +} + +int +kmip_compare_key_wrapping_data(const KeyWrappingData *a, const KeyWrappingData *b) +{ + if(a != b) + { + if((a == NULL) || (b == NULL)) + { + return(KMIP_FALSE); + } + + if(a->wrapping_method != b->wrapping_method) + { + return(KMIP_FALSE); + } + + if(a->encoding_option != b->encoding_option) + { + return(KMIP_FALSE); + } + + if(a->mac_signature != b->mac_signature) + { + if((a->mac_signature == NULL) || (b->mac_signature == NULL)) + { + return(KMIP_FALSE); + } + + if(kmip_compare_byte_string(a->mac_signature, b->mac_signature) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + + if(a->iv_counter_nonce != b->iv_counter_nonce) + { + if((a->iv_counter_nonce == NULL) || (b->iv_counter_nonce == NULL)) + { + return(KMIP_FALSE); + } + + if(kmip_compare_byte_string(a->iv_counter_nonce, b->iv_counter_nonce) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + + if(a->encryption_key_info != b->encryption_key_info) + { + if((a->encryption_key_info == NULL) || (b->encryption_key_info == NULL)) + { + return(KMIP_FALSE); + } + + if(kmip_compare_encryption_key_information(a->encryption_key_info, b->encryption_key_info) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + + if(a->mac_signature_key_info != b->mac_signature_key_info) + { + if((a->mac_signature_key_info == NULL) || (b->mac_signature_key_info == NULL)) + { + return(KMIP_FALSE); + } + + if(kmip_compare_mac_signature_key_information(a->mac_signature_key_info, b->mac_signature_key_info) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + } + + return(KMIP_TRUE); +} + +int +kmip_compare_key_block(const KeyBlock *a, const KeyBlock *b) +{ + if(a != b) + { + if((a == NULL) || (b == NULL)) + { + return(KMIP_FALSE); + } + + if(a->key_format_type != b->key_format_type) + { + return(KMIP_FALSE); + } + + if(a->key_compression_type != b->key_compression_type) + { + return(KMIP_FALSE); + } + + if(a->cryptographic_algorithm != b->cryptographic_algorithm) + { + return(KMIP_FALSE); + } + + if(a->cryptographic_length != b->cryptographic_length) + { + return(KMIP_FALSE); + } + + if(a->key_value_type != b->key_value_type) + { + return(KMIP_FALSE); + } + + if(a->key_value != b->key_value) + { + if((a->key_value == NULL) || (b->key_value == NULL)) + { + return(KMIP_FALSE); + } + + if(a->key_value_type == KMIP_TYPE_BYTE_STRING) + { + if(kmip_compare_byte_string((ByteString *)a->key_value, (ByteString *)b->key_value) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + else + { + if(kmip_compare_key_value(a->key_format_type, (KeyValue *)a->key_value, (KeyValue *)b->key_value) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + } + + if(a->key_wrapping_data != b->key_wrapping_data) + { + if((a->key_wrapping_data == NULL) || (b->key_wrapping_data == NULL)) + { + return(KMIP_FALSE); + } + + if(kmip_compare_key_wrapping_data(a->key_wrapping_data, b->key_wrapping_data) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + } + + return(KMIP_TRUE); +} + +int +kmip_compare_symmetric_key(const SymmetricKey *a, const SymmetricKey *b) +{ + if(a != b) + { + if((a == NULL) || (b == NULL)) + { + return(KMIP_FALSE); + } + + if(a->key_block != b->key_block) + { + if((a->key_block == NULL) || (b->key_block == NULL)) + { + return(KMIP_FALSE); + } + + if(kmip_compare_key_block(a->key_block, b->key_block) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + } + + return(KMIP_TRUE); +} + +int +kmip_compare_public_key(const PublicKey *a, const PublicKey *b) +{ + if(a != b) + { + if((a == NULL) || (b == NULL)) + { + return(KMIP_FALSE); + } + + if(a->key_block != b->key_block) + { + if((a->key_block == NULL) || (b->key_block == NULL)) + { + return(KMIP_FALSE); + } + + if(kmip_compare_key_block(a->key_block, b->key_block) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + } + + return(KMIP_TRUE); +} + +int +kmip_compare_private_key(const PrivateKey *a, const PrivateKey *b) +{ + if(a != b) + { + if((a == NULL) || (b == NULL)) + { + return(KMIP_FALSE); + } + + if(a->key_block != b->key_block) + { + if((a->key_block == NULL) || (b->key_block == NULL)) + { + return(KMIP_FALSE); + } + + if(kmip_compare_key_block(a->key_block, b->key_block) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + } + + return(KMIP_TRUE); +} + +int +kmip_compare_key_wrapping_specification(const KeyWrappingSpecification *a, const KeyWrappingSpecification *b) +{ + if(a != b) + { + if((a == NULL) || (b == NULL)) + { + return(KMIP_FALSE); + } + + if(a->wrapping_method != b->wrapping_method) + { + return(KMIP_FALSE); + } + + if(a->encoding_option != b->encoding_option) + { + return(KMIP_FALSE); + } + + if(a->attribute_name_count != b->attribute_name_count) + { + return(KMIP_FALSE); + } + + if(a->encryption_key_info != b->encryption_key_info) + { + if((a->encryption_key_info == NULL) || (b->encryption_key_info == NULL)) + { + return(KMIP_FALSE); + } + + if(kmip_compare_encryption_key_information(a->encryption_key_info, b->encryption_key_info) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + + if(a->mac_signature_key_info != b->mac_signature_key_info) + { + if((a->mac_signature_key_info == NULL) || (b->mac_signature_key_info == NULL)) + { + return(KMIP_FALSE); + } + + if(kmip_compare_mac_signature_key_information(a->mac_signature_key_info, b->mac_signature_key_info) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + + if(a->attribute_names != b->attribute_names) + { + if((a->attribute_names == NULL) || (b->attribute_names == NULL)) + { + return(KMIP_FALSE); + } + + for(size_t i = 0; i < a->attribute_name_count; i++) + { + if(kmip_compare_text_string(&a->attribute_names[i], &b->attribute_names[i]) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + } + } + + return(KMIP_TRUE); +} + +int +kmip_compare_create_request_payload(const CreateRequestPayload *a, const CreateRequestPayload *b) +{ + if(a != b) + { + if((a == NULL) || (b == NULL)) + { + return(KMIP_FALSE); + } + + if(a->object_type != b->object_type) + { + return(KMIP_FALSE); + } + + if(a->template_attribute != b->template_attribute) + { + if((a->template_attribute == NULL) || (b->template_attribute == NULL)) + { + return(KMIP_FALSE); + } + + if(kmip_compare_template_attribute(a->template_attribute, b->template_attribute) == 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); + } + } + + if(a->protection_storage_masks != b->protection_storage_masks) + { + if((a->protection_storage_masks == NULL) || (b->protection_storage_masks == NULL)) + { + return(KMIP_FALSE); + } + + if(kmip_compare_protection_storage_masks(a->protection_storage_masks, b->protection_storage_masks) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + } + + return(KMIP_TRUE); +} + +int +kmip_compare_create_response_payload(const CreateResponsePayload *a, const CreateResponsePayload *b) +{ + if(a != b) + { + if((a == NULL) || (b == NULL)) + { + return(KMIP_FALSE); + } + + if(a->object_type != b->object_type) + { + 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->template_attribute != b->template_attribute) + { + if((a->template_attribute == NULL) || (b->template_attribute == NULL)) + { + return(KMIP_FALSE); + } + + if(kmip_compare_template_attribute(a->template_attribute, b->template_attribute) == 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->object_group_member != b->object_group_member) + { + return(KMIP_FALSE); + } + + if(a->attribute_count != b->attribute_count) + { + return(KMIP_FALSE); + } + + if(a->attributes != b->attributes) + { + if((a->attributes == NULL) || (b->attributes == NULL)) + { + return(KMIP_FALSE); + } + for(int i = 0; i < a->attribute_count; ++i) + { + if(kmip_compare_attribute(a->attributes + i, b->attributes + i) == 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_identifiers_count != b->unique_identifiers_count) + { + return(KMIP_FALSE); + } + + if(a->unique_identifiers != b->unique_identifiers) + { + for(int i = 0; i < a->unique_identifiers_count; ++i) + { + if(kmip_compare_text_string(a->unique_identifiers + i, b->unique_identifiers + i) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + } + } + + return(KMIP_TRUE); +} + +int +kmip_compare_get_request_payload(const GetRequestPayload *a, const GetRequestPayload *b) +{ + if(a != b) + { + if((a == NULL) || (b == NULL)) + { + return(KMIP_FALSE); + } + + if(a->key_format_type != b->key_format_type) + { + return(KMIP_FALSE); + } + + if(a->key_compression_type != b->key_compression_type) + { + return(KMIP_FALSE); + } + + if(a->key_wrap_type != b->key_wrap_type) + { + 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->key_wrapping_spec != b->key_wrapping_spec) + { + if((a->key_wrapping_spec == NULL) || (b->key_wrapping_spec == NULL)) + { + return(KMIP_FALSE); + } + + if(kmip_compare_key_wrapping_specification(a->key_wrapping_spec, b->key_wrapping_spec) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + } + + return(KMIP_TRUE); +} + +int +kmip_compare_get_response_payload(const GetResponsePayload *a, const GetResponsePayload *b) +{ + if(a != b) + { + if((a == NULL) || (b == NULL)) + { + return(KMIP_FALSE); + } + + if(a->object_type != b->object_type) + { + 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->object != b->object) + { + switch(a->object_type) + { + case KMIP_OBJTYPE_SYMMETRIC_KEY: + if(kmip_compare_symmetric_key((SymmetricKey *)a->object, (SymmetricKey *)b->object) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + break; + + case KMIP_OBJTYPE_PUBLIC_KEY: + if(kmip_compare_public_key((PublicKey *)a->object, (PublicKey *)b->object) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + break; + + case KMIP_OBJTYPE_PRIVATE_KEY: + if(kmip_compare_private_key((PrivateKey *)a->object, (PrivateKey *)b->object) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + break; + + default: + /* NOTE (ph) Unsupported types cannot be compared. */ + return(KMIP_FALSE); + break; + }; + } + } + + 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_count != b->attribute_count) + { + return(KMIP_FALSE); + } + + if(a->attribute_names != b->attribute_names) + { + if((a->attribute_names == NULL) || (b->attribute_names == NULL)) + { + return(KMIP_FALSE); + } + for(int i = 0; i < a->attribute_count; ++i) + { + if (a->attribute_names[i] != b->attribute_names[i]) + 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); + } + for(int i = 0; i < a->attribute_count; ++i) + { + if(kmip_compare_attribute(a->attributes + i, b->attributes + i) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + } + } + + return(KMIP_TRUE); +} + +int +kmip_compare_get_attribute_list_request_payload(const GetAttributeListRequestPayload *a, const GetAttributeListRequestPayload *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_get_attribute_list_response_payload(const GetAttributeListResponsePayload *a, const GetAttributeListResponsePayload *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_count != b->attribute_names_count) + { + return(KMIP_FALSE); + } + + if(a->attribute_names != b->attribute_names) + { + if((a->attribute_names == NULL) || (b->attribute_names == NULL)) + { + return(KMIP_FALSE); + } + for(int i = 0; i < a->attribute_names_count; ++i) + { + if (a->attribute_names[i] != b->attribute_names[i]) + return KMIP_FALSE; + } + } + } + + return(KMIP_TRUE); +} + +int +kmip_compare_destroy_request_payload(const DestroyRequestPayload *a, const DestroyRequestPayload *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_response_payload(const DestroyResponsePayload *a, const DestroyResponsePayload *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_request_batch_item(const RequestBatchItem *a, const RequestBatchItem *b) +{ + if(a != b) + { + if((a == NULL) || (b == NULL)) + { + return(KMIP_FALSE); + } + + if(a->operation != b->operation) + { + return(KMIP_FALSE); + } + + if(a->ephemeral != b->ephemeral) + { + return(KMIP_FALSE); + } + + if(a->unique_batch_item_id != b->unique_batch_item_id) + { + if((a->unique_batch_item_id == NULL) || (b->unique_batch_item_id == NULL)) + { + return(KMIP_FALSE); + } + + if(kmip_compare_byte_string(a->unique_batch_item_id, b->unique_batch_item_id) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + + if(a->request_payload != b->request_payload) + { + if((a->request_payload == NULL) || (b->request_payload == NULL)) + { + return(KMIP_FALSE); + } + + switch(a->operation) + { + case KMIP_OP_CREATE: + if(kmip_compare_create_request_payload((CreateRequestPayload *)a->request_payload, (CreateRequestPayload *)b->request_payload) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + 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; + + case KMIP_OP_GET: + if(kmip_compare_get_request_payload((GetRequestPayload *)a->request_payload, (GetRequestPayload *)b->request_payload) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + break; + + case KMIP_OP_GET_ATTRIBUTES: + if(kmip_compare_get_attributes_request_payload((GetAttributesRequestPayload *)a->request_payload, (GetAttributesRequestPayload *)b->request_payload) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + break; + + case KMIP_OP_GET_ATTRIBUTE_LIST: + if(kmip_compare_get_attribute_list_request_payload((GetAttributeListRequestPayload *)a->request_payload, (GetAttributeListRequestPayload *)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) + { + return(KMIP_FALSE); + } + break; + + default: + /* NOTE (ph) Unsupported payloads cannot be compared. */ + return(KMIP_FALSE); + break; + }; + } + } + + return(KMIP_TRUE); +} + +int +kmip_compare_response_batch_item(const ResponseBatchItem *a, const ResponseBatchItem *b) +{ + if(a != b) + { + if((a == NULL) || (b == NULL)) + { + return(KMIP_FALSE); + } + + if(a->operation != b->operation) + { + return(KMIP_FALSE); + } + + if(a->result_status != b->result_status) + { + return(KMIP_FALSE); + } + + if(a->result_reason != b->result_reason) + { + return(KMIP_FALSE); + } + + if(a->unique_batch_item_id != b->unique_batch_item_id) + { + if((a->unique_batch_item_id == NULL) || (b->unique_batch_item_id == NULL)) + { + return(KMIP_FALSE); + } + + if(kmip_compare_byte_string(a->unique_batch_item_id, b->unique_batch_item_id) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + + if(a->result_message != b->result_message) + { + if((a->result_message == NULL) || (b->result_message == NULL)) + { + return(KMIP_FALSE); + } + + if(kmip_compare_text_string(a->result_message, b->result_message) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + + if(a->asynchronous_correlation_value != b->asynchronous_correlation_value) + { + if((a->asynchronous_correlation_value == NULL) || (b->asynchronous_correlation_value == NULL)) + { + return(KMIP_FALSE); + } + + if(kmip_compare_byte_string(a->asynchronous_correlation_value, b->asynchronous_correlation_value) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + + if(a->response_payload != b->response_payload) + { + if((a->response_payload == NULL) || (b->response_payload == NULL)) + { + return(KMIP_FALSE); + } + + switch(a->operation) + { + case KMIP_OP_CREATE: + if(kmip_compare_create_response_payload((CreateResponsePayload *)a->response_payload, (CreateResponsePayload *)b->response_payload) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + 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; + + case KMIP_OP_GET: + if(kmip_compare_get_response_payload((GetResponsePayload *)a->response_payload, (GetResponsePayload *)b->response_payload) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + break; + + case KMIP_OP_GET_ATTRIBUTES: + if(kmip_compare_get_attributes_response_payload((GetAttributesResponsePayload *)a->response_payload, (GetAttributesResponsePayload *)b->response_payload) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + break; + + case KMIP_OP_GET_ATTRIBUTE_LIST: + if(kmip_compare_get_attribute_list_response_payload((GetAttributeListResponsePayload *)a->response_payload, (GetAttributeListResponsePayload *)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) + { + return(KMIP_FALSE); + } + break; + + default: + /* NOTE (ph) Unsupported payloads cannot be compared. */ + return(KMIP_FALSE); + break; + }; + } + } + + return(KMIP_TRUE); +} + +int +kmip_compare_nonce(const Nonce *a, const Nonce *b) +{ + if(a != b) + { + if((a == NULL) || (b == NULL)) + { + return(KMIP_FALSE); + } + + if(a->nonce_id != b->nonce_id) + { + if((a->nonce_id == NULL) || (b->nonce_id == NULL)) + { + return(KMIP_FALSE); + } + + if(kmip_compare_byte_string(a->nonce_id, b->nonce_id) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + + if(a->nonce_value != b->nonce_value) + { + if((a->nonce_value == NULL) || (b->nonce_value == NULL)) + { + return(KMIP_FALSE); + } + + if(kmip_compare_byte_string(a->nonce_value, b->nonce_value) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + } + + return(KMIP_TRUE); +} + +int +kmip_compare_username_password_credential(const UsernamePasswordCredential *a, const UsernamePasswordCredential *b) +{ + if(a != b) + { + if((a == NULL) || (b == NULL)) + { + return(KMIP_FALSE); + } + + if(a->username != b->username) + { + if((a->username == NULL) || (b->username == NULL)) + { + return(KMIP_FALSE); + } + + if(kmip_compare_text_string(a->username, b->username) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + + if(a->password != b->password) + { + if((a->password == NULL) || (b->password == NULL)) + { + return(KMIP_FALSE); + } + + if(kmip_compare_text_string(a->password, b->password) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + } + + return(KMIP_TRUE); +} + +int +kmip_compare_device_credential(const DeviceCredential *a, const DeviceCredential *b) +{ + if(a != b) + { + if((a == NULL) || (b == NULL)) + { + return(KMIP_FALSE); + } + + if(a->device_serial_number != b->device_serial_number) + { + if((a->device_serial_number == NULL) || (b->device_serial_number == NULL)) + { + return(KMIP_FALSE); + } + + if(kmip_compare_text_string(a->device_serial_number, b->device_serial_number) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + + if(a->password != b->password) + { + if((a->password == NULL) || (b->password == NULL)) + { + return(KMIP_FALSE); + } + + if(kmip_compare_text_string(a->password, b->password) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + + if(a->device_identifier != b->device_identifier) + { + if((a->device_identifier == NULL) || (b->device_identifier == NULL)) + { + return(KMIP_FALSE); + } + + if(kmip_compare_text_string(a->device_identifier, b->device_identifier) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + + if(a->network_identifier != b->network_identifier) + { + if((a->network_identifier == NULL) || (b->network_identifier == NULL)) + { + return(KMIP_FALSE); + } + + if(kmip_compare_text_string(a->network_identifier, b->network_identifier) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + + if(a->machine_identifier != b->machine_identifier) + { + if((a->machine_identifier == NULL) || (b->machine_identifier == NULL)) + { + return(KMIP_FALSE); + } + + if(kmip_compare_text_string(a->machine_identifier, b->machine_identifier) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + + if(a->media_identifier != b->media_identifier) + { + if((a->media_identifier == NULL) || (b->media_identifier == NULL)) + { + return(KMIP_FALSE); + } + + if(kmip_compare_text_string(a->media_identifier, b->media_identifier) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + } + + return(KMIP_TRUE); +} + +int +kmip_compare_attestation_credential(const AttestationCredential *a, const AttestationCredential *b) +{ + if(a != b) + { + if((a == NULL) || (b == NULL)) + { + return(KMIP_FALSE); + } + + if(a->attestation_type != b->attestation_type) + { + return(KMIP_FALSE); + } + + if(a->nonce != b->nonce) + { + if((a->nonce == NULL) || (b->nonce == NULL)) + { + return(KMIP_FALSE); + } + + if(kmip_compare_nonce(a->nonce, b->nonce) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + + if(a->attestation_measurement != b->attestation_measurement) + { + if((a->attestation_measurement == NULL) || (b->attestation_measurement == NULL)) + { + return(KMIP_FALSE); + } + + if(kmip_compare_byte_string(a->attestation_measurement, b->attestation_measurement) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + + if(a->attestation_assertion != b->attestation_assertion) + { + if((a->attestation_assertion == NULL) || (b->attestation_assertion == NULL)) + { + return(KMIP_FALSE); + } + + if(kmip_compare_byte_string(a->attestation_assertion, b->attestation_assertion) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + } + + return(KMIP_TRUE); +} + +int +kmip_compare_credential_value(enum credential_type type, void **a, void **b) +{ + if(a != b) + { + if((a == NULL) || (b == NULL)) + { + return(KMIP_FALSE); + } + + if(*a != *b) + { + if((*a == NULL) || (*b == NULL)) + { + return(KMIP_FALSE); + } + + switch(type) + { + case KMIP_CRED_USERNAME_AND_PASSWORD: + if(kmip_compare_username_password_credential(*a, *b) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + break; + + case KMIP_CRED_DEVICE: + if(kmip_compare_device_credential(*a, *b) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + break; + + case KMIP_CRED_ATTESTATION: + if(kmip_compare_attestation_credential(*a, *b) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + break; + + default: + /* NOTE (ph) Unsupported types cannot be compared. */ + return(KMIP_FALSE); + break; + }; + } + } + + return(KMIP_TRUE); +} + +int +kmip_compare_credential(const Credential *a, const Credential *b) +{ + if(a != b) + { + if((a == NULL) || (b == NULL)) + { + return(KMIP_FALSE); + } + + if(a->credential_type != b->credential_type) + { + return(KMIP_FALSE); + } + + if(a->credential_value != b->credential_value) + { + if((a->credential_value == NULL) || (b->credential_value == NULL)) + { + return(KMIP_FALSE); + } + + if(kmip_compare_credential_value(a->credential_type, (void**)&a->credential_value, (void**)&b->credential_value) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + } + + return(KMIP_TRUE); +} + +int +kmip_compare_authentication(const Authentication *a, const Authentication *b) +{ + if(a != b) + { + if((a == NULL) || (b == NULL)) + { + return(KMIP_FALSE); + } + + if(a->credential != b->credential) + { + if((a->credential == NULL) || (b->credential == NULL)) + { + return(KMIP_FALSE); + } + + if(kmip_compare_credential(a->credential, b->credential) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + } + + return(KMIP_TRUE); +} + +int +kmip_compare_request_header(const RequestHeader *a, const RequestHeader *b) +{ + if(a != b) + { + if((a == NULL) || (b == NULL)) + { + return(KMIP_FALSE); + } + + if(a->maximum_response_size != b->maximum_response_size) + { + return(KMIP_FALSE); + } + + if(a->asynchronous_indicator != b->asynchronous_indicator) + { + return(KMIP_FALSE); + } + + if(a->batch_error_continuation_option != b->batch_error_continuation_option) + { + return(KMIP_FALSE); + } + + if(a->batch_order_option != b->batch_order_option) + { + return(KMIP_FALSE); + } + + if(a->time_stamp != b->time_stamp) + { + return(KMIP_FALSE); + } + + if(a->batch_count != b->batch_count) + { + return(KMIP_FALSE); + } + + if(a->attestation_capable_indicator != b->attestation_capable_indicator) + { + return(KMIP_FALSE); + } + + if(a->attestation_type_count != b->attestation_type_count) + { + return(KMIP_FALSE); + } + + if(a->protocol_version != b->protocol_version) + { + if((a->protocol_version == NULL) || (b->protocol_version == NULL)) + { + return(KMIP_FALSE); + } + + if(kmip_compare_protocol_version(a->protocol_version, b->protocol_version) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + + if(a->authentication != b->authentication) + { + if((a->authentication == NULL) || (b->authentication == NULL)) + { + return(KMIP_FALSE); + } + + if(kmip_compare_authentication(a->authentication, b->authentication) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + + if(a->attestation_types != b->attestation_types) + { + if((a->attestation_types == NULL) || (b->attestation_types == NULL)) + { + return(KMIP_FALSE); + } + + for(size_t i = 0; i < a->attestation_type_count; i++) + { + if(a->attestation_types[i] != b->attestation_types[i]) + { + return(KMIP_FALSE); + } + } + } + + if(a->client_correlation_value != b->client_correlation_value) + { + if((a->client_correlation_value == NULL) || (b->client_correlation_value == NULL)) + { + return(KMIP_FALSE); + } + + if(kmip_compare_text_string(a->client_correlation_value, b->client_correlation_value) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + + if(a->server_correlation_value != b->server_correlation_value) + { + if((a->server_correlation_value == NULL) || (b->server_correlation_value == NULL)) + { + return(KMIP_FALSE); + } + + if(kmip_compare_text_string(a->server_correlation_value, b->server_correlation_value) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + } + + return(KMIP_TRUE); +} + +int +kmip_compare_response_header(const ResponseHeader *a, const ResponseHeader *b) +{ + if(a != b) + { + if((a == NULL) || (b == NULL)) + { + return(KMIP_FALSE); + } + + if(a->time_stamp != b->time_stamp) + { + return(KMIP_FALSE); + } + + if(a->batch_count != b->batch_count) + { + return(KMIP_FALSE); + } + + if(a->attestation_type_count != b->attestation_type_count) + { + return(KMIP_FALSE); + } + + if(a->protocol_version != b->protocol_version) + { + if((a->protocol_version == NULL) || (b->protocol_version == NULL)) + { + return(KMIP_FALSE); + } + + if(kmip_compare_protocol_version(a->protocol_version, b->protocol_version) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + + if(a->nonce != b->nonce) + { + if((a->nonce == NULL) || (b->nonce == NULL)) + { + return(KMIP_FALSE); + } + + if(kmip_compare_nonce(a->nonce, b->nonce) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + + if(a->server_hashed_password != b->server_hashed_password) + { + if((a->server_hashed_password == NULL) || (b->server_hashed_password == NULL)) + return(KMIP_FALSE); + + if(kmip_compare_byte_string(a->server_hashed_password, b->server_hashed_password) == KMIP_FALSE) + return(KMIP_FALSE); + } + + if(a->attestation_types != b->attestation_types) + { + if((a->attestation_types == NULL) || (b->attestation_types == NULL)) + { + return(KMIP_FALSE); + } + + for(size_t i = 0; i < a->attestation_type_count; i++) + { + if(a->attestation_types[i] != b->attestation_types[i]) + { + return(KMIP_FALSE); + } + } + } + + if(a->client_correlation_value != b->client_correlation_value) + { + if((a->client_correlation_value == NULL) || (b->client_correlation_value == NULL)) + { + return(KMIP_FALSE); + } + + if(kmip_compare_text_string(a->client_correlation_value, b->client_correlation_value) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + + if(a->server_correlation_value != b->server_correlation_value) + { + if((a->server_correlation_value == NULL) || (b->server_correlation_value == NULL)) + { + return(KMIP_FALSE); + } + + if(kmip_compare_text_string(a->server_correlation_value, b->server_correlation_value) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + } + + return(KMIP_TRUE); +} + +int +kmip_compare_request_message(const RequestMessage *a, const RequestMessage *b) +{ + if(a != b) + { + if((a == NULL) || (b == NULL)) + { + return(KMIP_FALSE); + } + + if(a->batch_count != b->batch_count) + { + return(KMIP_FALSE); + } + + if(a->request_header != b->request_header) + { + if((a->request_header == NULL) || (b->request_header == NULL)) + { + return(KMIP_FALSE); + } + + if(kmip_compare_request_header(a->request_header, b->request_header) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + + if(a->batch_items != b->batch_items) + { + if((a->batch_items == NULL) || (b->batch_items == NULL)) + { + return(KMIP_FALSE); + } + + for(size_t i = 0; i < a->batch_count; i++) + { + if(kmip_compare_request_batch_item(&a->batch_items[i], &b->batch_items[i]) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + } + } + + return(KMIP_TRUE); +} + +int +kmip_compare_response_message(const ResponseMessage *a, const ResponseMessage *b) +{ + if(a != b) + { + if((a == NULL) || (b == NULL)) + { + return(KMIP_FALSE); + } + + if(a->batch_count != b->batch_count) + { + return(KMIP_FALSE); + } + + if(a->response_header != b->response_header) + { + if((a->response_header == NULL) || (b->response_header == NULL)) + { + return(KMIP_FALSE); + } + + if(kmip_compare_response_header(a->response_header, b->response_header) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + + if(a->batch_items != b->batch_items) + { + if((a->batch_items == NULL) || (b->batch_items == NULL)) + { + return(KMIP_FALSE); + } + + for(size_t i = 0; i < a->batch_count; i++) + { + if(kmip_compare_response_batch_item(&a->batch_items[i], &b->batch_items[i]) == KMIP_FALSE) + { + return(KMIP_FALSE); + } + } + } + } + + return(KMIP_TRUE); +} + +/* +Encoding Functions +*/ + +int +kmip_encode_int8_be(KMIP *ctx, int8 value) +{ + CHECK_BUFFER_FULL(ctx, sizeof(int8)); + + *ctx->index++ = value; + + return(KMIP_OK); +} + +int +kmip_encode_int32_be(KMIP *ctx, int32 value) +{ + CHECK_BUFFER_FULL(ctx, sizeof(int32)); + + *ctx->index++ = (value << 0) >> 24; + *ctx->index++ = (value << 8) >> 24; + *ctx->index++ = (value << 16) >> 24; + *ctx->index++ = (value << 24) >> 24; + + return(KMIP_OK); +} + +int +kmip_encode_int64_be(KMIP *ctx, int64 value) +{ + CHECK_BUFFER_FULL(ctx, sizeof(int64)); + + *ctx->index++ = (value << 0) >> 56; + *ctx->index++ = (value << 8) >> 56; + *ctx->index++ = (value << 16) >> 56; + *ctx->index++ = (value << 24) >> 56; + *ctx->index++ = (value << 32) >> 56; + *ctx->index++ = (value << 40) >> 56; + *ctx->index++ = (value << 48) >> 56; + *ctx->index++ = (value << 56) >> 56; + + return(KMIP_OK); +} + +int +kmip_encode_integer(KMIP *ctx, enum tag t, int32 value) +{ + CHECK_BUFFER_FULL(ctx, 16); + + kmip_encode_int32_be(ctx, TAG_TYPE(t, KMIP_TYPE_INTEGER)); + kmip_encode_int32_be(ctx, 4); + kmip_encode_int32_be(ctx, value); + kmip_encode_int32_be(ctx, 0); + + return(KMIP_OK); +} + +int +kmip_encode_long(KMIP *ctx, enum tag t, int64 value) +{ + CHECK_BUFFER_FULL(ctx, 16); + + kmip_encode_int32_be(ctx, TAG_TYPE(t, KMIP_TYPE_LONG_INTEGER)); + kmip_encode_int32_be(ctx, 8); + kmip_encode_int64_be(ctx, value); + + return(KMIP_OK); +} + +int +kmip_encode_enum(KMIP *ctx, enum tag t, int32 value) +{ + CHECK_BUFFER_FULL(ctx, 16); + + kmip_encode_int32_be(ctx, TAG_TYPE(t, KMIP_TYPE_ENUMERATION)); + kmip_encode_int32_be(ctx, 4); + kmip_encode_int32_be(ctx, value); + kmip_encode_int32_be(ctx, 0); + + return(KMIP_OK); +} + +int +kmip_encode_bool(KMIP *ctx, enum tag t, bool32 value) +{ + CHECK_BUFFER_FULL(ctx, 16); + + kmip_encode_int32_be(ctx, TAG_TYPE(t, KMIP_TYPE_BOOLEAN)); + kmip_encode_int32_be(ctx, 8); + kmip_encode_int32_be(ctx, 0); + kmip_encode_int32_be(ctx, value); + + return(KMIP_OK); +} + +int +kmip_encode_text_string(KMIP *ctx, enum tag t, const TextString *value) +{ + /* TODO (ph) What if value is NULL? */ + uint8 padding = (8 - (value->size % 8)) % 8; + CHECK_BUFFER_FULL(ctx, 8 + value->size + padding); + + kmip_encode_int32_be(ctx, TAG_TYPE(t, KMIP_TYPE_TEXT_STRING)); + kmip_encode_int32_be(ctx, value->size); + + for(uint32 i = 0; i < value->size; i++) + { + kmip_encode_int8_be(ctx, value->value[i]); + } + for(uint8 i = 0; i < padding; i++) + { + kmip_encode_int8_be(ctx, 0); + } + + return(KMIP_OK); +} + +int +kmip_encode_byte_string(KMIP *ctx, enum tag t, const ByteString *value) +{ + uint8 padding = (8 - (value->size % 8)) % 8; + CHECK_BUFFER_FULL(ctx, 8 + value->size + padding); + + kmip_encode_int32_be(ctx, TAG_TYPE(t, KMIP_TYPE_BYTE_STRING)); + kmip_encode_int32_be(ctx, value->size); + + for(uint32 i = 0; i < value->size; i++) + { + kmip_encode_int8_be(ctx, value->value[i]); + } + for(uint8 i = 0; i < padding; i++) + { + kmip_encode_int8_be(ctx, 0); + } + + return(KMIP_OK); +} + +int +kmip_encode_date_time(KMIP *ctx, enum tag t, uint64 value) +{ + CHECK_BUFFER_FULL(ctx, 16); + + kmip_encode_int32_be(ctx, TAG_TYPE(t, KMIP_TYPE_DATE_TIME)); + kmip_encode_int32_be(ctx, 8); + kmip_encode_int64_be(ctx, value); + + return(KMIP_OK); +} + +int +kmip_encode_interval(KMIP *ctx, enum tag t, uint32 value) +{ + CHECK_BUFFER_FULL(ctx, 16); + + kmip_encode_int32_be(ctx, TAG_TYPE(t, KMIP_TYPE_INTERVAL)); + kmip_encode_int32_be(ctx, 4); + kmip_encode_int32_be(ctx, value); + kmip_encode_int32_be(ctx, 0); + + return(KMIP_OK); +} + +int +kmip_encode_digest(KMIP *ctx, const Digest *value) +{ + int result = 0; + + result = kmip_encode_int32_be(ctx, TAG_TYPE(KMIP_TAG_DIGEST, KMIP_TYPE_STRUCTURE)); + CHECK_RESULT(ctx, result); + + uint8 *length_index = ctx->index; + uint8 *value_index = ctx->index += 4; + + result = kmip_encode_enum(ctx, KMIP_TAG_HASHING_ALGORITHM, value->hashing_algorithm); + CHECK_RESULT(ctx, result); + + if(value->digest_value != NULL) + { + result = kmip_encode_byte_string(ctx, KMIP_TAG_DIGEST_VALUE, value->digest_value); + CHECK_RESULT(ctx, result); + } + + if(value->key_format_type != 0) + { + result = kmip_encode_enum(ctx, KMIP_TAG_KEY_FORMAT_TYPE, value->key_format_type); + 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_name(KMIP *ctx, const Name *value) +{ + /* TODO (ph) Check for value == NULL? */ + + int result = 0; + + result = kmip_encode_int32_be(ctx, TAG_TYPE(KMIP_TAG_NAME, 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_NAME_VALUE, value->value); + CHECK_RESULT(ctx, result); + + result = kmip_encode_enum(ctx, KMIP_TAG_NAME_TYPE, value->type); + CHECK_RESULT(ctx, result); + + uint8 *curr_index = ctx->index; + ctx->index = length_index; + + result = kmip_encode_int32_be(ctx, curr_index - value_index); + CHECK_RESULT(ctx, result); + + ctx->index = curr_index; + + return(KMIP_OK); +} + +int +kmip_encode_protection_storage_masks(KMIP *ctx, const ProtectionStorageMasks *value) +{ + CHECK_ENCODE_ARGS(ctx, value); + CHECK_KMIP_VERSION(ctx, KMIP_2_0); + + int result = 0; + + result = kmip_encode_int32_be( + ctx, + TAG_TYPE(KMIP_TAG_PROTECTION_STORAGE_MASKS, KMIP_TYPE_STRUCTURE) + ); + CHECK_RESULT(ctx, result); + + uint8 *length_index = ctx->index; + uint8 *value_index = ctx->index += 4; + + if(value->masks != NULL) + { + LinkedListItem *curr = value->masks->head; + while(curr != NULL) + { + result = kmip_encode_integer(ctx, KMIP_TAG_PROTECTION_STORAGE_MASK, *(int32 *)curr->data); + CHECK_RESULT(ctx, result); + + curr = curr->next; + } + } + + uint8 *curr_index = ctx->index; + ctx->index = length_index; + + result = kmip_encode_int32_be(ctx, curr_index - value_index); + CHECK_RESULT(ctx, result); + + ctx->index = curr_index; + + return(KMIP_OK); +} + +int +kmip_encode_attribute_name(KMIP *ctx, enum attribute_type value) +{ + int result = 0; + enum tag t = KMIP_TAG_ATTRIBUTE_NAME; + TextString attribute_name = {0}; + + switch(value) + { + case KMIP_ATTR_UNIQUE_IDENTIFIER: + attribute_name.value = "Unique Identifier"; + attribute_name.size = 17; + break; + + case KMIP_ATTR_NAME: + attribute_name.value = "Name"; + attribute_name.size = 4; + break; + + case KMIP_ATTR_OBJECT_TYPE: + attribute_name.value = "Object Type"; + attribute_name.size = 11; + break; + + case KMIP_ATTR_CRYPTOGRAPHIC_ALGORITHM: + attribute_name.value = "Cryptographic Algorithm"; + attribute_name.size = 23; + break; + + case KMIP_ATTR_CRYPTOGRAPHIC_LENGTH: + attribute_name.value = "Cryptographic Length"; + attribute_name.size = 20; + break; + + case KMIP_ATTR_CRYPTOGRAPHIC_PARAMETERS: + attribute_name.value = "Cryptographic Parameters"; + attribute_name.size = 24; + break; + + case KMIP_ATTR_CRYPTOGRAPHIC_DOMAIN_PARAMETERS: + attribute_name.value = "Cryptographic Domain Parameters"; + attribute_name.size = 31; + break; + + case KMIP_ATTR_CERTIFICATE_TYPE: + attribute_name.value = "Certificate Type"; + attribute_name.size = 16; + break; + + case KMIP_ATTR_CERTIFICATE_LENGTH: + attribute_name.value = "Certificate Length"; + attribute_name.size = 18; + break; + + case KMIP_ATTR_X509_CERTIFICATE_IDENTIFIER: + attribute_name.value = "X.509 Certificate Identifier"; + attribute_name.size = 28; + break; + + case KMIP_ATTR_X509_CERTIFICATE_SUBJECT: + attribute_name.value = "X.509 Certificate Subject"; + attribute_name.size = 25; + break; + + case KMIP_ATTR_X509_CERTIFICATE_ISSUER: + attribute_name.value = "X.509 Certificate Issuer"; + attribute_name.size = 24; + break; + + case KMIP_ATTR_CERTIFICATE_IDENTIFIER: + attribute_name.value = "Certificate Identifier"; + attribute_name.size = 22; + break; + + case KMIP_ATTR_CERTIFICATE_SUBJECT: + attribute_name.value = "Certificate Subject"; + attribute_name.size = 19; + break; + + case KMIP_ATTR_CERTIFICATE_ISSUER: + attribute_name.value = "Certificate Issuer"; + attribute_name.size = 18; + break; + + case KMIP_ATTR_DIGITAL_SIGNATURE_ALGORITHM: + attribute_name.value = "Digital Signature Algorithm"; + attribute_name.size = 27; + break; + + case KMIP_ATTR_DIGEST: + attribute_name.value = "Digest"; + attribute_name.size = 6; + break; + + case KMIP_ATTR_OPERATION_POLICY_NAME: + attribute_name.value = "Operation Policy Name"; + attribute_name.size = 21; + break; + + case KMIP_ATTR_CRYPTOGRAPHIC_USAGE_MASK: + attribute_name.value = "Cryptographic Usage Mask"; + attribute_name.size = 24; + break; + + case KMIP_ATTR_LEASE_TIME: + attribute_name.value = "Lease Time"; + attribute_name.size = 10; + break; + + case KMIP_ATTR_USAGE_LIMITS: + attribute_name.value = "Usage Limits"; + attribute_name.size = 12; + break; + + case KMIP_ATTR_STATE: + attribute_name.value = "State"; + attribute_name.size = 5; + break; + + case KMIP_ATTR_INITIAL_DATE: + attribute_name.value = "Initial Date"; + attribute_name.size = 12; + break; + case KMIP_ATTR_ACTIVATION_DATE: + attribute_name.value = "Activation Date"; + attribute_name.size = 15; + break; + + case KMIP_ATTR_PROCESS_START_DATE: + attribute_name.value = "Process Start Date"; + attribute_name.size = 18; + break; + + case KMIP_ATTR_PROTECT_STOP_DATE: + attribute_name.value = "Protect Stop Date"; + attribute_name.size = 17; + break; + + case KMIP_ATTR_DEACTIVATION_DATE: + attribute_name.value = "Deactivation Date"; + attribute_name.size = 17; + break; + + case KMIP_ATTR_DESTROY_DATE: + attribute_name.value = "Destroy Date"; + attribute_name.size = 12; + break; + + case KMIP_ATTR_COMPROMISE_OCCURRENCE_DATE: + attribute_name.value = "Compromise Occurrence Date"; + attribute_name.size = 26; + break; + + case KMIP_ATTR_COMPROMISE_DATE: + attribute_name.value = "Compromise Date"; + attribute_name.size = 15; + break; + + case KMIP_ATTR_REVOCATION_REASON: + attribute_name.value = "Revocation Reason"; + attribute_name.size = 17; + break; + + case KMIP_ATTR_ARCHIVE_DATE: + attribute_name.value = "Archive Date"; + attribute_name.size = 12; + break; + + case KMIP_ATTR_OBJECT_GROUP: + attribute_name.value = "Object Group"; + attribute_name.size = 12; + break; + + case KMIP_ATTR_FRESH: + attribute_name.value = "Fresh"; + attribute_name.size = 5; + break; + + case KMIP_ATTR_LINK: + attribute_name.value = "Link"; + attribute_name.size = 4; + break; + + case KMIP_ATTR_APPLICATION_SPECIFIC_INFORMATION: + attribute_name.value = "Application Specific Information"; + attribute_name.size = 32; + break; + + case KMIP_ATTR_CONTACT_INFORMATION: + attribute_name.value = "Contact Information"; + attribute_name.size = 19; + break; + + case KMIP_ATTR_LAST_CHANGE_DATE: + attribute_name.value = "Last Change Date"; + attribute_name.size = 16; + break; + + case KMIP_ATTR_ALTERNATIVE_NAME: + attribute_name.value = "Alternative Name"; + attribute_name.size = 16; + break; + + case KMIP_ATTR_KEY_VALUE_PRESENT: + attribute_name.value = "Key Value Present"; + attribute_name.size = 17; + break; + + case KMIP_ATTR_KEY_VALUE_LOCATION: + attribute_name.value = "Key Value Location"; + attribute_name.size = 18; + break; + + case KMIP_ATTR_ORIGINAL_CREATION_DATE: + attribute_name.value = "Original Creation Date"; + attribute_name.size = 22; + break; + + case KMIP_ATTR_RANDOM_NUMBER_GENERATOR: + attribute_name.value = "Random Number Generator"; + attribute_name.size = 23; + break; + + case KMIP_ATTR_PKCS_12_FRIENDLY_NAME: + attribute_name.value = "PKCS#12 Friendly Name"; + attribute_name.size = 21; + break; + + case KMIP_ATTR_DESCRIPTION: + attribute_name.value = "Description"; + attribute_name.size = 11; + break; + + case KMIP_ATTR_COMMENT: + attribute_name.value = "Comment"; + attribute_name.size = 7; + break; + + case KMIP_ATTR_SENSITIVE: + attribute_name.value = "Sensitive"; + attribute_name.size = 9; + break; + + case KMIP_ATTR_ALWAYS_SENSITIVE: + attribute_name.value = "Always Sensitive"; + attribute_name.size = 16; + break; + + case KMIP_ATTR_EXTRACTABLE: + attribute_name.value = "Extractable"; + attribute_name.size = 11; + break; + + case KMIP_ATTR_NEVER_EXTRACTABLE: + attribute_name.value = "Never Extractable"; + attribute_name.size = 17; + break; + + case KMIP_ATTR_KEY_FORMAT_TYPE: + attribute_name.value = "Key Format Type"; + attribute_name.size = 15; + break; + + default: + kmip_push_error_frame(ctx, __func__, __LINE__); + return(KMIP_ERROR_ATTR_UNSUPPORTED); + break; + }; + + result = kmip_encode_text_string(ctx, t, &attribute_name); + CHECK_RESULT(ctx, result); + + return(KMIP_OK); +} + +int +kmip_encode_attribute_v1(KMIP *ctx, const Attribute *value) +{ + /* TODO (ph) Add CryptographicParameters support? */ + CHECK_ENCODE_ARGS(ctx, value); + + int result = 0; + + result = kmip_encode_int32_be(ctx, TAG_TYPE(KMIP_TAG_ATTRIBUTE, KMIP_TYPE_STRUCTURE)); + CHECK_RESULT(ctx, result); + + uint8 *length_index = ctx->index; + uint8 *value_index = ctx->index += 4; + + result = kmip_encode_attribute_name(ctx, value->type); + CHECK_RESULT(ctx, result); + + if(value->index != KMIP_UNSET) + { + result = kmip_encode_integer(ctx, KMIP_TAG_ATTRIBUTE_INDEX, value->index); + CHECK_RESULT(ctx, result); + } + + uint8 *curr_index = ctx->index; + uint8 *tag_index = ctx->index; + enum tag t = KMIP_TAG_ATTRIBUTE_VALUE; + + switch(value->type) + { + case KMIP_ATTR_UNIQUE_IDENTIFIER: + result = kmip_encode_text_string(ctx, t, (TextString*)value->value); + break; + + case KMIP_ATTR_NAME: + /* TODO (ph) This is messy. Clean it up? */ + result = kmip_encode_name(ctx, (Name*)value->value); + CHECK_RESULT(ctx, result); + + curr_index = ctx->index; + ctx->index = tag_index; + + result = kmip_encode_int32_be(ctx, TAG_TYPE(KMIP_TAG_ATTRIBUTE_VALUE, KMIP_TYPE_STRUCTURE)); + + ctx->index = curr_index; + break; + + case KMIP_ATTR_OBJECT_TYPE: + result = kmip_encode_enum(ctx, t, *(int32 *)value->value); + break; + + case KMIP_ATTR_CRYPTOGRAPHIC_ALGORITHM: + result = kmip_encode_enum(ctx, t, *(int32 *)value->value); + break; + + case KMIP_ATTR_CRYPTOGRAPHIC_LENGTH: + result = kmip_encode_integer(ctx, t, *(int32 *)value->value); + break; + + // case KMIP_ATTR_CRYPTOGRAPHIC_PARAMETERS: XXX how to hack struct? + // case KMIP_ATTR_CRYPTOGRAPHIC_DOMAIN_PARAMETERS: XXX how to hack struct? + + case KMIP_ATTR_CERTIFICATE_TYPE: + result = kmip_encode_enum(ctx, t, *(int32 *)value->value); + break; + + case KMIP_ATTR_CERTIFICATE_LENGTH: + result = kmip_encode_integer(ctx, t, *(int32 *)value->value); + break; + + // case KMIP_ATTR_X509_CERTIFICATE_IDENTIFIER: XXX how to hack struct? + // case KMIP_ATTR_X509_CERTIFICATE_SUBJECT: XXX how to hack struct? + // case KMIP_ATTR_X509_CERTIFICATE_ISSUER: XXX how to hack struct? + // case KMIP_ATTR_CERTIFICATE_IDENTIFIER: XXX how to hack struct? + // case KMIP_ATTR_CERTIFICATE_SUBJECT: XXX how to hack struct? + // case KMIP_ATTR_CERTIFICATE_ISSUER: XXX how to hack struct? + + case KMIP_ATTR_DIGITAL_SIGNATURE_ALGORITHM: + result = kmip_encode_enum(ctx, t, *(int32 *)value->value); + break; + + case KMIP_ATTR_DIGEST: + // messy... + result = kmip_encode_digest(ctx, (const Digest*)value->value); + CHECK_RESULT(ctx, result); + + curr_index = ctx->index; + ctx->index = tag_index; + + result = kmip_encode_int32_be(ctx, TAG_TYPE(KMIP_TAG_ATTRIBUTE_VALUE, KMIP_TYPE_STRUCTURE)); + + ctx->index = curr_index; + break; + + case KMIP_ATTR_OPERATION_POLICY_NAME: + result = kmip_encode_text_string(ctx, t, (TextString*)value->value); + break; + + case KMIP_ATTR_CRYPTOGRAPHIC_USAGE_MASK: + result = kmip_encode_integer(ctx, t, *(int32 *)value->value); + break; + + case KMIP_ATTR_LEASE_TIME: + result = kmip_encode_interval(ctx, t, *(uint32 *)value->value); + break; + + // case KMIP_ATTR_USAGE_LIMITS: XXX how to hack struct? + + case KMIP_ATTR_STATE: + result = kmip_encode_enum(ctx, t, *(int32 *)value->value); + break; + + case KMIP_ATTR_INITIAL_DATE: + result = kmip_encode_date_time(ctx, t, *(uint64 *)value->value); + break; + case KMIP_ATTR_ACTIVATION_DATE: + result = kmip_encode_date_time(ctx, t, *(uint64 *)value->value); + break; + + case KMIP_ATTR_PROCESS_START_DATE: + result = kmip_encode_date_time(ctx, t, *(uint64 *)value->value); + break; + + case KMIP_ATTR_PROTECT_STOP_DATE: + result = kmip_encode_date_time(ctx, t, *(uint64 *)value->value); + break; + + case KMIP_ATTR_DEACTIVATION_DATE: + result = kmip_encode_date_time(ctx, t, *(uint64 *)value->value); + break; + + case KMIP_ATTR_DESTROY_DATE: + result = kmip_encode_date_time(ctx, t, *(uint64 *)value->value); + break; + + case KMIP_ATTR_COMPROMISE_OCCURRENCE_DATE: + result = kmip_encode_date_time(ctx, t, *(uint64 *)value->value); + break; + + case KMIP_ATTR_COMPROMISE_DATE: + result = kmip_encode_date_time(ctx, t, *(uint64 *)value->value); + break; + + // case KMIP_ATTR_REVOCATION_REASON: XXX how to hack struct? + + case KMIP_ATTR_ARCHIVE_DATE: + result = kmip_encode_date_time(ctx, t, *(uint64 *)value->value); + break; + + case KMIP_ATTR_OBJECT_GROUP: + result = kmip_encode_text_string(ctx, t, (TextString*)value->value); + break; + + case KMIP_ATTR_FRESH: + result = kmip_encode_bool(ctx, t, *(bool32 *)value->value); + break; + + // case KMIP_ATTR_LINK: XXX how to hack struct? + // case KMIP_ATTR_APPLICATION_SPECIFIC_INFORMATION: XXX how to hack struct? + // case KMIP_ATTR_CONTACT_INFORMATION: XXX how to hack struct? + + case KMIP_ATTR_LAST_CHANGE_DATE: + result = kmip_encode_date_time(ctx, t, *(uint64 *)value->value); + break; + + // case KMIP_ATTR_CUSTOM_ATTRIBUTE: XXX how to hack custom? + // case KMIP_ATTR_ALTERNATIVE_NAME: XXX how to hack struct? + + case KMIP_ATTR_KEY_VALUE_PRESENT: + result = kmip_encode_bool(ctx, t, *(bool32 *)value->value); + break; + + // case KMIP_ATTR_KEY_VALUE_LOCATION: XXX how to hack struct? + + case KMIP_ATTR_ORIGINAL_CREATION_DATE: + result = kmip_encode_date_time(ctx, t, *(uint64 *)value->value); + break; + + case KMIP_ATTR_RANDOM_NUMBER_GENERATOR: + result = kmip_encode_text_string(ctx, t, (TextString*)value->value); + break; + + case KMIP_ATTR_PKCS_12_FRIENDLY_NAME: + result = kmip_encode_text_string(ctx, t, (TextString*)value->value); + break; + + case KMIP_ATTR_DESCRIPTION: + result = kmip_encode_text_string(ctx, t, (TextString*)value->value); + break; + + case KMIP_ATTR_COMMENT: + result = kmip_encode_text_string(ctx, t, (TextString*)value->value); + break; + + case KMIP_ATTR_SENSITIVE: + result = kmip_encode_bool(ctx, t, *(bool32 *)value->value); + break; + + case KMIP_ATTR_ALWAYS_SENSITIVE: + result = kmip_encode_bool(ctx, t, *(bool32 *)value->value); + break; + + case KMIP_ATTR_EXTRACTABLE: + result = kmip_encode_bool(ctx, t, *(bool32 *)value->value); + break; + + case KMIP_ATTR_NEVER_EXTRACTABLE: + result = kmip_encode_bool(ctx, t, *(bool32 *)value->value); + break; + + case KMIP_ATTR_KEY_FORMAT_TYPE: + result = kmip_encode_enum(ctx, t, *(int32 *)value->value); + break; + + default: + kmip_push_error_frame(ctx, __func__, __LINE__); + return(KMIP_ERROR_ATTR_UNSUPPORTED); + break; + }; + CHECK_RESULT(ctx, result); + + curr_index = ctx->index; + ctx->index = length_index; + + result = kmip_encode_int32_be(ctx, curr_index - value_index); + CHECK_RESULT(ctx, result); + + ctx->index = curr_index; + + return(KMIP_OK); +} + +int +kmip_encode_attribute_v2(KMIP *ctx, const Attribute *value) +{ + /* TODO (ph) Add CryptographicParameters support? */ + CHECK_ENCODE_ARGS(ctx, value); + + int result = 0; + + switch(value->type) + { + case KMIP_ATTR_UNIQUE_IDENTIFIER: + { + result = kmip_encode_text_string( + ctx, + KMIP_TAG_UNIQUE_IDENTIFIER, + (TextString*)value->value + ); + } + break; + + case KMIP_ATTR_NAME: + { + result = kmip_encode_name(ctx, (Name*)value->value); + } + break; + + case KMIP_ATTR_OBJECT_TYPE: + { + result = kmip_encode_enum( + ctx, + KMIP_TAG_OBJECT_TYPE, + *(int32 *)value->value + ); + } + break; + + case KMIP_ATTR_CRYPTOGRAPHIC_ALGORITHM: + { + result = kmip_encode_enum( + ctx, + KMIP_TAG_CRYPTOGRAPHIC_ALGORITHM, + *(int32 *)value->value + ); + } + break; + + case KMIP_ATTR_CRYPTOGRAPHIC_LENGTH: + { + result = kmip_encode_integer( + ctx, + KMIP_TAG_CRYPTOGRAPHIC_LENGTH, + *(int32 *)value->value + ); + } + break; + + // case KMIP_ATTR_CRYPTOGRAPHIC_PARAMETERS: XXX how to hack struct? + // case KMIP_ATTR_CRYPTOGRAPHIC_DOMAIN_PARAMETERS: XXX how to hack struct? + + case KMIP_ATTR_CERTIFICATE_TYPE: + { + result = kmip_encode_enum( + ctx, + KMIP_TAG_CERTIFICATE_TYPE, + *(int32 *)value->value + ); + } + break; + + case KMIP_ATTR_CERTIFICATE_LENGTH: + { + result = kmip_encode_integer( + ctx, + KMIP_TAG_CERTIFICATE_LENGTH, + *(int32 *)value->value + ); + } + break; + + // case KMIP_ATTR_X509_CERTIFICATE_IDENTIFIER: XXX how to hack struct? + // case KMIP_ATTR_X509_CERTIFICATE_SUBJECT: XXX how to hack struct? + // case KMIP_ATTR_X509_CERTIFICATE_ISSUER: XXX how to hack struct? + // case KMIP_ATTR_CERTIFICATE_IDENTIFIER: XXX how to hack struct? + // case KMIP_ATTR_CERTIFICATE_SUBJECT: XXX how to hack struct? + // case KMIP_ATTR_CERTIFICATE_ISSUER: XXX how to hack struct? + + case KMIP_ATTR_DIGITAL_SIGNATURE_ALGORITHM: + { + result = kmip_encode_enum( + ctx, + KMIP_TAG_DIGITAL_SIGNATURE_ALGORITHM, + *(int32 *)value->value + ); + } + break; + + case KMIP_ATTR_DIGEST: + { + result = kmip_encode_digest(ctx, (Digest*)value->value); + } + break; + + case KMIP_ATTR_OPERATION_POLICY_NAME: + { + result = kmip_encode_text_string( + ctx, + KMIP_TAG_OPERATION_POLICY_NAME, + (TextString*)value->value + ); + } + break; + + case KMIP_ATTR_CRYPTOGRAPHIC_USAGE_MASK: + { + result = kmip_encode_integer( + ctx, + KMIP_TAG_CRYPTOGRAPHIC_USAGE_MASK, + *(int32 *)value->value) + ; + } + break; + + case KMIP_ATTR_LEASE_TIME: + { + result = kmip_encode_interval( + ctx, + KMIP_TAG_LEASE_TIME, + *(uint32 *)value->value + ); + } + break; + + // case KMIP_ATTR_USAGE_LIMITS: XXX how to hack struct? + + case KMIP_ATTR_STATE: + { + result = kmip_encode_enum( + ctx, + KMIP_TAG_STATE, + *(int32 *)value->value + ); + } + break; + + case KMIP_ATTR_INITIAL_DATE: + { + result = kmip_encode_date_time( + ctx, + KMIP_TAG_INITIAL_DATE, + *(uint64 *)value->value) + ; + } + break; + + case KMIP_ATTR_ACTIVATION_DATE: + { + result = kmip_encode_date_time( + ctx, + KMIP_TAG_ACTIVATION_DATE, + *(uint64 *)value->value + ); + } + break; + + case KMIP_ATTR_PROCESS_START_DATE: + { + result = kmip_encode_date_time( + ctx, + KMIP_TAG_PROCESS_START_DATE, + *(uint64 *)value->value + ); + } + break; + + case KMIP_ATTR_PROTECT_STOP_DATE: + { + result = kmip_encode_date_time( + ctx, + KMIP_TAG_PROTECT_STOP_DATE, + *(uint64 *)value->value + ); + } + break; + + case KMIP_ATTR_DEACTIVATION_DATE: + { + result = kmip_encode_date_time( + ctx, + KMIP_TAG_DEACTIVATION_DATE, + *(uint64 *)value->value + ); + } + break; + + case KMIP_ATTR_DESTROY_DATE: + { + result = kmip_encode_date_time( + ctx, + KMIP_TAG_DESTROY_DATE, + *(uint64 *)value->value + ); + } + break; + + case KMIP_ATTR_COMPROMISE_OCCURRENCE_DATE: + { + result = kmip_encode_date_time( + ctx, + KMIP_TAG_COMPROMISE_OCCURRENCE_DATE, + *(uint64 *)value->value + ); + } + break; + + case KMIP_ATTR_COMPROMISE_DATE: + { + result = kmip_encode_date_time( + ctx, + KMIP_TAG_COMPROMISE_DATE, + *(uint64 *)value->value + ); + } + break; + + // case KMIP_ATTR_REVOCATION_REASON: XXX how to hack struct? + + case KMIP_ATTR_ARCHIVE_DATE: + { + result = kmip_encode_date_time( + ctx, + KMIP_TAG_ARCHIVE_DATE, + *(uint64 *)value->value + ); + } + break; + + case KMIP_ATTR_OBJECT_GROUP: + { + result = kmip_encode_text_string( + ctx, + KMIP_TAG_OBJECT_GROUP, + (TextString*)value->value + ); + } + break; + + case KMIP_ATTR_FRESH: + { + result = kmip_encode_bool( + ctx, + KMIP_TAG_FRESH, + *(bool32 *)value->value + ); + } + break; + + // case KMIP_ATTR_LINK: XXX how to hack struct? + // case KMIP_ATTR_APPLICATION_SPECIFIC_INFORMATION: XXX how to hack struct? + // case KMIP_ATTR_CONTACT_INFORMATION: XXX how to hack struct? + + case KMIP_ATTR_LAST_CHANGE_DATE: + { + result = kmip_encode_date_time( + ctx, + KMIP_TAG_LAST_CHANGE_DATE, + *(uint64 *)value->value + ); + } + break; + + // case KMIP_ATTR_CUSTOM_ATTRIBUTE: XXX how to hack custom? + // case KMIP_ATTR_ALTERNATIVE_NAME: XXX how to hack struct? + + case KMIP_ATTR_KEY_VALUE_PRESENT: + { + result = kmip_encode_bool( + ctx, + KMIP_TAG_KEY_VALUE_PRESENT, + *(bool32 *)value->value + ); + } + break; + + // case KMIP_ATTR_KEY_VALUE_LOCATION: XXX how to hack struct? + + case KMIP_ATTR_ORIGINAL_CREATION_DATE: + { + result = kmip_encode_date_time( + ctx, + KMIP_TAG_ORIGINAL_CREATION_DATE, + *(uint64 *)value->value + ); + } + break; + + case KMIP_ATTR_RANDOM_NUMBER_GENERATOR: + { + result = kmip_encode_text_string( + ctx, + KMIP_TAG_RANDOM_NUMBER_GENERATOR, + (TextString*)value->value + ); + } + break; + + case KMIP_ATTR_PKCS_12_FRIENDLY_NAME: + { + result = kmip_encode_text_string( + ctx, + KMIP_TAG_PKCS_12_FRIENDLY_NAME, + (TextString*)value->value + ); + } + break; + + case KMIP_ATTR_DESCRIPTION: + { + result = kmip_encode_text_string( + ctx, + KMIP_TAG_DESCRIPTION, + (TextString*)value->value + ); + } + break; + + case KMIP_ATTR_COMMENT: + { + result = kmip_encode_text_string( + ctx, + KMIP_TAG_COMMENT, + (TextString*)value->value + ); + } + break; + + case KMIP_ATTR_SENSITIVE: + { + result = kmip_encode_bool( + ctx, + KMIP_TAG_SENSITIVE, + *(bool32 *)value->value + ); + } + break; + + case KMIP_ATTR_ALWAYS_SENSITIVE: + { + result = kmip_encode_bool( + ctx, + KMIP_TAG_ALWAYS_SENSITIVE, + *(bool32 *)value->value + ); + } + break; + + case KMIP_ATTR_EXTRACTABLE: + { + result = kmip_encode_bool( + ctx, + KMIP_TAG_EXTRACTABLE, + *(bool32 *)value->value + ); + } + break; + + case KMIP_ATTR_NEVER_EXTRACTABLE: + { + result = kmip_encode_bool( + ctx, + KMIP_TAG_NEVER_EXTRACTABLE, + *(bool32 *)value->value + ); + } + break; + + case KMIP_ATTR_KEY_FORMAT_TYPE: + { + result = kmip_encode_enum( + ctx, + KMIP_TAG_KEY_FORMAT_TYPE, + *(int32 *)value->value + ); + } + break; + + default: + { + kmip_push_error_frame(ctx, __func__, __LINE__); + return(KMIP_ERROR_ATTR_UNSUPPORTED); + } + break; + }; + CHECK_RESULT(ctx, result); + + return(KMIP_OK); +} + +int +kmip_encode_attribute(KMIP *ctx, const Attribute *value) +{ + CHECK_ENCODE_ARGS(ctx, value); + + if(ctx->version < KMIP_2_0) + { + return(kmip_encode_attribute_v1(ctx, value)); + } + else + { + return(kmip_encode_attribute_v2(ctx, value)); + } +} + +int +kmip_encode_attributes(KMIP *ctx, const Attributes *value) +{ + CHECK_ENCODE_ARGS(ctx, value); + CHECK_KMIP_VERSION(ctx, KMIP_2_0); + + int result = 0; + + result = kmip_encode_int32_be( + ctx, + TAG_TYPE(KMIP_TAG_ATTRIBUTES, KMIP_TYPE_STRUCTURE) + ); + CHECK_RESULT(ctx, result); + + 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; + } + } + + uint8 *curr_index = ctx->index; + ctx->index = length_index; + + result = kmip_encode_int32_be(ctx, curr_index - value_index); + CHECK_RESULT(ctx, result); + + ctx->index = curr_index; + + return(KMIP_OK); +} + +int +kmip_encode_attributes_2(KMIP *ctx, const Attribute *value, int count) +{ + CHECK_ENCODE_ARGS(ctx, value); + CHECK_KMIP_VERSION(ctx, KMIP_2_0); + + int result = 0; + + result = kmip_encode_int32_be( + ctx, + TAG_TYPE(KMIP_TAG_ATTRIBUTES, KMIP_TYPE_STRUCTURE) + ); + CHECK_RESULT(ctx, result); + + uint8 *length_index = ctx->index; + uint8 *value_index = ctx->index += 4; + + if(value) { + for (int i = 0; i < count; ++i) + { + result = kmip_encode_attribute(ctx, value + i); + CHECK_RESULT(ctx, result); + } + } + + uint8 *curr_index = ctx->index; + ctx->index = length_index; + + result = kmip_encode_int32_be(ctx, curr_index - value_index); + CHECK_RESULT(ctx, result); + + ctx->index = curr_index; + + return(KMIP_OK); +} + +int +kmip_encode_template_attribute(KMIP *ctx, const TemplateAttribute *value) +{ + int result = 0; + + result = kmip_encode_int32_be(ctx, TAG_TYPE(KMIP_TAG_TEMPLATE_ATTRIBUTE, KMIP_TYPE_STRUCTURE)); + CHECK_RESULT(ctx, result); + + uint8 *length_index = ctx->index; + uint8 *value_index = ctx->index += 4; + + for(size_t i = 0; i < value->name_count; i++) + { + result = kmip_encode_name(ctx, &value->names[i]); + CHECK_RESULT(ctx, result); + } + + for(size_t i = 0; i <value->attribute_count; i++) + { + result = kmip_encode_attribute(ctx, &value->attributes[i]); + CHECK_RESULT(ctx, result); + } + + uint8 *curr_index = ctx->index; + ctx->index = length_index; + + result = kmip_encode_int32_be(ctx, curr_index - value_index); + CHECK_RESULT(ctx, result); + + ctx->index = curr_index; + + return(KMIP_OK); +} + +int +kmip_encode_protocol_version(KMIP *ctx, const ProtocolVersion *value) +{ + CHECK_BUFFER_FULL(ctx, 40); + + kmip_encode_int32_be(ctx, TAG_TYPE(KMIP_TAG_PROTOCOL_VERSION, KMIP_TYPE_STRUCTURE)); + + uint8 *length_index = ctx->index; + uint8 *value_index = ctx->index += 4; + + kmip_encode_integer(ctx, KMIP_TAG_PROTOCOL_VERSION_MAJOR, value->major); + kmip_encode_integer(ctx, KMIP_TAG_PROTOCOL_VERSION_MINOR, value->minor); + + 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_cryptographic_parameters(KMIP *ctx, const CryptographicParameters *value) +{ + int result = 0; + result = kmip_encode_int32_be(ctx, TAG_TYPE(KMIP_TAG_CRYPTOGRAPHIC_PARAMETERS, KMIP_TYPE_STRUCTURE)); + CHECK_RESULT(ctx, result); + + uint8 *length_index = ctx->index; + uint8 *value_index = ctx->index += 4; + + if(value->block_cipher_mode != 0) + { + result = kmip_encode_enum(ctx, KMIP_TAG_BLOCK_CIPHER_MODE, value->block_cipher_mode); + CHECK_RESULT(ctx, result); + } + + if(value->padding_method != 0) + { + result = kmip_encode_enum(ctx, KMIP_TAG_PADDING_METHOD, value->padding_method); + CHECK_RESULT(ctx, result); + } + + if(value->hashing_algorithm != 0) + { + result = kmip_encode_enum(ctx, KMIP_TAG_HASHING_ALGORITHM, value->hashing_algorithm); + CHECK_RESULT(ctx, result); + } + + if(value->key_role_type != 0) + { + result = kmip_encode_enum(ctx, KMIP_TAG_KEY_ROLE_TYPE, value->key_role_type); + CHECK_RESULT(ctx, result); + } + + if(ctx->version >= KMIP_1_2) + { + if(value->digital_signature_algorithm != 0) + { + result = kmip_encode_enum(ctx, KMIP_TAG_DIGITAL_SIGNATURE_ALGORITHM, value->digital_signature_algorithm); + CHECK_RESULT(ctx, result); + } + + if(value->cryptographic_algorithm != 0) + { + result = kmip_encode_enum(ctx, KMIP_TAG_CRYPTOGRAPHIC_ALGORITHM, value->cryptographic_algorithm); + CHECK_RESULT(ctx, result); + } + + if(value->random_iv != KMIP_UNSET) + { + result = kmip_encode_bool(ctx, KMIP_TAG_RANDOM_IV, value->random_iv); + CHECK_RESULT(ctx, result); + } + + if(value->iv_length != KMIP_UNSET) + { + result = kmip_encode_integer(ctx, KMIP_TAG_IV_LENGTH, value->iv_length); + CHECK_RESULT(ctx, result); + } + + if(value->tag_length != KMIP_UNSET) + { + result = kmip_encode_integer(ctx, KMIP_TAG_TAG_LENGTH, value->tag_length); + CHECK_RESULT(ctx, result); + } + + if(value->fixed_field_length != KMIP_UNSET) + { + result = kmip_encode_integer(ctx, KMIP_TAG_FIXED_FIELD_LENGTH, value->fixed_field_length); + CHECK_RESULT(ctx, result); + } + + if(value->invocation_field_length != KMIP_UNSET) + { + result = kmip_encode_integer(ctx, KMIP_TAG_INVOCATION_FIELD_LENGTH, value->invocation_field_length); + CHECK_RESULT(ctx, result); + } + + if(value->counter_length != KMIP_UNSET) + { + result = kmip_encode_integer(ctx, KMIP_TAG_COUNTER_LENGTH, value->counter_length); + CHECK_RESULT(ctx, result); + } + + if(value->initial_counter_value != KMIP_UNSET) + { + result = kmip_encode_integer(ctx, KMIP_TAG_INITIAL_COUNTER_VALUE, value->initial_counter_value); + CHECK_RESULT(ctx, result); + } + } + + if(ctx->version >= KMIP_1_4) + { + if(value->salt_length != KMIP_UNSET) + { + result = kmip_encode_integer(ctx, KMIP_TAG_SALT_LENGTH, value->salt_length); + CHECK_RESULT(ctx, result); + } + + if(value->mask_generator != 0) + { + result = kmip_encode_enum(ctx, KMIP_TAG_MASK_GENERATOR, value->mask_generator); + CHECK_RESULT(ctx, result); + } + + if(value->mask_generator_hashing_algorithm != 0) + { + result = kmip_encode_enum(ctx, KMIP_TAG_MASK_GENERATOR_HASHING_ALGORITHM, value->mask_generator_hashing_algorithm); + CHECK_RESULT(ctx, result); + } + + if(value->p_source != NULL) + { + result = kmip_encode_byte_string(ctx, KMIP_TAG_P_SOURCE, value->p_source); + CHECK_RESULT(ctx, result); + } + + if(value->trailer_field != KMIP_UNSET) + { + result = kmip_encode_integer(ctx, KMIP_TAG_TRAILER_FIELD, value->trailer_field); + 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_encryption_key_information(KMIP *ctx, const EncryptionKeyInformation *value) +{ + int result = 0; + result = kmip_encode_int32_be(ctx, TAG_TYPE(KMIP_TAG_ENCRYPTION_KEY_INFORMATION, 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); + + if(value->cryptographic_parameters != 0) + { + result = kmip_encode_cryptographic_parameters(ctx, value->cryptographic_parameters); + 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_mac_signature_key_information(KMIP *ctx, const MACSignatureKeyInformation *value) +{ + int result = 0; + result = kmip_encode_int32_be(ctx, TAG_TYPE(KMIP_TAG_MAC_SIGNATURE_KEY_INFORMATION, 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); + + if(value->cryptographic_parameters != 0) + { + result = kmip_encode_cryptographic_parameters(ctx, value->cryptographic_parameters); + 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_key_wrapping_data(KMIP *ctx, const KeyWrappingData *value) +{ + int result = 0; + result = kmip_encode_int32_be(ctx, TAG_TYPE(KMIP_TAG_KEY_WRAPPING_DATA, KMIP_TYPE_STRUCTURE)); + CHECK_RESULT(ctx, result); + + uint8 *length_index = ctx->index; + uint8 *value_index = ctx->index += 4; + + result = kmip_encode_enum(ctx, KMIP_TAG_WRAPPING_METHOD, value->wrapping_method); + CHECK_RESULT(ctx, result); + + if(value->encryption_key_info != NULL) + { + result = kmip_encode_encryption_key_information(ctx, value->encryption_key_info); + CHECK_RESULT(ctx, result); + } + + if(value->mac_signature_key_info != NULL) + { + result = kmip_encode_mac_signature_key_information(ctx, value->mac_signature_key_info); + CHECK_RESULT(ctx, result); + } + + if(value->mac_signature != NULL) + { + result = kmip_encode_byte_string(ctx, KMIP_TAG_MAC_SIGNATURE, value->mac_signature); + CHECK_RESULT(ctx, result); + } + + if(value->iv_counter_nonce != NULL) + { + result = kmip_encode_byte_string(ctx, KMIP_TAG_IV_COUNTER_NONCE, value->iv_counter_nonce); + CHECK_RESULT(ctx, result); + } + + if(ctx->version >= KMIP_1_1) + { + result = kmip_encode_enum(ctx, KMIP_TAG_ENCODING_OPTION, value->encoding_option); + 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_transparent_symmetric_key(KMIP *ctx, const TransparentSymmetricKey *value) +{ + int result = 0; + + result = kmip_encode_int32_be(ctx, TAG_TYPE(KMIP_TAG_KEY_MATERIAL, KMIP_TYPE_STRUCTURE)); + CHECK_RESULT(ctx, result); + + uint8 *length_index = ctx->index; + uint8 *value_index = ctx->index += 4; + + result = kmip_encode_byte_string(ctx, KMIP_TAG_KEY, value->key); + 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_key_material(KMIP *ctx, enum key_format_type format, const void *value) +{ + int result = 0; + + switch(format) + { + case KMIP_KEYFORMAT_RAW: + case KMIP_KEYFORMAT_OPAQUE: + case KMIP_KEYFORMAT_PKCS1: + case KMIP_KEYFORMAT_PKCS8: + case KMIP_KEYFORMAT_X509: + case KMIP_KEYFORMAT_EC_PRIVATE_KEY: + result = kmip_encode_byte_string(ctx, KMIP_TAG_KEY_MATERIAL, (ByteString*)value); + CHECK_RESULT(ctx, result); + return(KMIP_OK); + break; + + default: + break; + }; + + switch(format) + { + case KMIP_KEYFORMAT_TRANS_SYMMETRIC_KEY: + result = kmip_encode_transparent_symmetric_key(ctx, (TransparentSymmetricKey*)value); + CHECK_RESULT(ctx, result); + break; + + /* TODO (ph) The rest require BigInteger support. */ + + case KMIP_KEYFORMAT_TRANS_DSA_PRIVATE_KEY: + kmip_push_error_frame(ctx, __func__, __LINE__); + return(KMIP_NOT_IMPLEMENTED); + break; + + case KMIP_KEYFORMAT_TRANS_DSA_PUBLIC_KEY: + kmip_push_error_frame(ctx, __func__, __LINE__); + return(KMIP_NOT_IMPLEMENTED); + break; + + case KMIP_KEYFORMAT_TRANS_RSA_PRIVATE_KEY: + kmip_push_error_frame(ctx, __func__, __LINE__); + return(KMIP_NOT_IMPLEMENTED); + break; + + case KMIP_KEYFORMAT_TRANS_RSA_PUBLIC_KEY: + kmip_push_error_frame(ctx, __func__, __LINE__); + return(KMIP_NOT_IMPLEMENTED); + break; + + case KMIP_KEYFORMAT_TRANS_DH_PRIVATE_KEY: + kmip_push_error_frame(ctx, __func__, __LINE__); + return(KMIP_NOT_IMPLEMENTED); + break; + + case KMIP_KEYFORMAT_TRANS_DH_PUBLIC_KEY: + kmip_push_error_frame(ctx, __func__, __LINE__); + return(KMIP_NOT_IMPLEMENTED); + break; + + case KMIP_KEYFORMAT_TRANS_ECDSA_PRIVATE_KEY: + kmip_push_error_frame(ctx, __func__, __LINE__); + return(KMIP_NOT_IMPLEMENTED); + break; + + case KMIP_KEYFORMAT_TRANS_ECDSA_PUBLIC_KEY: + kmip_push_error_frame(ctx, __func__, __LINE__); + return(KMIP_NOT_IMPLEMENTED); + break; + + case KMIP_KEYFORMAT_TRANS_ECDH_PRIVATE_KEY: + kmip_push_error_frame(ctx, __func__, __LINE__); + return(KMIP_NOT_IMPLEMENTED); + break; + + case KMIP_KEYFORMAT_TRANS_ECDH_PUBLIC_KEY: + kmip_push_error_frame(ctx, __func__, __LINE__); + return(KMIP_NOT_IMPLEMENTED); + break; + + case KMIP_KEYFORMAT_TRANS_ECMQV_PRIVATE_KEY: + kmip_push_error_frame(ctx, __func__, __LINE__); + return(KMIP_NOT_IMPLEMENTED); + break; + + case KMIP_KEYFORMAT_TRANS_ECMQV_PUBLIC_KEY: + kmip_push_error_frame(ctx, __func__, __LINE__); + return(KMIP_NOT_IMPLEMENTED); + break; + + default: + kmip_push_error_frame(ctx, __func__, __LINE__); + return(KMIP_NOT_IMPLEMENTED); + break; + }; + + return(KMIP_OK); +} + +int +kmip_encode_key_value(KMIP *ctx, enum key_format_type format, const KeyValue *value) +{ + int result = 0; + result = kmip_encode_int32_be(ctx, TAG_TYPE(KMIP_TAG_KEY_VALUE, KMIP_TYPE_STRUCTURE)); + CHECK_RESULT(ctx, result); + + uint8 *length_index = ctx->index; + uint8 *value_index = ctx->index += 4; + + result = kmip_encode_key_material(ctx, format, value->key_material); + CHECK_RESULT(ctx, result); + + for(size_t i = 0; i < value->attribute_count; i++) + { + result = kmip_encode_attribute(ctx, &value->attributes[i]); + 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_key_block(KMIP *ctx, const KeyBlock *value) +{ + int result = 0; + result = kmip_encode_int32_be(ctx, TAG_TYPE(KMIP_TAG_KEY_BLOCK, KMIP_TYPE_STRUCTURE)); + CHECK_RESULT(ctx, result); + + uint8 *length_index = ctx->index; + uint8 *value_index = ctx->index += 4; + + result = kmip_encode_enum(ctx, KMIP_TAG_KEY_FORMAT_TYPE, value->key_format_type); + CHECK_RESULT(ctx, result); + + if(value->key_compression_type != 0) + { + result = kmip_encode_enum(ctx, KMIP_TAG_KEY_COMPRESSION_TYPE, value->key_compression_type); + CHECK_RESULT(ctx, result); + } + + if(value->key_wrapping_data != NULL) + { + result = kmip_encode_byte_string(ctx, KMIP_TAG_KEY_VALUE, (ByteString*)value->key_value); + } + else + { + result = kmip_encode_key_value(ctx, value->key_format_type, (KeyValue*)value->key_value); + } + CHECK_RESULT(ctx, result); + + if(value->cryptographic_algorithm != 0) + { + result = kmip_encode_enum(ctx, KMIP_TAG_CRYPTOGRAPHIC_ALGORITHM, value->cryptographic_algorithm); + CHECK_RESULT(ctx, result); + } + + if(value->cryptographic_length != KMIP_UNSET) + { + result = kmip_encode_integer(ctx, KMIP_TAG_CRYPTOGRAPHIC_LENGTH, value->cryptographic_length); + CHECK_RESULT(ctx, result); + } + + if(value->key_wrapping_data != NULL) + { + result = kmip_encode_key_wrapping_data(ctx, value->key_wrapping_data); + 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_symmetric_key(KMIP *ctx, const SymmetricKey *value) +{ + int result = 0; + result = kmip_encode_int32_be(ctx, TAG_TYPE(KMIP_TAG_SYMMETRIC_KEY, KMIP_TYPE_STRUCTURE)); + CHECK_RESULT(ctx, result); + + uint8 *length_index = ctx->index; + uint8 *value_index = ctx->index += 4; + + result = kmip_encode_key_block(ctx, value->key_block); + 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_public_key(KMIP *ctx, const PublicKey *value) +{ + int result = 0; + result = kmip_encode_int32_be(ctx, TAG_TYPE(KMIP_TAG_PUBLIC_KEY, KMIP_TYPE_STRUCTURE)); + CHECK_RESULT(ctx, result); + + uint8 *length_index = ctx->index; + uint8 *value_index = ctx->index += 4; + + result = kmip_encode_key_block(ctx, value->key_block); + 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_private_key(KMIP *ctx, const PrivateKey *value) +{ + int result = 0; + result = kmip_encode_int32_be(ctx, TAG_TYPE(KMIP_TAG_PRIVATE_KEY, KMIP_TYPE_STRUCTURE)); + CHECK_RESULT(ctx, result); + + uint8 *length_index = ctx->index; + uint8 *value_index = ctx->index += 4; + + result = kmip_encode_key_block(ctx, value->key_block); + 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_key_wrapping_specification(KMIP *ctx, const KeyWrappingSpecification *value) +{ + int result = 0; + result = kmip_encode_int32_be(ctx, TAG_TYPE(KMIP_TAG_KEY_WRAPPING_SPECIFICATION, KMIP_TYPE_STRUCTURE)); + CHECK_RESULT(ctx, result); + + uint8 *length_index = ctx->index; + uint8 *value_index = ctx->index += 4; + + result = kmip_encode_enum(ctx, KMIP_TAG_WRAPPING_METHOD, value->wrapping_method); + CHECK_RESULT(ctx, result); + + if(value->encryption_key_info != NULL) + { + result = kmip_encode_encryption_key_information(ctx, value->encryption_key_info); + CHECK_RESULT(ctx, result); + } + + if(value->mac_signature_key_info != NULL) + { + result = kmip_encode_mac_signature_key_information(ctx, value->mac_signature_key_info); + CHECK_RESULT(ctx, result); + } + + for(size_t i = 0; i < value->attribute_name_count; i++) + { + result = kmip_encode_text_string(ctx, KMIP_TAG_ATTRIBUTE_NAME, &value->attribute_names[i]); + CHECK_RESULT(ctx, result); + } + + if(ctx->version >= KMIP_1_1) + { + result = kmip_encode_enum(ctx, KMIP_TAG_ENCODING_OPTION, value->encoding_option); + 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_create_request_payload(KMIP *ctx, const CreateRequestPayload *value) +{ + CHECK_ENCODE_ARGS(ctx, 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; + + result = kmip_encode_enum(ctx, KMIP_TAG_OBJECT_TYPE, value->object_type); + CHECK_RESULT(ctx, result); + + if(ctx->version < KMIP_2_0) + { + result = kmip_encode_template_attribute(ctx, value->template_attribute); + CHECK_RESULT(ctx, result); + } + else + { + if(value->attributes) + { + result = kmip_encode_attributes(ctx, value->attributes); + CHECK_RESULT(ctx, result); + } + else if(value->template_attribute) + { + Attributes *attributes = ctx->calloc_func(ctx->state, 1, sizeof(Attributes)); + LinkedList *list = ctx->calloc_func(ctx->state, 1, sizeof(LinkedList)); + attributes->attribute_list = list; + for(size_t i = 0; i < value->template_attribute->attribute_count; i++) + { + LinkedListItem *item = ctx->calloc_func(ctx->state, 1, sizeof(LinkedListItem)); + item->data = kmip_deep_copy_attribute(ctx, &value->template_attribute->attributes[i]); + kmip_linked_list_enqueue(list, item); + } + + result = kmip_encode_attributes(ctx, attributes); + + kmip_free_attributes(ctx, attributes); + ctx->free_func(ctx->state, attributes); + + CHECK_RESULT(ctx, result); + } + + if(value->protection_storage_masks != NULL) + { + result = kmip_encode_protection_storage_masks(ctx, value->protection_storage_masks); + 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_create_response_payload(KMIP *ctx, const CreateResponsePayload *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; + + result = kmip_encode_enum(ctx, KMIP_TAG_OBJECT_TYPE, value->object_type); + CHECK_RESULT(ctx, result); + + result = kmip_encode_text_string(ctx, KMIP_TAG_UNIQUE_IDENTIFIER, value->unique_identifier); + CHECK_RESULT(ctx, result); + + if(ctx->version < KMIP_2_0) + { + if(value->template_attribute != NULL) + { + result = kmip_encode_template_attribute(ctx, value->template_attribute); + 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_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 != 0) + { + result = kmip_encode_enum(ctx, KMIP_TAG_MAXIMUM_ITEMS, value->maximum_items); + CHECK_RESULT(ctx, result); + } + + if(value->offset_items != 0) + { + result = kmip_encode_enum(ctx, KMIP_TAG_OFFSET_ITEMS, value->offset_items); + CHECK_RESULT(ctx, result); + } + + if(value->storage_status_mask != 0) + { + result = kmip_encode_enum(ctx, KMIP_TAG_STORAGE_STATUS_MASK, value->storage_status_mask); + CHECK_RESULT(ctx, result); + } + + if(value->object_group_member != 0) + { + result = kmip_encode_enum(ctx, KMIP_TAG_OBJECT_GROUP_MEMBER, value->object_group_member); + CHECK_RESULT(ctx, result); + } + + if (value->attributes) + { + if(ctx->version < KMIP_2_0) + { + for(int i = 0; i < value->attribute_count; ++i) + { + result = kmip_encode_attribute(ctx, value->attributes + i); + CHECK_RESULT(ctx, result); + } + } else { + result = kmip_encode_attributes_2(ctx, value->attributes, value->attribute_count); + 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) +{ + 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->located_items != 0) + { + result = kmip_encode_enum(ctx, KMIP_TAG_LOCATED_ITEMS, value->located_items); + CHECK_RESULT(ctx, result); + } + + if (value->unique_identifiers) { + for(int i = 0; i < value->unique_identifiers_count; ++i) + { + result = kmip_encode_text_string(ctx, KMIP_TAG_UNIQUE_IDENTIFIER, value->unique_identifiers + i); + 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_request_payload(KMIP *ctx, const GetRequestPayload *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->key_format_type != 0) + { + result = kmip_encode_enum(ctx, KMIP_TAG_KEY_FORMAT_TYPE, value->key_format_type); + CHECK_RESULT(ctx, result); + } + + if(ctx->version >= KMIP_1_4) + { + if(value->key_wrap_type != 0) + { + result = kmip_encode_enum(ctx, KMIP_TAG_KEY_WRAP_TYPE, value->key_wrap_type); + CHECK_RESULT(ctx, result); + } + } + + if(value->key_compression_type != 0) + { + result = kmip_encode_enum(ctx, KMIP_TAG_KEY_COMPRESSION_TYPE, value->key_compression_type); + CHECK_RESULT(ctx, result); + } + + if(value->key_wrapping_spec != NULL) + { + result = kmip_encode_key_wrapping_specification(ctx, value->key_wrapping_spec); + 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_response_payload(KMIP *ctx, const GetResponsePayload *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_enum(ctx, KMIP_TAG_OBJECT_TYPE, value->object_type); + CHECK_RESULT(ctx, result); + + result = kmip_encode_text_string(ctx, KMIP_TAG_UNIQUE_IDENTIFIER, value->unique_identifier); + CHECK_RESULT(ctx, result); + + switch(value->object_type) + { + case KMIP_OBJTYPE_SYMMETRIC_KEY: + result = kmip_encode_symmetric_key(ctx, (const SymmetricKey*)value->object); + CHECK_RESULT(ctx, result); + break; + + case KMIP_OBJTYPE_PUBLIC_KEY: + result = kmip_encode_public_key(ctx, (const PublicKey*)value->object); + CHECK_RESULT(ctx, result); + break; + + case KMIP_OBJTYPE_PRIVATE_KEY: + result = kmip_encode_private_key(ctx, (const PrivateKey*)value->object); + CHECK_RESULT(ctx, result); + break; + + default: + kmip_push_error_frame(ctx, __func__, __LINE__); + return(KMIP_NOT_IMPLEMENTED); + break; + }; + + 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_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) { + for(int i = 0; i < value->attribute_count; ++i) + { + result = kmip_encode_attribute_name(ctx, value->attribute_names[i]); + 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; + + result = kmip_encode_text_string(ctx, KMIP_TAG_UNIQUE_IDENTIFIER, value->unique_identifier); + CHECK_RESULT(ctx, result); + + if (value->attributes) + { + if(ctx->version < KMIP_2_0) + { + for(int i = 0; i < value->attribute_count; ++i) + { + result = kmip_encode_attribute(ctx, value->attributes + i); + CHECK_RESULT(ctx, result); + } + } else { + result = kmip_encode_attributes_2(ctx, value->attributes, value->attribute_count); + 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_attribute_list_request_payload(KMIP *ctx, const GetAttributeListRequestPayload *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; + + kmip_encode_int32_be(ctx, curr_index - value_index); + + ctx->index = curr_index; + + return(KMIP_OK); +} + +int +kmip_encode_get_attribute_list_response_payload(KMIP *ctx, const GetAttributeListResponsePayload *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); + + if (value->attribute_names) { + for(int i = 0; i < value->attribute_names_count; ++i) + { + result = kmip_encode_attribute_name(ctx, value->attribute_names[i]); + 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_destroy_request_payload(KMIP *ctx, const DestroyRequestPayload *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; + + kmip_encode_int32_be(ctx, curr_index - value_index); + + ctx->index = curr_index; + + return(KMIP_OK); +} + +int +kmip_encode_destroy_response_payload(KMIP *ctx, const DestroyResponsePayload *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; + + 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) +{ + int result = 0; + result = kmip_encode_int32_be(ctx, TAG_TYPE(KMIP_TAG_NONCE, KMIP_TYPE_STRUCTURE)); + CHECK_RESULT(ctx, result); + + uint8 *length_index = ctx->index; + uint8 *value_index = ctx->index += 4; + + result = kmip_encode_byte_string(ctx, KMIP_TAG_NONCE_ID, value->nonce_id); + CHECK_RESULT(ctx, result); + + result = kmip_encode_byte_string(ctx, KMIP_TAG_NONCE_VALUE, value->nonce_value); + 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_username_password_credential(KMIP *ctx, const UsernamePasswordCredential *value) +{ + int result = 0; + result = kmip_encode_int32_be(ctx, TAG_TYPE(KMIP_TAG_CREDENTIAL_VALUE, 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_USERNAME, value->username); + CHECK_RESULT(ctx, result); + + if(value->password != NULL) + { + result = kmip_encode_text_string(ctx, KMIP_TAG_PASSWORD, value->password); + 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_device_credential(KMIP *ctx, const DeviceCredential *value) +{ + int result = 0; + result = kmip_encode_int32_be(ctx, TAG_TYPE(KMIP_TAG_CREDENTIAL_VALUE, KMIP_TYPE_STRUCTURE)); + CHECK_RESULT(ctx, result); + + uint8 *length_index = ctx->index; + uint8 *value_index = ctx->index += 4; + + if(value->device_serial_number != NULL) + { + result = kmip_encode_text_string(ctx, KMIP_TAG_DEVICE_SERIAL_NUMBER, value->device_serial_number); + CHECK_RESULT(ctx, result); + } + + if(value->password != NULL) + { + result = kmip_encode_text_string(ctx, KMIP_TAG_PASSWORD, value->password); + CHECK_RESULT(ctx, result); + } + + if(value->device_identifier != NULL) + { + result = kmip_encode_text_string(ctx, KMIP_TAG_DEVICE_IDENTIFIER, value->device_identifier); + CHECK_RESULT(ctx, result); + } + + if(value->network_identifier != NULL) + { + result = kmip_encode_text_string(ctx, KMIP_TAG_NETWORK_IDENTIFIER, value->network_identifier); + CHECK_RESULT(ctx, result); + } + + if(value->machine_identifier != NULL) + { + result = kmip_encode_text_string(ctx, KMIP_TAG_MACHINE_IDENTIFIER, value->machine_identifier); + CHECK_RESULT(ctx, result); + } + + if(value->media_identifier != NULL) + { + result = kmip_encode_text_string(ctx, KMIP_TAG_MEDIA_IDENTIFIER, value->media_identifier); + 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_attestation_credential(KMIP *ctx, const AttestationCredential *value) +{ + int result = 0; + result = kmip_encode_int32_be(ctx, TAG_TYPE(KMIP_TAG_CREDENTIAL_VALUE, KMIP_TYPE_STRUCTURE)); + CHECK_RESULT(ctx, result); + + uint8 *length_index = ctx->index; + uint8 *value_index = ctx->index += 4; + + result = kmip_encode_nonce(ctx, value->nonce); + CHECK_RESULT(ctx, result); + + result = kmip_encode_enum(ctx, KMIP_TAG_ATTESTATION_TYPE, value->attestation_type); + CHECK_RESULT(ctx, result); + + if(value->attestation_measurement != NULL) + { + result = kmip_encode_byte_string(ctx, KMIP_TAG_ATTESTATION_MEASUREMENT, value->attestation_measurement); + CHECK_RESULT(ctx, result); + } + + if(value->attestation_assertion != NULL) + { + result = kmip_encode_byte_string(ctx, KMIP_TAG_ATTESTATION_ASSERTION, value->attestation_assertion); + 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_credential_value(KMIP *ctx, enum credential_type type, void *value) +{ + int result = 0; + + switch(type) + { + case KMIP_CRED_USERNAME_AND_PASSWORD: + result = kmip_encode_username_password_credential(ctx, (UsernamePasswordCredential*)value); + break; + + case KMIP_CRED_DEVICE: + result = kmip_encode_device_credential(ctx, (DeviceCredential*)value); + break; + + case KMIP_CRED_ATTESTATION: + result = kmip_encode_attestation_credential(ctx, (AttestationCredential*)value); + break; + + default: + kmip_push_error_frame(ctx, __func__, __LINE__); + return(KMIP_NOT_IMPLEMENTED); + break; + } + CHECK_RESULT(ctx, result); + + return(KMIP_OK); +} + +int +kmip_encode_credential(KMIP *ctx, const Credential *value) +{ + int result = 0; + result = kmip_encode_int32_be(ctx, TAG_TYPE(KMIP_TAG_CREDENTIAL, KMIP_TYPE_STRUCTURE)); + CHECK_RESULT(ctx, result); + + uint8 *length_index = ctx->index; + uint8 *value_index = ctx->index += 4; + + result = kmip_encode_enum(ctx, KMIP_TAG_CREDENTIAL_TYPE, value->credential_type); + CHECK_RESULT(ctx, result); + + result = kmip_encode_credential_value(ctx, value->credential_type, value->credential_value); + 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_authentication(KMIP *ctx, const Authentication *value) +{ + int result = 0; + result = kmip_encode_int32_be(ctx, TAG_TYPE(KMIP_TAG_AUTHENTICATION, KMIP_TYPE_STRUCTURE)); + CHECK_RESULT(ctx, result); + + uint8 *length_index = ctx->index; + uint8 *value_index = ctx->index += 4; + + result = kmip_encode_credential(ctx, value->credential); + 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_request_header(KMIP *ctx, const RequestHeader *value) +{ + int result = 0; + result = kmip_encode_int32_be(ctx, TAG_TYPE(KMIP_TAG_REQUEST_HEADER, KMIP_TYPE_STRUCTURE)); + CHECK_RESULT(ctx, result); + + uint8 *length_index = ctx->index; + uint8 *value_index = ctx->index += 4; + + result = kmip_encode_protocol_version(ctx, value->protocol_version); + CHECK_RESULT(ctx, result); + + /* HERE (ph) Stopped working here after bug with 0 vs KMIP_UNSET */ + if(value->maximum_response_size != KMIP_UNSET) + { + result = kmip_encode_integer(ctx, KMIP_TAG_MAXIMUM_RESPONSE_SIZE, value->maximum_response_size); + CHECK_RESULT(ctx, result); + } + + if(ctx->version >= KMIP_1_4) + { + if(value->client_correlation_value != NULL) + { + result = kmip_encode_text_string(ctx, KMIP_TAG_CLIENT_CORRELATION_VALUE, value->client_correlation_value); + CHECK_RESULT(ctx, result); + } + + if(value->server_correlation_value != NULL) + { + result = kmip_encode_text_string(ctx, KMIP_TAG_SERVER_CORRELATION_VALUE, value->server_correlation_value); + CHECK_RESULT(ctx, result); + } + } + + if(value->asynchronous_indicator != KMIP_UNSET) + { + result = kmip_encode_bool(ctx, KMIP_TAG_ASYNCHRONOUS_INDICATOR, value->asynchronous_indicator); + CHECK_RESULT(ctx, result); + } + + if(ctx->version >= KMIP_1_2) + { + if(value->attestation_capable_indicator != KMIP_UNSET) + { + result = kmip_encode_bool(ctx, KMIP_TAG_ATTESTATION_CAPABLE_INDICATOR, value->attestation_capable_indicator); + CHECK_RESULT(ctx, result); + } + + for(size_t i = 0; i < value->attestation_type_count; i++) + { + result = kmip_encode_enum(ctx, KMIP_TAG_ATTESTATION_TYPE, value->attestation_types[i]); + CHECK_RESULT(ctx, result); + } + } + + if(value->authentication != NULL) + { + result = kmip_encode_authentication(ctx, value->authentication); + CHECK_RESULT(ctx, result); + } + + if(value->batch_error_continuation_option != 0) + { + result = kmip_encode_enum(ctx, KMIP_TAG_BATCH_ERROR_CONTINUATION_OPTION, value->batch_error_continuation_option); + CHECK_RESULT(ctx, result); + } + + if(value->batch_order_option != KMIP_UNSET) + { + result = kmip_encode_bool(ctx, KMIP_TAG_BATCH_ORDER_OPTION, value->batch_order_option); + CHECK_RESULT(ctx, result); + } + + if(value->time_stamp != 0) + { + result = kmip_encode_date_time(ctx, KMIP_TAG_TIME_STAMP, value->time_stamp); + CHECK_RESULT(ctx, result); + } + + result = kmip_encode_integer(ctx, KMIP_TAG_BATCH_COUNT, value->batch_count); + 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_response_header(KMIP *ctx, const ResponseHeader *value) +{ + int result = 0; + result = kmip_encode_int32_be(ctx, TAG_TYPE(KMIP_TAG_RESPONSE_HEADER, KMIP_TYPE_STRUCTURE)); + CHECK_RESULT(ctx, result); + + uint8 *length_index = ctx->index; + uint8 *value_index = ctx->index += 4; + + result = kmip_encode_protocol_version(ctx, value->protocol_version); + CHECK_RESULT(ctx, result); + + result = kmip_encode_date_time(ctx, KMIP_TAG_TIME_STAMP, value->time_stamp); + CHECK_RESULT(ctx, result); + + if(ctx->version >= KMIP_1_2) + { + if(value->nonce != NULL) + { + result = kmip_encode_nonce(ctx, value->nonce); + CHECK_RESULT(ctx, result); + } + + if(ctx->version >= KMIP_2_0) + { + if(value->server_hashed_password != NULL) + { + result = kmip_encode_byte_string(ctx, KMIP_TAG_SERVER_HASHED_PASSWORD, value->server_hashed_password); + CHECK_RESULT(ctx, result); + } + } + + for(size_t i = 0; i < value->attestation_type_count; i++) + { + result = kmip_encode_enum(ctx, KMIP_TAG_ATTESTATION_TYPE, value->attestation_types[i]); + CHECK_RESULT(ctx, result); + } + } + + if(ctx->version >= KMIP_1_4) + { + if(value->client_correlation_value != NULL) + { + result = kmip_encode_text_string(ctx, KMIP_TAG_CLIENT_CORRELATION_VALUE, value->client_correlation_value); + CHECK_RESULT(ctx, result); + } + + if(value->server_correlation_value != NULL) + { + result = kmip_encode_text_string(ctx, KMIP_TAG_SERVER_CORRELATION_VALUE, value->server_correlation_value); + CHECK_RESULT(ctx, result); + } + } + + result = kmip_encode_integer(ctx, KMIP_TAG_BATCH_COUNT, value->batch_count); + 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_request_batch_item(KMIP *ctx, const RequestBatchItem *value) +{ + CHECK_ENCODE_ARGS(ctx, value); + + int result = 0; + result = kmip_encode_int32_be(ctx, TAG_TYPE(KMIP_TAG_BATCH_ITEM, KMIP_TYPE_STRUCTURE)); + CHECK_RESULT(ctx, result); + + uint8 *length_index = ctx->index; + uint8 *value_index = ctx->index += 4; + + result = kmip_encode_enum(ctx, KMIP_TAG_OPERATION, value->operation); + CHECK_RESULT(ctx, result); + + if(ctx->version >= KMIP_2_0) + { + if(value->ephemeral != KMIP_UNSET) + { + result=kmip_encode_bool(ctx, KMIP_TAG_EPHEMERAL, value->ephemeral); + CHECK_RESULT(ctx, result); + } + } + + if(value->unique_batch_item_id != NULL) + { + result = kmip_encode_byte_string(ctx, KMIP_TAG_UNIQUE_BATCH_ITEM_ID, value->unique_batch_item_id); + CHECK_RESULT(ctx, result); + } + + switch(value->operation) + { + case KMIP_OP_CREATE: + result = kmip_encode_create_request_payload(ctx, (CreateRequestPayload*)value->request_payload); + break; + + case KMIP_OP_LOCATE: + result = kmip_encode_locate_request_payload(ctx, (LocateRequestPayload*)value->request_payload); + break; + + case KMIP_OP_GET: + result = kmip_encode_get_request_payload(ctx, (GetRequestPayload*)value->request_payload); + break; + + case KMIP_OP_GET_ATTRIBUTES: + result = kmip_encode_get_attributes_request_payload(ctx, (GetAttributesRequestPayload*)value->request_payload); + break; + + case KMIP_OP_GET_ATTRIBUTE_LIST: + result = kmip_encode_get_attribute_list_request_payload(ctx, (GetAttributeListRequestPayload*)value->request_payload); + break; + + case KMIP_OP_DESTROY: + result = kmip_encode_destroy_request_payload(ctx, (DestroyRequestPayload*)value->request_payload); + break; + + default: + kmip_push_error_frame(ctx, __func__, __LINE__); + return(KMIP_NOT_IMPLEMENTED); + break; + }; + 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_response_batch_item(KMIP *ctx, const ResponseBatchItem *value) +{ + int result = 0; + result = kmip_encode_int32_be(ctx, TAG_TYPE(KMIP_TAG_BATCH_ITEM, KMIP_TYPE_STRUCTURE)); + CHECK_RESULT(ctx, result); + + uint8 *length_index = ctx->index; + uint8 *value_index = ctx->index += 4; + + result = kmip_encode_enum(ctx, KMIP_TAG_OPERATION, value->operation); + CHECK_RESULT(ctx, result); + + if(value->unique_batch_item_id != NULL) + { + result = kmip_encode_byte_string(ctx, KMIP_TAG_UNIQUE_BATCH_ITEM_ID, value->unique_batch_item_id); + CHECK_RESULT(ctx, result); + } + + result = kmip_encode_enum(ctx, KMIP_TAG_RESULT_STATUS, value->result_status); + CHECK_RESULT(ctx, result); + + if(value->result_reason != 0) + { + result = kmip_encode_enum(ctx, KMIP_TAG_RESULT_REASON, value->result_reason); + CHECK_RESULT(ctx, result); + } + + if(value->result_message != NULL) + { + result = kmip_encode_text_string(ctx, KMIP_TAG_RESULT_MESSAGE, value->result_message); + CHECK_RESULT(ctx, result); + } + + if(value->asynchronous_correlation_value != NULL) + { + result = kmip_encode_byte_string(ctx, KMIP_TAG_ASYNCHRONOUS_CORRELATION_VALUE, value->asynchronous_correlation_value); + CHECK_RESULT(ctx, result); + } + + switch(value->operation) + { + case KMIP_OP_CREATE: + result = kmip_encode_create_response_payload(ctx, (CreateResponsePayload*)value->response_payload); + break; + + case KMIP_OP_LOCATE: + result = kmip_encode_locate_response_payload(ctx, (LocateResponsePayload*)value->response_payload); + break; + + case KMIP_OP_GET: + result = kmip_encode_get_response_payload(ctx, (GetResponsePayload*)value->response_payload); + break; + + case KMIP_OP_GET_ATTRIBUTES: + result = kmip_encode_get_attributes_response_payload(ctx, (GetAttributesResponsePayload*)value->response_payload); + break; + + case KMIP_OP_GET_ATTRIBUTE_LIST: + result = kmip_encode_get_attribute_list_response_payload(ctx, (GetAttributeListResponsePayload*)value->response_payload); + break; + + case KMIP_OP_DESTROY: + result = kmip_encode_destroy_response_payload(ctx, (DestroyResponsePayload*)value->response_payload); + break; + + default: + kmip_push_error_frame(ctx, __func__, __LINE__); + return(KMIP_NOT_IMPLEMENTED); + break; + }; + 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_request_message(KMIP *ctx, const RequestMessage *value) +{ + int result = 0; + result = kmip_encode_int32_be(ctx, TAG_TYPE(KMIP_TAG_REQUEST_MESSAGE, KMIP_TYPE_STRUCTURE)); + CHECK_RESULT(ctx, result); + + uint8 *length_index = ctx->index; + uint8 *value_index = ctx->index += 4; + + result = kmip_encode_request_header(ctx, value->request_header); + CHECK_RESULT(ctx, result); + + for(size_t i = 0; i < value->batch_count; i++) + { + result = kmip_encode_request_batch_item(ctx, &value->batch_items[i]); + 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_response_message(KMIP *ctx, const ResponseMessage *value) +{ + int result = 0; + result = kmip_encode_int32_be(ctx, TAG_TYPE(KMIP_TAG_RESPONSE_MESSAGE, KMIP_TYPE_STRUCTURE)); + CHECK_RESULT(ctx, result); + + uint8 *length_index = ctx->index; + uint8 *value_index = ctx->index += 4; + + result = kmip_encode_response_header(ctx, value->response_header); + CHECK_RESULT(ctx, result); + + for(size_t i = 0; i < value->batch_count; i++) + { + result = kmip_encode_response_batch_item(ctx, &value->batch_items[i]); + 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); +} + +/* +Decoding Functions +*/ + +int +kmip_decode_int8_be(KMIP *ctx, void *value) +{ + CHECK_BUFFER_FULL(ctx, sizeof(int8)); + + int8 *i = (int8*)value; + + *i = 0; + *i = *ctx->index++; + + return(KMIP_OK); +} + +int +kmip_decode_int32_be(KMIP *ctx, void *value) +{ + CHECK_BUFFER_FULL(ctx, sizeof(int32)); + + int32 *i = (int32*)value; + + *i = 0; + *i |= ((int32)*ctx->index++ << 24); + *i |= ((int32)*ctx->index++ << 16); + *i |= ((int32)*ctx->index++ << 8); + *i |= ((int32)*ctx->index++ << 0); + + return(KMIP_OK); +} + +int +kmip_decode_int64_be(KMIP *ctx, void *value) +{ + CHECK_BUFFER_FULL(ctx, sizeof(int64)); + + int64 *i = (int64*)value; + + *i = 0; + *i |= ((int64)*ctx->index++ << 56); + *i |= ((int64)*ctx->index++ << 48); + *i |= ((int64)*ctx->index++ << 40); + *i |= ((int64)*ctx->index++ << 32); + *i |= ((int64)*ctx->index++ << 24); + *i |= ((int64)*ctx->index++ << 16); + *i |= ((int64)*ctx->index++ << 8); + *i |= ((int64)*ctx->index++ << 0); + + return(KMIP_OK); +} + +int +kmip_decode_integer(KMIP *ctx, enum tag t, int32 *value) +{ + CHECK_BUFFER_FULL(ctx, 16); + + int32 tag_type = 0; + int32 length = 0; + int32 padding = 0; + + kmip_decode_int32_be(ctx, &tag_type); + CHECK_TAG_TYPE(ctx, tag_type, t, KMIP_TYPE_INTEGER); + + kmip_decode_int32_be(ctx, &length); + CHECK_LENGTH(ctx, length, 4); + + kmip_decode_int32_be(ctx, value); + + kmip_decode_int32_be(ctx, &padding); + CHECK_PADDING(ctx, padding); + + return(KMIP_OK); +} + +int +kmip_decode_long(KMIP *ctx, enum tag t, int64 *value) +{ + CHECK_BUFFER_FULL(ctx, 16); + + int32 tag_type = 0; + int32 length = 0; + + kmip_decode_int32_be(ctx, &tag_type); + CHECK_TAG_TYPE(ctx, tag_type, t, KMIP_TYPE_LONG_INTEGER); + + kmip_decode_int32_be(ctx, &length); + CHECK_LENGTH(ctx, length, 8); + + kmip_decode_int64_be(ctx, value); + + return(KMIP_OK); +} + +int +kmip_decode_enum(KMIP *ctx, enum tag t, void *value) +{ + CHECK_BUFFER_FULL(ctx, 16); + + int32 tag_type = 0; + int32 length = 0; + int32 *v = (int32*)value; + int32 padding = 0; + + kmip_decode_int32_be(ctx, &tag_type); + CHECK_TAG_TYPE(ctx, tag_type, t, KMIP_TYPE_ENUMERATION); + + kmip_decode_int32_be(ctx, &length); + CHECK_LENGTH(ctx, length, 4); + + kmip_decode_int32_be(ctx, v); + + kmip_decode_int32_be(ctx, &padding); + CHECK_PADDING(ctx, padding); + + return(KMIP_OK); +} + +int +kmip_decode_bool(KMIP *ctx, enum tag t, bool32 *value) +{ + CHECK_BUFFER_FULL(ctx, 16); + + int32 tag_type = 0; + int32 length = 0; + int32 padding = 0; + + kmip_decode_int32_be(ctx, &tag_type); + CHECK_TAG_TYPE(ctx, tag_type, t, KMIP_TYPE_BOOLEAN); + + kmip_decode_int32_be(ctx, &length); + CHECK_LENGTH(ctx, length, 8); + + kmip_decode_int32_be(ctx, &padding); + CHECK_PADDING(ctx, padding); + + kmip_decode_int32_be(ctx, value); + CHECK_BOOLEAN(ctx, *value); + + return(KMIP_OK); +} + +int +kmip_decode_text_string(KMIP *ctx, enum tag t, TextString *value) +{ + CHECK_BUFFER_FULL(ctx, 8); + + int32 tag_type = 0; + int32 length = 0; + int32 padding = 0; + int8 spacer = 0; + + kmip_decode_int32_be(ctx, &tag_type); + CHECK_TAG_TYPE(ctx, tag_type, t, KMIP_TYPE_TEXT_STRING); + + kmip_decode_int32_be(ctx, &length); + padding = (8 - (length % 8)) % 8; + CHECK_BUFFER_FULL(ctx, (uint32)(length + padding)); + + value->value = ctx->calloc_func(ctx->state, 1, length); + value->size = length; + + char *index = value->value; + + for(int32 i = 0; i < length; i++) + { + kmip_decode_int8_be(ctx, (int8*)index++); + } + for(int32 i = 0; i < padding; i++) + { + kmip_decode_int8_be(ctx, &spacer); + CHECK_PADDING(ctx, spacer); + } + + return(KMIP_OK); +} + +int +kmip_decode_byte_string(KMIP *ctx, enum tag t, ByteString *value) +{ + CHECK_BUFFER_FULL(ctx, 8); + + int32 tag_type = 0; + int32 length = 0; + int32 padding = 0; + int8 spacer = 0; + + kmip_decode_int32_be(ctx, &tag_type); + CHECK_TAG_TYPE(ctx, tag_type, t, KMIP_TYPE_BYTE_STRING); + + kmip_decode_int32_be(ctx, &length); + padding = (8 - (length % 8)) % 8; + CHECK_BUFFER_FULL(ctx, (uint32)(length + padding)); + + value->value = ctx->calloc_func(ctx->state, 1, length); + value->size = length; + + uint8 *index = value->value; + + for(int32 i = 0; i < length; i++) + { + kmip_decode_int8_be(ctx, index++); + } + for(int32 i = 0; i < padding; i++) + { + kmip_decode_int8_be(ctx, &spacer); + CHECK_PADDING(ctx, spacer); + } + + return(KMIP_OK); +} + +int +kmip_decode_date_time(KMIP *ctx, enum tag t, uint64 *value) +{ + CHECK_BUFFER_FULL(ctx, 16); + + int32 tag_type = 0; + int32 length = 0; + + kmip_decode_int32_be(ctx, &tag_type); + CHECK_TAG_TYPE(ctx, tag_type, t, KMIP_TYPE_DATE_TIME); + + kmip_decode_int32_be(ctx, &length); + CHECK_LENGTH(ctx, length, 8); + + kmip_decode_int64_be(ctx, value); + + return(KMIP_OK); +} + +int +kmip_decode_digest(KMIP *ctx, Digest *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_DIGEST, KMIP_TYPE_STRUCTURE); + + kmip_decode_int32_be(ctx, &length); + CHECK_BUFFER_FULL(ctx, length); + + result = kmip_decode_enum(ctx, KMIP_TAG_HASHING_ALGORITHM, &value->hashing_algorithm); + CHECK_RESULT(ctx, result); + CHECK_ENUM(ctx, KMIP_TAG_HASHING_ALGORITHM, value->hashing_algorithm); + + if(kmip_is_tag_next(ctx, KMIP_TAG_DIGEST_VALUE)) + { + value->digest_value = ctx->calloc_func(ctx->state, 1, sizeof(ByteString)); + CHECK_NEW_MEMORY(ctx, value->digest_value, sizeof(ByteString), "Digest byte string"); + result = kmip_decode_byte_string(ctx, KMIP_TAG_DIGEST_VALUE, value->digest_value); + CHECK_RESULT(ctx, result); + } + + if(kmip_is_tag_next(ctx, KMIP_TAG_KEY_FORMAT_TYPE)) + { + result = kmip_decode_enum(ctx, KMIP_TAG_KEY_FORMAT_TYPE, &value->key_format_type); + CHECK_RESULT(ctx, result); + CHECK_ENUM(ctx, KMIP_TAG_KEY_FORMAT_TYPE, value->key_format_type); + } + + return(KMIP_OK); +} + +int +kmip_decode_interval(KMIP *ctx, enum tag t, uint32 *value) +{ + CHECK_BUFFER_FULL(ctx, 16); + + int32 tag_type = 0; + int32 length = 0; + int32 padding = 0; + + kmip_decode_int32_be(ctx, &tag_type); + CHECK_TAG_TYPE(ctx, tag_type, t, KMIP_TYPE_INTERVAL); + + kmip_decode_int32_be(ctx, &length); + CHECK_LENGTH(ctx, length, 4); + + kmip_decode_int32_be(ctx, value); + + kmip_decode_int32_be(ctx, &padding); + CHECK_PADDING(ctx, padding); + + return(KMIP_OK); +} + +int +kmip_decode_name(KMIP *ctx, Name *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_NAME, KMIP_TYPE_STRUCTURE); + + kmip_decode_int32_be(ctx, &length); + CHECK_BUFFER_FULL(ctx, length); + + value->value = ctx->calloc_func(ctx->state, 1, sizeof(TextString)); + + result = kmip_decode_text_string(ctx, KMIP_TAG_NAME_VALUE, value->value); + CHECK_RESULT(ctx, result); + + result = kmip_decode_enum(ctx, KMIP_TAG_NAME_TYPE, (int32*)&value->type); + CHECK_RESULT(ctx, result); + CHECK_ENUM(ctx, KMIP_TAG_NAME_TYPE, value->type); + + return(KMIP_OK); +} + +int +kmip_decode_attribute_name(KMIP *ctx, enum attribute_type *value) +{ + int result = 0; + enum tag t = KMIP_TAG_ATTRIBUTE_NAME; + TextString n = {0}; + + result = kmip_decode_text_string(ctx, t, &n); + CHECK_RESULT(ctx, result); + + if((n.size == 17) && (strncmp(n.value, "Unique Identifier", 17) == 0)) + { + *value = KMIP_ATTR_UNIQUE_IDENTIFIER; + } + else if((n.size == 4) && (strncmp(n.value, "Name", 4) == 0)) + { + *value = KMIP_ATTR_NAME; + } + else if((n.size == 11) && (strncmp(n.value, "Object Type", 11) == 0)) + { + *value = KMIP_ATTR_OBJECT_TYPE; + } + else if((n.size == 23) && (strncmp(n.value, "Cryptographic Algorithm", 23) == 0)) + { + *value = KMIP_ATTR_CRYPTOGRAPHIC_ALGORITHM; + } + else if((n.size == 20) && (strncmp(n.value, "Cryptographic Length", 20) == 0)) + { + *value = KMIP_ATTR_CRYPTOGRAPHIC_LENGTH; + } + else if((n.size == 24) && (strncmp(n.value, "Cryptographic Parameters", 24) == 0)) + { + *value = KMIP_ATTR_CRYPTOGRAPHIC_PARAMETERS; + } + else if((n.size == 31) && (strncmp(n.value, "Cryptographic Domain Parameters", 31) == 0)) + { + *value = KMIP_ATTR_CRYPTOGRAPHIC_DOMAIN_PARAMETERS; + } + else if((n.size == 16) && (strncmp(n.value, "Certificate Type", 16) == 0)) + { + *value = KMIP_ATTR_CERTIFICATE_TYPE; + } + else if((n.size == 18) && (strncmp(n.value, "Certificate Length", 18) == 0)) + { + *value = KMIP_ATTR_CERTIFICATE_LENGTH; + } + else if((n.size == 28) && (strncmp(n.value, "X.509 Certificate Identifier", 28) == 0)) + { + *value = KMIP_ATTR_X509_CERTIFICATE_IDENTIFIER; + } + else if((n.size == 25) && (strncmp(n.value, "X.509 Certificate Subject", 25) == 0)) + { + *value = KMIP_ATTR_X509_CERTIFICATE_SUBJECT; + } + else if((n.size == 24) && (strncmp(n.value, "X.509 Certificate Issuer", 24) == 0)) + { + *value = KMIP_ATTR_X509_CERTIFICATE_ISSUER; + } + else if((n.size == 22) && (strncmp(n.value, "Certificate Identifier", 22) == 0)) + { + *value = KMIP_ATTR_CERTIFICATE_IDENTIFIER; + } + else if((n.size == 19) && (strncmp(n.value, "Certificate Subject", 19) == 0)) + { + *value = KMIP_ATTR_CERTIFICATE_SUBJECT; + } + else if((n.size == 18) && (strncmp(n.value, "Certificate Issuer", 18) == 0)) + { + *value = KMIP_ATTR_CERTIFICATE_ISSUER; + } + else if((n.size == 27) && (strncmp(n.value, "Digital Signature Algorithm", 27) == 0)) + { + *value = KMIP_ATTR_DIGITAL_SIGNATURE_ALGORITHM; + } + else if((n.size == 6) && (strncmp(n.value, "Digest", 6) == 0)) + { + *value = KMIP_ATTR_DIGEST; + } + else if((n.size == 21) && (strncmp(n.value, "Operation Policy Name", 21) == 0)) + { + *value = KMIP_ATTR_OPERATION_POLICY_NAME; + } + else if((n.size == 24) && (strncmp(n.value, "Cryptographic Usage Mask", 24) == 0)) + { + *value = KMIP_ATTR_CRYPTOGRAPHIC_USAGE_MASK; + } + else if((n.size == 10) && (strncmp(n.value, "Lease Time", 10) == 0)) + { + *value = KMIP_ATTR_LEASE_TIME; + } + else if((n.size == 12) && (strncmp(n.value, "Usage Limits", 12) == 0)) + { + *value = KMIP_ATTR_USAGE_LIMITS; + } + else if((n.size == 5) && (strncmp(n.value, "State", 5) == 0)) + { + *value = KMIP_ATTR_STATE; + } + else if((n.size == 12) && (strncmp(n.value, "Initial Date", 12) == 0)) + { + *value = KMIP_ATTR_INITIAL_DATE; + } + else if((n.size == 15) && (strncmp(n.value, "Activation Date", 15) == 0)) + { + *value = KMIP_ATTR_ACTIVATION_DATE; + } + else if((n.size == 18) && (strncmp(n.value, "Process Start Date", 18) == 0)) + { + *value = KMIP_ATTR_PROCESS_START_DATE; + } + else if((n.size == 17) && (strncmp(n.value, "Protect Stop Date", 17) == 0)) + { + *value = KMIP_ATTR_PROTECT_STOP_DATE; + } + else if((n.size == 17) && (strncmp(n.value, "Deactivation Date", 17) == 0)) + { + *value = KMIP_ATTR_DEACTIVATION_DATE; + } + else if((n.size == 12) && (strncmp(n.value, "Destroy Date", 12) == 0)) + { + *value = KMIP_ATTR_DESTROY_DATE; + } + else if((n.size == 26) && (strncmp(n.value, "Compromise Occurrence Date", 26) == 0)) + { + *value = KMIP_ATTR_COMPROMISE_OCCURRENCE_DATE; + } + else if((n.size == 15) && (strncmp(n.value, "Compromise Date", 15) == 0)) + { + *value = KMIP_ATTR_COMPROMISE_DATE; + } + else if((n.size == 17) && (strncmp(n.value, "Revocation Reason", 17) == 0)) + { + *value = KMIP_ATTR_REVOCATION_REASON; + } + else if((n.size == 12) && (strncmp(n.value, "Archive Date", 12) == 0)) + { + *value = KMIP_ATTR_ARCHIVE_DATE; + } + else if((n.size == 12) && (strncmp(n.value, "Object Group", 12) == 0)) + { + *value = KMIP_ATTR_OBJECT_GROUP; + } + else if((n.size == 5) && (strncmp(n.value, "Fresh", 5) == 0)) + { + *value = KMIP_ATTR_FRESH; + } + else if((n.size == 4) && (strncmp(n.value, "Link", 4) == 0)) + { + *value = KMIP_ATTR_LINK; + } + else if((n.size == 32) && (strncmp(n.value, "Application Specific Information", 32) == 0)) + { + *value = KMIP_ATTR_APPLICATION_SPECIFIC_INFORMATION; + } + else if((n.size == 19) && (strncmp(n.value, "Contact Information", 19) == 0)) + { + *value = KMIP_ATTR_CONTACT_INFORMATION; + } + else if((n.size == 16) && (strncmp(n.value, "Last Change Date", 16) == 0)) + { + *value = KMIP_ATTR_LAST_CHANGE_DATE; + } + else if((n.size == 16) && (strncmp(n.value, "Alternative Name", 16) == 0)) + { + *value = KMIP_ATTR_ALTERNATIVE_NAME; + } + else if((n.size == 17) && (strncmp(n.value, "Key Value Present", 17) == 0)) + { + *value = KMIP_ATTR_KEY_VALUE_PRESENT; + } + else if((n.size == 18) && (strncmp(n.value, "Key Value Location", 18) == 0)) + { + *value = KMIP_ATTR_KEY_VALUE_LOCATION; + } + else if((n.size == 22) && (strncmp(n.value, "Original Creation Date", 22) == 0)) + { + *value = KMIP_ATTR_ORIGINAL_CREATION_DATE; + } + else if((n.size == 23) && (strncmp(n.value, "Random Number Generator", 23) == 0)) + { + *value = KMIP_ATTR_RANDOM_NUMBER_GENERATOR; + } + else if((n.size == 21) && (strncmp(n.value, "PKCS#12 Friendly Name", 21) == 0)) + { + *value = KMIP_ATTR_PKCS_12_FRIENDLY_NAME; + } + else if((n.size == 11) && (strncmp(n.value, "Description", 11) == 0)) + { + *value = KMIP_ATTR_DESCRIPTION; + } + else if((n.size == 7) && (strncmp(n.value, "Comment", 7) == 0)) + { + *value = KMIP_ATTR_COMMENT; + } + else if((n.size == 9) && (strncmp(n.value, "Sensitive", 9) == 0)) + { + *value = KMIP_ATTR_SENSITIVE; + } + else if((n.size == 16) && (strncmp(n.value, "Always Sensitive", 16) == 0)) + { + *value = KMIP_ATTR_ALWAYS_SENSITIVE; + } + else if((n.size == 11) && (strncmp(n.value, "Extractable", 11) == 0)) + { + *value = KMIP_ATTR_EXTRACTABLE; + } + else if((n.size == 17) && (strncmp(n.value, "Never Extractable", 17) == 0)) + { + *value = KMIP_ATTR_NEVER_EXTRACTABLE; + } + else if((n.size == 15) && (strncmp(n.value, "Key Format Type", 15) == 0)) + { + *value = KMIP_ATTR_KEY_FORMAT_TYPE; + } + + /* TODO (ph) Add all remaining attributes here. */ + else + { + kmip_push_error_frame(ctx, __func__, __LINE__); + kmip_free_text_string(ctx, &n); + return(KMIP_ERROR_ATTR_UNSUPPORTED); + } + + kmip_free_text_string(ctx, &n); + return(KMIP_OK); +} + +int +kmip_decode_protection_storage_masks(KMIP *ctx, ProtectionStorageMasks *value) +{ + CHECK_DECODE_ARGS(ctx, value); + CHECK_KMIP_VERSION(ctx, KMIP_2_0); + CHECK_BUFFER_FULL(ctx, 8); + + int result = 0; + int32 tag_type = 0; + uint32 length = 0; + + result = kmip_decode_int32_be(ctx, &tag_type); + CHECK_RESULT(ctx, result); + CHECK_TAG_TYPE(ctx, tag_type, KMIP_TAG_PROTECTION_STORAGE_MASKS, KMIP_TYPE_STRUCTURE); + + result = kmip_decode_int32_be(ctx, &length); + CHECK_RESULT(ctx, result); + CHECK_BUFFER_FULL(ctx, length); + + value->masks = ctx->calloc_func(ctx->state, 1, sizeof(LinkedList)); + CHECK_NEW_MEMORY(ctx, value->masks, sizeof(LinkedList), "LinkedList"); + + uint32 tag = kmip_peek_tag(ctx); + while(tag == KMIP_TAG_PROTECTION_STORAGE_MASK) + { + LinkedListItem *item = ctx->calloc_func(ctx->state, 1, sizeof(LinkedListItem)); + CHECK_NEW_MEMORY(ctx, item, sizeof(LinkedListItem), "LinkedListItem"); + kmip_linked_list_enqueue(value->masks, item); + + item->data = ctx->calloc_func(ctx->state, 1, sizeof(int32)); + CHECK_NEW_MEMORY(ctx, item->data, sizeof(int32), "Protection Storage Mask"); + + result = kmip_decode_integer(ctx, KMIP_TAG_PROTECTION_STORAGE_MASK, (int32 *)item->data); + CHECK_RESULT(ctx, result); + + tag = kmip_peek_tag(ctx); + } + + return(KMIP_OK); +} + +int +kmip_decode_attribute_v1(KMIP *ctx, Attribute *value) +{ + CHECK_BUFFER_FULL(ctx, 8); + + kmip_init_attribute(value); + + 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_ATTRIBUTE, KMIP_TYPE_STRUCTURE); + + kmip_decode_int32_be(ctx, &length); + CHECK_BUFFER_FULL(ctx, length); + + result = kmip_decode_attribute_name(ctx, &value->type); + CHECK_RESULT(ctx, result); + + if(kmip_is_tag_next(ctx, KMIP_TAG_ATTRIBUTE_INDEX)) + { + result = kmip_decode_integer(ctx, KMIP_TAG_ATTRIBUTE_INDEX, &value->index); + CHECK_RESULT(ctx, result); + } + + uint8 *curr_index = ctx->index; + uint8 *tag_index = ctx->index; + enum tag t = KMIP_TAG_ATTRIBUTE_VALUE; + + switch(value->type) + { + case KMIP_ATTR_UNIQUE_IDENTIFIER: + value->value = ctx->calloc_func(ctx->state, 1, sizeof(TextString)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(TextString), "UniqueIdentifier text string"); + result = kmip_decode_text_string(ctx, t, (TextString*)value->value); + CHECK_RESULT(ctx, result); + break; + + case KMIP_ATTR_NAME: + /* TODO (ph) Like encoding, this is messy. Better solution? */ + value->value = ctx->calloc_func(ctx->state, 1, sizeof(Name)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(Name), "Name structure"); + + if(kmip_is_tag_type_next(ctx, KMIP_TAG_ATTRIBUTE_VALUE, KMIP_TYPE_STRUCTURE)) + { + /* NOTE (ph) Decoding name structures will fail if the name tag */ + /* is not present in the encoding. Temporarily swap the tags, */ + /* decode the name structure, and then swap the tags back to */ + /* preserve the encoding. The tag/type check above guarantees */ + /* space exists for this to succeed. */ + kmip_encode_int32_be(ctx, TAG_TYPE(KMIP_TAG_NAME, KMIP_TYPE_STRUCTURE)); + ctx->index = tag_index; + + result = kmip_decode_name(ctx, (Name*)value->value); + + curr_index = ctx->index; + ctx->index = tag_index; + + kmip_encode_int32_be(ctx, TAG_TYPE(KMIP_TAG_ATTRIBUTE_VALUE, KMIP_TYPE_STRUCTURE)); + ctx->index = curr_index; + } + else + { + result = KMIP_TAG_MISMATCH; + } + + CHECK_RESULT(ctx, result); + break; + + case KMIP_ATTR_OBJECT_TYPE: + value->value = ctx->calloc_func(ctx->state, 1, sizeof(int32)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(int32), "ObjectType enumeration"); + result = kmip_decode_enum(ctx, t, (int32 *)value->value); + CHECK_RESULT(ctx, result); + CHECK_ENUM(ctx, KMIP_TAG_OBJECT_TYPE, *(int32 *)value->value); + break; + + case KMIP_ATTR_CRYPTOGRAPHIC_ALGORITHM: + value->value = ctx->calloc_func(ctx->state, 1, sizeof(int32)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(int32), "CryptographicAlgorithm enumeration"); + result = kmip_decode_enum(ctx, t, (int32 *)value->value); + CHECK_RESULT(ctx, result); + CHECK_ENUM(ctx, KMIP_TAG_CRYPTOGRAPHIC_ALGORITHM, *(int32 *)value->value); + break; + + case KMIP_ATTR_CRYPTOGRAPHIC_LENGTH: + value->value = ctx->calloc_func(ctx->state, 1, sizeof(int32)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(int32), "CryptographicLength integer"); + result = kmip_decode_integer(ctx, t, (int32 *)value->value); + CHECK_RESULT(ctx, result); + break; + + // case KMIP_ATTR_CRYPTOGRAPHIC_PARAMETERS: XXX how to hack struct? + // case KMIP_ATTR_CRYPTOGRAPHIC_DOMAIN_PARAMETERS: XXX how to hack struct? + + case KMIP_ATTR_CERTIFICATE_TYPE: + value->value = ctx->calloc_func(ctx->state, 1, sizeof(int32)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(int32), "CertificateType enumeration"); + result = kmip_decode_enum(ctx, t, (int32 *)value->value); + CHECK_RESULT(ctx, result); + CHECK_ENUM(ctx, KMIP_TAG_CERTIFICATE_TYPE, *(int32 *)value->value); + break; + + case KMIP_ATTR_CERTIFICATE_LENGTH: + value->value = ctx->calloc_func(ctx->state, 1, sizeof(int32)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(int32), "CertificateLength integer"); + result = kmip_decode_integer(ctx, t, (int32 *)value->value); + CHECK_RESULT(ctx, result); + break; + + // case KMIP_ATTR_X509_CERTIFICATE_IDENTIFIER: XXX how to hack struct? + // case KMIP_ATTR_X509_CERTIFICATE_SUBJECT: XXX how to hack struct? + // case KMIP_ATTR_X509_CERTIFICATE_ISSUER: XXX how to hack struct? + // case KMIP_ATTR_CERTIFICATE_IDENTIFIER: XXX how to hack struct? + // case KMIP_ATTR_CERTIFICATE_SUBJECT: XXX how to hack struct? + // case KMIP_ATTR_CERTIFICATE_ISSUER: XXX how to hack struct? + + case KMIP_ATTR_DIGITAL_SIGNATURE_ALGORITHM: + value->value = ctx->calloc_func(ctx->state, 1, sizeof(int32)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(int32), "DigitalSignatureAlgorithm enumeration"); + result = kmip_decode_enum(ctx, t, (int32 *)value->value); + CHECK_RESULT(ctx, result); + CHECK_ENUM(ctx, KMIP_TAG_DIGITAL_SIGNATURE_ALGORITHM, *(int32 *)value->value); + break; + + case KMIP_ATTR_DIGEST: + // same issues as Name above, all the same uglies. + value->value = ctx->calloc_func(ctx->state, 1, sizeof(Digest)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(Digest), "Digest structure"); + if(kmip_is_tag_type_next(ctx, KMIP_TAG_ATTRIBUTE_VALUE, KMIP_TYPE_STRUCTURE)) + { + kmip_encode_int32_be(ctx, TAG_TYPE(KMIP_TAG_DIGEST, KMIP_TYPE_STRUCTURE)); + ctx->index = tag_index; + + result = kmip_decode_digest(ctx, (Digest*)value->value); + + curr_index = ctx->index; + ctx->index = tag_index; + + kmip_encode_int32_be(ctx, TAG_TYPE(KMIP_TAG_ATTRIBUTE_VALUE, KMIP_TYPE_STRUCTURE)); + ctx->index = curr_index; + } else { + result = KMIP_TAG_MISMATCH; + } + CHECK_RESULT(ctx, result); + break; + + case KMIP_ATTR_OPERATION_POLICY_NAME: + value->value = ctx->calloc_func(ctx->state, 1, sizeof(TextString)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(TextString), "OperationPolicyName text string"); + result = kmip_decode_text_string(ctx, t, (TextString*)value->value); + CHECK_RESULT(ctx, result); + break; + + case KMIP_ATTR_CRYPTOGRAPHIC_USAGE_MASK: + value->value = ctx->calloc_func(ctx->state, 1, sizeof(int32)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(int32), "CryptographicUsageMask integer"); + result = kmip_decode_integer(ctx, t, (int32 *)value->value); + CHECK_RESULT(ctx, result); + break; + + case KMIP_ATTR_LEASE_TIME: + value->value = ctx->calloc_func(ctx->state, 1, sizeof(uint32)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(uint32), "LeaseTime interval"); + result = kmip_decode_interval(ctx, t, (uint32 *)value->value); + CHECK_RESULT(ctx, result); + break; + + // case KMIP_ATTR_USAGE_LIMITS: XXX how to hack struct? + + case KMIP_ATTR_STATE: + value->value = ctx->calloc_func(ctx->state, 1, sizeof(int32)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(int32), "State enumeration"); + result = kmip_decode_enum(ctx, t, (int32 *)value->value); + CHECK_RESULT(ctx, result); + CHECK_ENUM(ctx, KMIP_TAG_STATE, *(int32 *)value->value); + break; + + case KMIP_ATTR_INITIAL_DATE: + value->value = ctx->calloc_func(ctx->state, 1, sizeof(int64)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(int64), "InitialDate datetime"); + result = kmip_decode_date_time(ctx, t, (uint64 *)value->value); + CHECK_RESULT(ctx, result); + break; + + case KMIP_ATTR_ACTIVATION_DATE: + value->value = ctx->calloc_func(ctx->state, 1, sizeof(int64)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(int64), "ActivationDate datetime"); + result = kmip_decode_date_time(ctx, t, (uint64 *)value->value); + CHECK_RESULT(ctx, result); + break; + + case KMIP_ATTR_PROCESS_START_DATE: + value->value = ctx->calloc_func(ctx->state, 1, sizeof(int64)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(int64), "ProcessStartDate datetime"); + result = kmip_decode_date_time(ctx, t, (uint64 *)value->value); + CHECK_RESULT(ctx, result); + break; + + case KMIP_ATTR_PROTECT_STOP_DATE: + value->value = ctx->calloc_func(ctx->state, 1, sizeof(int64)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(int64), "ProtectStopDate datetime"); + result = kmip_decode_date_time(ctx, t, (uint64 *)value->value); + CHECK_RESULT(ctx, result); + break; + + case KMIP_ATTR_DEACTIVATION_DATE: + value->value = ctx->calloc_func(ctx->state, 1, sizeof(int64)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(int64), "DeactivationDate datetime"); + result = kmip_decode_date_time(ctx, t, (uint64 *)value->value); + CHECK_RESULT(ctx, result); + break; + + case KMIP_ATTR_DESTROY_DATE: + value->value = ctx->calloc_func(ctx->state, 1, sizeof(int64)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(int64), "DestroyDate datetime"); + result = kmip_decode_date_time(ctx, t, (uint64 *)value->value); + CHECK_RESULT(ctx, result); + break; + + case KMIP_ATTR_COMPROMISE_OCCURRENCE_DATE: + value->value = ctx->calloc_func(ctx->state, 1, sizeof(int64)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(int64), "CompromiseOccurrenceDate datetime"); + result = kmip_decode_date_time(ctx, t, (uint64 *)value->value); + CHECK_RESULT(ctx, result); + break; + + case KMIP_ATTR_COMPROMISE_DATE: + value->value = ctx->calloc_func(ctx->state, 1, sizeof(int64)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(int64), "CompromiseDate datetime"); + result = kmip_decode_date_time(ctx, t, (uint64 *)value->value); + CHECK_RESULT(ctx, result); + break; + + // case KMIP_ATTR_REVOCATION_REASON: XXX how to hack struct? + + case KMIP_ATTR_ARCHIVE_DATE: + value->value = ctx->calloc_func(ctx->state, 1, sizeof(int64)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(int64), "ArchiveDate datetime"); + result = kmip_decode_date_time(ctx, t, (uint64 *)value->value); + CHECK_RESULT(ctx, result); + break; + + case KMIP_ATTR_OBJECT_GROUP: + value->value = ctx->calloc_func(ctx->state, 1, sizeof(TextString)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(TextString), "ObjectGroup text string"); + result = kmip_decode_text_string(ctx, t, (TextString*)value->value); + CHECK_RESULT(ctx, result); + break; + + case KMIP_ATTR_FRESH: + value->value = ctx->calloc_func(ctx->state, 1, sizeof(bool32)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(bool32), "Fresh boolean"); + result = kmip_decode_bool(ctx, t, (bool32 *)value->value); + CHECK_RESULT(ctx, result); + break; + + // case KMIP_ATTR_LINK: XXX how to hack struct? + // case KMIP_ATTR_APPLICATION_SPECIFIC_INFORMATION: XXX how to hack struct? + // case KMIP_ATTR_CONTACT_INFORMATION: XXX how to hack struct? + + case KMIP_ATTR_LAST_CHANGE_DATE: + value->value = ctx->calloc_func(ctx->state, 1, sizeof(int64)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(int64), "LastChangeDate datetime"); + result = kmip_decode_date_time(ctx, t, (uint64 *)value->value); + CHECK_RESULT(ctx, result); + break; + + // case KMIP_ATTR_CUSTOM_ATTRIBUTE: XXX how to hack custom? + // case KMIP_ATTR_ALTERNATIVE_NAME: XXX how to hack struct? + + case KMIP_ATTR_KEY_VALUE_PRESENT: + value->value = ctx->calloc_func(ctx->state, 1, sizeof(bool32)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(bool32), "KeyValuePresent boolean"); + result = kmip_decode_bool(ctx, t, (bool32 *)value->value); + CHECK_RESULT(ctx, result); + break; + + // case KMIP_ATTR_KEY_VALUE_LOCATION: XXX how to hack struct? + + case KMIP_ATTR_ORIGINAL_CREATION_DATE: + value->value = ctx->calloc_func(ctx->state, 1, sizeof(int64)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(int64), "OriginalCreationDate datetime"); + result = kmip_decode_date_time(ctx, t, (uint64 *)value->value); + CHECK_RESULT(ctx, result); + break; + + case KMIP_ATTR_RANDOM_NUMBER_GENERATOR: + value->value = ctx->calloc_func(ctx->state, 1, sizeof(TextString)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(TextString), "RandomNumberGenerator text string"); + result = kmip_decode_text_string(ctx, t, (TextString*)value->value); + CHECK_RESULT(ctx, result); + break; + + case KMIP_ATTR_PKCS_12_FRIENDLY_NAME: + value->value = ctx->calloc_func(ctx->state, 1, sizeof(TextString)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(TextString), "Pkcs12FriendlyName text string"); + result = kmip_decode_text_string(ctx, t, (TextString*)value->value); + CHECK_RESULT(ctx, result); + break; + + case KMIP_ATTR_DESCRIPTION: + value->value = ctx->calloc_func(ctx->state, 1, sizeof(TextString)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(TextString), "Description text string"); + result = kmip_decode_text_string(ctx, t, (TextString*)value->value); + CHECK_RESULT(ctx, result); + break; + + case KMIP_ATTR_COMMENT: + value->value = ctx->calloc_func(ctx->state, 1, sizeof(TextString)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(TextString), "Comment text string"); + result = kmip_decode_text_string(ctx, t, (TextString*)value->value); + CHECK_RESULT(ctx, result); + break; + + case KMIP_ATTR_SENSITIVE: + value->value = ctx->calloc_func(ctx->state, 1, sizeof(bool32)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(bool32), "Sensitive boolean"); + result = kmip_decode_bool(ctx, t, (bool32 *)value->value); + CHECK_RESULT(ctx, result); + break; + + case KMIP_ATTR_ALWAYS_SENSITIVE: + value->value = ctx->calloc_func(ctx->state, 1, sizeof(bool32)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(bool32), "AlwaysSensitive boolean"); + result = kmip_decode_bool(ctx, t, (bool32 *)value->value); + CHECK_RESULT(ctx, result); + break; + + case KMIP_ATTR_EXTRACTABLE: + value->value = ctx->calloc_func(ctx->state, 1, sizeof(bool32)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(bool32), "Extractable boolean"); + result = kmip_decode_bool(ctx, t, (bool32 *)value->value); + CHECK_RESULT(ctx, result); + break; + + case KMIP_ATTR_NEVER_EXTRACTABLE: + value->value = ctx->calloc_func(ctx->state, 1, sizeof(bool32)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(bool32), "NeverExtractable boolean"); + result = kmip_decode_bool(ctx, t, (bool32 *)value->value); + CHECK_RESULT(ctx, result); + break; + + case KMIP_ATTR_KEY_FORMAT_TYPE: + value->value = ctx->calloc_func(ctx->state, 1, sizeof(int32)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(int32), "KeyFormatType enumeration"); + result = kmip_decode_enum(ctx, t, (int32 *)value->value); + CHECK_RESULT(ctx, result); + CHECK_ENUM(ctx, KMIP_TAG_KEY_FORMAT_TYPE, *(int32 *)value->value); + break; + + default: + kmip_push_error_frame(ctx, __func__, __LINE__); + return(KMIP_ERROR_ATTR_UNSUPPORTED); + break; + }; + CHECK_RESULT(ctx, result); + + return(KMIP_OK); +} + +int +kmip_decode_attribute_v2(KMIP *ctx, Attribute *value) +{ + CHECK_DECODE_ARGS(ctx, value); + CHECK_KMIP_VERSION(ctx, KMIP_2_0); + + kmip_init_attribute(value); + + int result = 0; + uint32 tag = kmip_peek_tag(ctx); + if(tag == 0) + { + /* Record an error for an underfull buffer here and return. */ + } + + CHECK_RESULT(ctx, result); + + switch(tag) + { + case KMIP_TAG_UNIQUE_IDENTIFIER: + { + value->type = KMIP_ATTR_UNIQUE_IDENTIFIER; + value->value = ctx->calloc_func(ctx->state, 1, sizeof(TextString)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(TextString), "UniqueIdentifier text string"); + + result = kmip_decode_text_string(ctx, KMIP_TAG_UNIQUE_IDENTIFIER, (TextString *)value->value); + CHECK_RESULT(ctx, result); + } + break; + + case KMIP_TAG_NAME: + { + value->type = KMIP_ATTR_NAME; + value->value = ctx->calloc_func(ctx->state, 1, sizeof(Name)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(Name), "Name structure"); + + result = kmip_decode_name(ctx, (Name *)value->value); + CHECK_RESULT(ctx, result); + } + break; + + case KMIP_TAG_OBJECT_TYPE: + { + value->type = KMIP_ATTR_OBJECT_TYPE; + value->value = ctx->calloc_func(ctx->state, 1, sizeof(int32)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(int32), "ObjectType enumeration"); + + result = kmip_decode_enum(ctx, KMIP_TAG_OBJECT_TYPE, (int32 *)value->value); + CHECK_RESULT(ctx, result); + + CHECK_ENUM(ctx, KMIP_TAG_OBJECT_TYPE, *(int32 *)value->value); + } + break; + + case KMIP_TAG_CRYPTOGRAPHIC_ALGORITHM: + { + value->type = KMIP_ATTR_CRYPTOGRAPHIC_ALGORITHM; + value->value = ctx->calloc_func(ctx->state, 1, sizeof(int32)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(int32), "CrypographicAlgorithm enumeration"); + + result = kmip_decode_enum(ctx, KMIP_TAG_CRYPTOGRAPHIC_ALGORITHM, (int32 *)value->value); + CHECK_RESULT(ctx, result); + + CHECK_ENUM(ctx, KMIP_TAG_CRYPTOGRAPHIC_ALGORITHM, *(int32 *)value->value); + } + break; + + case KMIP_TAG_CRYPTOGRAPHIC_LENGTH: + { + value->type = KMIP_ATTR_CRYPTOGRAPHIC_LENGTH; + value->value = ctx->calloc_func(ctx->state, 1, sizeof(int32)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(int32), "CryptographicLength integer"); + + result = kmip_decode_integer(ctx, KMIP_TAG_CRYPTOGRAPHIC_LENGTH, (int32 *)value->value); + CHECK_RESULT(ctx, result); + } + break; + + // case KMIP_TAG_CRYPTOGRAPHIC_PARAMETERS: XXX how to hack struct? + // case KMIP_TAG_CRYPTOGRAPHIC_DOMAIN_PARAMETERS: XXX how to hack struct? + + case KMIP_TAG_CERTIFICATE_TYPE: + { + value->type = KMIP_ATTR_CERTIFICATE_TYPE; + value->value = ctx->calloc_func(ctx->state, 1, sizeof(int32)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(int32), "CertificateType enumeration"); + + result = kmip_decode_enum(ctx, KMIP_TAG_CERTIFICATE_TYPE, (int32 *)value->value); + CHECK_RESULT(ctx, result); + + CHECK_ENUM(ctx, KMIP_TAG_CERTIFICATE_TYPE, *(int32 *)value->value); + } + break; + + case KMIP_TAG_CERTIFICATE_LENGTH: + { + value->type = KMIP_ATTR_CERTIFICATE_LENGTH; + value->value = ctx->calloc_func(ctx->state, 1, sizeof(int32)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(int32), "CertificateLength integer"); + + result = kmip_decode_integer(ctx, KMIP_TAG_CERTIFICATE_LENGTH, (int32 *)value->value); + CHECK_RESULT(ctx, result); + } + break; + + // case KMIP_TAG_X509_CERTIFICATE_IDENTIFIER: XXX how to hack struct? + // case KMIP_TAG_X509_CERTIFICATE_SUBJECT: XXX how to hack struct? + // case KMIP_TAG_X509_CERTIFICATE_ISSUER: XXX how to hack struct? + // case KMIP_TAG_CERTIFICATE_IDENTIFIER: XXX how to hack struct? + // case KMIP_TAG_CERTIFICATE_SUBJECT: XXX how to hack struct? + // case KMIP_TAG_CERTIFICATE_ISSUER: XXX how to hack struct? + + case KMIP_TAG_DIGITAL_SIGNATURE_ALGORITHM: + { + value->type = KMIP_ATTR_DIGITAL_SIGNATURE_ALGORITHM; + value->value = ctx->calloc_func(ctx->state, 1, sizeof(int32)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(int32), "DigitalSignatureAlgorithm enumeration"); + + result = kmip_decode_enum(ctx, KMIP_TAG_DIGITAL_SIGNATURE_ALGORITHM, (int32 *)value->value); + CHECK_RESULT(ctx, result); + + CHECK_ENUM(ctx, KMIP_TAG_DIGITAL_SIGNATURE_ALGORITHM, *(int32 *)value->value); + } + break; + + case KMIP_TAG_DIGEST: + { + value->type = KMIP_ATTR_DIGEST; + value->value = ctx->calloc_func(ctx->state, 1, sizeof(Digest)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(Digest), "Digest structure"); + + result = kmip_decode_digest(ctx, (Digest *)value->value); + CHECK_RESULT(ctx, result); + } + break; + + case KMIP_TAG_OPERATION_POLICY_NAME: + { + value->type = KMIP_ATTR_OPERATION_POLICY_NAME; + value->value = ctx->calloc_func(ctx->state, 1, sizeof(TextString)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(TextString), "OperationPolicyName text string"); + + result = kmip_decode_text_string(ctx, KMIP_TAG_OPERATION_POLICY_NAME, (TextString *)value->value); + CHECK_RESULT(ctx, result); + } + break; + + case KMIP_TAG_CRYPTOGRAPHIC_USAGE_MASK: + { + value->type = KMIP_ATTR_CRYPTOGRAPHIC_USAGE_MASK; + value->value = ctx->calloc_func(ctx->state, 1, sizeof(int32)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(int32), "CryptographicUsageMask integer"); + + result = kmip_decode_integer(ctx, KMIP_TAG_CRYPTOGRAPHIC_USAGE_MASK, (int32 *)value->value); + CHECK_RESULT(ctx, result); + } + break; + + case KMIP_TAG_LEASE_TIME: + { + value->type = KMIP_ATTR_LEASE_TIME; + value->value = ctx->calloc_func(ctx->state, 1, sizeof(uint32)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(uint32), "LeaseTime interval"); + + result = kmip_decode_interval(ctx, KMIP_TAG_LEASE_TIME, (uint32 *)value->value); + CHECK_RESULT(ctx, result); + } + break; + + // case KMIP_TAG_USAGE_LIMITS: XXX how to hack struct? + + case KMIP_TAG_STATE: + { + value->type = KMIP_ATTR_STATE; + value->value = ctx->calloc_func(ctx->state, 1, sizeof(int32)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(int32), "State enumeration"); + + result = kmip_decode_enum(ctx, KMIP_TAG_STATE, (int32 *)value->value); + CHECK_RESULT(ctx, result); + + CHECK_ENUM(ctx, KMIP_TAG_STATE, *(int32 *)value->value); + } + break; + + case KMIP_TAG_INITIAL_DATE: + { + value->type = KMIP_ATTR_INITIAL_DATE; + value->value = ctx->calloc_func(ctx->state, 1, sizeof(int64)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(int64), "InitialDate integer"); + + result = kmip_decode_date_time(ctx, KMIP_TAG_INITIAL_DATE, (uint64 *)value->value); + CHECK_RESULT(ctx, result); + } + break; + + case KMIP_TAG_ACTIVATION_DATE: + { + value->type = KMIP_ATTR_ACTIVATION_DATE; + value->value = ctx->calloc_func(ctx->state, 1, sizeof(int64)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(int64), "ActivationDate integer"); + + result = kmip_decode_date_time(ctx, KMIP_TAG_ACTIVATION_DATE, (uint64 *)value->value); + CHECK_RESULT(ctx, result); + } + break; + + case KMIP_TAG_PROCESS_START_DATE: + { + value->type = KMIP_ATTR_PROCESS_START_DATE; + value->value = ctx->calloc_func(ctx->state, 1, sizeof(int64)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(int64), "ProcessStartDate integer"); + + result = kmip_decode_date_time(ctx, KMIP_TAG_PROCESS_START_DATE, (uint64 *)value->value); + CHECK_RESULT(ctx, result); + } + break; + + case KMIP_TAG_PROTECT_STOP_DATE: + { + value->type = KMIP_ATTR_PROTECT_STOP_DATE; + value->value = ctx->calloc_func(ctx->state, 1, sizeof(int64)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(int64), "ProtectStopDate integer"); + + result = kmip_decode_date_time(ctx, KMIP_TAG_PROTECT_STOP_DATE, (uint64 *)value->value); + CHECK_RESULT(ctx, result); + } + break; + + case KMIP_TAG_DEACTIVATION_DATE: + { + value->type = KMIP_ATTR_DEACTIVATION_DATE; + value->value = ctx->calloc_func(ctx->state, 1, sizeof(int64)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(int64), "DeactivationDate integer"); + + result = kmip_decode_date_time(ctx, KMIP_TAG_DEACTIVATION_DATE, (uint64 *)value->value); + CHECK_RESULT(ctx, result); + } + break; + + case KMIP_TAG_DESTROY_DATE: + { + value->type = KMIP_ATTR_DESTROY_DATE; + value->value = ctx->calloc_func(ctx->state, 1, sizeof(int64)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(int64), "DestroyDate integer"); + + result = kmip_decode_date_time(ctx, KMIP_TAG_DESTROY_DATE, (uint64 *)value->value); + CHECK_RESULT(ctx, result); + } + break; + + case KMIP_TAG_COMPROMISE_OCCURRENCE_DATE: + { + value->type = KMIP_ATTR_COMPROMISE_OCCURRENCE_DATE; + value->value = ctx->calloc_func(ctx->state, 1, sizeof(int64)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(int64), "CompromiseOccurrenceDate integer"); + + result = kmip_decode_date_time(ctx, KMIP_TAG_COMPROMISE_OCCURRENCE_DATE, (uint64 *)value->value); + CHECK_RESULT(ctx, result); + } + break; + + case KMIP_TAG_COMPROMISE_DATE: + { + value->type = KMIP_ATTR_COMPROMISE_DATE; + value->value = ctx->calloc_func(ctx->state, 1, sizeof(int64)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(int64), "CompromiseDate integer"); + + result = kmip_decode_date_time(ctx, KMIP_TAG_COMPROMISE_DATE, (uint64 *)value->value); + CHECK_RESULT(ctx, result); + } + break; + + // case KMIP_TAG_REVOCATION_REASON: XXX how to hack struct? + + case KMIP_TAG_ARCHIVE_DATE: + { + value->type = KMIP_ATTR_ARCHIVE_DATE; + value->value = ctx->calloc_func(ctx->state, 1, sizeof(int64)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(int64), "ArchiveDate integer"); + + result = kmip_decode_date_time(ctx, KMIP_TAG_ARCHIVE_DATE, (uint64 *)value->value); + CHECK_RESULT(ctx, result); + } + break; + + case KMIP_TAG_OBJECT_GROUP: + { + value->type = KMIP_ATTR_OBJECT_GROUP; + value->value = ctx->calloc_func(ctx->state, 1, sizeof(TextString)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(TextString), "ObjectGroup text string"); + + result = kmip_decode_text_string(ctx, KMIP_TAG_OBJECT_GROUP, (TextString *)value->value); + CHECK_RESULT(ctx, result); + } + break; + + case KMIP_TAG_FRESH: + { + value->type = KMIP_ATTR_FRESH; + value->value = ctx->calloc_func(ctx->state, 1, sizeof(bool32)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(bool32), "Fresh boolean"); + + result = kmip_decode_bool(ctx, KMIP_TAG_FRESH, (bool32 *)value->value); + CHECK_RESULT(ctx, result); + } + break; + + // case KMIP_TAG_LINK: XXX how to hack struct? + // case KMIP_TAG_APPLICATION_SPECIFIC_INFORMATION: XXX how to hack struct? + // case KMIP_TAG_CONTACT_INFORMATION: XXX how to hack struct? + + case KMIP_TAG_LAST_CHANGE_DATE: + { + value->type = KMIP_ATTR_LAST_CHANGE_DATE; + value->value = ctx->calloc_func(ctx->state, 1, sizeof(int64)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(int64), "LastChangeDate integer"); + + result = kmip_decode_date_time(ctx, KMIP_TAG_LAST_CHANGE_DATE, (uint64 *)value->value); + CHECK_RESULT(ctx, result); + } + break; + + // case KMIP_TAG_CUSTOM_ATTRIBUTE: XXX how to hack custom? + // case KMIP_TAG_ALTERNATIVE_NAME: XXX how to hack struct? + + case KMIP_TAG_KEY_VALUE_PRESENT: + { + value->type = KMIP_ATTR_KEY_VALUE_PRESENT; + value->value = ctx->calloc_func(ctx->state, 1, sizeof(bool32)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(bool32), "KeyValuePresent boolean"); + + result = kmip_decode_bool(ctx, KMIP_TAG_KEY_VALUE_PRESENT, (bool32 *)value->value); + CHECK_RESULT(ctx, result); + } + break; + + // case KMIP_TAG_KEY_VALUE_LOCATION: XXX how to hack struct? + + case KMIP_TAG_ORIGINAL_CREATION_DATE: + { + value->type = KMIP_ATTR_ORIGINAL_CREATION_DATE; + value->value = ctx->calloc_func(ctx->state, 1, sizeof(int64)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(int64), "OriginalCreationDate integer"); + + result = kmip_decode_date_time(ctx, KMIP_TAG_ORIGINAL_CREATION_DATE, (uint64 *)value->value); + CHECK_RESULT(ctx, result); + } + break; + + case KMIP_TAG_RANDOM_NUMBER_GENERATOR: + { + value->type = KMIP_ATTR_RANDOM_NUMBER_GENERATOR; + value->value = ctx->calloc_func(ctx->state, 1, sizeof(TextString)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(TextString), "RandomNumberGenerator text string"); + + result = kmip_decode_text_string(ctx, KMIP_TAG_RANDOM_NUMBER_GENERATOR, (TextString *)value->value); + CHECK_RESULT(ctx, result); + } + break; + + case KMIP_TAG_PKCS_12_FRIENDLY_NAME: + { + value->type = KMIP_ATTR_PKCS_12_FRIENDLY_NAME; + value->value = ctx->calloc_func(ctx->state, 1, sizeof(TextString)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(TextString), "Pkcs12FriendlyName text string"); + + result = kmip_decode_text_string(ctx, KMIP_TAG_PKCS_12_FRIENDLY_NAME, (TextString *)value->value); + CHECK_RESULT(ctx, result); + } + break; + + case KMIP_TAG_DESCRIPTION: + { + value->type = KMIP_ATTR_DESCRIPTION; + value->value = ctx->calloc_func(ctx->state, 1, sizeof(TextString)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(TextString), "Description text string"); + + result = kmip_decode_text_string(ctx, KMIP_TAG_DESCRIPTION, (TextString *)value->value); + CHECK_RESULT(ctx, result); + } + break; + + case KMIP_TAG_COMMENT: + { + value->type = KMIP_ATTR_COMMENT; + value->value = ctx->calloc_func(ctx->state, 1, sizeof(TextString)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(TextString), "Comment text string"); + + result = kmip_decode_text_string(ctx, KMIP_TAG_COMMENT, (TextString *)value->value); + CHECK_RESULT(ctx, result); + } + break; + + case KMIP_TAG_SENSITIVE: + { + value->type = KMIP_ATTR_SENSITIVE; + value->value = ctx->calloc_func(ctx->state, 1, sizeof(bool32)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(bool32), "Sensitive boolean"); + + result = kmip_decode_bool(ctx, KMIP_TAG_SENSITIVE, (bool32 *)value->value); + CHECK_RESULT(ctx, result); + } + break; + + case KMIP_TAG_ALWAYS_SENSITIVE: + { + value->type = KMIP_ATTR_ALWAYS_SENSITIVE; + value->value = ctx->calloc_func(ctx->state, 1, sizeof(bool32)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(bool32), "AlwaysSensitive boolean"); + + result = kmip_decode_bool(ctx, KMIP_TAG_ALWAYS_SENSITIVE, (bool32 *)value->value); + CHECK_RESULT(ctx, result); + } + break; + + case KMIP_TAG_EXTRACTABLE: + { + value->type = KMIP_ATTR_EXTRACTABLE; + value->value = ctx->calloc_func(ctx->state, 1, sizeof(bool32)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(bool32), "Extractable boolean"); + + result = kmip_decode_bool(ctx, KMIP_TAG_EXTRACTABLE, (bool32 *)value->value); + CHECK_RESULT(ctx, result); + } + break; + + case KMIP_TAG_NEVER_EXTRACTABLE: + { + value->type = KMIP_ATTR_NEVER_EXTRACTABLE; + value->value = ctx->calloc_func(ctx->state, 1, sizeof(bool32)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(bool32), "NeverExtractable boolean"); + + result = kmip_decode_bool(ctx, KMIP_TAG_NEVER_EXTRACTABLE, (bool32 *)value->value); + CHECK_RESULT(ctx, result); + } + break; + + case KMIP_TAG_KEY_FORMAT_TYPE: + { + value->type = KMIP_ATTR_KEY_FORMAT_TYPE; + value->value = ctx->calloc_func(ctx->state, 1, sizeof(int32)); + CHECK_NEW_MEMORY(ctx, value->value, sizeof(int32), "KeyFormatType enumeration"); + + result = kmip_decode_enum(ctx, KMIP_TAG_KEY_FORMAT_TYPE, (int32 *)value->value); + CHECK_RESULT(ctx, result); + + CHECK_ENUM(ctx, KMIP_TAG_KEY_FORMAT_TYPE, *(int32 *)value->value); + } + break; + + default: + { + kmip_push_error_frame(ctx, __func__, __LINE__); + return(KMIP_ERROR_ATTR_UNSUPPORTED); + } + break; + }; + + return(KMIP_OK); +} + +int +kmip_decode_attribute(KMIP *ctx, Attribute *value) +{ + CHECK_DECODE_ARGS(ctx, value); + + if(ctx->version < KMIP_2_0) + { + return(kmip_decode_attribute_v1(ctx, value)); + } + else + { + return(kmip_decode_attribute_v2(ctx, value)); + } +} + +int +kmip_decode_attributes(KMIP *ctx, Attributes *value) +{ + CHECK_DECODE_ARGS(ctx, value); + CHECK_KMIP_VERSION(ctx, KMIP_2_0); + CHECK_BUFFER_FULL(ctx, 8); + + int result = 0; + int32 tag_type = 0; + uint32 length = 0; + + result = kmip_decode_int32_be(ctx, &tag_type); + CHECK_RESULT(ctx, result); + CHECK_TAG_TYPE(ctx, tag_type, KMIP_TAG_ATTRIBUTES, KMIP_TYPE_STRUCTURE); + + result = kmip_decode_int32_be(ctx, &length); + CHECK_RESULT(ctx, result); + CHECK_BUFFER_FULL(ctx, length); + + value->attribute_list = ctx->calloc_func(ctx->state, 1, sizeof(LinkedList)); + CHECK_NEW_MEMORY(ctx, value->attribute_list, sizeof(LinkedList), "LinkedList"); + + uint32 tag = kmip_peek_tag(ctx); + while(tag != 0 && kmip_is_attribute_tag(tag)) + { + LinkedListItem *item = ctx->calloc_func(ctx->state, 1, sizeof(LinkedListItem)); + CHECK_NEW_MEMORY(ctx, item, sizeof(LinkedListItem), "LinkedListItem"); + kmip_linked_list_enqueue(value->attribute_list, 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_attributes_2(KMIP *ctx, Attribute **valuep, int *countp) +{ + CHECK_KMIP_VERSION(ctx, KMIP_2_0); + CHECK_BUFFER_FULL(ctx, 8); + uint8 *backup, *lim; + int i, count; + Attribute *attribute_list; + + int result = 0; + int32 tag_type = 0; + uint32 length = 0, sublen; + + *valuep = 0; + *countp = 0; + result = kmip_decode_int32_be(ctx, &tag_type); + CHECK_RESULT(ctx, result); + CHECK_TAG_TYPE(ctx, tag_type, KMIP_TAG_ATTRIBUTES, KMIP_TYPE_STRUCTURE); + + result = kmip_decode_int32_be(ctx, &length); + CHECK_RESULT(ctx, result); + CHECK_BUFFER_FULL(ctx, length); + + backup = ctx->index; + lim = backup + length; + count = 0; + while (ctx->index < lim-8) + { + ctx->index += 4; + result = kmip_decode_int32_be(ctx, &sublen); + if (result != KMIP_OK) + { + break; + } + sublen += CALCULATE_PADDING(length); + if (ctx->index + sublen > lim) + { + break; + } + ++count; + } + ctx->index = backup; + attribute_list = ctx->calloc_func(ctx->state, count, sizeof(Attribute*)); + CHECK_NEW_MEMORY(ctx, attribute_list, count*sizeof(Attribute*), "Attribute List"); + *valuep = attribute_list; + *countp = count; + for (i = 0; i < count; ++i) + { + result = kmip_decode_attribute(ctx, attribute_list + i); + CHECK_RESULT(ctx, result); + } + + return(KMIP_OK); +} + +int +kmip_decode_template_attribute(KMIP *ctx, TemplateAttribute *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_TEMPLATE_ATTRIBUTE, KMIP_TYPE_STRUCTURE); + + kmip_decode_int32_be(ctx, &length); + CHECK_BUFFER_FULL(ctx, length); + + value->name_count = kmip_get_num_items_next(ctx, KMIP_TAG_NAME); + if(value->name_count > 0) + { + value->names = ctx->calloc_func(ctx->state, value->name_count, sizeof(Name)); + CHECK_NEW_MEMORY(ctx, value->names, value->name_count * sizeof(Name), "sequence of Name structures"); + + for(size_t i = 0; i < value->name_count; i++) + { + result = kmip_decode_name(ctx, &value->names[i]); + CHECK_RESULT(ctx, result); + } + } + + value->attribute_count = kmip_get_num_items_next(ctx, KMIP_TAG_ATTRIBUTE); + if(value->attribute_count > 0) + { + value->attributes = ctx->calloc_func(ctx->state, value->attribute_count, sizeof(Attribute)); + CHECK_NEW_MEMORY(ctx, value->attributes, value->attribute_count * sizeof(Attribute), "sequence of Attribute structures"); + + for(size_t i = 0; i < value->attribute_count; i++) + { + result = kmip_decode_attribute(ctx, &value->attributes[i]); + CHECK_RESULT(ctx, result); + } + } + + return(KMIP_OK); +} + +int +kmip_decode_protocol_version(KMIP *ctx, ProtocolVersion *value) +{ + CHECK_BUFFER_FULL(ctx, 40); + + 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_PROTOCOL_VERSION, KMIP_TYPE_STRUCTURE); + + kmip_decode_int32_be(ctx, &length); + CHECK_LENGTH(ctx, length, 32); + + result = kmip_decode_integer(ctx, KMIP_TAG_PROTOCOL_VERSION_MAJOR, &value->major); + CHECK_RESULT(ctx, result); + + result = kmip_decode_integer(ctx, KMIP_TAG_PROTOCOL_VERSION_MINOR, &value->minor); + CHECK_RESULT(ctx, result); + + return(KMIP_OK); +} + +int +kmip_decode_transparent_symmetric_key(KMIP *ctx, TransparentSymmetricKey *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_KEY_MATERIAL, KMIP_TYPE_STRUCTURE); + + kmip_decode_int32_be(ctx, &length); + CHECK_BUFFER_FULL(ctx, length); + + value->key = ctx->calloc_func(ctx->state, 1, sizeof(ByteString)); + CHECK_NEW_MEMORY(ctx, value->key, sizeof(ByteString), "Key byte string"); + + result = kmip_decode_byte_string(ctx, KMIP_TAG_KEY, value->key); + CHECK_RESULT(ctx, result); + + return(KMIP_OK); +} + +int +kmip_decode_key_material(KMIP *ctx, enum key_format_type format, void **value) +{ + int result = 0; + + switch(format) + { + case KMIP_KEYFORMAT_RAW: + case KMIP_KEYFORMAT_OPAQUE: + case KMIP_KEYFORMAT_PKCS1: + case KMIP_KEYFORMAT_PKCS8: + case KMIP_KEYFORMAT_X509: + case KMIP_KEYFORMAT_EC_PRIVATE_KEY: + *value = ctx->calloc_func(ctx->state, 1, sizeof(ByteString)); + CHECK_NEW_MEMORY(ctx, *value, sizeof(ByteString), "KeyMaterial byte string"); + result = kmip_decode_byte_string(ctx, KMIP_TAG_KEY_MATERIAL, (ByteString*)*value); + CHECK_RESULT(ctx, result); + return(KMIP_OK); + break; + + default: + break; + }; + + switch(format) + { + case KMIP_KEYFORMAT_TRANS_SYMMETRIC_KEY: + *value = ctx->calloc_func(ctx->state, 1, sizeof(TransparentSymmetricKey)); + CHECK_NEW_MEMORY(ctx, *value, sizeof(TransparentSymmetricKey), "TransparentSymmetricKey structure"); + result = kmip_decode_transparent_symmetric_key(ctx, (TransparentSymmetricKey*)*value); + CHECK_RESULT(ctx, result); + break; + + /* TODO (ph) The rest require BigInteger support. */ + + case KMIP_KEYFORMAT_TRANS_DSA_PRIVATE_KEY: + case KMIP_KEYFORMAT_TRANS_DSA_PUBLIC_KEY: + case KMIP_KEYFORMAT_TRANS_RSA_PRIVATE_KEY: + case KMIP_KEYFORMAT_TRANS_RSA_PUBLIC_KEY: + case KMIP_KEYFORMAT_TRANS_DH_PRIVATE_KEY: + case KMIP_KEYFORMAT_TRANS_DH_PUBLIC_KEY: + case KMIP_KEYFORMAT_TRANS_ECDSA_PRIVATE_KEY: + case KMIP_KEYFORMAT_TRANS_ECDSA_PUBLIC_KEY: + case KMIP_KEYFORMAT_TRANS_ECDH_PRIVATE_KEY: + case KMIP_KEYFORMAT_TRANS_ECDH_PUBLIC_KEY: + case KMIP_KEYFORMAT_TRANS_ECMQV_PRIVATE_KEY: + case KMIP_KEYFORMAT_TRANS_ECMQV_PUBLIC_KEY: + default: + kmip_push_error_frame(ctx, __func__, __LINE__); + return(KMIP_NOT_IMPLEMENTED); + break; + }; + + return(KMIP_OK); +} + +int +kmip_decode_key_value(KMIP *ctx, enum key_format_type format, KeyValue *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_KEY_VALUE, KMIP_TYPE_STRUCTURE); + + kmip_decode_int32_be(ctx, &length); + CHECK_BUFFER_FULL(ctx, length); + + result = kmip_decode_key_material(ctx, format, &value->key_material); + CHECK_RESULT(ctx, result); + + value->attribute_count = kmip_get_num_items_next(ctx, KMIP_TAG_ATTRIBUTE); + if(value->attribute_count > 0) + { + value->attributes = ctx->calloc_func(ctx->state, value->attribute_count, sizeof(Attribute)); + CHECK_NEW_MEMORY(ctx, value->attributes, value->attribute_count * sizeof(Attribute), "sequence of Attribute structures"); + + for(size_t i = 0; i < value->attribute_count; i++) + { + result = kmip_decode_attribute(ctx, &value->attributes[i]); + CHECK_RESULT(ctx, result); + } + } + + return(KMIP_OK); +} + +int +kmip_decode_cryptographic_parameters(KMIP *ctx, CryptographicParameters *value) +{ + CHECK_BUFFER_FULL(ctx, 8); + + kmip_init_cryptographic_parameters(value); + + 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_CRYPTOGRAPHIC_PARAMETERS, KMIP_TYPE_STRUCTURE); + + kmip_decode_int32_be(ctx, &length); + CHECK_BUFFER_FULL(ctx, length); + + if(kmip_is_tag_next(ctx, KMIP_TAG_BLOCK_CIPHER_MODE)) + { + result = kmip_decode_enum(ctx, KMIP_TAG_BLOCK_CIPHER_MODE, &value->block_cipher_mode); + CHECK_RESULT(ctx, result); + CHECK_ENUM(ctx, KMIP_TAG_BLOCK_CIPHER_MODE, value->block_cipher_mode); + } + + if(kmip_is_tag_next(ctx, KMIP_TAG_PADDING_METHOD)) + { + result = kmip_decode_enum(ctx, KMIP_TAG_PADDING_METHOD, &value->padding_method); + CHECK_RESULT(ctx, result); + CHECK_ENUM(ctx, KMIP_TAG_PADDING_METHOD, value->padding_method); + } + + if(kmip_is_tag_next(ctx, KMIP_TAG_HASHING_ALGORITHM)) + { + result = kmip_decode_enum(ctx, KMIP_TAG_HASHING_ALGORITHM, &value->hashing_algorithm); + CHECK_RESULT(ctx, result); + CHECK_ENUM(ctx, KMIP_TAG_HASHING_ALGORITHM, value->hashing_algorithm); + } + + if(kmip_is_tag_next(ctx, KMIP_TAG_KEY_ROLE_TYPE)) + { + result = kmip_decode_enum(ctx, KMIP_TAG_KEY_ROLE_TYPE, &value->key_role_type); + CHECK_RESULT(ctx, result); + CHECK_ENUM(ctx, KMIP_TAG_KEY_ROLE_TYPE, value->key_role_type); + } + + if(ctx->version >= KMIP_1_2) + { + if(kmip_is_tag_next(ctx, KMIP_TAG_DIGITAL_SIGNATURE_ALGORITHM)) + { + result = kmip_decode_enum(ctx, KMIP_TAG_DIGITAL_SIGNATURE_ALGORITHM, &value->digital_signature_algorithm); + CHECK_RESULT(ctx, result); + CHECK_ENUM(ctx, KMIP_TAG_DIGITAL_SIGNATURE_ALGORITHM, value->digital_signature_algorithm); + } + + if(kmip_is_tag_next(ctx, KMIP_TAG_CRYPTOGRAPHIC_ALGORITHM)) + { + result = kmip_decode_enum(ctx, KMIP_TAG_CRYPTOGRAPHIC_ALGORITHM, &value->cryptographic_algorithm); + CHECK_RESULT(ctx, result); + CHECK_ENUM(ctx, KMIP_TAG_CRYPTOGRAPHIC_ALGORITHM, value->cryptographic_algorithm); + } + + if(kmip_is_tag_next(ctx, KMIP_TAG_RANDOM_IV)) + { + result = kmip_decode_bool(ctx, KMIP_TAG_RANDOM_IV, &value->random_iv); + CHECK_RESULT(ctx, result); + } + + if(kmip_is_tag_next(ctx, KMIP_TAG_IV_LENGTH)) + { + result = kmip_decode_integer(ctx, KMIP_TAG_IV_LENGTH, &value->iv_length); + CHECK_RESULT(ctx, result); + } + + if(kmip_is_tag_next(ctx, KMIP_TAG_TAG_LENGTH)) + { + result = kmip_decode_integer(ctx, KMIP_TAG_TAG_LENGTH, &value->tag_length); + CHECK_RESULT(ctx, result); + } + + if(kmip_is_tag_next(ctx, KMIP_TAG_FIXED_FIELD_LENGTH)) + { + result = kmip_decode_integer(ctx, KMIP_TAG_FIXED_FIELD_LENGTH, &value->fixed_field_length); + CHECK_RESULT(ctx, result); + } + + if(kmip_is_tag_next(ctx, KMIP_TAG_INVOCATION_FIELD_LENGTH)) + { + result = kmip_decode_integer(ctx, KMIP_TAG_INVOCATION_FIELD_LENGTH, &value->invocation_field_length); + CHECK_RESULT(ctx, result); + } + + if(kmip_is_tag_next(ctx, KMIP_TAG_COUNTER_LENGTH)) + { + result = kmip_decode_integer(ctx, KMIP_TAG_COUNTER_LENGTH, &value->counter_length); + CHECK_RESULT(ctx, result); + } + + if(kmip_is_tag_next(ctx, KMIP_TAG_INITIAL_COUNTER_VALUE)) + { + result = kmip_decode_integer(ctx, KMIP_TAG_INITIAL_COUNTER_VALUE, &value->initial_counter_value); + CHECK_RESULT(ctx, result); + } + } + + if(ctx->version >= KMIP_1_4) + { + if(kmip_is_tag_next(ctx, KMIP_TAG_SALT_LENGTH)) + { + result = kmip_decode_integer(ctx, KMIP_TAG_SALT_LENGTH, &value->salt_length); + CHECK_RESULT(ctx, result); + } + + if(kmip_is_tag_next(ctx, KMIP_TAG_MASK_GENERATOR)) + { + result = kmip_decode_enum(ctx, KMIP_TAG_MASK_GENERATOR, &value->mask_generator); + CHECK_RESULT(ctx, result); + CHECK_ENUM(ctx, KMIP_TAG_MASK_GENERATOR, value->mask_generator); + } + + if(kmip_is_tag_next(ctx, KMIP_TAG_MASK_GENERATOR_HASHING_ALGORITHM)) + { + result = kmip_decode_enum(ctx, KMIP_TAG_MASK_GENERATOR_HASHING_ALGORITHM, &value->mask_generator_hashing_algorithm); + CHECK_RESULT(ctx, result); + CHECK_ENUM(ctx, KMIP_TAG_HASHING_ALGORITHM, value->mask_generator_hashing_algorithm); + } + + if(kmip_is_tag_next(ctx, KMIP_TAG_P_SOURCE)) + { + value->p_source = ctx->calloc_func(ctx->state, 1, sizeof(ByteString)); + CHECK_NEW_MEMORY(ctx, value->p_source, sizeof(ByteString), "P Source byte string"); + + result = kmip_decode_byte_string(ctx, KMIP_TAG_P_SOURCE, value->p_source); + CHECK_RESULT(ctx, result); + } + + if(kmip_is_tag_next(ctx, KMIP_TAG_TRAILER_FIELD)) + { + result = kmip_decode_integer(ctx, KMIP_TAG_TRAILER_FIELD, &value->trailer_field); + CHECK_RESULT(ctx, result); + } + } + + return(KMIP_OK); +} + +int +kmip_decode_encryption_key_information(KMIP *ctx, EncryptionKeyInformation *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_ENCRYPTION_KEY_INFORMATION, KMIP_TYPE_STRUCTURE); + + kmip_decode_int32_be(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); + + if(kmip_is_tag_next(ctx, KMIP_TAG_CRYPTOGRAPHIC_PARAMETERS)) + { + value->cryptographic_parameters = ctx->calloc_func(ctx->state, 1, sizeof(CryptographicParameters)); + CHECK_NEW_MEMORY(ctx, value->cryptographic_parameters, sizeof(CryptographicParameters), "CryptographicParameters structure"); + + result = kmip_decode_cryptographic_parameters(ctx, value->cryptographic_parameters); + CHECK_RESULT(ctx, result); + } + + return(KMIP_OK); +} + +int +kmip_decode_mac_signature_key_information(KMIP *ctx, MACSignatureKeyInformation *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_MAC_SIGNATURE_KEY_INFORMATION, KMIP_TYPE_STRUCTURE); + + kmip_decode_int32_be(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); + + if(kmip_is_tag_next(ctx, KMIP_TAG_CRYPTOGRAPHIC_PARAMETERS)) + { + value->cryptographic_parameters = ctx->calloc_func(ctx->state, 1, sizeof(CryptographicParameters)); + CHECK_NEW_MEMORY(ctx, value->cryptographic_parameters, sizeof(CryptographicParameters), "CryptographicParameters structure"); + + result = kmip_decode_cryptographic_parameters(ctx, value->cryptographic_parameters); + CHECK_RESULT(ctx, result); + } + + return(KMIP_OK); +} + + +int +kmip_decode_key_wrapping_data(KMIP *ctx, KeyWrappingData *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_KEY_WRAPPING_DATA, KMIP_TYPE_STRUCTURE); + + kmip_decode_int32_be(ctx, &length); + CHECK_BUFFER_FULL(ctx, length); + + result = kmip_decode_enum(ctx, KMIP_TAG_WRAPPING_METHOD, &value->wrapping_method); + CHECK_RESULT(ctx, result); + CHECK_ENUM(ctx, KMIP_TAG_WRAPPING_METHOD, value->wrapping_method); + + if(kmip_is_tag_next(ctx, KMIP_TAG_ENCRYPTION_KEY_INFORMATION)) + { + value->encryption_key_info = ctx->calloc_func(ctx->state, 1, sizeof(EncryptionKeyInformation)); + CHECK_NEW_MEMORY(ctx, value->encryption_key_info, sizeof(EncryptionKeyInformation), "EncryptionKeyInformation structure"); + + result = kmip_decode_encryption_key_information(ctx, value->encryption_key_info); + CHECK_RESULT(ctx, result); + } + + if(kmip_is_tag_next(ctx, KMIP_TAG_MAC_SIGNATURE_KEY_INFORMATION)) + { + value->mac_signature_key_info = ctx->calloc_func(ctx->state, 1, sizeof(MACSignatureKeyInformation)); + CHECK_NEW_MEMORY(ctx, value->mac_signature_key_info, sizeof(MACSignatureKeyInformation), "MAC/SignatureKeyInformation structure"); + + result = kmip_decode_mac_signature_key_information(ctx, value->mac_signature_key_info); + CHECK_RESULT(ctx, result); + } + + if(kmip_is_tag_next(ctx, KMIP_TAG_MAC_SIGNATURE)) + { + value->mac_signature = ctx->calloc_func(ctx->state, 1, sizeof(ByteString)); + CHECK_NEW_MEMORY(ctx, value->mac_signature, sizeof(ByteString), "MAC/Signature byte string"); + + result = kmip_decode_byte_string(ctx, KMIP_TAG_MAC_SIGNATURE, value->mac_signature); + CHECK_RESULT(ctx, result); + } + + if(kmip_is_tag_next(ctx, KMIP_TAG_IV_COUNTER_NONCE)) + { + value->iv_counter_nonce = ctx->calloc_func(ctx->state, 1, sizeof(ByteString)); + CHECK_NEW_MEMORY(ctx, value->iv_counter_nonce, sizeof(ByteString), "IV/Counter/Nonce byte string"); + + result = kmip_decode_byte_string(ctx, KMIP_TAG_IV_COUNTER_NONCE, value->iv_counter_nonce); + CHECK_RESULT(ctx, result); + } + + if(ctx->version >= KMIP_1_1) + { + if(kmip_is_tag_next(ctx, KMIP_TAG_ENCODING_OPTION)) + { + result = kmip_decode_enum(ctx, KMIP_TAG_ENCODING_OPTION, &value->encoding_option); + CHECK_RESULT(ctx, result); + CHECK_ENUM(ctx, KMIP_TAG_ENCODING_OPTION, value->encoding_option); + } + } + + return(KMIP_OK); +} + +int +kmip_decode_key_block(KMIP *ctx, KeyBlock *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_KEY_BLOCK, KMIP_TYPE_STRUCTURE); + + kmip_decode_int32_be(ctx, &length); + CHECK_BUFFER_FULL(ctx, length); + + result = kmip_decode_enum(ctx, KMIP_TAG_KEY_FORMAT_TYPE, &value->key_format_type); + CHECK_RESULT(ctx, result); + CHECK_ENUM(ctx, KMIP_TAG_KEY_FORMAT_TYPE, value->key_format_type); + + if(kmip_is_tag_next(ctx, KMIP_TAG_KEY_COMPRESSION_TYPE)) + { + result = kmip_decode_enum(ctx, KMIP_TAG_KEY_COMPRESSION_TYPE, &value->key_compression_type); + CHECK_RESULT(ctx, result); + CHECK_ENUM(ctx, KMIP_TAG_KEY_COMPRESSION_TYPE, value->key_compression_type); + } + + if(kmip_is_tag_type_next(ctx, KMIP_TAG_KEY_VALUE, KMIP_TYPE_BYTE_STRING)) + { + value->key_value_type = KMIP_TYPE_BYTE_STRING; + value->key_value = ctx->calloc_func(ctx->state, 1, sizeof(ByteString)); + CHECK_NEW_MEMORY(ctx, value->key_value, sizeof(ByteString), "KeyValue byte string"); + + result = kmip_decode_byte_string(ctx, KMIP_TAG_KEY_VALUE, (ByteString *)value->key_value); + } + else + { + value->key_value_type = KMIP_TYPE_STRUCTURE; + value->key_value = ctx->calloc_func(ctx->state, 1, sizeof(KeyValue)); + CHECK_NEW_MEMORY(ctx, value->key_value, sizeof(KeyValue), "KeyValue structure"); + + result = kmip_decode_key_value(ctx, value->key_format_type, (KeyValue *)value->key_value); + } + CHECK_RESULT(ctx, result); + + if(kmip_is_tag_next(ctx, KMIP_TAG_CRYPTOGRAPHIC_ALGORITHM)) + { + result = kmip_decode_enum(ctx, KMIP_TAG_CRYPTOGRAPHIC_ALGORITHM, &value->cryptographic_algorithm); + CHECK_RESULT(ctx, result); + CHECK_ENUM(ctx, KMIP_TAG_CRYPTOGRAPHIC_ALGORITHM, value->cryptographic_algorithm); + } + + if(kmip_is_tag_next(ctx, KMIP_TAG_CRYPTOGRAPHIC_LENGTH)) + { + result = kmip_decode_integer(ctx, KMIP_TAG_CRYPTOGRAPHIC_LENGTH, &value->cryptographic_length); + CHECK_RESULT(ctx, result); + } + + if(kmip_is_tag_next(ctx, KMIP_TAG_KEY_WRAPPING_DATA)) + { + value->key_wrapping_data = ctx->calloc_func(ctx->state, 1, sizeof(KeyWrappingData)); + CHECK_NEW_MEMORY(ctx, value->key_wrapping_data, sizeof(KeyWrappingData), "KeyWrappingData structure"); + + result = kmip_decode_key_wrapping_data(ctx, value->key_wrapping_data); + CHECK_RESULT(ctx, result); + } + + return(KMIP_OK); +} + +int +kmip_decode_symmetric_key(KMIP *ctx, SymmetricKey *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_SYMMETRIC_KEY, KMIP_TYPE_STRUCTURE); + + kmip_decode_int32_be(ctx, &length); + CHECK_BUFFER_FULL(ctx, length); + + value->key_block = ctx->calloc_func(ctx->state, 1, sizeof(KeyBlock)); + CHECK_NEW_MEMORY(ctx, value->key_block, sizeof(KeyBlock), "KeyBlock structure"); + + result = kmip_decode_key_block(ctx, value->key_block); + CHECK_RESULT(ctx, result); + + return(KMIP_OK); +} + +int +kmip_decode_public_key(KMIP *ctx, PublicKey *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_PUBLIC_KEY, KMIP_TYPE_STRUCTURE); + + kmip_decode_int32_be(ctx, &length); + CHECK_BUFFER_FULL(ctx, length); + + value->key_block = ctx->calloc_func(ctx->state, 1, sizeof(KeyBlock)); + CHECK_NEW_MEMORY(ctx, value->key_block, sizeof(KeyBlock), "KeyBlock structure"); + + result = kmip_decode_key_block(ctx, value->key_block); + CHECK_RESULT(ctx, result); + + return(KMIP_OK); +} + +int +kmip_decode_private_key(KMIP *ctx, PrivateKey *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_PRIVATE_KEY, KMIP_TYPE_STRUCTURE); + + kmip_decode_int32_be(ctx, &length); + CHECK_BUFFER_FULL(ctx, length); + + value->key_block = ctx->calloc_func(ctx->state, 1, sizeof(KeyBlock)); + CHECK_NEW_MEMORY(ctx, value->key_block, sizeof(KeyBlock), "KeyBlock structure"); + + result = kmip_decode_key_block(ctx, value->key_block); + CHECK_RESULT(ctx, result); + + return(KMIP_OK); +} + +int +kmip_decode_key_wrapping_specification(KMIP *ctx, KeyWrappingSpecification *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_KEY_WRAPPING_SPECIFICATION, KMIP_TYPE_STRUCTURE); + + kmip_decode_int32_be(ctx, &length); + CHECK_BUFFER_FULL(ctx, length); + + result = kmip_decode_enum(ctx, KMIP_TAG_WRAPPING_METHOD, &value->wrapping_method); + CHECK_RESULT(ctx, result); + CHECK_ENUM(ctx, KMIP_TAG_WRAPPING_METHOD, value->wrapping_method); + + if(kmip_is_tag_next(ctx, KMIP_TAG_ENCRYPTION_KEY_INFORMATION)) + { + value->encryption_key_info = ctx->calloc_func(ctx->state, 1, sizeof(EncryptionKeyInformation)); + CHECK_NEW_MEMORY(ctx, value->encryption_key_info, sizeof(EncryptionKeyInformation), "EncryptionKeyInformation structure"); + result = kmip_decode_encryption_key_information(ctx, value->encryption_key_info); + CHECK_RESULT(ctx, result); + } + + if(kmip_is_tag_next(ctx, KMIP_TAG_MAC_SIGNATURE_KEY_INFORMATION)) + { + value->mac_signature_key_info = ctx->calloc_func(ctx->state, 1, sizeof(MACSignatureKeyInformation)); + CHECK_NEW_MEMORY(ctx, value->mac_signature_key_info, sizeof(MACSignatureKeyInformation), "MACSignatureKeyInformation structure"); + result = kmip_decode_mac_signature_key_information(ctx, value->mac_signature_key_info); + CHECK_RESULT(ctx, result); + } + + value->attribute_name_count = kmip_get_num_items_next(ctx, KMIP_TAG_ATTRIBUTE_NAME); + if(value->attribute_name_count > 0) + { + value->attribute_names = ctx->calloc_func(ctx->state, value->attribute_name_count, sizeof(TextString)); + CHECK_NEW_MEMORY(ctx, value->attribute_names, value->attribute_name_count * sizeof(TextString), "sequence of AttributeName text strings"); + + for(size_t i = 0; i < value->attribute_name_count; i++) + { + result = kmip_decode_text_string(ctx, KMIP_TAG_ATTRIBUTE_NAME, &value->attribute_names[i]); + CHECK_RESULT(ctx, result); + } + } + + if(ctx->version >= KMIP_1_1) + { + result = kmip_decode_enum(ctx, KMIP_TAG_ENCODING_OPTION, &value->encoding_option); + CHECK_RESULT(ctx, result); + CHECK_ENUM(ctx, KMIP_TAG_ENCODING_OPTION, value->encoding_option); + } + + return(KMIP_OK); +} + +int +kmip_decode_create_request_payload(KMIP *ctx, CreateRequestPayload *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_int32_be(ctx, &length); + CHECK_BUFFER_FULL(ctx, length); + + result = kmip_decode_enum(ctx, KMIP_TAG_OBJECT_TYPE, &value->object_type); + CHECK_RESULT(ctx, result); + CHECK_ENUM(ctx, KMIP_TAG_OBJECT_TYPE, value->object_type); + + if(ctx->version < KMIP_2_0) + { + value->template_attribute = ctx->calloc_func(ctx->state, 1, sizeof(TemplateAttribute)); + if(value->template_attribute == NULL) + { + HANDLE_FAILED_ALLOC(ctx, sizeof(TemplateAttribute), "TemplateAttribute"); + } + result = kmip_decode_template_attribute(ctx, value->template_attribute); + if(result != KMIP_OK) + { + kmip_free_template_attribute(ctx, value->template_attribute); + ctx->free_func(ctx, value->template_attribute); + value->template_attribute = NULL; + HANDLE_FAILURE(ctx, result); + } + } + else + { + value->attributes = ctx->calloc_func(ctx->state, 1, sizeof(Attributes)); + if(value->attributes == NULL) + { + HANDLE_FAILED_ALLOC(ctx, sizeof(Attributes), "Attributes"); + } + result = kmip_decode_attributes(ctx, value->attributes); + if(result != KMIP_OK) + { + kmip_free_attributes(ctx, value->attributes); + ctx->free_func(ctx, value->attributes); + value->attributes = NULL; + + HANDLE_FAILURE(ctx, result); + } + + if(kmip_is_tag_next(ctx, KMIP_TAG_PROTECTION_STORAGE_MASKS)) + { + value->protection_storage_masks = ctx->calloc_func(ctx->state, 1, sizeof(ProtectionStorageMasks)); + if(value->protection_storage_masks == NULL) + { + kmip_free_attributes(ctx, value->attributes); + ctx->free_func(ctx, value->attributes); + value->attributes = NULL; + + HANDLE_FAILED_ALLOC(ctx, sizeof(ProtectionStorageMasks), "ProtectionStorageMasks"); + } + result = kmip_decode_protection_storage_masks(ctx, value->protection_storage_masks); + if(result != KMIP_OK) + { + kmip_free_attributes(ctx, value->attributes); + kmip_free_protection_storage_masks(ctx, value->protection_storage_masks); + ctx->free_func(ctx, value->attributes); + ctx->free_func(ctx, value->protection_storage_masks); + value->attributes = NULL; + value->protection_storage_masks = NULL; + + HANDLE_FAILURE(ctx, result); + } + } + } + + return(KMIP_OK); +} + +int +kmip_decode_create_response_payload(KMIP *ctx, CreateResponsePayload *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_RESPONSE_PAYLOAD, KMIP_TYPE_STRUCTURE); + + kmip_decode_int32_be(ctx, &length); + CHECK_BUFFER_FULL(ctx, length); + + result = kmip_decode_enum(ctx, KMIP_TAG_OBJECT_TYPE, &value->object_type); + CHECK_RESULT(ctx, result); + CHECK_ENUM(ctx, KMIP_TAG_OBJECT_TYPE, value->object_type); + + 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(ctx->version < KMIP_2_0) + { + if(kmip_is_tag_next(ctx, KMIP_TAG_TEMPLATE_ATTRIBUTE)) + { + value->template_attribute = ctx->calloc_func(ctx->state, 1, sizeof(TemplateAttribute)); + CHECK_NEW_MEMORY(ctx, value->template_attribute, sizeof(TemplateAttribute), "TemplateAttribute structure"); + + result = kmip_decode_template_attribute(ctx, value->template_attribute); + CHECK_RESULT(ctx, result); + } + } + + 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; + int i; + + value->attributes = 0; + kmip_decode_int32_be(ctx, &tag_type); + CHECK_TAG_TYPE(ctx, tag_type, KMIP_TAG_REQUEST_PAYLOAD, KMIP_TYPE_STRUCTURE); + + kmip_decode_int32_be(ctx, &length); + CHECK_BUFFER_FULL(ctx, length); + + if(kmip_is_tag_next(ctx, KMIP_TAG_MAXIMUM_ITEMS)) + { + result = kmip_decode_enum(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_enum(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_enum(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->object_group_member); + CHECK_RESULT(ctx, result); + } + + if(ctx->version < KMIP_2_0) + { + value->attribute_count = kmip_get_num_items_next(ctx, KMIP_TAG_ATTRIBUTE); + + value->attributes = ctx->calloc_func(ctx->state, value->attribute_count, sizeof(Attributes)); + CHECK_NEW_MEMORY(ctx, value->attributes, + value->attribute_count*sizeof(Attributes), "Attributes list"); + for (i = 0; i < value->attribute_count; ++i) + { + result = kmip_decode_attribute(ctx, value->attributes + i); + CHECK_RESULT(ctx, result); + } + } else { + if(kmip_is_tag_next(ctx, KMIP_TAG_ATTRIBUTES)) + { + result = kmip_decode_attributes_2(ctx, &value->attributes, &value->attribute_count); + if (result != KMIP_OK) + { + kmip_free_attributes_2(ctx, value->attributes, value->attribute_count); + value->attributes = 0; + value->attribute_count = 0; + return 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; + int i; + + value->unique_identifiers = NULL; + 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_enum(ctx, KMIP_TAG_MAXIMUM_ITEMS, &value->located_items); + CHECK_RESULT(ctx, result); + } + + value->unique_identifiers_count = kmip_get_num_items_next(ctx, KMIP_TAG_UNIQUE_IDENTIFIER); + value->unique_identifiers = ctx->calloc_func(ctx->state, value->unique_identifiers_count, sizeof(TextString)); + CHECK_NEW_MEMORY(ctx, value->unique_identifiers, + value->unique_identifiers_count*sizeof(TextString), "UniqueIdentifier list"); + for (i = 0; i < value->unique_identifiers_count; ++i) + { + result = kmip_decode_text_string(ctx, KMIP_TAG_UNIQUE_IDENTIFIER, value->unique_identifiers +i); + CHECK_RESULT(ctx, result); + } + + return(KMIP_OK); +} + +int +kmip_decode_get_request_payload(KMIP *ctx, GetRequestPayload *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_int32_be(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_KEY_FORMAT_TYPE)) + { + result = kmip_decode_enum(ctx, KMIP_TAG_KEY_FORMAT_TYPE, &value->key_format_type); + CHECK_RESULT(ctx, result); + CHECK_ENUM(ctx, KMIP_TAG_KEY_FORMAT_TYPE, value->key_format_type); + } + + if(ctx->version >= KMIP_1_4) + { + if(kmip_is_tag_next(ctx, KMIP_TAG_KEY_WRAP_TYPE)) + { + result = kmip_decode_enum(ctx, KMIP_TAG_KEY_WRAP_TYPE, &value->key_wrap_type); + CHECK_RESULT(ctx, result); + CHECK_ENUM(ctx, KMIP_TAG_KEY_WRAP_TYPE, value->key_wrap_type); + } + } + + if(kmip_is_tag_next(ctx, KMIP_TAG_KEY_COMPRESSION_TYPE)) + { + result = kmip_decode_enum(ctx, KMIP_TAG_KEY_COMPRESSION_TYPE, &value->key_compression_type); + CHECK_RESULT(ctx, result); + CHECK_ENUM(ctx, KMIP_TAG_KEY_COMPRESSION_TYPE, value->key_compression_type); + } + + if(kmip_is_tag_next(ctx, KMIP_TAG_KEY_WRAPPING_SPECIFICATION)) + { + value->key_wrapping_spec = ctx->calloc_func(ctx->state, 1, sizeof(KeyWrappingSpecification)); + CHECK_NEW_MEMORY(ctx, value->key_wrapping_spec, sizeof(KeyWrappingSpecification), "KeyWrappingSpecification structure"); + result = kmip_decode_key_wrapping_specification(ctx, value->key_wrapping_spec); + CHECK_RESULT(ctx, result); + } + + return(KMIP_OK); +} + +int +kmip_decode_get_response_payload(KMIP *ctx, GetResponsePayload *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); + + result = kmip_decode_enum(ctx, KMIP_TAG_OBJECT_TYPE, &value->object_type); + CHECK_RESULT(ctx, result); + CHECK_ENUM(ctx, KMIP_TAG_OBJECT_TYPE, value->object_type); + + 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); + + switch(value->object_type) + { + case KMIP_OBJTYPE_SYMMETRIC_KEY: + value->object = ctx->calloc_func(ctx->state, 1, sizeof(SymmetricKey)); + CHECK_NEW_MEMORY(ctx, value->object, sizeof(SymmetricKey), "SymmetricKey structure"); + result = kmip_decode_symmetric_key(ctx, (SymmetricKey*)value->object); + CHECK_RESULT(ctx, result); + break; + + case KMIP_OBJTYPE_PUBLIC_KEY: + value->object = ctx->calloc_func(ctx->state, 1, sizeof(PublicKey)); + CHECK_NEW_MEMORY(ctx, value->object, sizeof(PublicKey), "PublicKey structure"); + result = kmip_decode_public_key(ctx, (PublicKey*)value->object); + CHECK_RESULT(ctx, result); + break; + + case KMIP_OBJTYPE_PRIVATE_KEY: + value->object = ctx->calloc_func(ctx->state, 1, sizeof(PrivateKey)); + CHECK_NEW_MEMORY(ctx, value->object, sizeof(PrivateKey), "PrivateKey structure"); + result = kmip_decode_private_key(ctx, (PrivateKey*)value->object); + CHECK_RESULT(ctx, result); + break; + + default: + kmip_push_error_frame(ctx, __func__, __LINE__); + return(KMIP_NOT_IMPLEMENTED); + break; + }; + + return(KMIP_OK); +} + +int +kmip_decode_get_attributes_request_payload(KMIP *ctx, GetAttributesRequestPayload *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_int32_be(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(ctx->version < KMIP_2_0) + { + value->attribute_count = kmip_get_num_items_next(ctx, KMIP_TAG_ATTRIBUTE_NAME); + + value->attribute_names = ctx->calloc_func(ctx->state, value->attribute_count, sizeof(enum attribute_type)); + CHECK_NEW_MEMORY(ctx, value->attribute_names, + value->attribute_count*sizeof(Attributes), "Attribute name list"); + for (int i = 0; i < value->attribute_count; ++i) + { + result = kmip_decode_attribute_name(ctx, value->attribute_names + i); + CHECK_RESULT(ctx, result); + } + } else { +// XXX something weird goes here. + return(KMIP_NOT_IMPLEMENTED); + } + + 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_int32_be(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); + + if(ctx->version < KMIP_2_0) + { + value->attribute_count = kmip_get_num_items_next(ctx, KMIP_TAG_ATTRIBUTE); + + value->attributes = ctx->calloc_func(ctx->state, value->attribute_count, sizeof(Attribute)); + CHECK_NEW_MEMORY(ctx, value->attributes, + value->attribute_count*sizeof(Attributes), "Attributes list"); + for (int i = 0; i < value->attribute_count; ++i) + { + result = kmip_decode_attribute(ctx, value->attributes + i); + CHECK_RESULT(ctx, result); + } + } else { + if(kmip_is_tag_next(ctx, KMIP_TAG_ATTRIBUTES)) + { + result = kmip_decode_attributes_2(ctx, &value->attributes, &value->attribute_count); + if (result != KMIP_OK) + { + kmip_free_attributes_2(ctx, value->attributes, value->attribute_count); + value->attributes = 0; + value->attribute_count = 0; + return result; + } + } + } + + return(KMIP_OK); +} + +int +kmip_decode_get_attribute_list_request_payload(KMIP *ctx, GetAttributeListRequestPayload *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_int32_be(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_get_attribute_list_response_payload(KMIP *ctx, GetAttributeListResponsePayload *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); + + 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(ctx->version < KMIP_2_0) + { + value->attribute_names_count = kmip_get_num_items_next(ctx, KMIP_TAG_ATTRIBUTE_NAME); + + value->attribute_names = ctx->calloc_func(ctx->state, value->attribute_names_count, sizeof(enum attribute_type)); + CHECK_NEW_MEMORY(ctx, value->attribute_names, + value->attribute_names_count*sizeof(Attributes), "Attribute name list"); + for (int i = 0; i < value->attribute_names_count; ++i) + { + result = kmip_decode_attribute_name(ctx, value->attribute_names + i); + CHECK_RESULT(ctx, result); + } + } else { +// XXX something weird goes here. + return(KMIP_NOT_IMPLEMENTED); + } + + return(KMIP_OK); +} + +int +kmip_decode_destroy_request_payload(KMIP *ctx, DestroyRequestPayload *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_int32_be(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_destroy_response_payload(KMIP *ctx, DestroyResponsePayload *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); + + 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_request_batch_item(KMIP *ctx, RequestBatchItem *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_BATCH_ITEM, KMIP_TYPE_STRUCTURE); + + kmip_decode_int32_be(ctx, &length); + CHECK_BUFFER_FULL(ctx, length); + + result = kmip_decode_enum(ctx, KMIP_TAG_OPERATION, &value->operation); + CHECK_RESULT(ctx, result); + CHECK_ENUM(ctx, KMIP_TAG_OPERATION, value->operation); + + if(ctx->version >= KMIP_2_0) + { + if(kmip_is_tag_next(ctx, KMIP_TAG_EPHEMERAL)) + { + result = kmip_decode_bool(ctx, KMIP_TAG_EPHEMERAL, &value->ephemeral); + CHECK_RESULT(ctx, result); + } + } + + if(kmip_is_tag_next(ctx, KMIP_TAG_UNIQUE_BATCH_ITEM_ID)) + { + value->unique_batch_item_id = ctx->calloc_func(ctx->state, 1, sizeof(ByteString)); + CHECK_NEW_MEMORY(ctx, value->unique_batch_item_id, sizeof(ByteString), "UniqueBatchItemID byte string"); + result = kmip_decode_byte_string(ctx, KMIP_TAG_UNIQUE_BATCH_ITEM_ID, value->unique_batch_item_id); + CHECK_RESULT(ctx, result); + } + + switch(value->operation) + { + case KMIP_OP_CREATE: + value->request_payload = ctx->calloc_func(ctx->state, 1, sizeof(CreateRequestPayload)); + CHECK_NEW_MEMORY(ctx, value->request_payload, sizeof(CreateRequestPayload), "CreateRequestPayload structure"); + result = kmip_decode_create_request_payload(ctx, (CreateRequestPayload *)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; + + case KMIP_OP_GET: + value->request_payload = ctx->calloc_func(ctx->state, 1, sizeof(GetRequestPayload)); + 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_GET_ATTRIBUTES: + value->request_payload = ctx->calloc_func(ctx->state, 1, sizeof(GetAttributesRequestPayload)); + CHECK_NEW_MEMORY(ctx, value->request_payload, sizeof(GetAttributesRequestPayload), "GetAttributesRequestPayload structure"); + result = kmip_decode_get_attributes_request_payload(ctx, (GetAttributesRequestPayload*)value->request_payload); + break; + + case KMIP_OP_GET_ATTRIBUTE_LIST: + value->request_payload = ctx->calloc_func(ctx->state, 1, sizeof(GetAttributeListRequestPayload)); + CHECK_NEW_MEMORY(ctx, value->request_payload, sizeof(GetAttributeListRequestPayload), "GetAttributeListRequestPayload structure"); + result = kmip_decode_get_attribute_list_request_payload(ctx, (GetAttributeListRequestPayload*)value->request_payload); + break; + + case KMIP_OP_DESTROY: + value->request_payload = ctx->calloc_func(ctx->state, 1, sizeof(DestroyRequestPayload)); + CHECK_NEW_MEMORY(ctx, value->request_payload, sizeof(DestroyRequestPayload), "DestroyRequestPayload structure"); + result = kmip_decode_destroy_request_payload(ctx, (DestroyRequestPayload*)value->request_payload); + break; + + default: + kmip_push_error_frame(ctx, __func__, __LINE__); + return(KMIP_NOT_IMPLEMENTED); + break; + }; + CHECK_RESULT(ctx, result); + + return(KMIP_OK); +} + +int +kmip_decode_response_batch_item(KMIP *ctx, ResponseBatchItem *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_BATCH_ITEM, KMIP_TYPE_STRUCTURE); + + kmip_decode_int32_be(ctx, &length); + CHECK_BUFFER_FULL(ctx, length); + + if(kmip_is_tag_next(ctx, KMIP_TAG_OPERATION)) + { + result = kmip_decode_enum(ctx, KMIP_TAG_OPERATION, &value->operation); + CHECK_RESULT(ctx, result); + CHECK_ENUM(ctx, KMIP_TAG_OPERATION, value->operation); + } + + if(kmip_is_tag_next(ctx, KMIP_TAG_UNIQUE_BATCH_ITEM_ID)) + { + value->unique_batch_item_id = ctx->calloc_func(ctx->state, 1, sizeof(ByteString)); + CHECK_NEW_MEMORY(ctx, value->unique_batch_item_id, sizeof(ByteString), "UniqueBatchItemID byte string"); + + result = kmip_decode_byte_string(ctx, KMIP_TAG_UNIQUE_BATCH_ITEM_ID, value->unique_batch_item_id); + CHECK_RESULT(ctx, result); + } + + result = kmip_decode_enum(ctx, KMIP_TAG_RESULT_STATUS, &value->result_status); + CHECK_RESULT(ctx, result); + CHECK_ENUM(ctx, KMIP_TAG_RESULT_STATUS, value->result_status); + + if(kmip_is_tag_next(ctx, KMIP_TAG_RESULT_REASON)) + { + result = kmip_decode_enum(ctx, KMIP_TAG_RESULT_REASON, &value->result_reason); + CHECK_RESULT(ctx, result); + } + + if(kmip_is_tag_next(ctx, KMIP_TAG_RESULT_MESSAGE)) + { + value->result_message = ctx->calloc_func(ctx->state, 1, sizeof(TextString)); + CHECK_NEW_MEMORY(ctx, value->result_message, sizeof(TextString), "ResultMessage text string"); + + result = kmip_decode_text_string(ctx, KMIP_TAG_RESULT_MESSAGE, value->result_message); + CHECK_RESULT(ctx, result); + } + + if(kmip_is_tag_next(ctx, KMIP_TAG_ASYNCHRONOUS_CORRELATION_VALUE)) + { + value->asynchronous_correlation_value = ctx->calloc_func(ctx->state, 1, sizeof(ByteString)); + CHECK_NEW_MEMORY(ctx, value->asynchronous_correlation_value, sizeof(ByteString), "AsynchronousCorrelationValue byte string"); + + result = kmip_decode_byte_string(ctx, KMIP_TAG_ASYNCHRONOUS_CORRELATION_VALUE, value->asynchronous_correlation_value); + CHECK_RESULT(ctx, result); + } + + /* NOTE (ph) Omitting the tag check is a good way to test error output. */ + if(kmip_is_tag_next(ctx, KMIP_TAG_RESPONSE_PAYLOAD)) + { + switch(value->operation) + { + case KMIP_OP_CREATE: + value->response_payload = ctx->calloc_func(ctx->state, 1, sizeof(CreateResponsePayload)); + CHECK_NEW_MEMORY(ctx, value->response_payload, sizeof(CreateResponsePayload), "CreateResponsePayload structure"); + result = kmip_decode_create_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; + + case KMIP_OP_GET: + value->response_payload = ctx->calloc_func(ctx->state, 1, sizeof(GetResponsePayload)); + CHECK_NEW_MEMORY(ctx, value->response_payload, sizeof(GetResponsePayload), "GetResponsePayload structure"); + + result = kmip_decode_get_response_payload(ctx, value->response_payload); + break; + + case KMIP_OP_GET_ATTRIBUTES: + value->response_payload = ctx->calloc_func(ctx->state, 1, sizeof(GetAttributesResponsePayload)); + CHECK_NEW_MEMORY(ctx, value->response_payload, sizeof(GetAttributesResponsePayload), "GetAttributesResponsePayload structure"); + + result = kmip_decode_get_attributes_response_payload(ctx, value->response_payload); + break; + + case KMIP_OP_GET_ATTRIBUTE_LIST: + value->response_payload = ctx->calloc_func(ctx->state, 1, sizeof(GetAttributeListResponsePayload)); + CHECK_NEW_MEMORY(ctx, value->response_payload, sizeof(GetAttributeListResponsePayload), "GetAttributeListResponsePayload structure"); + + result = kmip_decode_get_attribute_list_response_payload(ctx, value->response_payload); + break; + + case KMIP_OP_DESTROY: + value->response_payload = ctx->calloc_func(ctx->state, 1, sizeof(DestroyResponsePayload)); + CHECK_NEW_MEMORY(ctx, value->response_payload, sizeof(DestroyResponsePayload), "DestroyResponsePayload structure"); + result = kmip_decode_destroy_response_payload(ctx, value->response_payload); + break; + + default: + kmip_push_error_frame(ctx, __func__, __LINE__); + return(KMIP_NOT_IMPLEMENTED); + break; + }; + CHECK_RESULT(ctx, result); + } + + return(KMIP_OK); +} + +int +kmip_decode_nonce(KMIP *ctx, Nonce *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_NONCE, KMIP_TYPE_STRUCTURE); + + kmip_decode_int32_be(ctx, &length); + CHECK_BUFFER_FULL(ctx, length); + + value->nonce_id = ctx->calloc_func(ctx->state, 1, sizeof(ByteString)); + CHECK_NEW_MEMORY(ctx, value->nonce_id, sizeof(ByteString), "NonceID byte string"); + + result = kmip_decode_byte_string(ctx, KMIP_TAG_NONCE_ID, value->nonce_id); + CHECK_RESULT(ctx, result); + + value->nonce_value = ctx->calloc_func(ctx->state, 1, sizeof(ByteString)); + CHECK_NEW_MEMORY(ctx, value->nonce_value, sizeof(ByteString), "NonceValue byte string"); + + result = kmip_decode_byte_string(ctx, KMIP_TAG_NONCE_VALUE, value->nonce_value); + CHECK_RESULT(ctx, result); + + return(KMIP_OK); +} + +int +kmip_decode_username_password_credential(KMIP *ctx, UsernamePasswordCredential *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_CREDENTIAL_VALUE, KMIP_TYPE_STRUCTURE); + + kmip_decode_int32_be(ctx, &length); + CHECK_BUFFER_FULL(ctx, length); + + value->username = ctx->calloc_func(ctx->state, 1, sizeof(TextString)); + CHECK_NEW_MEMORY(ctx, value->username, sizeof(TextString), "Username text string"); + + result = kmip_decode_text_string(ctx, KMIP_TAG_USERNAME, value->username); + CHECK_RESULT(ctx, result); + + if(kmip_is_tag_next(ctx, KMIP_TAG_PASSWORD)) + { + value->password = ctx->calloc_func(ctx->state, 1, sizeof(TextString)); + CHECK_NEW_MEMORY(ctx, value->password, sizeof(TextString), "Password text string"); + + result = kmip_decode_text_string(ctx, KMIP_TAG_PASSWORD, value->password); + CHECK_RESULT(ctx, result); + } + + return(KMIP_OK); +} + +int +kmip_decode_device_credential(KMIP *ctx, DeviceCredential *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_CREDENTIAL_VALUE, KMIP_TYPE_STRUCTURE); + + kmip_decode_int32_be(ctx, &length); + CHECK_BUFFER_FULL(ctx, length); + + if(kmip_is_tag_next(ctx, KMIP_TAG_DEVICE_SERIAL_NUMBER)) + { + value->device_serial_number = ctx->calloc_func(ctx->state, 1, sizeof(TextString)); + CHECK_NEW_MEMORY(ctx, value->device_serial_number, sizeof(TextString), "DeviceSerialNumber text string"); + + result = kmip_decode_text_string(ctx, KMIP_TAG_DEVICE_SERIAL_NUMBER, value->device_serial_number); + CHECK_RESULT(ctx, result); + } + + if(kmip_is_tag_next(ctx, KMIP_TAG_PASSWORD)) + { + value->password = ctx->calloc_func(ctx->state, 1, sizeof(TextString)); + CHECK_NEW_MEMORY(ctx, value->password, sizeof(TextString), "Password text string"); + + result = kmip_decode_text_string(ctx, KMIP_TAG_PASSWORD, value->password); + CHECK_RESULT(ctx, result); + } + + if(kmip_is_tag_next(ctx, KMIP_TAG_DEVICE_IDENTIFIER)) + { + value->device_identifier = ctx->calloc_func(ctx->state, 1, sizeof(TextString)); + CHECK_NEW_MEMORY(ctx, value->device_identifier, sizeof(TextString), "DeviceIdentifier text string"); + + result = kmip_decode_text_string(ctx, KMIP_TAG_DEVICE_IDENTIFIER, value->device_identifier); + CHECK_RESULT(ctx, result); + } + + if(kmip_is_tag_next(ctx, KMIP_TAG_NETWORK_IDENTIFIER)) + { + value->network_identifier = ctx->calloc_func(ctx->state, 1, sizeof(TextString)); + CHECK_NEW_MEMORY(ctx, value->network_identifier, sizeof(TextString), "NetworkIdentifier text string"); + + result = kmip_decode_text_string(ctx, KMIP_TAG_NETWORK_IDENTIFIER, value->network_identifier); + CHECK_RESULT(ctx, result); + } + + if(kmip_is_tag_next(ctx, KMIP_TAG_MACHINE_IDENTIFIER)) + { + value->machine_identifier = ctx->calloc_func(ctx->state, 1, sizeof(TextString)); + CHECK_NEW_MEMORY(ctx, value->machine_identifier, sizeof(TextString), "MachineIdentifier text string"); + + result = kmip_decode_text_string(ctx, KMIP_TAG_MACHINE_IDENTIFIER, value->machine_identifier); + CHECK_RESULT(ctx, result); + } + + if(kmip_is_tag_next(ctx, KMIP_TAG_MEDIA_IDENTIFIER)) + { + value->media_identifier = ctx->calloc_func(ctx->state, 1, sizeof(TextString)); + CHECK_NEW_MEMORY(ctx, value->media_identifier, sizeof(TextString), "MediaIdentifier text string"); + + result = kmip_decode_text_string(ctx, KMIP_TAG_MEDIA_IDENTIFIER, value->media_identifier); + CHECK_RESULT(ctx, result); + } + + return(KMIP_OK); +} + +int +kmip_decode_attestation_credential(KMIP *ctx, AttestationCredential *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_CREDENTIAL_VALUE, KMIP_TYPE_STRUCTURE); + + kmip_decode_int32_be(ctx, &length); + CHECK_BUFFER_FULL(ctx, length); + + value->nonce = ctx->calloc_func(ctx->state, 1, sizeof(Nonce)); + CHECK_NEW_MEMORY(ctx, value->nonce, sizeof(Nonce), "Nonce structure"); + + result = kmip_decode_nonce(ctx, value->nonce); + CHECK_RESULT(ctx, result); + + result = kmip_decode_enum(ctx, KMIP_TAG_ATTESTATION_TYPE, &value->attestation_type); + CHECK_RESULT(ctx, result); + CHECK_ENUM(ctx, KMIP_TAG_ATTESTATION_TYPE, value->attestation_type); + + if(kmip_is_tag_next(ctx, KMIP_TAG_ATTESTATION_MEASUREMENT)) + { + value->attestation_measurement = ctx->calloc_func(ctx->state, 1, sizeof(ByteString)); + CHECK_NEW_MEMORY(ctx, value->attestation_measurement, sizeof(ByteString), "AttestationMeasurement byte string"); + + result = kmip_decode_byte_string(ctx, KMIP_TAG_ATTESTATION_MEASUREMENT, value->attestation_measurement); + CHECK_RESULT(ctx, result); + } + + if(kmip_is_tag_next(ctx, KMIP_TAG_ATTESTATION_ASSERTION)) + { + value->attestation_assertion = ctx->calloc_func(ctx->state, 1, sizeof(ByteString)); + CHECK_NEW_MEMORY(ctx, value->attestation_assertion, sizeof(ByteString), "AttestationAssertion byte string"); + + result = kmip_decode_byte_string(ctx, KMIP_TAG_ATTESTATION_ASSERTION, value->attestation_assertion); + CHECK_RESULT(ctx, result); + } + + return(KMIP_OK); +} + +int +kmip_decode_credential_value(KMIP *ctx, enum credential_type type, void **value) +{ + int result = 0; + + switch(type) + { + case KMIP_CRED_USERNAME_AND_PASSWORD: + *value = ctx->calloc_func(ctx->state, 1, sizeof(UsernamePasswordCredential)); + CHECK_NEW_MEMORY(ctx, *value, sizeof(UsernamePasswordCredential), "UsernamePasswordCredential structure"); + result = kmip_decode_username_password_credential(ctx, (UsernamePasswordCredential *)*value); + break; + + case KMIP_CRED_DEVICE: + *value = ctx->calloc_func(ctx->state, 1, sizeof(DeviceCredential)); + CHECK_NEW_MEMORY(ctx, *value, sizeof(DeviceCredential), "DeviceCredential structure"); + result = kmip_decode_device_credential(ctx, (DeviceCredential *)*value); + break; + + case KMIP_CRED_ATTESTATION: + *value = ctx->calloc_func(ctx->state, 1, sizeof(AttestationCredential)); + CHECK_NEW_MEMORY(ctx, *value, sizeof(AttestationCredential), "AttestationCredential structure"); + result = kmip_decode_attestation_credential(ctx, (AttestationCredential*)*value); + break; + + default: + kmip_push_error_frame(ctx, __func__, __LINE__); + return(KMIP_NOT_IMPLEMENTED); + break; + } + CHECK_RESULT(ctx, result); + + return(KMIP_OK); +} + +int +kmip_decode_credential(KMIP *ctx, Credential *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_CREDENTIAL, KMIP_TYPE_STRUCTURE); + + kmip_decode_int32_be(ctx, &length); + CHECK_BUFFER_FULL(ctx, length); + + result = kmip_decode_enum(ctx, KMIP_TAG_CREDENTIAL_TYPE, &value->credential_type); + CHECK_RESULT(ctx, result); + CHECK_ENUM(ctx, KMIP_TAG_CREDENTIAL_TYPE, value->credential_type); + + result = kmip_decode_credential_value(ctx, value->credential_type, &value->credential_value); + CHECK_RESULT(ctx, result); + + return(KMIP_OK); +} + +int +kmip_decode_authentication(KMIP *ctx, Authentication *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_AUTHENTICATION, KMIP_TYPE_STRUCTURE); + + kmip_decode_int32_be(ctx, &length); + CHECK_BUFFER_FULL(ctx, length); + + value->credential = ctx->calloc_func(ctx->state, 1, sizeof(Credential)); + CHECK_NEW_MEMORY(ctx, value->credential, sizeof(Credential), "Credential structure"); + + result = kmip_decode_credential(ctx, value->credential); + CHECK_RESULT(ctx, result); + + return(KMIP_OK); +} + +int +kmip_decode_request_header(KMIP *ctx, RequestHeader *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_HEADER, KMIP_TYPE_STRUCTURE); + + kmip_decode_int32_be(ctx, &length); + CHECK_BUFFER_FULL(ctx, length); + + value->protocol_version = ctx->calloc_func(ctx->state, 1, sizeof(ProtocolVersion)); + CHECK_NEW_MEMORY(ctx, value->protocol_version, sizeof(ProtocolVersion), "ProtocolVersion structure"); + + result = kmip_decode_protocol_version(ctx, value->protocol_version); + CHECK_RESULT(ctx, result); + + if(kmip_is_tag_next(ctx, KMIP_TAG_MAXIMUM_RESPONSE_SIZE)) + { + result = kmip_decode_integer(ctx, KMIP_TAG_MAXIMUM_RESPONSE_SIZE, &value->maximum_response_size); + CHECK_RESULT(ctx, result); + } + + if(ctx->version >= KMIP_1_4) + { + if(kmip_is_tag_next(ctx, KMIP_TAG_CLIENT_CORRELATION_VALUE)) + { + value->client_correlation_value = ctx->calloc_func(ctx->state, 1, sizeof(TextString)); + CHECK_NEW_MEMORY(ctx, value->client_correlation_value, sizeof(TextString), "ClientCorrelationValue text string"); + + result = kmip_decode_text_string(ctx, KMIP_TAG_CLIENT_CORRELATION_VALUE, value->client_correlation_value); + CHECK_RESULT(ctx, result); + } + + if(kmip_is_tag_next(ctx, KMIP_TAG_SERVER_CORRELATION_VALUE)) + { + value->server_correlation_value = ctx->calloc_func(ctx->state, 1, sizeof(TextString)); + CHECK_NEW_MEMORY(ctx, value->server_correlation_value, sizeof(TextString), "ServerCorrelationValue text string"); + + result = kmip_decode_text_string(ctx, KMIP_TAG_SERVER_CORRELATION_VALUE, value->server_correlation_value); + CHECK_RESULT(ctx, result); + } + } + + if(kmip_is_tag_next(ctx, KMIP_TAG_ASYNCHRONOUS_INDICATOR)) + { + result = kmip_decode_bool(ctx, KMIP_TAG_ASYNCHRONOUS_INDICATOR, &value->asynchronous_indicator); + CHECK_RESULT(ctx, result); + } + + if(ctx->version >= KMIP_1_2) + { + if(kmip_is_tag_next(ctx, KMIP_TAG_ATTESTATION_CAPABLE_INDICATOR)) + { + result = kmip_decode_bool(ctx, KMIP_TAG_ATTESTATION_CAPABLE_INDICATOR, &value->attestation_capable_indicator); + CHECK_RESULT(ctx, result); + } + + value->attestation_type_count = kmip_get_num_items_next(ctx, KMIP_TAG_ATTESTATION_TYPE); + if(value->attestation_type_count > 0) + { + value->attestation_types = ctx->calloc_func(ctx->state, value->attestation_type_count, sizeof(enum attestation_type)); + CHECK_NEW_MEMORY(ctx, value->attestation_types, value->attestation_type_count * sizeof(enum attestation_type), "sequence of AttestationType enumerations"); + + for(size_t i = 0; i < value->attestation_type_count; i++) + { + result = kmip_decode_enum(ctx, KMIP_TAG_ATTESTATION_TYPE, &value->attestation_types[i]); + CHECK_RESULT(ctx, result); + CHECK_ENUM(ctx, KMIP_TAG_ATTESTATION_TYPE, value->attestation_types[i]); + } + } + } + + if(kmip_is_tag_next(ctx, KMIP_TAG_AUTHENTICATION)) + { + value->authentication = ctx->calloc_func(ctx->state,1, sizeof(Authentication)); + CHECK_NEW_MEMORY(ctx, value->authentication, sizeof(Authentication), "Authentication structure"); + + result = kmip_decode_authentication(ctx, value->authentication); + CHECK_RESULT(ctx, result); + } + + if(kmip_is_tag_next(ctx, KMIP_TAG_BATCH_ERROR_CONTINUATION_OPTION)) + { + result = kmip_decode_enum(ctx, KMIP_TAG_BATCH_ERROR_CONTINUATION_OPTION, &value->batch_error_continuation_option); + CHECK_RESULT(ctx, result); + CHECK_ENUM(ctx, KMIP_TAG_BATCH_ERROR_CONTINUATION_OPTION, value->batch_error_continuation_option); + } + + if(kmip_is_tag_next(ctx, KMIP_TAG_BATCH_ORDER_OPTION)) + { + result = kmip_decode_bool(ctx, KMIP_TAG_BATCH_ORDER_OPTION, &value->batch_order_option); + CHECK_RESULT(ctx, result); + } + + if(kmip_is_tag_next(ctx, KMIP_TAG_TIME_STAMP)) + { + result = kmip_decode_date_time(ctx, KMIP_TAG_TIME_STAMP, &value->time_stamp); + CHECK_RESULT(ctx, result); + } + + result = kmip_decode_integer(ctx, KMIP_TAG_BATCH_COUNT, &value->batch_count); + CHECK_RESULT(ctx, result); + + return(KMIP_OK); +} + +int +kmip_decode_response_header(KMIP *ctx, ResponseHeader *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_HEADER, KMIP_TYPE_STRUCTURE); + + kmip_decode_int32_be(ctx, &length); + CHECK_BUFFER_FULL(ctx, length); + + value->protocol_version = ctx->calloc_func(ctx->state, 1, sizeof(ProtocolVersion)); + CHECK_NEW_MEMORY(ctx, value->protocol_version, sizeof(ProtocolVersion), "ProtocolVersion structure"); + + result = kmip_decode_protocol_version(ctx, value->protocol_version); + CHECK_RESULT(ctx, result); + + result = kmip_decode_date_time(ctx, KMIP_TAG_TIME_STAMP, &value->time_stamp); + CHECK_RESULT(ctx, result); + + if(ctx->version >= KMIP_1_2) + { + if(kmip_is_tag_next(ctx, KMIP_TAG_NONCE)) + { + value->nonce = ctx->calloc_func(ctx->state, 1, sizeof(Nonce)); + CHECK_NEW_MEMORY(ctx, value->nonce, sizeof(Nonce), "Nonce structure"); + + result = kmip_decode_nonce(ctx, value->nonce); + CHECK_RESULT(ctx, result); + } + + if(ctx->version >= KMIP_2_0) + { + if(kmip_is_tag_next(ctx, KMIP_TAG_SERVER_HASHED_PASSWORD)) + { + value->server_hashed_password = ctx->calloc_func(ctx->state, 1, sizeof(ByteString)); + CHECK_NEW_MEMORY(ctx, value->server_hashed_password, sizeof(ByteString), "ByteString"); + + result = kmip_decode_byte_string(ctx, KMIP_TAG_SERVER_HASHED_PASSWORD, value->server_hashed_password); + CHECK_RESULT(ctx, result); + } + } + + value->attestation_type_count = kmip_get_num_items_next(ctx, KMIP_TAG_ATTESTATION_TYPE); + if(value->attestation_type_count > 0) + { + value->attestation_types = ctx->calloc_func(ctx->state, value->attestation_type_count, sizeof(enum attestation_type)); + CHECK_NEW_MEMORY(ctx, value->attestation_types, value->attestation_type_count * sizeof(enum attestation_type), "sequence of AttestationType enumerations"); + + for(size_t i = 0; i < value->attestation_type_count; i++) + { + result = kmip_decode_enum(ctx, KMIP_TAG_ATTESTATION_TYPE, &value->attestation_types[i]); + CHECK_RESULT(ctx, result); + CHECK_ENUM(ctx, KMIP_TAG_ATTESTATION_TYPE, value->attestation_types[i]); + } + } + } + + if(ctx->version >= KMIP_1_4) + { + if(kmip_is_tag_next(ctx, KMIP_TAG_CLIENT_CORRELATION_VALUE)) + { + value->client_correlation_value = ctx->calloc_func(ctx->state, 1, sizeof(TextString)); + CHECK_NEW_MEMORY(ctx, value->client_correlation_value, sizeof(TextString), "ClientCorrelationValue text string"); + + result = kmip_decode_text_string(ctx, KMIP_TAG_CLIENT_CORRELATION_VALUE, value->client_correlation_value); + CHECK_RESULT(ctx, result); + } + + if(kmip_is_tag_next(ctx, KMIP_TAG_SERVER_CORRELATION_VALUE)) + { + value->server_correlation_value = ctx->calloc_func(ctx->state, 1, sizeof(TextString)); + CHECK_NEW_MEMORY(ctx, value->server_correlation_value, sizeof(TextString), "ServerCorrelationValue text string"); + + result = kmip_decode_text_string(ctx, KMIP_TAG_SERVER_CORRELATION_VALUE, value->server_correlation_value); + CHECK_RESULT(ctx, result); + } + } + + result = kmip_decode_integer(ctx, KMIP_TAG_BATCH_COUNT, &value->batch_count); + CHECK_RESULT(ctx, result); + + return(KMIP_OK); +} + +int +kmip_decode_request_message(KMIP *ctx, RequestMessage *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_MESSAGE, KMIP_TYPE_STRUCTURE); + + kmip_decode_int32_be(ctx, &length); + CHECK_BUFFER_FULL(ctx, length); + + value->request_header = ctx->calloc_func(ctx->state, 1, sizeof(RequestHeader)); + CHECK_NEW_MEMORY(ctx, value->request_header, sizeof(RequestHeader), "RequestHeader structure"); + kmip_init_request_header(value->request_header); + result = kmip_decode_request_header(ctx, value->request_header); + CHECK_RESULT(ctx, result); + + value->batch_count = kmip_get_num_items_next(ctx, KMIP_TAG_BATCH_ITEM); + if(value->batch_count > 0) + { + value->batch_items = ctx->calloc_func(ctx->state, value->batch_count, sizeof(RequestBatchItem)); + CHECK_NEW_MEMORY(ctx, value->batch_items, value->batch_count * sizeof(RequestBatchItem), "sequence of RequestBatchItem structures"); + + for(size_t i = 0; i < value->batch_count; i++) + { + kmip_init_request_batch_item(&value->batch_items[i]); + result = kmip_decode_request_batch_item(ctx, &value->batch_items[i]); + CHECK_RESULT(ctx, result); + } + } + + return(KMIP_OK); +} + +int +kmip_decode_response_message(KMIP *ctx, ResponseMessage *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_MESSAGE, KMIP_TYPE_STRUCTURE); + + kmip_decode_int32_be(ctx, &length); + CHECK_BUFFER_FULL(ctx, length); + + value->response_header = ctx->calloc_func(ctx->state, 1, sizeof(ResponseHeader)); + CHECK_NEW_MEMORY(ctx, value->response_header, sizeof(ResponseHeader), "ResponseHeader structure"); + + result = kmip_decode_response_header(ctx, value->response_header); + CHECK_RESULT(ctx, result); + + value->batch_count = kmip_get_num_items_next(ctx, KMIP_TAG_BATCH_ITEM); + if(value->batch_count > 0) + { + value->batch_items = ctx->calloc_func(ctx->state, value->batch_count, sizeof(ResponseBatchItem)); + CHECK_NEW_MEMORY(ctx, value->batch_items, value->batch_count * sizeof(ResponseBatchItem), "sequence of ResponseBatchItem structures"); + + for(size_t i = 0; i < value->batch_count; i++) + { + result = kmip_decode_response_batch_item(ctx, &value->batch_items[i]); + CHECK_RESULT(ctx, result); + } + } + + return(KMIP_OK); +} diff --git a/src/libkmip/kmip.h b/src/libkmip/kmip.h new file mode 100644 index 000000000..e4c9b3056 --- /dev/null +++ b/src/libkmip/kmip.h @@ -0,0 +1,1956 @@ +/* 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. + */ + +#ifndef KMIP_H +#define KMIP_H + +#include <stddef.h> +#include <stdint.h> + +/* +Types and Constants +*/ + +typedef int8_t int8; +typedef int16_t int16; +typedef int32_t int32; +typedef int64_t int64; +typedef int32 bool32; + +typedef uint8_t uint8; +typedef uint16_t uint16; +typedef uint32_t uint32; +typedef uint64_t uint64; + +typedef size_t memory_index; + +typedef float real32; +typedef double real64; + +#define KMIP_TRUE (1) +#define KMIP_FALSE (0) + +#define KMIP_UNSET (-1) + +#define KMIP_OK (0) +#define KMIP_NOT_IMPLEMENTED (-1) +#define KMIP_ERROR_BUFFER_FULL (-2) +#define KMIP_ERROR_ATTR_UNSUPPORTED (-3) +#define KMIP_TAG_MISMATCH (-4) +#define KMIP_TYPE_MISMATCH (-5) +#define KMIP_LENGTH_MISMATCH (-6) +#define KMIP_PADDING_MISMATCH (-7) +#define KMIP_BOOLEAN_MISMATCH (-8) +#define KMIP_ENUM_MISMATCH (-9) +#define KMIP_ENUM_UNSUPPORTED (-10) +#define KMIP_INVALID_FOR_VERSION (-11) +#define KMIP_MEMORY_ALLOC_FAILED (-12) +#define KMIP_IO_FAILURE (-13) +#define KMIP_EXCEED_MAX_MESSAGE_SIZE (-14) +#define KMIP_MALFORMED_RESPONSE (-15) +#define KMIP_OBJECT_MISMATCH (-16) +#define KMIP_ARG_INVALID (-17) +#define KMIP_ERROR_BUFFER_UNDERFULL (-18) + +/* +Enumerations +*/ + +enum attestation_type +{ + /* KMIP 1.2 */ + KMIP_ATTEST_TPM_QUOTE = 0x01, + KMIP_ATTEST_TCG_INTEGRITY_REPORT = 0x02, + KMIP_ATTEST_SAML_ASSERTION = 0x03 +}; + +enum attribute_type +{ + /* KMIP 1.0 */ + KMIP_ATTR_UNIQUE_IDENTIFIER = 0, + KMIP_ATTR_NAME = 1, + KMIP_ATTR_OBJECT_TYPE = 2, + KMIP_ATTR_CRYPTOGRAPHIC_ALGORITHM = 3, + KMIP_ATTR_CRYPTOGRAPHIC_LENGTH = 4, + KMIP_ATTR_CRYPTOGRAPHIC_PARAMETERS = 5, + KMIP_ATTR_CRYPTOGRAPHIC_DOMAIN_PARAMETERS = 6, + KMIP_ATTR_CERTIFICATE_TYPE = 7, + KMIP_ATTR_CERTIFICATE_LENGTH = 8, + KMIP_ATTR_X509_CERTIFICATE_IDENTIFIER = 9, + KMIP_ATTR_X509_CERTIFICATE_SUBJECT = 10, + KMIP_ATTR_X509_CERTIFICATE_ISSUER = 11, + KMIP_ATTR_CERTIFICATE_IDENTIFIER = 12, + KMIP_ATTR_CERTIFICATE_SUBJECT = 13, + KMIP_ATTR_CERTIFICATE_ISSUER = 14, + KMIP_ATTR_DIGITAL_SIGNATURE_ALGORITHM = 15, + KMIP_ATTR_DIGEST = 16, + KMIP_ATTR_OPERATION_POLICY_NAME = 17, + KMIP_ATTR_CRYPTOGRAPHIC_USAGE_MASK = 18, + KMIP_ATTR_LEASE_TIME = 19, + KMIP_ATTR_USAGE_LIMITS = 20, + KMIP_ATTR_STATE = 21, + KMIP_ATTR_INITIAL_DATE = 22, + KMIP_ATTR_ACTIVATION_DATE = 23, + KMIP_ATTR_PROCESS_START_DATE = 24, + KMIP_ATTR_PROTECT_STOP_DATE = 25, + KMIP_ATTR_DEACTIVATION_DATE = 26, + KMIP_ATTR_DESTROY_DATE = 27, + KMIP_ATTR_COMPROMISE_OCCURRENCE_DATE = 28, + KMIP_ATTR_COMPROMISE_DATE = 29, + KMIP_ATTR_REVOCATION_REASON = 30, + KMIP_ATTR_ARCHIVE_DATE = 31, + KMIP_ATTR_OBJECT_GROUP = 32, + KMIP_ATTR_FRESH = 33, + KMIP_ATTR_LINK = 34, + KMIP_ATTR_APPLICATION_SPECIFIC_INFORMATION = 35, + KMIP_ATTR_CONTACT_INFORMATION = 36, + KMIP_ATTR_LAST_CHANGE_DATE = 37, + KMIP_ATTR_CUSTOM_ATTRIBUTE = 38, + KMIP_ATTR_ALTERNATIVE_NAME = 39, + KMIP_ATTR_KEY_VALUE_PRESENT = 40, + KMIP_ATTR_KEY_VALUE_LOCATION = 41, + KMIP_ATTR_ORIGINAL_CREATION_DATE = 42, + KMIP_ATTR_RANDOM_NUMBER_GENERATOR = 43, + KMIP_ATTR_PKCS_12_FRIENDLY_NAME = 44, + KMIP_ATTR_DESCRIPTION = 45, + KMIP_ATTR_COMMENT = 46, + KMIP_ATTR_SENSITIVE = 47, + KMIP_ATTR_ALWAYS_SENSITIVE = 48, + KMIP_ATTR_EXTRACTABLE = 49, + KMIP_ATTR_NEVER_EXTRACTABLE = 50, + KMIP_ATTR_KEY_FORMAT_TYPE = 51 +}; + +enum batch_error_continuation_option +{ + /* KMIP 1.0 */ + KMIP_BATCH_CONTINUE = 0x01, + KMIP_BATCH_STOP = 0x02, + KMIP_BATCH_UNDO = 0x03 +}; + +enum block_cipher_mode +{ + /* KMIP 1.0 */ + KMIP_BLOCK_CBC = 0x01, + KMIP_BLOCK_ECB = 0x02, + KMIP_BLOCK_PCBC = 0x03, + KMIP_BLOCK_CFB = 0x04, + KMIP_BLOCK_OFB = 0x05, + KMIP_BLOCK_CTR = 0x06, + KMIP_BLOCK_CMAC = 0x07, + KMIP_BLOCK_CCM = 0x08, + KMIP_BLOCK_GCM = 0x09, + KMIP_BLOCK_CBC_MAC = 0x0A, + KMIP_BLOCK_XTS = 0x0B, + KMIP_BLOCK_AES_KEY_WRAP_PADDING = 0x0C, + KMIP_BLOCK_NIST_KEY_WRAP = 0x0D, + KMIP_BLOCK_X9102_AESKW = 0x0E, + KMIP_BLOCK_X9102_TDKW = 0x0F, + KMIP_BLOCK_X9102_AKW1 = 0x10, + KMIP_BLOCK_X9102_AKW2 = 0x11, + /* KMIP 1.4 */ + KMIP_BLOCK_AEAD = 0x12 +}; + +enum certificate_type +{ + KMIP_CERT_X509 = 1, + KMIP_CERT_PGP = 2 +}; + +enum credential_type +{ + /* KMIP 1.0 */ + KMIP_CRED_USERNAME_AND_PASSWORD = 0x01, + /* KMIP 1.1 */ + KMIP_CRED_DEVICE = 0x02, + /* KMIP 1.2 */ + KMIP_CRED_ATTESTATION = 0x03, + /* KMIP 2.0 */ + KMIP_CRED_ONE_TIME_PASSWORD = 0x04, + KMIP_CRED_HASHED_PASSWORD = 0x05, + KMIP_CRED_TICKET = 0x06 +}; + +enum cryptographic_algorithm +{ + /* KMIP 1.0 */ + KMIP_CRYPTOALG_DES = 0x01, + KMIP_CRYPTOALG_TRIPLE_DES = 0x02, + KMIP_CRYPTOALG_AES = 0x03, + KMIP_CRYPTOALG_RSA = 0x04, + KMIP_CRYPTOALG_DSA = 0x05, + KMIP_CRYPTOALG_ECDSA = 0x06, + KMIP_CRYPTOALG_HMAC_SHA1 = 0x07, + KMIP_CRYPTOALG_HMAC_SHA224 = 0x08, + KMIP_CRYPTOALG_HMAC_SHA256 = 0x09, + KMIP_CRYPTOALG_HMAC_SHA384 = 0x0A, + KMIP_CRYPTOALG_HMAC_SHA512 = 0x0B, + KMIP_CRYPTOALG_HMAC_MD5 = 0x0C, + KMIP_CRYPTOALG_DH = 0x0D, + KMIP_CRYPTOALG_ECDH = 0x0E, + KMIP_CRYPTOALG_ECMQV = 0x0F, + KMIP_CRYPTOALG_BLOWFISH = 0x10, + KMIP_CRYPTOALG_CAMELLIA = 0x11, + KMIP_CRYPTOALG_CAST5 = 0x12, + KMIP_CRYPTOALG_IDEA = 0x13, + KMIP_CRYPTOALG_MARS = 0x14, + KMIP_CRYPTOALG_RC2 = 0x15, + KMIP_CRYPTOALG_RC4 = 0x16, + KMIP_CRYPTOALG_RC5 = 0x17, + KMIP_CRYPTOALG_SKIPJACK = 0x18, + KMIP_CRYPTOALG_TWOFISH = 0x19, + /* KMIP 1.2 */ + KMIP_CRYPTOALG_EC = 0x1A, + /* KMIP 1.3 */ + KMIP_CRYPTOALG_ONE_TIME_PAD = 0x1B, + /* KMIP 1.4 */ + KMIP_CRYPTOALG_CHACHA20 = 0x1C, + KMIP_CRYPTOALG_POLY1305 = 0x1D, + KMIP_CRYPTOALG_CHACHA20_POLY1305 = 0x1E, + KMIP_CRYPTOALG_SHA3_224 = 0x1F, + KMIP_CRYPTOALG_SHA3_256 = 0x20, + KMIP_CRYPTOALG_SHA3_384 = 0x21, + KMIP_CRYPTOALG_SHA3_512 = 0x22, + KMIP_CRYPTOALG_HMAC_SHA3_224 = 0x23, + KMIP_CRYPTOALG_HMAC_SHA3_256 = 0x24, + KMIP_CRYPTOALG_HMAC_SHA3_384 = 0x25, + KMIP_CRYPTOALG_HMAC_SHA3_512 = 0x26, + KMIP_CRYPTOALG_SHAKE_128 = 0x27, + KMIP_CRYPTOALG_SHAKE_256 = 0x28, + /* KMIP 2.0 */ + KMIP_CRYPTOALG_ARIA = 0x29, + KMIP_CRYPTOALG_SEED = 0x2A, + KMIP_CRYPTOALG_SM2 = 0x2B, + KMIP_CRYPTOALG_SM3 = 0x2C, + KMIP_CRYPTOALG_SM4 = 0x2D, + KMIP_CRYPTOALG_GOST_R_34_10_2012 = 0x2E, + KMIP_CRYPTOALG_GOST_R_34_11_2012 = 0x2F, + KMIP_CRYPTOALG_GOST_R_34_13_2015 = 0x30, + KMIP_CRYPTOALG_GOST_28147_89 = 0x31, + KMIP_CRYPTOALG_XMSS = 0x32, + KMIP_CRYPTOALG_SPHINCS_256 = 0x33, + KMIP_CRYPTOALG_MCELIECE = 0x34, + KMIP_CRYPTOALG_MCELIECE_6960119 = 0x35, + KMIP_CRYPTOALG_MCELIECE_8192128 = 0x36, + KMIP_CRYPTOALG_ED25519 = 0x37, + KMIP_CRYPTOALG_ED448 = 0x38 +}; + +enum cryptographic_usage_mask +{ + /* KMIP 1.0 */ + KMIP_CRYPTOMASK_SIGN = 0x00000001, + KMIP_CRYPTOMASK_VERIFY = 0x00000002, + KMIP_CRYPTOMASK_ENCRYPT = 0x00000004, + KMIP_CRYPTOMASK_DECRYPT = 0x00000008, + KMIP_CRYPTOMASK_WRAP_KEY = 0x00000010, + KMIP_CRYPTOMASK_UNWRAP_KEY = 0x00000020, + KMIP_CRYPTOMASK_EXPORT = 0x00000040, + KMIP_CRYPTOMASK_MAC_GENERATE = 0x00000080, + KMIP_CRYPTOMASK_MAC_VERIFY = 0x00000100, + KMIP_CRYPTOMASK_DERIVE_KEY = 0x00000200, + KMIP_CRYPTOMASK_CONTENT_COMMITMENT = 0x00000400, + KMIP_CRYPTOMASK_KEY_AGREEMENT = 0x00000800, + KMIP_CRYPTOMASK_CERTIFICATE_SIGN = 0x00001000, + KMIP_CRYPTOMASK_CRL_SIGN = 0x00002000, + KMIP_CRYPTOMASK_GENERATE_CRYPTOGRAM = 0x00004000, + KMIP_CRYPTOMASK_VALIDATE_CRYPTOGRAM = 0x00008000, + KMIP_CRYPTOMASK_TRANSLATE_ENCRYPT = 0x00010000, + KMIP_CRYPTOMASK_TRANSLATE_DECRYPT = 0x00020000, + KMIP_CRYPTOMASK_TRANSLATE_WRAP = 0x00040000, + KMIP_CRYPTOMASK_TRANSLATE_UNWRAP = 0x00080000, + /* KMIP 2.0 */ + KMIP_CRYPTOMASK_AUTHENTICATE = 0x00100000, + KMIP_CRYPTOMASK_UNRESTRICTED = 0x00200000, + KMIP_CRYPTOMASK_FPE_ENCRYPT = 0x00400000, + KMIP_CRYPTOMASK_FPE_DECRYPT = 0x00800000 +}; + +enum digital_signature_algorithm +{ + /* KMIP 1.1 */ + KMIP_DIGITAL_MD2_WITH_RSA = 0x01, + KMIP_DIGITAL_MD5_WITH_RSA = 0x02, + KMIP_DIGITAL_SHA1_WITH_RSA = 0x03, + KMIP_DIGITAL_SHA224_WITH_RSA = 0x04, + KMIP_DIGITAL_SHA256_WITH_RSA = 0x05, + KMIP_DIGITAL_SHA384_WITH_RSA = 0x06, + KMIP_DIGITAL_SHA512_WITH_RSA = 0x07, + KMIP_DIGITAL_RSASSA_PSS = 0x08, + KMIP_DIGITAL_DSA_WITH_SHA1 = 0x09, + KMIP_DIGITAL_DSA_WITH_SHA224 = 0x0A, + KMIP_DIGITAL_DSA_WITH_SHA256 = 0x0B, + KMIP_DIGITAL_ECDSA_WITH_SHA1 = 0x0C, + KMIP_DIGITAL_ECDSA_WITH_SHA224 = 0x0D, + KMIP_DIGITAL_ECDSA_WITH_SHA256 = 0x0E, + KMIP_DIGITAL_ECDSA_WITH_SHA384 = 0x0F, + KMIP_DIGITAL_ECDSA_WITH_SHA512 = 0x10, + /* KMIP 1.4 */ + KMIP_DIGITAL_SHA3_256_WITH_RSA = 0x11, + KMIP_DIGITAL_SHA3_384_WITH_RSA = 0x12, + KMIP_DIGITAL_SHA3_512_WITH_RSA = 0x13 +}; + +enum encoding_option +{ + /* KMIP 1.1 */ + KMIP_ENCODE_NO_ENCODING = 0x01, + KMIP_ENCODE_TTLV_ENCODING = 0x02 +}; + +enum hashing_algorithm +{ + /* KMIP 1.0 */ + KMIP_HASH_MD2 = 0x01, + KMIP_HASH_MD4 = 0x02, + KMIP_HASH_MD5 = 0x03, + KMIP_HASH_SHA1 = 0x04, + KMIP_HASH_SHA224 = 0x05, + KMIP_HASH_SHA256 = 0x06, + KMIP_HASH_SHA384 = 0x07, + KMIP_HASH_SHA512 = 0x08, + KMIP_HASH_RIPEMD160 = 0x09, + KMIP_HASH_TIGER = 0x0A, + KMIP_HASH_WHIRLPOOL = 0x0B, + /* KMIP 1.2 */ + KMIP_HASH_SHA512_224 = 0x0C, + KMIP_HASH_SHA512_256 = 0x0D, + /* KMIP 1.4 */ + KMIP_HASH_SHA3_224 = 0x0E, + KMIP_HASH_SHA3_256 = 0x0F, + KMIP_HASH_SHA3_384 = 0x10, + KMIP_HASH_SHA3_512 = 0x11 +}; + +enum key_compression_type +{ + /* KMIP 1.0 */ + KMIP_KEYCOMP_EC_PUB_UNCOMPRESSED = 0x01, + KMIP_KEYCOMP_EC_PUB_X962_COMPRESSED_PRIME = 0x02, + KMIP_KEYCOMP_EC_PUB_X962_COMPRESSED_CHAR2 = 0x03, + KMIP_KEYCOMP_EC_PUB_X962_HYBRID = 0x04 +}; + +enum key_format_type +{ + /* KMIP 1.0 */ + KMIP_KEYFORMAT_RAW = 0x01, + KMIP_KEYFORMAT_OPAQUE = 0x02, + KMIP_KEYFORMAT_PKCS1 = 0x03, + KMIP_KEYFORMAT_PKCS8 = 0x04, + KMIP_KEYFORMAT_X509 = 0x05, + KMIP_KEYFORMAT_EC_PRIVATE_KEY = 0x06, + KMIP_KEYFORMAT_TRANS_SYMMETRIC_KEY = 0x07, + KMIP_KEYFORMAT_TRANS_DSA_PRIVATE_KEY = 0x08, + KMIP_KEYFORMAT_TRANS_DSA_PUBLIC_KEY = 0x09, + KMIP_KEYFORMAT_TRANS_RSA_PRIVATE_KEY = 0x0A, + KMIP_KEYFORMAT_TRANS_RSA_PUBLIC_KEY = 0x0B, + KMIP_KEYFORMAT_TRANS_DH_PRIVATE_KEY = 0x0C, + KMIP_KEYFORMAT_TRANS_DH_PUBLIC_KEY = 0x0D, + KMIP_KEYFORMAT_TRANS_ECDSA_PRIVATE_KEY = 0x0E, /* Deprecated as of KMIP 1.3 */ + KMIP_KEYFORMAT_TRANS_ECDSA_PUBLIC_KEY = 0x0F, /* Deprecated as of KMIP 1.3 */ + KMIP_KEYFORMAT_TRANS_ECDH_PRIVATE_KEY = 0x10, /* Deprecated as of KMIP 1.3 */ + KMIP_KEYFORMAT_TRANS_ECDH_PUBLIC_KEY = 0x11, /* Deprecated as of KMIP 1.3 */ + KMIP_KEYFORMAT_TRANS_ECMQV_PRIVATE_KEY = 0x12, /* Deprecated as of KMIP 1.3 */ + KMIP_KEYFORMAT_TRANS_ECMQV_PUBLIC_KEY = 0x13, /* Deprecated as of KMIP 1.3 */ + /* KMIP 1.3 */ + KMIP_KEYFORMAT_TRANS_EC_PRIVATE_KEY = 0x14, + KMIP_KEYFORMAT_TRANS_EC_PUBLIC_KEY = 0x15, + /* KMIP 1.4 */ + KMIP_KEYFORMAT_PKCS12 = 0x16, + /* KMIP 2.0 */ + KMIP_KEYFORMAT_PKCS10 = 0x17 +}; + +enum key_role_type +{ + /* KMIP 1.0 */ + KMIP_ROLE_BDK = 0x01, + KMIP_ROLE_CVK = 0x02, + KMIP_ROLE_DEK = 0x03, + KMIP_ROLE_MKAC = 0x04, + KMIP_ROLE_MKSMC = 0x05, + KMIP_ROLE_MKSMI = 0x06, + KMIP_ROLE_MKDAC = 0x07, + KMIP_ROLE_MKDN = 0x08, + KMIP_ROLE_MKCP = 0x09, + KMIP_ROLE_MKOTH = 0x0A, + KMIP_ROLE_KEK = 0x0B, + KMIP_ROLE_MAC16609 = 0x0C, + KMIP_ROLE_MAC97971 = 0x0D, + KMIP_ROLE_MAC97972 = 0x0E, + KMIP_ROLE_MAC97973 = 0x0F, + KMIP_ROLE_MAC97974 = 0x10, + KMIP_ROLE_MAC97975 = 0x11, + KMIP_ROLE_ZPK = 0x12, + KMIP_ROLE_PVKIBM = 0x13, + KMIP_ROLE_PVKPVV = 0x14, + KMIP_ROLE_PVKOTH = 0x15, + /* KMIP 1.4 */ + KMIP_ROLE_DUKPT = 0x16, + KMIP_ROLE_IV = 0x17, + KMIP_ROLE_TRKBK = 0x18 +}; + +enum key_wrap_type +{ + /* KMIP 1.4 */ + KMIP_WRAPTYPE_NOT_WRAPPED = 0x01, + KMIP_WRAPTYPE_AS_REGISTERED = 0x02 +}; + +enum kmip_version +{ + KMIP_1_0 = 0, + KMIP_1_1 = 1, + KMIP_1_2 = 2, + KMIP_1_3 = 3, + KMIP_1_4 = 4, + KMIP_2_0 = 5 +}; + +enum mask_generator +{ + /* KMIP 1.4 */ + KMIP_MASKGEN_MGF1 = 0x01 +}; + +enum name_type +{ + /* KMIP 1.0 */ + KMIP_NAME_UNINTERPRETED_TEXT_STRING = 0x01, + KMIP_NAME_URI = 0x02 +}; + +enum object_type +{ + /* KMIP 1.0 */ + KMIP_OBJTYPE_CERTIFICATE = 0x01, + KMIP_OBJTYPE_SYMMETRIC_KEY = 0x02, + KMIP_OBJTYPE_PUBLIC_KEY = 0x03, + KMIP_OBJTYPE_PRIVATE_KEY = 0x04, + KMIP_OBJTYPE_SPLIT_KEY = 0x05, + KMIP_OBJTYPE_TEMPLATE = 0x06, /* Deprecated as of KMIP 1.3 */ + KMIP_OBJTYPE_SECRET_DATA = 0x07, + KMIP_OBJTYPE_OPAQUE_OBJECT = 0x08, + /* KMIP 1.2 */ + KMIP_OBJTYPE_PGP_KEY = 0x09, + /* KMIP 2.0 */ + KMIP_OBJTYPE_CERTIFICATE_REQUEST = 0x0A +}; + +enum operation +{ + /* KMIP 1.0 */ + KMIP_OP_CREATE = 0x01, + KMIP_OP_CREATE_KEY_PAIR = 0x02, + KMIP_OP_REGISTER = 0x03, + KMIP_OP_REKEY = 0x04, + KMIP_OP_DERIVE_KEY = 0x05, + KMIP_OP_CERTIFY = 0x06, + KMIP_OP_RECERTIFY = 0x07, + KMIP_OP_LOCATE = 0x08, + KMIP_OP_CHECK = 0x09, + KMIP_OP_GET = 0x0A, + KMIP_OP_GET_ATTRIBUTES = 0x0B, + KMIP_OP_GET_ATTRIBUTE_LIST = 0x0C, + KMIP_OP_ADD_ATTRIBUTE = 0x0D, + KMIP_OP_MODIFY_ATTRIBUTE = 0x0E, + KMIP_OP_DELETE_ATTRIBUTE = 0x0F, + KMIP_OP_OBTAIN_LEASE = 0x10, + KMIP_OP_GET_USAGE_ALLOCATION = 0x11, + KMIP_OP_ACTIVATE = 0x12, + KMIP_OP_REVOKE = 0x13, + KMIP_OP_DESTROY = 0x14, + KMIP_OP_ARCHIVE = 0x15, + KMIP_OP_RECOVER = 0x16, + KMIP_OP_VALIDATE = 0x17, + KMIP_OP_QUERY = 0x18, + KMIP_OP_CANCEL = 0x19, + KMIP_OP_POLL = 0x1A, + KMIP_OP_NOTIFY = 0x1B, + KMIP_OP_PUT = 0x1C, + /* KMIP 1.1 */ + KMIP_OP_REKEY_KEY_PAIR = 0x1D, + KMIP_OP_DISCOVER_VERSIONS = 0x1E, + /* KMIP 1.2 */ + KMIP_OP_ENCRYPT = 0x1F, + KMIP_OP_DECRYPT = 0x20, + KMIP_OP_SIGN = 0x21, + KMIP_OP_SIGNATURE_VERIFY = 0x22, + KMIP_OP_MAC = 0x23, + KMIP_OP_MAC_VERIFY = 0x24, + KMIP_OP_RNG_RETRIEVE = 0x25, + KMIP_OP_RNG_SEED = 0x26, + KMIP_OP_HASH = 0x27, + KMIP_OP_CREATE_SPLIT_KEY = 0x28, + KMIP_OP_JOIN_SPLIT_KEY = 0x29, + /* KMIP 1.4 */ + KMIP_OP_IMPORT = 0x2A, + KMIP_OP_EXPORT = 0x2B +}; + +enum padding_method +{ + /* KMIP 1.0 */ + KMIP_PAD_NONE = 0x01, + KMIP_PAD_OAEP = 0x02, + KMIP_PAD_PKCS5 = 0x03, + KMIP_PAD_SSL3 = 0x04, + KMIP_PAD_ZEROS = 0x05, + KMIP_PAD_ANSI_X923 = 0x06, + KMIP_PAD_ISO_10126 = 0x07, + KMIP_PAD_PKCS1v15 = 0x08, + KMIP_PAD_X931 = 0x09, + KMIP_PAD_PSS = 0x0A +}; + +enum protection_storage_mask +{ + /* KMIP 2.0 */ + KMIP_PROTECT_SOFTWARE = 0x00000001, + KMIP_PROTECT_HARDWARE = 0x00000002, + KMIP_PROTECT_ON_PROCESSOR = 0x00000004, + KMIP_PROTECT_ON_SYSTEM = 0x00000008, + KMIP_PROTECT_OFF_SYSTEM = 0x00000010, + KMIP_PROTECT_HYPERVISOR = 0x00000020, + KMIP_PROTECT_OPERATING_SYSTEM = 0x00000040, + KMIP_PROTECT_CONTAINER = 0x00000080, + KMIP_PROTECT_ON_PREMISES = 0x00000100, + KMIP_PROTECT_OFF_PREMISES = 0x00000200, + KMIP_PROTECT_SELF_MANAGED = 0x00000400, + KMIP_PROTECT_OUTSOURCED = 0x00000800, + KMIP_PROTECT_VALIDATED = 0x00001000, + KMIP_PROTECT_SAME_JURISDICTION = 0x00002000 +}; + +enum result_reason +{ + /* KMIP 1.0 */ + KMIP_REASON_GENERAL_FAILURE = 0x0100, + KMIP_REASON_ITEM_NOT_FOUND = 0x0001, + KMIP_REASON_RESPONSE_TOO_LARGE = 0x0002, + KMIP_REASON_AUTHENTICATION_NOT_SUCCESSFUL = 0x0003, + KMIP_REASON_INVALID_MESSAGE = 0x0004, + KMIP_REASON_OPERATION_NOT_SUPPORTED = 0x0005, + KMIP_REASON_MISSING_DATA = 0x0006, + KMIP_REASON_INVALID_FIELD = 0x0007, + KMIP_REASON_FEATURE_NOT_SUPPORTED = 0x0008, + KMIP_REASON_OPERATION_CANCELED_BY_REQUESTER = 0x0009, + KMIP_REASON_CRYPTOGRAPHIC_FAILURE = 0x000A, + KMIP_REASON_ILLEGAL_OPERATION = 0x000B, + KMIP_REASON_PERMISSION_DENIED = 0x000C, + KMIP_REASON_OBJECT_ARCHIVED = 0x000D, + KMIP_REASON_INDEX_OUT_OF_BOUNDS = 0x000E, + KMIP_REASON_APPLICATION_NAMESPACE_NOT_SUPPORTED = 0x000F, + KMIP_REASON_KEY_FORMAT_TYPE_NOT_SUPPORTED = 0x0010, + KMIP_REASON_KEY_COMPRESSION_TYPE_NOT_SUPPORTED = 0x0011, + /* KMIP 1.1 */ + KMIP_REASON_ENCODING_OPTION_FAILURE = 0x0012, + /* KMIP 1.2 */ + KMIP_REASON_KEY_VALUE_NOT_PRESENT = 0x0013, + KMIP_REASON_ATTESTATION_REQUIRED = 0x0014, + KMIP_REASON_ATTESTATION_FAILED = 0x0015, + /* KMIP 1.4 */ + KMIP_REASON_SENSITIVE = 0x0016, + KMIP_REASON_NOT_EXTRACTABLE = 0x0017, + KMIP_REASON_OBJECT_ALREADY_EXISTS = 0x0018, + /* KMIP 2.0 */ + KMIP_REASON_INVALID_TICKET = 0x0019, + KMIP_REASON_USAGE_LIMIT_EXCEEDED = 0x001A, + KMIP_REASON_NUMERIC_RANGE = 0x001B, + KMIP_REASON_INVALID_DATA_TYPE = 0x001C, + KMIP_REASON_READ_ONLY_ATTRIBUTE = 0x001D, + KMIP_REASON_MULTI_VALUED_ATTRIBUTE = 0x001E, + KMIP_REASON_UNSUPPORTED_ATTRIBUTE = 0x001F, + KMIP_REASON_ATTRIBUTE_INSTANCE_NOT_FOUND = 0x0020, + KMIP_REASON_ATTRIBUTE_NOT_FOUND = 0x0021, + KMIP_REASON_ATTRIBUTE_READ_ONLY = 0x0022, + KMIP_REASON_ATTRIBUTE_SINGLE_VALUED = 0x0023, + KMIP_REASON_BAD_CRYPTOGRAPHIC_PARAMETERS = 0x0024, + KMIP_REASON_BAD_PASSWORD = 0x0025, + KMIP_REASON_CODEC_ERROR = 0x0026, + /* Reserved = 0x0027, */ + KMIP_REASON_ILLEGAL_OBJECT_TYPE = 0x0028, + KMIP_REASON_INCOMPATIBLE_CRYPTOGRAPHIC_USAGE_MASK = 0x0029, + KMIP_REASON_INTERNAL_SERVER_ERROR = 0x002A, + KMIP_REASON_INVALID_ASYNCHRONOUS_CORRELATION_VALUE = 0x002B, + KMIP_REASON_INVALID_ATTRIBUTE = 0x002C, + KMIP_REASON_INVALID_ATTRIBUTE_VALUE = 0x002D, + KMIP_REASON_INVALID_CORRELATION_VALUE = 0x002E, + KMIP_REASON_INVALID_CSR = 0x002F, + KMIP_REASON_INVALID_OBJECT_TYPE = 0x0030, + /* Reserved = 0x0031, */ + KMIP_REASON_KEY_WRAP_TYPE_NOT_SUPPORTED = 0x0032, + /* Reserved = 0x0033, */ + KMIP_REASON_MISSING_INITIALIZATION_VECTOR = 0x0034, + KMIP_REASON_NON_UNIQUE_NAME_ATTRIBUTE = 0x0035, + KMIP_REASON_OBJECT_DESTROYED = 0x0036, + KMIP_REASON_OBJECT_NOT_FOUND = 0x0037, + /* Reserved = 0x0038, */ + KMIP_REASON_NOT_AUTHORISED = 0x0039, + KMIP_REASON_SERVER_LIMIT_EXCEEDED = 0x003A, + KMIP_REASON_UNKNOWN_ENUMERATION = 0x003B, + KMIP_REASON_UNKNOWN_MESSAGE_EXTENSION = 0x003C, + KMIP_REASON_UNKNOWN_TAG = 0x003D, + KMIP_REASON_UNSUPPORTED_CRYPTOGRAPHIC_PARAMETERS = 0x003E, + KMIP_REASON_UNSUPPORTED_PROTOCOL_VERSION = 0x003F, + KMIP_REASON_WRAPPING_OBJECT_ARCHIVED = 0x0040, + KMIP_REASON_WRAPPING_OBJECT_DESTROYED = 0x0041, + KMIP_REASON_WRAPPING_OBJECT_NOT_FOUND = 0x0042, + KMIP_REASON_WRONG_KEY_LIFECYCLE_STATE = 0x0043, + KMIP_REASON_PROTECTION_STORAGE_UNAVAILABLE = 0x0044, + KMIP_REASON_PKCS11_CODEC_ERROR = 0x0045, + KMIP_REASON_PKCS11_INVALID_FUNCTION = 0x0046, + KMIP_REASON_PKCS11_INVALID_INTERFACE = 0x0047, + KMIP_REASON_PRIVATE_PROTECTION_STORAGE_UNAVAILABLE = 0x0048, + KMIP_REASON_PUBLIC_PROTECTION_STORAGE_UNAVAILABLE = 0x0049 +}; + +enum result_status +{ + /* KMIP 1.0 */ + KMIP_STATUS_SUCCESS = 0x00, + KMIP_STATUS_OPERATION_FAILED = 0x01, + KMIP_STATUS_OPERATION_PENDING = 0x02, + KMIP_STATUS_OPERATION_UNDONE = 0x03 +}; + +enum state +{ + /* KMIP 1.0 */ + KMIP_STATE_PRE_ACTIVE = 0x01, + KMIP_STATE_ACTIVE = 0x02, + KMIP_STATE_DEACTIVATED = 0x03, + KMIP_STATE_COMPROMISED = 0x04, + KMIP_STATE_DESTROYED = 0x05, + KMIP_STATE_DESTROYED_COMPROMISED = 0x06 +}; + +enum tag +{ + KMIP_TAG_TAG = 0x000000, + KMIP_TAG_TYPE = 0x000001, + KMIP_TAG_DEFAULT = 0x420000, + KMIP_TAG_ACTIVATION_DATE = 0x420001, + KMIP_TAG_APPLICATION_DATA = 0x420002, + KMIP_TAG_APPLICATION_NAMESPACE = 0x420003, + KMIP_TAG_APPLICATION_SPECIFIC_INFORMATION = 0x420004, + KMIP_TAG_ARCHIVE_DATE = 0x420005, + /* KMIP 1.0 */ + KMIP_TAG_ASYNCHRONOUS_CORRELATION_VALUE = 0x420006, + KMIP_TAG_ASYNCHRONOUS_INDICATOR = 0x420007, + KMIP_TAG_ATTRIBUTE = 0x420008, + KMIP_TAG_ATTRIBUTE_INDEX = 0x420009, + KMIP_TAG_ATTRIBUTE_NAME = 0x42000A, + KMIP_TAG_ATTRIBUTE_VALUE = 0x42000B, + KMIP_TAG_AUTHENTICATION = 0x42000C, + KMIP_TAG_BATCH_COUNT = 0x42000D, + KMIP_TAG_BATCH_ERROR_CONTINUATION_OPTION = 0x42000E, + KMIP_TAG_BATCH_ITEM = 0x42000F, + KMIP_TAG_BATCH_ORDER_OPTION = 0x420010, + KMIP_TAG_BLOCK_CIPHER_MODE = 0x420011, + KMIP_TAG_CANCELLATION_RESULT = 0x420012, + KMIP_TAG_CERTIFICATE = 0x420013, + KMIP_TAG_CERTIFICATE_IDENTIFIER = 0x420014, + KMIP_TAG_CERTIFICATE_ISSUER = 0x420015, + KMIP_TAG_CERTIFICATE_ISSUER_ALTERNATIVE_NAME = 0x420016, + KMIP_TAG_CERTIFICATE_ISSUER_DISTINGUISHED_NAME = 0x420017, + KMIP_TAG_CERTIFICATE_REQUEST = 0x420018, + KMIP_TAG_CERTIFICATE_REQUEST_TYPE = 0x420019, + KMIP_TAG_CERTIFICATE_SUBJECT = 0x42001A, + KMIP_TAG_CERTIFICATE_SUBJECT_ALTERNATIVE_NAME = 0x42001B, + KMIP_TAG_CERTIFICATE_SUBJECT_DISTINGUISHED_NAME = 0x42001C, + KMIP_TAG_CERTIFICATE_TYPE = 0x42001D, + KMIP_TAG_CERTIFICATE_VALUE = 0x42001E, + KMIP_TAG_COMMON_TEMPLATE_ATTRIBUTE = 0x42001F, + KMIP_TAG_COMPROMISE_DATE = 0x420020, + KMIP_TAG_COMPROMISE_OCCURRENCE_DATE = 0x420021, + KMIP_TAG_CONTACT_INFORMATION = 0x420022, + KMIP_TAG_CREDENTIAL = 0x420023, + KMIP_TAG_CREDENTIAL_TYPE = 0x420024, + KMIP_TAG_CREDENTIAL_VALUE = 0x420025, + KMIP_TAG_CRITICALITY_INDICATOR = 0x420026, + KMIP_TAG_CRT_COEFFICIENT = 0x420027, + KMIP_TAG_CRYPTOGRAPHIC_ALGORITHM = 0x420028, + KMIP_TAG_CRYPTOGRAPHIC_DOMAIN_PARAMETERS = 0x420029, + KMIP_TAG_CRYPTOGRAPHIC_LENGTH = 0x42002A, + KMIP_TAG_CRYPTOGRAPHIC_PARAMETERS = 0x42002B, + KMIP_TAG_CRYPTOGRAPHIC_USAGE_MASK = 0x42002C, + KMIP_TAG_CUSTOM_ATTRIBUTE = 0x42002D, + KMIP_TAG_D = 0x42002E, + KMIP_TAG_DEACTIVATION_DATE = 0x42002F, + KMIP_TAG_DERIVATION_DATA = 0x420030, + KMIP_TAG_DERIVATION_METHOD = 0x420031, + KMIP_TAG_DERIVATION_PARAMETERS = 0x420032, + KMIP_TAG_DESTROY_DATE = 0x420033, + KMIP_TAG_DIGEST = 0x420034, + KMIP_TAG_DIGEST_VALUE = 0x420035, + KMIP_TAG_ENCRYPTION_KEY_INFORMATION = 0x420036, + KMIP_TAG_G = 0x420037, + KMIP_TAG_HASHING_ALGORITHM = 0x420038, + KMIP_TAG_INITIAL_DATE = 0x420039, + KMIP_TAG_INITIALIZATION_VECTOR = 0x42003A, + KMIP_TAG_ISSUER = 0x42003B, + KMIP_TAG_ITERATION_COUNT = 0x42003C, + KMIP_TAG_IV_COUNTER_NONCE = 0x42003D, + KMIP_TAG_J = 0x42003E, + KMIP_TAG_KEY = 0x42003F, + KMIP_TAG_KEY_BLOCK = 0x420040, + KMIP_TAG_KEY_COMPRESSION_TYPE = 0x420041, + KMIP_TAG_KEY_FORMAT_TYPE = 0x420042, + KMIP_TAG_KEY_MATERIAL = 0x420043, + KMIP_TAG_KEY_PART_IDENTIFIER = 0x420044, + KMIP_TAG_KEY_VALUE = 0x420045, + KMIP_TAG_KEY_WRAPPING_DATA = 0x420046, + KMIP_TAG_KEY_WRAPPING_SPECIFICATION = 0x420047, + KMIP_TAG_LAST_CHANGE_DATE = 0x420048, + KMIP_TAG_LEASE_TIME = 0x420049, + KMIP_TAG_LINK = 0x42004A, + KMIP_TAG_LINK_TYPE = 0x42004B, + KMIP_TAG_LINKED_OBJECT_IDENTIFIER = 0x42004C, + KMIP_TAG_MAC_SIGNATURE = 0x42004D, + KMIP_TAG_MAC_SIGNATURE_KEY_INFORMATION = 0x42004E, + KMIP_TAG_MAXIMUM_ITEMS = 0x42004F, + KMIP_TAG_MAXIMUM_RESPONSE_SIZE = 0x420050, + KMIP_TAG_MESSAGE_EXTENSION = 0x420051, + KMIP_TAG_MODULUS = 0x420052, + KMIP_TAG_NAME = 0x420053, + KMIP_TAG_NAME_TYPE = 0x420054, + KMIP_TAG_NAME_VALUE = 0x420055, + KMIP_TAG_OBJECT_GROUP = 0x420056, + KMIP_TAG_OBJECT_TYPE = 0x420057, + KMIP_TAG_OFFSET = 0x420058, + KMIP_TAG_OPAQUE_DATA_TYPE = 0x420059, + KMIP_TAG_OPAQUE_DATA_VALUE = 0x42005A, + KMIP_TAG_OPAQUE_OBJECT = 0x42005B, + KMIP_TAG_OPERATION = 0x42005C, + KMIP_TAG_OPERATION_POLICY_NAME = 0x42005D, + KMIP_TAG_P = 0x42005E, + KMIP_TAG_PADDING_METHOD = 0x42005F, + KMIP_TAG_PRIME_EXPONENT_P = 0x420060, + KMIP_TAG_PRIME_EXPONENT_Q = 0x420061, + KMIP_TAG_PRIME_FIELD_SIZE = 0x420062, + KMIP_TAG_PRIVATE_EXPONENT = 0x420063, + KMIP_TAG_PRIVATE_KEY = 0x420064, + KMIP_TAG_PRIVATE_KEY_TEMPLATE_ATTRIBUTE = 0x420065, + KMIP_TAG_PRIVATE_KEY_UNIQUE_IDENTIFIER = 0x420066, + KMIP_TAG_PROCESS_START_DATE = 0x420067, + KMIP_TAG_PROTECT_STOP_DATE = 0x420068, + KMIP_TAG_PROTOCOL_VERSION = 0x420069, + KMIP_TAG_PROTOCOL_VERSION_MAJOR = 0x42006A, + KMIP_TAG_PROTOCOL_VERSION_MINOR = 0x42006B, + KMIP_TAG_PUBLIC_EXPONENT = 0x42006C, + KMIP_TAG_PUBLIC_KEY = 0x42006D, + KMIP_TAG_PUBLIC_KEY_TEMPLATE_ATTRIBUTE = 0x42006E, + KMIP_TAG_PUBLIC_KEY_UNIQUE_IDENTIFIER = 0x42006F, + KMIP_TAG_PUT_FUNCTION = 0x420070, + KMIP_TAG_Q = 0x420071, + KMIP_TAG_Q_STRING = 0x420072, + KMIP_TAG_QLENGTH = 0x420073, + KMIP_TAG_QUERY_FUNCTION = 0x420074, + KMIP_TAG_RECOMMENDED_CURVE = 0x420075, + KMIP_TAG_REPLACED_UNIQUE_IDENTIFIER = 0x420076, + KMIP_TAG_REQUEST_HEADER = 0x420077, + KMIP_TAG_REQUEST_MESSAGE = 0x420078, + KMIP_TAG_REQUEST_PAYLOAD = 0x420079, + KMIP_TAG_RESPONSE_HEADER = 0x42007A, + KMIP_TAG_RESPONSE_MESSAGE = 0x42007B, + KMIP_TAG_RESPONSE_PAYLOAD = 0x42007C, + KMIP_TAG_RESULT_MESSAGE = 0x42007D, + KMIP_TAG_RESULT_REASON = 0x42007E, + KMIP_TAG_RESULT_STATUS = 0x42007F, + KMIP_TAG_REVOCATION_MESSAGE = 0x420080, + KMIP_TAG_REVOCATION_REASON = 0x420081, + KMIP_TAG_REVOCATION_REASON_CODE = 0x420082, + KMIP_TAG_KEY_ROLE_TYPE = 0x420083, + KMIP_TAG_SALT = 0x420084, + KMIP_TAG_SECRET_DATA = 0x420085, + KMIP_TAG_SECRET_DATA_TYPE = 0x420086, + KMIP_TAG_SERIAL_NUMBER = 0x420087, + KMIP_TAG_SERVER_INFORMATION = 0x420088, + KMIP_TAG_SPLIT_KEY = 0x420089, + KMIP_TAG_SPLIT_KEY_METHOD = 0x42008A, + KMIP_TAG_SPLIT_KEY_PARTS = 0x42008B, + KMIP_TAG_SPLIT_KEY_THRESHOLD = 0x42008C, + KMIP_TAG_STATE = 0x42008D, + KMIP_TAG_STORAGE_STATUS_MASK = 0x42008E, + KMIP_TAG_SYMMETRIC_KEY = 0x42008F, + KMIP_TAG_TEMPLATE = 0x420090, + KMIP_TAG_TEMPLATE_ATTRIBUTE = 0x420091, + KMIP_TAG_TIME_STAMP = 0x420092, + KMIP_TAG_UNIQUE_BATCH_ITEM_ID = 0x420093, + KMIP_TAG_UNIQUE_IDENTIFIER = 0x420094, + KMIP_TAG_USAGE_LIMITS = 0x420095, + KMIP_TAG_USAGE_LIMITS_COUNT = 0x420096, + KMIP_TAG_USAGE_LIMITS_TOTAL = 0x420097, + KMIP_TAG_USAGE_LIMITS_UNIT = 0x420098, + KMIP_TAG_USERNAME = 0x420099, + KMIP_TAG_VALIDITY_DATE = 0x42009A, + KMIP_TAG_VALIDITY_INDICATOR = 0x42009B, + KMIP_TAG_VENDOR_EXTENSION = 0x42009C, + KMIP_TAG_VENDOR_IDENTIFICATION = 0x42009D, + KMIP_TAG_WRAPPING_METHOD = 0x42009E, + KMIP_TAG_X = 0x42009F, + KMIP_TAG_Y = 0x4200A0, + KMIP_TAG_PASSWORD = 0x4200A1, + /* KMIP 1.1 */ + KMIP_TAG_DEVICE_IDENTIFIER = 0x4200A2, + KMIP_TAG_ENCODING_OPTION = 0x4200A3, + KMIP_TAG_EXTENSION_INFORMATION = 0x4200A4, + KMIP_TAG_EXTENSION_NAME = 0x4200A5, + KMIP_TAG_EXTENSION_TAG = 0x4200A6, + KMIP_TAG_EXTENSION_TYPE = 0x4200A7, + KMIP_TAG_FRESH = 0x4200A8, + KMIP_TAG_MACHINE_IDENTIFIER = 0x4200A9, + KMIP_TAG_MEDIA_IDENTIFIER = 0x4200AA, + KMIP_TAG_NETWORK_IDENTIFIER = 0x4200AB, + KMIP_TAG_OBJECT_GROUP_MEMBER = 0x4200AC, + KMIP_TAG_CERTIFICATE_LENGTH = 0x4200AD, + KMIP_TAG_DIGITAL_SIGNATURE_ALGORITHM = 0x4200AE, + KMIP_TAG_CERTIFICATE_SERIAL_NUMBER = 0x4200AF, + KMIP_TAG_DEVICE_SERIAL_NUMBER = 0x4200B0, + KMIP_TAG_ISSUER_ALTERNATIVE_NAME = 0x4200B1, + KMIP_TAG_ISSUER_DISTINGUISHED_NAME = 0x4200B2, + KMIP_TAG_SUBJECT_ALTERNATIVE_NAME = 0x4200B3, + KMIP_TAG_SUBJECT_DISTINGUISHED_NAME = 0x4200B4, + KMIP_TAG_X509_CERTIFICATE_IDENTIFIER = 0x4200B5, + KMIP_TAG_X509_CERTIFICATE_ISSUER = 0x4200B6, + KMIP_TAG_X509_CERTIFICATE_SUBJECT = 0x4200B7, + /* KMIP 1.2 */ + KMIP_TAG_KEY_VALUE_LOCATION = 0x4200B8, + KMIP_TAG_KEY_VALUE_LOCATION_VALUE = 0x4200B9, + KMIP_TAG_KEY_VALUE_LOCATION_TYPE = 0x4200BA, + KMIP_TAG_KEY_VALUE_PRESENT = 0x4200BB, + KMIP_TAG_ORIGINAL_CREATION_DATE = 0x4200BC, + KMIP_TAG_PGP_KEY = 0x4200BD, + KMIP_TAG_PGP_KEY_VERSION = 0x4200BE, + KMIP_TAG_ALTERNATIVE_NAME = 0x4200BF, + KMIP_TAG_ALTERNATIVE_NAME_VALUE = 0x4200C0, + KMIP_TAG_ALTERNATIVE_NAME_TYPE = 0x4200C1, + KMIP_TAG_DATA = 0x4200C2, + KMIP_TAG_SIGNATURE_DATA = 0x4200C3, + KMIP_TAG_DATA_LENGTH = 0x4200C4, + KMIP_TAG_RANDOM_IV = 0x4200C5, + KMIP_TAG_MAC_DATA = 0x4200C6, + KMIP_TAG_ATTESTATION_TYPE = 0x4200C7, + KMIP_TAG_NONCE = 0x4200C8, + KMIP_TAG_NONCE_ID = 0x4200C9, + KMIP_TAG_NONCE_VALUE = 0x4200CA, + KMIP_TAG_ATTESTATION_MEASUREMENT = 0x4200CB, + KMIP_TAG_ATTESTATION_ASSERTION = 0x4200CC, + KMIP_TAG_IV_LENGTH = 0x4200CD, + KMIP_TAG_TAG_LENGTH = 0x4200CE, + KMIP_TAG_FIXED_FIELD_LENGTH = 0x4200CF, + KMIP_TAG_COUNTER_LENGTH = 0x4200D0, + KMIP_TAG_INITIAL_COUNTER_VALUE = 0x4200D1, + KMIP_TAG_INVOCATION_FIELD_LENGTH = 0x4200D2, + KMIP_TAG_ATTESTATION_CAPABLE_INDICATOR = 0x4200D3, + /* KMIP 1.3 */ + KMIP_TAG_OFFSET_ITEMS = 0x4200D4, + KMIP_TAG_LOCATED_ITEMS = 0x4200D5, + KMIP_TAG_CORRELATION_VALUE = 0x4200D6, + KMIP_TAG_INIT_INDICATOR = 0x4200D7, + KMIP_TAG_FINAL_INDICATOR = 0x4200D8, + KMIP_TAG_RNG_PARAMETERS = 0x4200D9, + KMIP_TAG_RNG_ALGORITHM = 0x4200DA, + KMIP_TAG_DRBG_ALGORITHM = 0x4200DB, + KMIP_TAG_FIPS186_VARIATION = 0x4200DC, + KMIP_TAG_PREDICTION_RESISTANCE = 0x4200DD, + KMIP_TAG_RANDOM_NUMBER_GENERATOR = 0x4200DE, + KMIP_TAG_VALIDATION_INFORMATION = 0x4200DF, + KMIP_TAG_VALIDATION_AUTHORITY_TYPE = 0x4200E0, + KMIP_TAG_VALIDATION_AUTHORITY_COUNTRY = 0x4200E1, + KMIP_TAG_VALIDATION_AUTHORITY_URI = 0x4200E2, + KMIP_TAG_VALIDATION_VERSION_MAJOR = 0x4200E3, + KMIP_TAG_VALIDATION_VERSION_MINOR = 0x4200E4, + KMIP_TAG_VALIDATION_TYPE = 0x4200E5, + KMIP_TAG_VALIDATION_LEVEL = 0x4200E6, + KMIP_TAG_VALIDATION_CERTIFICATE_IDENTIFIER = 0x4200E7, + KMIP_TAG_VALIDATION_CERTIFICATE_URI = 0x4200E8, + KMIP_TAG_VALIDATION_VENDOR_URI = 0x4200E9, + KMIP_TAG_VALIDATION_PROFILE = 0x4200EA, + KMIP_TAG_PROFILE_INFORMATION = 0x4200EB, + KMIP_TAG_PROFILE_NAME = 0x4200EC, + KMIP_TAG_SERVER_URI = 0x4200ED, + KMIP_TAG_SERVER_PORT = 0x4200EE, + KMIP_TAG_STREAMING_CAPABILITY = 0x4200EF, + KMIP_TAG_ASYNCHRONOUS_CAPABILITY = 0x4200F0, + KMIP_TAG_ATTESTATION_CAPABILITY = 0x4200F1, + KMIP_TAG_UNWRAP_MODE = 0x4200F2, + KMIP_TAG_DESTROY_ACTION = 0x4200F3, + KMIP_TAG_SHREDDING_ALGORITHM = 0x4200F4, + KMIP_TAG_RNG_MODE = 0x4200F5, + KMIP_TAG_CLIENT_REGISTRATION_METHOD = 0x4200F6, + KMIP_TAG_CAPABILITY_INFORMATION = 0x4200F7, + /* KMIP 1.4 */ + KMIP_TAG_KEY_WRAP_TYPE = 0x4200F8, + KMIP_TAG_BATCH_UNDO_CAPABILITY = 0x4200F9, + KMIP_TAG_BATCH_CONTINUE_CAPABILITY = 0x4200FA, + KMIP_TAG_PKCS_12_FRIENDLY_NAME = 0x4200FB, + KMIP_TAG_DESCRIPTION = 0x4200FC, + KMIP_TAG_COMMENT = 0x4200FD, + KMIP_TAG_AUTHENTICATED_ENCRYPTION_ADDITIONAL_DATA = 0x4200FE, + KMIP_TAG_AUTHENTICATED_ENCRYPTION_TAG = 0x4200FF, + KMIP_TAG_SALT_LENGTH = 0x420100, + KMIP_TAG_MASK_GENERATOR = 0x420101, + KMIP_TAG_MASK_GENERATOR_HASHING_ALGORITHM = 0x420102, + KMIP_TAG_P_SOURCE = 0x420103, + KMIP_TAG_TRAILER_FIELD = 0x420104, + KMIP_TAG_CLIENT_CORRELATION_VALUE = 0x420105, + KMIP_TAG_SERVER_CORRELATION_VALUE = 0x420106, + KMIP_TAG_DIGESTED_DATA = 0x420107, + KMIP_TAG_CERTIFICATE_SUBJECT_CN = 0x420108, + KMIP_TAG_CERTIFICATE_SUBJECT_O = 0x420109, + KMIP_TAG_CERTIFICATE_SUBJECT_OU = 0x42010A, + KMIP_TAG_CERTIFICATE_SUBJECT_EMAIL = 0x42010B, + KMIP_TAG_CERTIFICATE_SUBJECT_C = 0x42010C, + KMIP_TAG_CERTIFICATE_SUBJECT_ST = 0x42010D, + KMIP_TAG_CERTIFICATE_SUBJECT_L = 0x42010E, + KMIP_TAG_CERTIFICATE_SUBJECT_UID = 0x42010F, + KMIP_TAG_CERTIFICATE_SUBJECT_SERIAL_NUMBER = 0x420110, + KMIP_TAG_CERTIFICATE_SUBJECT_TITLE = 0x420111, + KMIP_TAG_CERTIFICATE_SUBJECT_DC = 0x420112, + KMIP_TAG_CERTIFICATE_SUBJECT_DN_QUALIFIER = 0x420113, + KMIP_TAG_CERTIFICATE_ISSUER_CN = 0x420114, + KMIP_TAG_CERTIFICATE_ISSUER_O = 0x420115, + KMIP_TAG_CERTIFICATE_ISSUER_OU = 0x420116, + KMIP_TAG_CERTIFICATE_ISSUER_EMAIL = 0x420117, + KMIP_TAG_CERTIFICATE_ISSUER_C = 0x420118, + KMIP_TAG_CERTIFICATE_ISSUER_ST = 0x420119, + KMIP_TAG_CERTIFICATE_ISSUER_L = 0x42011A, + KMIP_TAG_CERTIFICATE_ISSUER_UID = 0x42011B, + KMIP_TAG_CERTIFICATE_ISSUER_SERIAL_NUMBER = 0x42011C, + KMIP_TAG_CERTIFICATE_ISSUER_TITLE = 0x42011D, + KMIP_TAG_CERTIFICATE_ISSUER_DC = 0x42011E, + KMIP_TAG_CERTIFICATE_ISSUER_DN_QUALIFIER = 0x42011F, + KMIP_TAG_SENSITIVE = 0x420120, + KMIP_TAG_ALWAYS_SENSITIVE = 0x420121, + KMIP_TAG_EXTRACTABLE = 0x420122, + KMIP_TAG_NEVER_EXTRACTABLE = 0x420123, + KMIP_TAG_REPLACE_EXISTING = 0x420124, + /* KMIP 2.0 */ + KMIP_TAG_ATTRIBUTES = 0x420125, + KMIP_TAG_EPHEMERAL = 0x420154, + KMIP_TAG_SERVER_HASHED_PASSWORD = 0x420155, + KMIP_TAG_PROTECTION_STORAGE_MASK = 0x42015E, + KMIP_TAG_PROTECTION_STORAGE_MASKS = 0x42015F, + KMIP_TAG_COMMON_PROTECTION_STORAGE_MASKS = 0x420163, + KMIP_TAG_PRIVATE_PROTECTION_STORAGE_MASKS = 0x420164, + KMIP_TAG_PUBLIC_PROTECTION_STORAGE_MASKS = 0x420165 +}; + +enum type +{ + /* KMIP 1.0 */ + KMIP_TYPE_STRUCTURE = 0x01, + KMIP_TYPE_INTEGER = 0x02, + KMIP_TYPE_LONG_INTEGER = 0x03, + KMIP_TYPE_BIG_INTEGER = 0x04, + KMIP_TYPE_ENUMERATION = 0x05, + KMIP_TYPE_BOOLEAN = 0x06, + KMIP_TYPE_TEXT_STRING = 0x07, + KMIP_TYPE_BYTE_STRING = 0x08, + KMIP_TYPE_DATE_TIME = 0x09, + KMIP_TYPE_INTERVAL = 0x0A, + /* KMIP 2.0 */ + KMIP_TYPE_DATE_TIME_EXTENDED = 0x0B +}; + +enum wrapping_method +{ + /* KMIP 1.0 */ + KMIP_WRAP_ENCRYPT = 0x01, + KMIP_WRAP_MAC_SIGN = 0x02, + KMIP_WRAP_ENCRYPT_MAC_SIGN = 0x03, + KMIP_WRAP_MAC_SIGN_ENCRYPT = 0x04, + KMIP_WRAP_TR31 = 0x05 +}; + +enum storage_status_mask +{ + /* KMIP 1.0 */ + KMIP_SSM_ONLINE_STORAGE = 0x1, + KMIP_SSM_ARCHIVAL_STORAGE = 0x2, + /* KMIP 2.0 */ + KMIP_SSM_DESTROYED_STORAGE = 0x4 +}; + +enum object_group_member +{ + /* KMIP 1.1 */ + KMIP_OGM_GROUP_MEMBER_FRESH = 1, + KMIP_OGM_GROUP_MEMBER_DEFAULT = 2 +}; + +/* +Structures +*/ + +typedef struct linked_list_item +{ + struct linked_list_item *next; + struct linked_list_item *prev; + + void *data; +} LinkedListItem; + +typedef struct linked_list +{ + LinkedListItem *head; + LinkedListItem *tail; + + size_t size; +} LinkedList; + +typedef struct text_string +{ + char *value; + size_t size; +} TextString; + +typedef struct byte_string +{ + uint8 *value; + size_t size; +} ByteString; + +typedef struct error_frame +{ + char function[100]; + int line; +} ErrorFrame; + +typedef struct kmip +{ + /* Encoding buffer */ + uint8 *buffer; + uint8 *index; + size_t size; + + /* KMIP message settings */ + enum kmip_version version; + int max_message_size; + LinkedList *credential_list; + + /* Error handling information */ + char *error_message; + size_t error_message_size; + /* TODO (ph) Switch the following to a LinkedList. */ + ErrorFrame errors[20]; + size_t error_frame_count; + struct error_frame *frame_index; + + /* Memory management function pointers */ + void *(*calloc_func)(void *state, size_t num, size_t size); + void *(*realloc_func)(void *state, void *ptr, size_t size); + void (*free_func)(void *state, void *ptr); + void *(*memcpy_func)(void *state, void *destination, const void* source, size_t size); + void *(*memset_func)(void *ptr, int value, size_t size); + void *state; +} KMIP; + +typedef struct attribute +{ + enum attribute_type type; + int32 index; + void *value; +} Attribute; + +typedef struct attributes +{ + LinkedList *attribute_list; +} Attributes; + +typedef struct name +{ + struct text_string *value; + enum name_type type; +} Name; + +typedef struct template_attribute +{ + /* TODO (ph) Change these to linked lists */ + Name *names; + size_t name_count; + Attribute *attributes; + size_t attribute_count; +} TemplateAttribute; + +typedef struct protocol_version +{ + int32 major; + int32 minor; +} ProtocolVersion; + +typedef struct protection_storage_masks +{ + /* KMIP 2.0 */ + LinkedList *masks; +} ProtectionStorageMasks; + +typedef struct cryptographic_parameters +{ + /* KMIP 1.0 */ + enum block_cipher_mode block_cipher_mode; + enum padding_method padding_method; + enum hashing_algorithm hashing_algorithm; + enum key_role_type key_role_type; + /* KMIP 1.2 */ + enum digital_signature_algorithm digital_signature_algorithm; + enum cryptographic_algorithm cryptographic_algorithm; + bool32 random_iv; + int32 iv_length; + int32 tag_length; + int32 fixed_field_length; + int32 invocation_field_length; + int32 counter_length; + int32 initial_counter_value; + /* KMIP 1.4 */ + int32 salt_length; + enum mask_generator mask_generator; + enum hashing_algorithm mask_generator_hashing_algorithm; + ByteString *p_source; + int32 trailer_field; +} CryptographicParameters; + +typedef struct digest +{ + enum hashing_algorithm hashing_algorithm; + ByteString *digest_value; + enum key_format_type key_format_type; +} Digest; + +typedef struct encryption_key_information +{ + TextString *unique_identifier; + CryptographicParameters *cryptographic_parameters; +} EncryptionKeyInformation; + +typedef struct mac_signature_key_information +{ + TextString *unique_identifier; + CryptographicParameters *cryptographic_parameters; +} MACSignatureKeyInformation; + +typedef struct key_wrapping_data +{ + /* KMIP 1.0 */ + enum wrapping_method wrapping_method; + EncryptionKeyInformation *encryption_key_info; + MACSignatureKeyInformation *mac_signature_key_info; + ByteString *mac_signature; + ByteString *iv_counter_nonce; + /* KMIP 1.1 */ + enum encoding_option encoding_option; +} KeyWrappingData; + +typedef struct transparent_symmetric_key +{ + ByteString *key; +} TransparentSymmetricKey; + +typedef struct key_value +{ + void *key_material; + /* TODO (ph) Change this to a linked list */ + Attribute *attributes; + size_t attribute_count; +} KeyValue; + +typedef struct key_block +{ + enum key_format_type key_format_type; + enum key_compression_type key_compression_type; + void *key_value; + enum type key_value_type; + enum cryptographic_algorithm cryptographic_algorithm; + int32 cryptographic_length; + KeyWrappingData *key_wrapping_data; +} KeyBlock; + +typedef struct symmetric_key +{ + KeyBlock *key_block; +} SymmetricKey; + +typedef struct public_key +{ + KeyBlock *key_block; +} PublicKey; + +typedef struct private_key +{ + KeyBlock *key_block; +} PrivateKey; + +typedef struct key_wrapping_specification +{ + /* KMIP 1.0 */ + enum wrapping_method wrapping_method; + EncryptionKeyInformation *encryption_key_info; + MACSignatureKeyInformation *mac_signature_key_info; + /* TODO (ph) Change this to a linked list */ + TextString *attribute_names; + size_t attribute_name_count; + /* KMIP 1.1 */ + enum encoding_option encoding_option; +} KeyWrappingSpecification; + +typedef struct nonce +{ + ByteString *nonce_id; + ByteString *nonce_value; +} Nonce; + +/* Operation Payloads */ + +typedef struct create_request_payload +{ + /* KMIP 1.0 */ + enum object_type object_type; + TemplateAttribute *template_attribute; + /* KMIP 2.0 */ + Attributes *attributes; + ProtectionStorageMasks *protection_storage_masks; +} CreateRequestPayload; + +typedef struct create_response_payload +{ + /* KMIP 1.0 */ + enum object_type object_type; + TextString *unique_identifier; + TemplateAttribute *template_attribute; +} CreateResponsePayload; + +typedef struct locate_request_payload +{ + /* KMIP 1.0 */ + size_t maximum_items; + size_t offset_items; + enum storage_status_mask storage_status_mask; + enum object_group_member object_group_member; + Attribute *attributes; + int attribute_count; +} LocateRequestPayload; + +typedef struct locate_response_payload +{ + /* KMIP 1.0 */ + size_t located_items; + TextString *unique_identifiers; + int unique_identifiers_count; +} LocateResponsePayload; + +typedef struct get_request_payload +{ + /* KMIP 1.0 */ + TextString *unique_identifier; + enum key_format_type key_format_type; + enum key_compression_type key_compression_type; + KeyWrappingSpecification *key_wrapping_spec; + /* KMIP 1.4 */ + enum key_wrap_type key_wrap_type; +} GetRequestPayload; + +typedef struct get_response_payload +{ + enum object_type object_type; + TextString *unique_identifier; + void *object; +} GetResponsePayload; + +typedef struct get_attributes_request_payload +{ + /* KMIP 1.0 */ + TextString *unique_identifier; + enum attribute_type *attribute_names; + int attribute_count; +} GetAttributesRequestPayload; + +typedef struct get_attributes_response_payload +{ + TextString *unique_identifier; + Attribute *attributes; + int attribute_count; +} GetAttributesResponsePayload; + +typedef struct get_attribute_list_request_payload +{ + /* KMIP 1.0 */ + TextString *unique_identifier; +} GetAttributeListRequestPayload; + +typedef struct get_attribute_list_response_payload +{ + TextString *unique_identifier; + enum attribute_type *attribute_names; + int attribute_names_count; +} GetAttributeListResponsePayload; + +typedef struct destroy_request_payload +{ + TextString *unique_identifier; +} DestroyRequestPayload; + +typedef struct destroy_response_payload +{ + TextString *unique_identifier; +} DestroyResponsePayload; + +/* Authentication Structures */ + +typedef struct credential +{ + enum credential_type credential_type; + void *credential_value; +} Credential; + +typedef struct username_password_credential +{ + TextString *username; + TextString *password; +} UsernamePasswordCredential; + +typedef struct device_credential +{ + TextString *device_serial_number; + TextString *password; + TextString *device_identifier; + TextString *network_identifier; + TextString *machine_identifier; + TextString *media_identifier; +} DeviceCredential; + +typedef struct attestation_credential +{ + Nonce *nonce; + enum attestation_type attestation_type; + ByteString *attestation_measurement; + ByteString *attestation_assertion; +} AttestationCredential; + +typedef struct authentication +{ + /* NOTE (ph) KMIP 1.2+ supports multiple credentials here. */ + /* NOTE (ph) Polymorphism makes this tricky. Omitting for now. */ + /* TODO (ph) Credential structs are constant size, so no problem here. */ + /* TODO (ph) Change this to a linked list */ + Credential *credential; +} Authentication; + +/* Message Structures */ + +typedef struct request_header +{ + /* KMIP 1.0 */ + ProtocolVersion *protocol_version; + int32 maximum_response_size; + bool32 asynchronous_indicator; + Authentication *authentication; + enum batch_error_continuation_option batch_error_continuation_option; + bool32 batch_order_option; + uint64 time_stamp; + int32 batch_count; + /* KMIP 1.2 */ + bool32 attestation_capable_indicator; + enum attestation_type *attestation_types; + size_t attestation_type_count; + /* KMIP 1.4 */ + TextString *client_correlation_value; + TextString *server_correlation_value; +} RequestHeader; + +typedef struct response_header +{ + /* KMIP 1.0 */ + ProtocolVersion *protocol_version; + uint64 time_stamp; + int32 batch_count; + /* KMIP 1.2 */ + Nonce *nonce; + /* TODO (ph) Change this to a linked list */ + enum attestation_type *attestation_types; + size_t attestation_type_count; + /* KMIP 1.4 */ + TextString *client_correlation_value; + TextString *server_correlation_value; + /* KMIP 2.0 */ + ByteString *server_hashed_password; +} ResponseHeader; + +typedef struct request_batch_item +{ + /* KMIP 1.0 */ + enum operation operation; + ByteString *unique_batch_item_id; + void *request_payload; + /* KMIP 2.0 */ + bool32 ephemeral; + /* NOTE (ph) Omitting the message extension field for now. */ +} RequestBatchItem; + +typedef struct response_batch_item +{ + enum operation operation; + ByteString *unique_batch_item_id; + enum result_status result_status; + enum result_reason result_reason; + TextString *result_message; + ByteString *asynchronous_correlation_value; + void *response_payload; + /* NOTE (ph) Omitting the message extension field for now. */ +} ResponseBatchItem; + +typedef struct request_message +{ + RequestHeader *request_header; + /* TODO (ph) Change this to a linked list */ + RequestBatchItem *batch_items; + size_t batch_count; +} RequestMessage; + +typedef struct response_message +{ + ResponseHeader *response_header; + /* TODO (ph) Change this to a linked list */ + ResponseBatchItem *batch_items; + size_t batch_count; +} ResponseMessage; + +/* +Macros +*/ + +#define ARRAY_LENGTH(A) (sizeof((A)) / sizeof((A)[0])) + +#define BUFFER_BYTES_LEFT(A) ((A)->size - ((A)->index - (A)->buffer)) + +#define CHECK_BUFFER_FULL(A, B) CHECK_BUFFER_SIZE((A), (B), KMIP_ERROR_BUFFER_FULL) + +#define CHECK_BUFFER_SIZE(A, B, C) \ +do \ +{ \ + if(BUFFER_BYTES_LEFT(A) < (B)) \ + { \ + kmip_push_error_frame((A), __func__, __LINE__); \ + return((C)); \ + } \ +} while(0) + +#define CHECK_RESULT(A, B) \ +do \ +{ \ + if((B) != KMIP_OK) \ + { \ + kmip_push_error_frame((A), __func__, __LINE__); \ + return((B)); \ + } \ +} while(0) + +#define HANDLE_FAILURE(A, B) \ +do \ +{ \ + kmip_push_error_frame((A), __func__, __LINE__); \ + return((B)); \ +} while(0) + +#define TAG_TYPE(A, B) (((A) << 8) | (uint8)(B)) + +#define CHECK_TAG_TYPE(A, B, C, D) \ +do \ +{ \ + if((int32)((B) >> 8) != (int32)(C)) \ + { \ + kmip_push_error_frame((A), __func__, __LINE__); \ + return(KMIP_TAG_MISMATCH); \ + } \ + else if((int32)(((B) << 24) >> 24) != (int32)(D)) \ + { \ + kmip_push_error_frame((A), __func__, __LINE__); \ + return(KMIP_TYPE_MISMATCH); \ + } \ +} while(0) + +#define CHECK_LENGTH(A, B, C) \ +do \ +{ \ + if((B) != (C)) \ + { \ + kmip_push_error_frame((A), __func__, __LINE__); \ + return(KMIP_LENGTH_MISMATCH); \ + } \ +} while(0) + +#define CHECK_PADDING(A, B) \ +do \ +{ \ + if((B) != 0) \ + { \ + kmip_push_error_frame((A), __func__, __LINE__); \ + return(KMIP_PADDING_MISMATCH); \ + } \ +} while(0) + +#define CHECK_BOOLEAN(A, B) \ +do \ +{ \ + if(((B) != KMIP_TRUE) && ((B) != KMIP_FALSE)) \ + { \ + kmip_push_error_frame((A), __func__, __LINE__); \ + return(KMIP_BOOLEAN_MISMATCH); \ + } \ +} while(0) + +#define CHECK_ENUM(A, B, C) \ +do \ +{ \ + int result = kmip_check_enum_value((A)->version, (B), (C)); \ + if(result != KMIP_OK) \ + { \ + kmip_set_enum_error_message((A), (B), (C), result); \ + kmip_push_error_frame((A), __func__, __LINE__); \ + return(result); \ + } \ +} while(0) + +#define CHECK_NEW_MEMORY(A, B, C, D) \ +do \ +{ \ + if((B) == NULL) \ + { \ + kmip_set_alloc_error_message((A), (C), (D)); \ + kmip_push_error_frame((A), __func__, __LINE__); \ + return(KMIP_MEMORY_ALLOC_FAILED); \ + } \ +} while(0) + +#define HANDLE_FAILED_ALLOC(A, B, C) \ +do \ +{ \ + kmip_set_alloc_error_message((A), (B), (C)); \ + kmip_push_error_frame((A), __func__, __LINE__); \ + return(KMIP_MEMORY_ALLOC_FAILED); \ +} while(0) + +#define CHECK_ENCODE_ARGS(A, B) \ +do \ +{ \ + if((A) == NULL) \ + { \ + return(KMIP_ARG_INVALID); \ + } \ + if((B) == NULL) \ + { \ + return(KMIP_OK); \ + } \ +} while(0) + +#define CHECK_DECODE_ARGS(A, B) \ +do \ +{ \ + if((A) == NULL || (B) == NULL) \ + { \ + return(KMIP_ARG_INVALID); \ + } \ +} while(0) + +#define CHECK_KMIP_VERSION(A, B) \ +do \ +{ \ + if((A)->version < (B)) \ + { \ + kmip_push_error_frame((A), __func__, __LINE__); \ + return(KMIP_INVALID_FOR_VERSION); \ + } \ +} while(0) + +#define CALCULATE_PADDING(A) ((8 - ((A) % 8)) % 8) + +/* +Miscellaneous Utilities +*/ + +size_t kmip_strnlen_s(const char *, size_t); +LinkedListItem *kmip_linked_list_pop(LinkedList *); +void kmip_linked_list_push(LinkedList *, LinkedListItem *); +void kmip_linked_list_enqueue(LinkedList *, LinkedListItem *); + +/* +Memory Handlers +*/ + +void *kmip_calloc(void *, size_t, size_t); +void *kmip_realloc(void *, void *, size_t); +void kmip_free(void *, void *); +void *kmip_memcpy(void *, void *, const void *, size_t); + +/* +Enumeration Utilities +*/ + +int kmip_get_enum_string_index(enum tag); +int kmip_check_enum_value(enum kmip_version, enum tag, int); + +/* +Context Utilities +*/ + +void kmip_clear_errors(KMIP *); +void kmip_init(KMIP *, void *, size_t, enum kmip_version); +void kmip_init_error_message(KMIP *); +int kmip_add_credential(KMIP *, Credential *); +void kmip_remove_credentials(KMIP *); +void kmip_reset(KMIP *); +void kmip_rewind(KMIP *); +void kmip_set_buffer(KMIP *, void *, size_t); +void kmip_destroy(KMIP *); +void kmip_push_error_frame(KMIP *, const char *, const int); +void kmip_set_enum_error_message(KMIP *, enum tag, int, int); +void kmip_set_alloc_error_message(KMIP *, size_t, const char *); +void kmip_set_error_message(KMIP *, const char *); +int kmip_is_tag_next(const KMIP *, enum tag); +int kmip_is_tag_type_next(const KMIP *, enum tag, enum type); +int kmip_get_num_items_next(KMIP *, enum tag); +uint32 kmip_peek_tag(KMIP *); +int kmip_is_attribute_tag(uint32); + +/* +Initialization Functions +*/ + +void kmip_init_protocol_version(ProtocolVersion *, enum kmip_version); +void kmip_init_attribute(Attribute *); +void kmip_init_cryptographic_parameters(CryptographicParameters *); +void kmip_init_key_block(KeyBlock *); +void kmip_init_request_header(RequestHeader *); +void kmip_init_response_header(ResponseHeader *); +void kmip_init_request_batch_item(RequestBatchItem *); + +/* +Printing Functions +*/ + +void kmip_print_buffer(void *, int); +void kmip_print_stack_trace(KMIP *); +void kmip_print_error_string(int); +void kmip_print_batch_error_continuation_option(enum batch_error_continuation_option); +void kmip_print_operation_enum(enum operation); +void kmip_print_result_status_enum(enum result_status); +void kmip_print_result_reason_enum(enum result_reason); +void kmip_print_object_type_enum(enum object_type); +void kmip_print_key_format_type_enum(enum key_format_type); +void kmip_print_key_compression_type_enum(enum key_compression_type); +void kmip_print_cryptographic_algorithm_enum(enum cryptographic_algorithm); +void kmip_print_name_type_enum(enum name_type); +void kmip_print_attribute_type_enum(enum attribute_type); +void kmip_print_state_enum(enum state); +void kmip_print_block_cipher_mode_enum(enum block_cipher_mode); +void kmip_print_certificate_type_mode_enum(enum certificate_type); +void kmip_print_padding_method_enum(enum padding_method); +void kmip_print_hashing_algorithm_enum(enum hashing_algorithm); +void kmip_print_key_role_type_enum(enum key_role_type); +void kmip_print_digital_signature_algorithm_enum(enum digital_signature_algorithm); +void kmip_print_mask_generator_enum(enum mask_generator); +void kmip_print_wrapping_method_enum(enum wrapping_method); +void kmip_print_encoding_option_enum(enum encoding_option); +void kmip_print_key_wrap_type_enum(enum key_wrap_type); +void kmip_print_credential_type_enum(enum credential_type); +void kmip_print_cryptographic_usage_mask_enums(int, int32); +void kmip_print_integer(int32); +void kmip_print_bool(int32); +void kmip_print_date_time(int64); +void kmip_print_text_string(int, const char *, TextString *); +void kmip_print_byte_string(int, const char *, ByteString *); +void kmip_print_protocol_version(int, ProtocolVersion *); +void kmip_print_name(int, Name *); +void kmip_print_nonce(int, Nonce *); +void kmip_print_storage_status_mask_enum(enum storage_status_mask); +void kmip_print_object_group_member_enum(enum object_group_member); +void kmip_print_protection_storage_masks_enum(int, int32); +void kmip_print_protection_storage_masks(int, ProtectionStorageMasks *); +void kmip_print_cryptographic_parameters(int, CryptographicParameters *); +void kmip_print_encryption_key_information(int, EncryptionKeyInformation *); +void kmip_print_mac_signature_key_information(int, MACSignatureKeyInformation *); +void kmip_print_key_wrapping_data(int, KeyWrappingData *); +void kmip_print_attribute_value(int, enum attribute_type, void *); +void kmip_print_attribute(int, Attribute *); +void kmip_print_attributes(int, Attributes *); +void kmip_print_key_material(int, enum key_format_type, void *); +void kmip_print_key_value(int, enum type, enum key_format_type, void *); +void kmip_print_key_block(int, KeyBlock *); +void kmip_print_symmetric_key(int, SymmetricKey *); +void kmip_print_object(int, enum object_type, void *); +void kmip_print_key_wrapping_specification(int, KeyWrappingSpecification *); +void kmip_print_template_attribute(int, TemplateAttribute *); +void kmip_print_create_request_payload(int, CreateRequestPayload *); +void kmip_print_create_response_payload(int, CreateResponsePayload *); +void kmip_print_locate_request_payload(int, LocateRequestPayload *); +void kmip_print_locate_response_payload(int, LocateResponsePayload *); +void kmip_print_get_request_payload(int, GetRequestPayload *); +void kmip_print_get_response_payload(int, GetResponsePayload *); +void kmip_print_get_attributes_request_payload(int, GetAttributesRequestPayload *); +void kmip_print_get_attributes_response_payload(int, GetAttributesResponsePayload *); +void kmip_print_get_attribute_list_request_payload(int, GetAttributeListRequestPayload *); +void kmip_print_get_attribute_list_response_payload(int, GetAttributeListResponsePayload *); +void kmip_print_destroy_request_payload(int, DestroyRequestPayload *); +void kmip_print_destroy_response_payload(int, DestroyResponsePayload *); +void kmip_print_request_payload(int, enum operation, void *); +void kmip_print_response_payload(int, enum operation, void *); +void kmip_print_username_password_credential(int, UsernamePasswordCredential *); +void kmip_print_device_credential(int, DeviceCredential *); +void kmip_print_attestation_credential(int, AttestationCredential *); +void kmip_print_credential_value(int, enum credential_type, void *); +void kmip_print_credential(int, Credential *); +void kmip_print_authentication(int, Authentication *); +void kmip_print_request_batch_item(int, RequestBatchItem *); +void kmip_print_response_batch_item(int, ResponseBatchItem *); +void kmip_print_request_header(int, RequestHeader *); +void kmip_print_response_header(int, ResponseHeader *); +void kmip_print_request_message(RequestMessage *); +void kmip_print_response_message(ResponseMessage *); + +/* +Freeing Functions +*/ + +void kmip_free_buffer(KMIP *, void *, size_t); +void kmip_free_text_string(KMIP *, TextString *); +void kmip_free_byte_string(KMIP *, ByteString *); +void kmip_free_name(KMIP *, Name *); +void kmip_free_attribute(KMIP *, Attribute *); +void kmip_free_attributes(KMIP *, Attributes *); +void kmip_free_attributes_2(KMIP *, Attribute *, int); +void kmip_free_template_attribute(KMIP *, TemplateAttribute *); +void kmip_free_transparent_symmetric_key(KMIP *, TransparentSymmetricKey *); +void kmip_free_key_material(KMIP *, enum key_format_type, void **); +void kmip_free_key_value(KMIP *, enum key_format_type, KeyValue *); +void kmip_free_protection_storage_masks(KMIP *, ProtectionStorageMasks *); +void kmip_free_cryptographic_parameters(KMIP *, CryptographicParameters *); +void kmip_free_encryption_key_information(KMIP *, EncryptionKeyInformation *); +void kmip_free_mac_signature_key_information(KMIP *, MACSignatureKeyInformation *); +void kmip_free_key_wrapping_data(KMIP *, KeyWrappingData *); +void kmip_free_key_block(KMIP *, KeyBlock *); +void kmip_free_symmetric_key(KMIP *, SymmetricKey *); +void kmip_free_public_key(KMIP *, PublicKey *); +void kmip_free_private_key(KMIP *, PrivateKey *); +void kmip_free_key_wrapping_specification(KMIP *, KeyWrappingSpecification *); +void kmip_free_create_request_payload(KMIP *, CreateRequestPayload *); +void kmip_free_create_response_payload(KMIP *, CreateResponsePayload *); +void kmip_free_locate_request_payload(KMIP *, LocateRequestPayload *); +void kmip_free_locate_response_payload(KMIP *, LocateResponsePayload *); +void kmip_free_get_request_payload(KMIP *, GetRequestPayload *); +void kmip_free_get_response_payload(KMIP *, GetResponsePayload *); +void kmip_free_get_attributes_request_payload(KMIP *, GetAttributesRequestPayload *); +void kmip_free_get_attributes_response_payload(KMIP *, GetAttributesResponsePayload *); +void kmip_free_get_attribute_list_request_payload(KMIP *, GetAttributeListRequestPayload *); +void kmip_free_get_attribute_list_response_payload(KMIP *, GetAttributeListResponsePayload *); +void kmip_free_destroy_request_payload(KMIP *, DestroyRequestPayload *); +void kmip_free_destroy_response_payload(KMIP *, DestroyResponsePayload *); +void kmip_free_request_batch_item(KMIP *, RequestBatchItem *); +void kmip_free_response_batch_item(KMIP *, ResponseBatchItem *); +void kmip_free_nonce(KMIP *, Nonce *); +void kmip_free_username_password_credential(KMIP *, UsernamePasswordCredential *); +void kmip_free_device_credential(KMIP *, DeviceCredential *); +void kmip_free_attestation_credential(KMIP *, AttestationCredential *); +void kmip_free_credential_value(KMIP *, enum credential_type, void **); +void kmip_free_credential(KMIP *, Credential *); +void kmip_free_authentication(KMIP *, Authentication *); +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 *); + +/* +Copying Functions +*/ + +int32 * kmip_deep_copy_int32(KMIP *, const int32 *); +TextString * kmip_deep_copy_text_string(KMIP *, const TextString *); +Name * kmip_deep_copy_name(KMIP *, const Name *); +Attribute * kmip_deep_copy_attribute(KMIP *, const Attribute *); + +/* +Comparison Functions +*/ + +int kmip_compare_text_string(const TextString *, const TextString *); +int kmip_compare_byte_string(const ByteString *, const ByteString *); +int kmip_compare_name(const Name *, const Name *); +int kmip_compare_attribute(const Attribute *, const Attribute *); +int kmip_compare_attributes(const Attributes *, const Attributes *); +int kmip_compare_template_attribute(const TemplateAttribute *, const TemplateAttribute *); +int kmip_compare_protocol_version(const ProtocolVersion *, const ProtocolVersion *); +int kmip_compare_transparent_symmetric_key(const TransparentSymmetricKey *, const TransparentSymmetricKey *); +int kmip_compare_key_material(enum key_format_type, void **, void **); +int kmip_compare_key_value(enum key_format_type, const KeyValue *, const KeyValue *); +int kmip_compare_protection_storage_masks(const ProtectionStorageMasks *, const ProtectionStorageMasks *); +int kmip_compare_cryptographic_parameters(const CryptographicParameters *, const CryptographicParameters *); +int kmip_compare_encryption_key_information(const EncryptionKeyInformation *, const EncryptionKeyInformation *); +int kmip_compare_mac_signature_key_information(const MACSignatureKeyInformation *, const MACSignatureKeyInformation *); +int kmip_compare_key_wrapping_data(const KeyWrappingData *, const KeyWrappingData *); +int kmip_compare_key_block(const KeyBlock *, const KeyBlock *); +int kmip_compare_symmetric_key(const SymmetricKey *, const SymmetricKey *); +int kmip_compare_public_key(const PublicKey *, const PublicKey *); +int kmip_compare_private_key(const PrivateKey *, const PrivateKey *); +int kmip_compare_key_wrapping_specification(const KeyWrappingSpecification *, const KeyWrappingSpecification *); +int kmip_compare_create_request_payload(const CreateRequestPayload *, const CreateRequestPayload *); +int kmip_compare_create_response_payload(const CreateResponsePayload *, const CreateResponsePayload *); +int kmip_compare_locate_request_payload(const LocateRequestPayload *, const LocateRequestPayload *); +int kmip_compare_locate_response_payload(const LocateResponsePayload *, const LocateResponsePayload *); +int kmip_compare_get_request_payload(const GetRequestPayload *, const GetRequestPayload *); +int kmip_compare_get_response_payload(const GetResponsePayload *, const GetResponsePayload *); +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_get_attribute_list_request_payload(const GetAttributeListRequestPayload *, const GetAttributeListRequestPayload *); +int kmip_compare_get_attribute_list_response_payload(const GetAttributeListResponsePayload *, const GetAttributeListResponsePayload *); +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 *); +int kmip_compare_response_batch_item(const ResponseBatchItem *, const ResponseBatchItem *); +int kmip_compare_nonce(const Nonce *, const Nonce *); +int kmip_compare_username_password_credential(const UsernamePasswordCredential *, const UsernamePasswordCredential *); +int kmip_compare_device_credential(const DeviceCredential *, const DeviceCredential *); +int kmip_compare_attestation_credential(const AttestationCredential *, const AttestationCredential *); +int kmip_compare_credential_value(enum credential_type, void **, void **); +int kmip_compare_credential(const Credential *, const Credential *); +int kmip_compare_authentication(const Authentication *, const Authentication *); +int kmip_compare_request_header(const RequestHeader *, const RequestHeader *); +int kmip_compare_response_header(const ResponseHeader *, const ResponseHeader *); +int kmip_compare_request_message(const RequestMessage *, const RequestMessage *); +int kmip_compare_response_message(const ResponseMessage *, const ResponseMessage *); + +/* +Encoding Functions +*/ + +int kmip_encode_int8_be(KMIP *, int8); +int kmip_encode_int32_be(KMIP *, int32); +int kmip_encode_int64_be(KMIP *, int64); +int kmip_encode_integer(KMIP *, enum tag, int32); +int kmip_encode_long(KMIP *, enum tag, int64); +int kmip_encode_enum(KMIP *, enum tag, int32); +int kmip_encode_bool(KMIP *, enum tag, bool32); +int kmip_encode_text_string(KMIP *, enum tag, const TextString *); +int kmip_encode_byte_string(KMIP *, enum tag, const ByteString *); +int kmip_encode_date_time(KMIP *, enum tag, uint64); +int kmip_encode_interval(KMIP *, enum tag, uint32); +int kmip_encode_name(KMIP *, const Name *); +int kmip_encode_attribute_name(KMIP *, enum attribute_type); +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_attributes_2(KMIP *, const Attribute *, int count); +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 *); +int kmip_encode_cryptographic_parameters(KMIP *, const CryptographicParameters *); +int kmip_encode_encryption_key_information(KMIP *, const EncryptionKeyInformation *); +int kmip_encode_mac_signature_key_information(KMIP *, const MACSignatureKeyInformation *); +int kmip_encode_key_wrapping_data(KMIP *, const KeyWrappingData *); +int kmip_encode_transparent_symmetric_key(KMIP *, const TransparentSymmetricKey *); +int kmip_encode_key_material(KMIP *, enum key_format_type, const void *); +int kmip_encode_key_value(KMIP *, enum key_format_type, const KeyValue *); +int kmip_encode_key_block(KMIP *, const KeyBlock *); +int kmip_encode_symmetric_key(KMIP *, const SymmetricKey *); +int kmip_encode_public_key(KMIP *, const PublicKey *); +int kmip_encode_private_key(KMIP *, const PrivateKey *); +int kmip_encode_key_wrapping_specification(KMIP *, const KeyWrappingSpecification *); +int kmip_encode_create_request_payload(KMIP *, const CreateRequestPayload *); +int kmip_encode_create_response_payload(KMIP *, const CreateResponsePayload *); +int kmip_encode_locate_request_payload(KMIP *, const LocateRequestPayload *); +int kmip_encode_locate_response_payload(KMIP *, const LocateResponsePayload *); +int kmip_encode_get_request_payload(KMIP *, const GetRequestPayload *); +int kmip_encode_get_response_payload(KMIP *, const GetResponsePayload *); +int kmip_encode_get_attributes_request_payload(KMIP *, const GetAttributesRequestPayload *); +int kmip_encode_get_attributes_response_payload(KMIP *, const GetAttributesResponsePayload *); +int kmip_encode_get_attribute_list_request_payload(KMIP *, const GetAttributeListRequestPayload *); +int kmip_encode_get_attribute_list_response_payload(KMIP *, const GetAttributeListResponsePayload *); +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 *); +int kmip_encode_username_password_credential(KMIP *, const UsernamePasswordCredential *); +int kmip_encode_device_credential(KMIP *, const DeviceCredential *); +int kmip_encode_attestation_credential(KMIP *, const AttestationCredential *); +int kmip_encode_credential_value(KMIP *, enum credential_type, void *); +int kmip_encode_credential(KMIP *, const Credential *); +int kmip_encode_authentication(KMIP *, const Authentication *); +int kmip_encode_request_header(KMIP *, const RequestHeader *); +int kmip_encode_response_header(KMIP *, const ResponseHeader *); +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 *); + +/* +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_integer(KMIP *, enum tag, int32 *); +int kmip_decode_long(KMIP *, enum tag, int64 *); +int kmip_decode_enum(KMIP *, enum tag, void *); +int kmip_decode_bool(KMIP *, enum tag, bool32 *); +int kmip_decode_text_string(KMIP *, enum tag, TextString *); +int kmip_decode_byte_string(KMIP *, enum tag, ByteString *); +int kmip_decode_date_time(KMIP *, enum tag, uint64 *); +int kmip_decode_interval(KMIP *, enum tag, uint32 *); +int kmip_decode_name(KMIP *, Name *); +int kmip_decode_attribute_name(KMIP *, enum attribute_type *); +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_attributes_2(KMIP *, Attribute **, int *); +int kmip_decode_template_attribute(KMIP *, TemplateAttribute *); +int kmip_decode_protocol_version(KMIP *, ProtocolVersion *); +int kmip_decode_transparent_symmetric_key(KMIP *, TransparentSymmetricKey *); +int kmip_decode_key_material(KMIP *, enum key_format_type, void **); +int kmip_decode_key_value(KMIP *, enum key_format_type, KeyValue *); +int kmip_decode_protection_storage_masks(KMIP *, ProtectionStorageMasks *); +int kmip_decode_cryptographic_parameters(KMIP *, CryptographicParameters *); +int kmip_decode_encryption_key_information(KMIP *, EncryptionKeyInformation *); +int kmip_decode_mac_signature_key_information(KMIP *, MACSignatureKeyInformation *); +int kmip_decode_key_wrapping_data(KMIP *, KeyWrappingData *); +int kmip_decode_key_block(KMIP *, KeyBlock *); +int kmip_decode_symmetric_key(KMIP *, SymmetricKey *); +int kmip_decode_public_key(KMIP *, PublicKey *); +int kmip_decode_private_key(KMIP *, PrivateKey *); +int kmip_decode_key_wrapping_specification(KMIP *, KeyWrappingSpecification *); +int kmip_decode_create_request_payload(KMIP *, CreateRequestPayload *); +int kmip_decode_create_response_payload(KMIP *, CreateResponsePayload *); +int kmip_decode_locate_request_payload(KMIP *, LocateRequestPayload *); +int kmip_decode_locate_response_payload(KMIP *, LocateResponsePayload *); +int kmip_decode_get_request_payload(KMIP *, GetRequestPayload *); +int kmip_decode_get_response_payload(KMIP *, GetResponsePayload *); +int kmip_decode_get_attributes_request_payload(KMIP *, GetAttributesRequestPayload *); +int kmip_decode_get_attributes_response_payload(KMIP *, GetAttributesResponsePayload *); +int kmip_decode_get_attribute_list_request_payload(KMIP *, GetAttributeListRequestPayload *); +int kmip_decode_get_attribute_list_response_payload(KMIP *, GetAttributeListResponsePayload *); +int kmip_decode_destroy_request_payload(KMIP *, DestroyRequestPayload *); +int kmip_decode_destroy_response_payload(KMIP *, DestroyResponsePayload *); +int kmip_decode_request_batch_item(KMIP *, RequestBatchItem *); +int kmip_decode_response_batch_item(KMIP *, ResponseBatchItem *); +int kmip_decode_nonce(KMIP *, Nonce *); +int kmip_decode_username_password_credential(KMIP *, UsernamePasswordCredential *); +int kmip_decode_device_credential(KMIP *, DeviceCredential *); +int kmip_decode_attestation_credential(KMIP *, AttestationCredential *); +int kmip_decode_credential_value(KMIP *, enum credential_type, void **); +int kmip_decode_credential(KMIP *, Credential *); +int kmip_decode_authentication(KMIP *, Authentication *); +int kmip_decode_request_header(KMIP *, RequestHeader *); +int kmip_decode_response_header(KMIP *, ResponseHeader *); +int kmip_decode_request_message(KMIP *, RequestMessage *); +int kmip_decode_response_message(KMIP *, ResponseMessage *); + +#endif /* KMIP_H */ diff --git a/src/libkmip/kmip_bio.c b/src/libkmip/kmip_bio.c new file mode 100644 index 000000000..0798515c8 --- /dev/null +++ b/src/libkmip/kmip_bio.c @@ -0,0 +1,1613 @@ +/* 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 <openssl/ssl.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <time.h> + +#include "kmip.h" +#include "kmip_bio.h" +#include "kmip_memset.h" + +/* +OpenSSH BIO API +*/ + +int kmip_bio_create_symmetric_key(BIO *bio, + TemplateAttribute *template_attribute, + char **id, int *id_size) +{ + if(bio == NULL || template_attribute == NULL || id == NULL || id_size == NULL) + 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; + + CreateRequestPayload crp = {0}; + crp.object_type = KMIP_OBJTYPE_SYMMETRIC_KEY; + crp.template_attribute = template_attribute; + + RequestBatchItem rbi = {0}; + kmip_init_request_batch_item(&rbi); + rbi.operation = KMIP_OP_CREATE; + rbi.request_payload = &crp; + + 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(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_destroy(&ctx); + return(KMIP_IO_FAILURE); + } + + kmip_set_buffer(&ctx, encoding, buffer_block_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_buffer(&ctx, encoding, buffer_total_size); + encoding = NULL; + kmip_destroy(&ctx); + return(decode_result); + } + + enum result_status result = KMIP_STATUS_OPERATION_FAILED; + if(resp_m.batch_count != 1 || resp_m.batch_items == NULL) + { + 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]; + result = resp_item.result_status; + + CreateResponsePayload *pld = (CreateResponsePayload *)resp_item.response_payload; + TextString *unique_identifier = pld->unique_identifier; + + /* KMIP text strings are not null-terminated by default. Add an extra */ + /* character to the end of the UUID copy to make space for the null */ + /* terminator. */ + char *result_id = ctx.calloc_func( + ctx.state, + 1, + unique_identifier->size + 1); + *id_size = unique_identifier->size; + for(int i = 0; i < *id_size; i++) + result_id[i] = unique_identifier->value[i]; + *id = result_id; + + /* 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_locate(BIO *bio, + Attribute *attributes, + size_t attribute_count, + size_t *located_item_count, + char ***located_item_uuids) +{ + KMIP ctx[1] = {{0}}; + kmip_init(ctx, NULL, 0, KMIP_1_0); + return kmip_bio_locate_with_context(ctx, bio, attributes, attribute_count, located_item_count, located_item_uuids); +} + +int kmip_bio_destroy_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; + + DestroyRequestPayload drp = {0}; + drp.unique_identifier = &id; + + RequestBatchItem rbi = {0}; + kmip_init_request_batch_item(&rbi); + rbi.operation = KMIP_OP_DESTROY; + rbi.request_payload = &drp; + + 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_buffer(&ctx, encoding, buffer_total_size); + encoding = NULL; + kmip_destroy(&ctx); + return(decode_result); + } + + enum result_status result = KMIP_STATUS_OPERATION_FAILED; + if(resp_m.batch_count != 1 || resp_m.batch_items == NULL) + { + 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]; + 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) +{ + if(bio == NULL || id == NULL || id_size <= 0 || key == NULL || key_size == NULL) + { + 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 uuid = {0}; + uuid.value = id; + uuid.size = id_size; + + GetRequestPayload grp = {0}; + grp.unique_identifier = &uuid; + + RequestBatchItem rbi = {0}; + kmip_init_request_batch_item(&rbi); + rbi.operation = KMIP_OP_GET; + rbi.request_payload = &grp; + + 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(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_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_buffer(&ctx, encoding, buffer_total_size); + encoding = NULL; + kmip_destroy(&ctx); + return(decode_result); + } + + kmip_free_buffer(&ctx, encoding, buffer_total_size); + encoding = NULL; + + enum result_status result = KMIP_STATUS_OPERATION_FAILED; + if(resp_m.batch_count != 1 || resp_m.batch_items == NULL) + { + kmip_free_response_message(&ctx, &resp_m); + kmip_set_buffer(&ctx, NULL, 0); + kmip_destroy(&ctx); + return(KMIP_MALFORMED_RESPONSE); + } + + ResponseBatchItem resp_item = resp_m.batch_items[0]; + result = resp_item.result_status; + + if(result != KMIP_STATUS_SUCCESS) + { + kmip_free_response_message(&ctx, &resp_m); + kmip_set_buffer(&ctx, NULL, 0); + kmip_destroy(&ctx); + return(result); + } + + GetResponsePayload *pld = (GetResponsePayload *)resp_item.response_payload; + + if(pld->object_type != KMIP_OBJTYPE_SYMMETRIC_KEY) + { + kmip_free_response_message(&ctx, &resp_m); + kmip_set_buffer(&ctx, NULL, 0); + kmip_destroy(&ctx); + return(KMIP_OBJECT_MISMATCH); + } + + SymmetricKey *symmetric_key = (SymmetricKey *)pld->object; + KeyBlock *block = symmetric_key->key_block; + if((block->key_format_type != KMIP_KEYFORMAT_RAW) || + (block->key_wrapping_data != NULL)) + { + kmip_free_response_message(&ctx, &resp_m); + kmip_set_buffer(&ctx, NULL, 0); + kmip_destroy(&ctx); + return(KMIP_OBJECT_MISMATCH); + } + + KeyValue *block_value = block->key_value; + ByteString *material = (ByteString *)block_value->key_material; + + char *result_key = ctx.calloc_func(ctx.state, 1, material->size); + *key_size = material->size; + for(int i = 0; i < *key_size; i++) + { + result_key[i] = material->value[i]; + } + *key = result_key; + + /* 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_create_symmetric_key_with_context(KMIP *ctx, BIO *bio, + TemplateAttribute *template_attribute, + char **id, int *id_size) +{ + if(ctx == NULL || bio == NULL || template_attribute == NULL || id == NULL || id_size == NULL) + { + 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; + + CreateRequestPayload crp = {0}; + crp.object_type = KMIP_OBJTYPE_SYMMETRIC_KEY; + crp.template_attribute = template_attribute; + + RequestBatchItem rbi = {0}; + kmip_init_request_batch_item(&rbi); + rbi.operation = KMIP_OP_CREATE; + rbi.request_payload = &crp; + + 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 results. */ + 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_buffer(ctx, encoding, buffer_total_size); + encoding = NULL; + return(decode_result); + } + + enum result_status result = KMIP_STATUS_OPERATION_FAILED; + if(resp_m.batch_count != 1 || resp_m.batch_items == NULL) + { + kmip_free_buffer(ctx, encoding, buffer_total_size); + encoding = NULL; + return(KMIP_MALFORMED_RESPONSE); + } + + ResponseBatchItem resp_item = resp_m.batch_items[0]; + result = resp_item.result_status; + + CreateResponsePayload *pld = (CreateResponsePayload *)resp_item.response_payload; + TextString *unique_identifier = pld->unique_identifier; + + char *result_id = ctx->calloc_func(ctx->state, 1, unique_identifier->size); + *id_size = unique_identifier->size; + for(int i = 0; i < *id_size; i++) + { + result_id[i] = unique_identifier->value[i]; + } + *id = result_id; + + /* 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_locate_with_context(KMIP *ctx, BIO *bio, + Attribute *attributes, + size_t attribute_count, + size_t *located_item_count, + char ***located_item_uuids) +{ + if(ctx == NULL || bio == NULL || attributes == NULL || located_item_count == NULL || located_item_uuids == NULL) + { + 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; + + LocateRequestPayload lrp = {0}; + lrp.attributes = attributes; + lrp.attribute_count = attribute_count; + + RequestBatchItem rbi = {0}; + kmip_init_request_batch_item(&rbi); + rbi.operation = KMIP_OP_CREATE; + rbi.request_payload = &lrp; + + 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 results. */ + 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_buffer(ctx, encoding, buffer_total_size); + encoding = NULL; + return(decode_result); + } + + enum result_status result = KMIP_STATUS_OPERATION_FAILED; + if(resp_m.batch_count != 1 || resp_m.batch_items == NULL) + { + kmip_free_buffer(ctx, encoding, buffer_total_size); + encoding = NULL; + return(KMIP_MALFORMED_RESPONSE); + } + + ResponseBatchItem resp_item = resp_m.batch_items[0]; + result = resp_item.result_status; + + LocateResponsePayload *pld = (LocateResponsePayload *)resp_item.response_payload; + TextString *unique_identifier = pld->unique_identifiers; + + char **result_id = ctx->calloc_func(ctx->state, 1, sizeof (char *)); + *located_item_count = pld->unique_identifiers_count; + for(int i = 0; i < pld->unique_identifiers_count; i++, ++unique_identifier) + { + result_id[i] = unique_identifier->value; + unique_identifier->value = 0; + } + *located_item_uuids = result_id; + + /* 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_get_symmetric_key_with_context(KMIP *ctx, BIO *bio, + char *uuid, int uuid_size, + char **key, int *key_size) +{ + if(ctx == NULL || bio == NULL || uuid == NULL || uuid_size <= 0 || key == NULL || key_size == NULL) + { + 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; + + GetRequestPayload grp = {0}; + grp.unique_identifier = &id; + + RequestBatchItem rbi = {0}; + kmip_init_request_batch_item(&rbi); + rbi.operation = KMIP_OP_GET; + rbi.request_payload = &grp; + + 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) + { + 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; + 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; + 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) + { + 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; + 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; + 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; + 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_buffer(ctx, encoding, buffer_total_size); + encoding = NULL; + return(decode_result); + } + + kmip_free_buffer(ctx, encoding, buffer_total_size); + encoding = NULL; + + enum result_status result = KMIP_STATUS_OPERATION_FAILED; + if(resp_m.batch_count != 1 || resp_m.batch_items == NULL) + { + kmip_free_response_message(ctx, &resp_m); + kmip_set_buffer(ctx, NULL, 0); + return(KMIP_MALFORMED_RESPONSE); + } + + ResponseBatchItem resp_item = resp_m.batch_items[0]; + result = resp_item.result_status; + + if(result != KMIP_STATUS_SUCCESS) + { + kmip_free_response_message(ctx, &resp_m); + kmip_set_buffer(ctx, NULL, 0); + return(result); + } + + GetResponsePayload *pld = (GetResponsePayload *)resp_item.response_payload; + + if(pld->object_type != KMIP_OBJTYPE_SYMMETRIC_KEY) + { + kmip_free_response_message(ctx, &resp_m); + kmip_set_buffer(ctx, NULL, 0); + return(KMIP_OBJECT_MISMATCH); + } + + SymmetricKey *symmetric_key = (SymmetricKey *)pld->object; + KeyBlock *block = symmetric_key->key_block; + if((block->key_format_type != KMIP_KEYFORMAT_RAW) || + (block->key_wrapping_data != NULL)) + { + kmip_free_response_message(ctx, &resp_m); + kmip_set_buffer(ctx, NULL, 0); + return(KMIP_OBJECT_MISMATCH); + } + + KeyValue *block_value = block->key_value; + ByteString *material = (ByteString *)block_value->key_material; + + char *result_key = ctx->calloc_func(ctx->state, 1, material->size); + *key_size = material->size; + for(int i = 0; i < *key_size; i++) + { + result_key[i] = material->value[i]; + } + *key = result_key; + + /* 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); + + return(result); +} + +int kmip_bio_destroy_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; + + DestroyRequestPayload drp = {0}; + drp.unique_identifier = &id; + + RequestBatchItem rbi = {0}; + kmip_init_request_batch_item(&rbi); + rbi.operation = KMIP_OP_DESTROY; + rbi.request_payload = &drp; + + 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_buffer(ctx, encoding, buffer_total_size); + encoding = NULL; + return(decode_result); + } + + enum result_status result = KMIP_STATUS_OPERATION_FAILED; + if(resp_m.batch_count != 1 || resp_m.batch_items == NULL) + { + kmip_free_buffer(ctx, encoding, buffer_total_size); + encoding = NULL; + return(KMIP_MALFORMED_RESPONSE); + } + + ResponseBatchItem resp_item = resp_m.batch_items[0]; + 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) +{ + if(ctx == NULL || bio == NULL || request == NULL || request_size <= 0 || response == NULL || response_size == NULL) + { + return(KMIP_ARG_INVALID); + } + + /* Send the request message. */ + int sent = BIO_write(bio, request, request_size); + if(sent != request_size) + { + return(KMIP_IO_FAILURE); + } + + /* Read the response message. Dynamically resize the receiving buffer */ + /* to align with the message size advertised by the message encoding. */ + /* Reject the message if the message size is too large. */ + size_t buffer_blocks = 1; + size_t buffer_block_size = 8; + 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); + } + + 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; + 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); + } + + *response_size = buffer_total_size; + *response = (char *)encoding; + + kmip_set_buffer(ctx, NULL, 0); + + return(KMIP_OK); +} diff --git a/src/libkmip/kmip_bio.h b/src/libkmip/kmip_bio.h new file mode 100644 index 000000000..1877c41fa --- /dev/null +++ b/src/libkmip/kmip_bio.h @@ -0,0 +1,31 @@ +/* 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. + */ + +#ifndef KMIP_BIO_H +#define KMIP_BIO_H + +#include <openssl/ssl.h> +#include "kmip.h" + +/* +OpenSSH BIO API +*/ + +int kmip_bio_create_symmetric_key(BIO *, TemplateAttribute *, char **, int *); +int kmip_bio_locate(BIO *, Attribute *, size_t, size_t *, char ***); +int kmip_bio_get_symmetric_key(BIO *, char *, int, char **, int *); +int kmip_bio_destroy_symmetric_key(BIO *, char *, int); + +int kmip_bio_create_symmetric_key_with_context(KMIP *, BIO *, TemplateAttribute *, char **, int *); +int kmip_bio_locate_with_context(KMIP *, BIO *, Attribute *, size_t, size_t *, char ***); +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_send_request_encoding(KMIP *, BIO *, char *, int, char **, int *); + +#endif /* KMIP_BIO_H */ diff --git a/src/libkmip/kmip_memset.c b/src/libkmip/kmip_memset.c new file mode 100644 index 000000000..5c59e0876 --- /dev/null +++ b/src/libkmip/kmip_memset.c @@ -0,0 +1,59 @@ +/* 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 "kmip_memset.h" + +#if defined __STDC_LIB_EXT1__ + +#define __STDC_WANT_LIB_EXT1__ 1 +#include <string.h> + +void * +kmip_memset(void *ptr, int value, size_t size) +{ + if(ptr == NULL) + { + return(ptr); + } + + memset_s(ptr, size, value, size); + return(ptr); +} + +#else + +void * +kmip_base_memset(void *ptr, int value, size_t size) +{ + if(ptr != NULL) + { + unsigned char *index = (unsigned char*)ptr; + for(size_t i = 0; i < size; i++) + { + *index++ = (unsigned char)value; + } + } + + return(ptr); +} + +static void * +(* volatile kmip_indirect_memset)(void *, int, size_t) = kmip_base_memset; + +void * +kmip_memset(void *ptr, int value, size_t size) +{ + if(ptr != NULL) + { + kmip_indirect_memset(ptr, value, size); + } + + return(ptr); +} + +#endif diff --git a/src/libkmip/kmip_memset.h b/src/libkmip/kmip_memset.h new file mode 100644 index 000000000..b0aa9e7e9 --- /dev/null +++ b/src/libkmip/kmip_memset.h @@ -0,0 +1,15 @@ +/* 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. + */ + +#ifndef KMIP_MEMSET_H + +#include <stddef.h> + +void* kmip_memset(void *ptr, int value, size_t size); + +#endif /* KMIP_MEMSET_H */
\ No newline at end of file diff --git a/src/libkmip/tests.c b/src/libkmip/tests.c new file mode 100644 index 000000000..c48222923 --- /dev/null +++ b/src/libkmip/tests.c @@ -0,0 +1,11400 @@ +/* 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 <stdio.h> +#include <string.h> +#include "kmip.h" + + + +#define TEST_PASSED(A, B) \ +do \ +{ \ + printf("PASS - %s\n", (B)); \ + (A)->tests_passed++; \ + return(0); \ +} while(0) + +#define TEST_FAILED(A, B, C) \ +do \ +{ \ + printf("FAIL - %s @ L%d\n", (B), (C)); \ + (A)->tests_failed++; \ + return(1); \ +} while(0) + +#define TRACK_TEST(A) ((A)->test_count++) + + +typedef struct test_tracker +{ + uint16 test_count; + uint16 tests_failed; + uint16 tests_passed; +} TestTracker; + + +int +report_encoding_test_result( + TestTracker *tracker, + struct kmip *ctx, + const uint8 *expected, + const uint8 *observed, + int result, + const char *function) +{ + if(result == KMIP_OK) + { + for(size_t i = 0; i < ctx->size; i++) + { + if(expected[i] != observed[i]) + { + printf("FAIL - %s\n", function); + printf("- byte mismatch at: %zu (exp: %X, obs: %X)\n", + i, expected[i], observed[i]); + for(size_t j = 0; j < ctx->size; j++) + { + printf("- %zu: %X - %X\n", j, expected[j], observed[j]); + } + tracker->tests_failed++; + return(1); + } + } + + TEST_PASSED(tracker, function); + } + else + { + printf("FAIL - %s\n", function); + if(result == KMIP_ERROR_BUFFER_FULL) + { + printf("- context buffer is full\n"); + } + kmip_print_stack_trace(ctx); + tracker->tests_failed++; + return(1); + } +} + +int +report_decoding_test_result( + TestTracker *tracker, + struct kmip *ctx, + int comparison, + int result, + const char *function) +{ + if(result == KMIP_OK) + { + if(comparison) + { + TEST_PASSED(tracker, function); + } + else + { + printf("FAIL - %s\n", function); + printf("- compared objects are not identical\n"); + tracker->tests_failed++; + return(1); + } + } + else + { + printf("FAIL - %s\n", function); + if(result == KMIP_ERROR_BUFFER_FULL) + { + printf("- context buffer is underfull\n"); + } + kmip_print_stack_trace(ctx); + tracker->tests_failed++; + return(1); + } +} + +int +report_result(TestTracker *tracker, int observed, int expected, const char *function) +{ + if(observed == expected) + { + TEST_PASSED(tracker, function); + } + else + { + printf("FAIL - %s\n", function); + tracker->tests_failed++; + return(1); + } +} + +int +test_linked_list_push(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + LinkedList list = {0}; + + LinkedListItem a = {0}; + LinkedListItem b = {0}; + LinkedListItem c = {0}; + + if(list.head != NULL || list.tail != NULL || list.size != 0) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + kmip_linked_list_push(&list, &a); + + if(list.head != &a || list.tail != &a || list.size != 1) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + kmip_linked_list_push(&list, &b); + + if(list.head != &b || list.tail != &a || list.size != 2) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + kmip_linked_list_push(&list, &c); + + if(list.head != &c || list.tail != &a || list.size != 3) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + LinkedListItem *curr = list.head; + if(curr != &c || curr->next != &b || curr->prev != NULL) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + curr = curr->next; + if(curr != &b || curr->next != &a || curr->prev != &c) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + curr = curr->next; + if(curr != &a || curr->next != NULL || curr->prev != &b) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + TEST_PASSED(tracker, __func__); +} + +int +test_linked_list_pop(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + LinkedList list = {0}; + + if(list.head != NULL || list.tail != NULL || list.size != 0) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + LinkedListItem *item = kmip_linked_list_pop(&list); + + if(item != NULL || list.head != NULL || list.tail != NULL || list.size != 0) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + LinkedListItem a = {0}; + LinkedListItem b = {0}; + LinkedListItem c = {0}; + + a.next = &b; + a.prev = NULL; + b.next = &c; + b.prev = &a; + c.next = NULL; + c.prev = &b; + + list.head = &a; + list.tail = &c; + list.size = 3; + + item = kmip_linked_list_pop(&list); + + if(item != &a || list.head != &b || list.tail != &c || list.size != 2) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + item = kmip_linked_list_pop(&list); + + if(item != &b || list.head != &c || list.tail != &c || list.size != 1) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + item = kmip_linked_list_pop(&list); + + if(item != &c || list.head != NULL || list.tail != NULL || list.size != 0) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + TEST_PASSED(tracker, __func__); +} + +int +test_linked_list_enqueue(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + LinkedList list = {0}; + + LinkedListItem a = {0}; + LinkedListItem b = {0}; + LinkedListItem c = {0}; + + if(list.head != NULL || list.tail != NULL || list.size != 0) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + kmip_linked_list_enqueue(&list, &a); + + if(list.head != &a || list.tail != &a || list.size != 1) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + kmip_linked_list_enqueue(&list, &b); + + if(list.head != &a || list.tail != &b || list.size != 2) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + kmip_linked_list_enqueue(&list, &c); + + if(list.head != &a || list.tail != &c || list.size != 3) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + LinkedListItem *curr = list.head; + if(curr != &a || curr->next != &b || curr->prev != NULL) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + curr = curr->next; + if(curr != &b || curr->next != &c || curr->prev != &a) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + curr = curr->next; + if(curr != &c || curr->next != NULL || curr->prev != &b) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + TEST_PASSED(tracker, __func__); +} + +int +test_buffer_full_and_resize(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[40] = { + 0x42, 0x00, 0x69, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x42, 0x00, 0x6A, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x6B, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 too_small[30] = {0}; + uint8 large_enough[40] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, too_small, ARRAY_LENGTH(too_small), KMIP_1_0); + + struct protocol_version pv = {0}; + pv.major = 1; + pv.minor = 0; + + int result = kmip_encode_protocol_version(&ctx, &pv); + + if(result == KMIP_ERROR_BUFFER_FULL) + { + kmip_reset(&ctx); + kmip_set_buffer(&ctx, large_enough, ARRAY_LENGTH(large_enough)); + + result = kmip_encode_protocol_version(&ctx, &pv); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + large_enough, + result, + __func__); + + kmip_destroy(&ctx); + + return(result); + } + else + { + printf("FAIL - %s\n", __func__); + printf("- expected buffer full\n"); + + kmip_destroy(&ctx); + tracker->tests_failed++; + return(1); + } +} + +int +test_is_tag_next(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[3] = {0x42, 0x00, 0x08}; + + struct kmip ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0); + + uint8 *before = ctx.index; + int result = 0; + + if(kmip_is_tag_next(&ctx, KMIP_TAG_ATTRIBUTE) == KMIP_FALSE) + { + printf("FAIL - %s\n", __func__); + printf("- expected tag is not next\n"); + tracker->tests_failed++; + result = 1; + } + + uint8 *after = ctx.index; + + if(before != after) + { + printf("FAIL - %s\n", __func__); + printf("- tag checking modifies context buffer index\n"); + tracker->tests_failed++; + result = 1; + } + + kmip_destroy(&ctx); + + if(result == 0) + { + printf("PASS - %s\n", __func__); + tracker->tests_passed++; + } + + return(result); +} + +int +test_get_num_items_next(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[168] = { + 0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x17, + 0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x41, 0x6C, + 0x67, 0x6F, 0x72, 0x69, 0x74, 0x68, 0x6D, 0x00, + 0x42, 0x00, 0x0B, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x14, + 0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x4C, 0x65, + 0x6E, 0x67, 0x74, 0x68, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x18, + 0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x55, 0x73, + 0x61, 0x67, 0x65, 0x20, 0x4D, 0x61, 0x73, 0x6B, + 0x42, 0x00, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00 + }; + + struct kmip ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0); + + uint8 *before = ctx.index; + int result = 0; + int count = 0; + + count = kmip_get_num_items_next(&ctx, KMIP_TAG_ATTRIBUTE); + if(count != 3) + { + printf("FAIL - %s\n", __func__); + printf("- expected item count not found (exp. 3, obs. %d)\n", + count); + tracker->tests_failed++; + result = 1; + } + + uint8 *after = ctx.index; + + if(before != after) + { + printf("FAIL - %s\n", __func__); + printf("- item count checking modifies context buffer index\n"); + tracker->tests_failed++; + result = 1; + } + + kmip_destroy(&ctx); + + if(result == 0) + { + printf("PASS - %s\n", __func__); + tracker->tests_passed++; + } + + return(result); +} + +int +test_get_num_items_next_with_partial_item(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[136] = { + 0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x14, + 0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x4C, 0x65, + 0x6E, 0x67, 0x74, 0x68, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x18, + 0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x55, 0x73, + 0x61, 0x67, 0x65, 0x20, 0x4D, 0x61, 0x73, 0x6B, + 0x42, 0x00, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x18, + 0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72 + }; + + struct kmip ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0); + + uint8 *before = ctx.index; + int result = 0; + int count = 0; + + count = kmip_get_num_items_next(&ctx, KMIP_TAG_ATTRIBUTE); + if(count != 2) + { + printf("FAIL - %s\n", __func__); + printf("- expected item count not found (exp. 2, obs. %d)\n", + count); + tracker->tests_failed++; + result = 1; + } + + uint8 *after = ctx.index; + + if(before != after) + { + printf("FAIL - %s\n", __func__); + printf("- item count checking modifies context buffer index\n"); + tracker->tests_failed++; + result = 1; + } + + kmip_destroy(&ctx); + + if(result == 0) + { + printf("PASS - %s\n", __func__); + tracker->tests_passed++; + } + + return(result); +} + +int +test_get_num_items_next_with_mismatch_item(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[80] = { + 0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x18, + 0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x55, 0x73, + 0x61, 0x67, 0x65, 0x20, 0x4D, 0x61, 0x73, 0x6B, + 0x42, 0x00, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x30, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x18, + 0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72 + }; + + struct kmip ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0); + + uint8 *before = ctx.index; + int result = 0; + int count = 0; + + count = kmip_get_num_items_next(&ctx, KMIP_TAG_ATTRIBUTE); + if(count != 1) + { + printf("FAIL - %s\n", __func__); + printf("- expected item count not found (exp. 1, obs. %d)\n", + count); + tracker->tests_failed++; + result = 1; + } + + uint8 *after = ctx.index; + + if(before != after) + { + printf("FAIL - %s\n", __func__); + printf("- item count checking modifies context buffer index\n"); + tracker->tests_failed++; + result = 1; + } + + kmip_destroy(&ctx); + + if(result == 0) + { + printf("PASS - %s\n", __func__); + tracker->tests_passed++; + } + + return(result); +} + +int +test_get_num_items_next_with_no_matches(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[80] = { + 0x42, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x30, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x18, + 0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x55, 0x73, + 0x61, 0x67, 0x65, 0x20, 0x4D, 0x61, 0x73, 0x6B, + 0x42, 0x00, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x30, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x18, + 0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72 + }; + + struct kmip ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0); + + uint8 *before = ctx.index; + int result = 0; + int count = 0; + + count = kmip_get_num_items_next(&ctx, KMIP_TAG_ATTRIBUTE); + if(count != 0) + { + printf("FAIL - %s\n", __func__); + printf("- expected item count not found (exp. 0, obs. %d)\n", + count); + tracker->tests_failed++; + result = 1; + } + + uint8 *after = ctx.index; + + if(before != after) + { + printf("FAIL - %s\n", __func__); + printf("- item count checking modifies context buffer index\n"); + tracker->tests_failed++; + result = 1; + } + + kmip_destroy(&ctx); + + if(result == 0) + { + printf("PASS - %s\n", __func__); + tracker->tests_passed++; + } + + return(result); +} + +int +test_get_num_items_next_with_non_structures(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[144] = { + 0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x26, + 0x31, 0x30, 0x30, 0x31, 0x38, 0x32, 0x64, 0x35, + 0x2D, 0x37, 0x32, 0x62, 0x38, 0x2D, 0x34, 0x37, + 0x61, 0x61, 0x2D, 0x38, 0x33, 0x38, 0x33, 0x2D, + 0x34, 0x64, 0x39, 0x37, 0x64, 0x35, 0x31, 0x32, + 0x65, 0x39, 0x38, 0x61, 0x11, 0x11, 0x00, 0x00, + 0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x25, + 0x31, 0x30, 0x30, 0x31, 0x38, 0x32, 0x64, 0x35, + 0x2D, 0x37, 0x32, 0x62, 0x38, 0x2D, 0x34, 0x37, + 0x61, 0x61, 0x2D, 0x38, 0x33, 0x38, 0x33, 0x2D, + 0x34, 0x64, 0x39, 0x37, 0x64, 0x35, 0x31, 0x32, + 0x65, 0x39, 0x38, 0x61, 0x11, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, + 0x31, 0x30, 0x30, 0x31, 0x38, 0x32, 0x64, 0x35, + 0x2D, 0x37, 0x32, 0x62, 0x38, 0x2D, 0x34, 0x37, + 0x61, 0x61, 0x2D, 0x38, 0x33, 0x38, 0x33, 0x2D, + 0x34, 0x64, 0x39, 0x37, 0x64, 0x35, 0x31, 0x32, + 0x65, 0x39, 0x38, 0x61, 0x00, 0x00, 0x00, 0x00 + }; + + struct kmip ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0); + + uint8 *before = ctx.index; + int result = 0; + int count = 0; + + count = kmip_get_num_items_next(&ctx, KMIP_TAG_UNIQUE_IDENTIFIER); + if(count != 3) + { + printf("FAIL - %s\n", __func__); + printf("- expected item count not found (exp. 3, obs. %d)\n", + count); + tracker->tests_failed++; + result = 1; + } + + uint8 *after = ctx.index; + + if(before != after) + { + printf("FAIL - %s\n", __func__); + printf("- item count checking modifies context buffer index\n"); + tracker->tests_failed++; + result = 1; + } + + kmip_destroy(&ctx); + + if(result == 0) + { + printf("PASS - %s\n", __func__); + tracker->tests_passed++; + } + + return(result); +} + +int +test_buffer_bytes_left(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 a[1] = {0x42}; + uint8 b[3] = {0x42, 0x00, 0x08}; + uint8 c[5] = {0x42, 0x00, 0x53, 0x01, 0x00}; + + KMIP ctx = {0}; + kmip_init(&ctx, a, ARRAY_LENGTH(a), KMIP_1_0); + + if(BUFFER_BYTES_LEFT(&ctx) != 1) + { + kmip_destroy(&ctx); + TEST_FAILED(tracker, __func__, __LINE__); + } + + kmip_destroy(&ctx); + kmip_init(&ctx, b, ARRAY_LENGTH(b), KMIP_1_0); + + if(BUFFER_BYTES_LEFT(&ctx) != 3) + { + kmip_destroy(&ctx); + TEST_FAILED(tracker, __func__, __LINE__); + } + + kmip_destroy(&ctx); + kmip_init(&ctx, c, ARRAY_LENGTH(c), KMIP_1_0); + + if(BUFFER_BYTES_LEFT(&ctx) != 5) + { + kmip_destroy(&ctx); + TEST_FAILED(tracker, __func__, __LINE__); + } + + kmip_destroy(&ctx); + + TEST_PASSED(tracker, __func__); +} + +int +test_get_num_attributes_next(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + /* Need to build an encoding with one of each type of support + attribute. Verify that this function returns the correct + count. + + Need to build an encoding with bad attribute length? Handle + weird corner cases? + */ + TEST_FAILED(tracker, __func__, __LINE__); +} + +int +test_peek_tag(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + /* Build an encoding with an arbitrary tag value. Verify that this + function reads and returns this tag value without changing the + context buffer. + */ + + uint8 underfull_encoding[1] = {0x42}; + uint8 full_encoding[3] = {0x42, 0x00, 0x08}; + uint8 overfull_encoding[5] = {0x42, 0x00, 0x53, 0x01, 0x00}; + + uint32 tag = 0; + uint8 *prev_buffer = NULL; + uint8 *prev_index = NULL; + size_t prev_size = 0; + KMIP ctx = {0}; + kmip_init(&ctx, underfull_encoding, ARRAY_LENGTH(underfull_encoding), KMIP_1_0); + + prev_buffer = ctx.buffer; + prev_index = ctx.index; + prev_size = ctx.size; + tag = kmip_peek_tag(&ctx); + if(tag != 0 || ctx.buffer != prev_buffer || ctx.index != prev_index || ctx.size != prev_size) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + kmip_destroy(&ctx); + kmip_init(&ctx, full_encoding, ARRAY_LENGTH(full_encoding), KMIP_1_0); + + prev_buffer = ctx.buffer; + prev_index = ctx.index; + prev_size = ctx.size; + tag = kmip_peek_tag(&ctx); + if(tag != KMIP_TAG_ATTRIBUTE || ctx.buffer != prev_buffer || ctx.index != prev_index || ctx.size != prev_size) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + kmip_destroy(&ctx); + kmip_init(&ctx, overfull_encoding, ARRAY_LENGTH(overfull_encoding), KMIP_1_0); + + prev_buffer = ctx.buffer; + prev_index = ctx.index; + prev_size = ctx.size; + tag = kmip_peek_tag(&ctx); + if(tag != KMIP_TAG_NAME || ctx.buffer != prev_buffer || ctx.index != prev_index || ctx.size != prev_size) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + kmip_destroy(&ctx); + + TEST_PASSED(tracker, __func__); +} + +int +test_is_attribute_tag(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + if(!kmip_is_attribute_tag(KMIP_TAG_UNIQUE_IDENTIFIER)) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_is_attribute_tag(KMIP_TAG_NAME)) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_is_attribute_tag(KMIP_TAG_OBJECT_TYPE)) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_is_attribute_tag(KMIP_TAG_CRYPTOGRAPHIC_ALGORITHM)) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_is_attribute_tag(KMIP_TAG_CRYPTOGRAPHIC_LENGTH)) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_is_attribute_tag(KMIP_TAG_CRYPTOGRAPHIC_PARAMETERS)) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_is_attribute_tag(KMIP_TAG_CRYPTOGRAPHIC_DOMAIN_PARAMETERS)) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_is_attribute_tag(KMIP_TAG_CERTIFICATE_TYPE)) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_is_attribute_tag(KMIP_TAG_CERTIFICATE_LENGTH)) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_is_attribute_tag(KMIP_TAG_X509_CERTIFICATE_IDENTIFIER)) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_is_attribute_tag(KMIP_TAG_X509_CERTIFICATE_SUBJECT)) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_is_attribute_tag(KMIP_TAG_X509_CERTIFICATE_ISSUER)) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_is_attribute_tag(KMIP_TAG_CERTIFICATE_IDENTIFIER)) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_is_attribute_tag(KMIP_TAG_CERTIFICATE_SUBJECT)) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_is_attribute_tag(KMIP_TAG_CERTIFICATE_ISSUER)) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_is_attribute_tag(KMIP_TAG_DIGITAL_SIGNATURE_ALGORITHM)) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_is_attribute_tag(KMIP_TAG_DIGEST)) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_is_attribute_tag(KMIP_TAG_OPERATION_POLICY_NAME)) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_is_attribute_tag(KMIP_TAG_CRYPTOGRAPHIC_USAGE_MASK)) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_is_attribute_tag(KMIP_TAG_LEASE_TIME)) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_is_attribute_tag(KMIP_TAG_USAGE_LIMITS)) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_is_attribute_tag(KMIP_TAG_STATE)) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_is_attribute_tag(KMIP_TAG_INITIAL_DATE)) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_is_attribute_tag(KMIP_TAG_ACTIVATION_DATE)) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_is_attribute_tag(KMIP_TAG_PROCESS_START_DATE)) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_is_attribute_tag(KMIP_TAG_PROTECT_STOP_DATE)) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_is_attribute_tag(KMIP_TAG_DEACTIVATION_DATE)) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_is_attribute_tag(KMIP_TAG_DESTROY_DATE)) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_is_attribute_tag(KMIP_TAG_COMPROMISE_OCCURRENCE_DATE)) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_is_attribute_tag(KMIP_TAG_COMPROMISE_DATE)) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_is_attribute_tag(KMIP_TAG_REVOCATION_REASON)) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_is_attribute_tag(KMIP_TAG_ARCHIVE_DATE)) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_is_attribute_tag(KMIP_TAG_OBJECT_GROUP)) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_is_attribute_tag(KMIP_TAG_FRESH)) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_is_attribute_tag(KMIP_TAG_LINK)) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_is_attribute_tag(KMIP_TAG_APPLICATION_SPECIFIC_INFORMATION)) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_is_attribute_tag(KMIP_TAG_CONTACT_INFORMATION)) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_is_attribute_tag(KMIP_TAG_LAST_CHANGE_DATE)) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_is_attribute_tag(KMIP_TAG_ALTERNATIVE_NAME)) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_is_attribute_tag(KMIP_TAG_KEY_VALUE_PRESENT)) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_is_attribute_tag(KMIP_TAG_KEY_VALUE_LOCATION)) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_is_attribute_tag(KMIP_TAG_ORIGINAL_CREATION_DATE)) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_is_attribute_tag(KMIP_TAG_RANDOM_NUMBER_GENERATOR)) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_is_attribute_tag(KMIP_TAG_PKCS_12_FRIENDLY_NAME)) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_is_attribute_tag(KMIP_TAG_DESCRIPTION)) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_is_attribute_tag(KMIP_TAG_COMMENT)) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_is_attribute_tag(KMIP_TAG_SENSITIVE)) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_is_attribute_tag(KMIP_TAG_ALWAYS_SENSITIVE)) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_is_attribute_tag(KMIP_TAG_EXTRACTABLE)) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_is_attribute_tag(KMIP_TAG_NEVER_EXTRACTABLE)) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_is_attribute_tag(KMIP_TAG_KEY_FORMAT_TYPE)) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_is_attribute_tag(KMIP_TAG_REQUEST_MESSAGE)) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + TEST_PASSED(tracker, __func__); +} + +int +test_get_enum_string_index(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + if(kmip_get_enum_string_index(KMIP_TAG_UNIQUE_IDENTIFIER) != 0) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_get_enum_string_index(KMIP_TAG_NAME) != 1) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_get_enum_string_index(KMIP_TAG_OBJECT_TYPE) != 2) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_get_enum_string_index(KMIP_TAG_CRYPTOGRAPHIC_ALGORITHM) != 3) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_get_enum_string_index(KMIP_TAG_CRYPTOGRAPHIC_LENGTH) != 4) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_get_enum_string_index(KMIP_TAG_CRYPTOGRAPHIC_PARAMETERS) != 5) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_get_enum_string_index(KMIP_TAG_CRYPTOGRAPHIC_DOMAIN_PARAMETERS) != 6) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_get_enum_string_index(KMIP_TAG_CERTIFICATE_TYPE) != 7) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_get_enum_string_index(KMIP_TAG_CERTIFICATE_LENGTH) != 8) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_get_enum_string_index(KMIP_TAG_X509_CERTIFICATE_IDENTIFIER) != 9) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_get_enum_string_index(KMIP_TAG_X509_CERTIFICATE_SUBJECT) != 10) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_get_enum_string_index(KMIP_TAG_X509_CERTIFICATE_ISSUER) != 11) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_get_enum_string_index(KMIP_TAG_CERTIFICATE_IDENTIFIER) != 12) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_get_enum_string_index(KMIP_TAG_CERTIFICATE_SUBJECT) != 13) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_get_enum_string_index(KMIP_TAG_CERTIFICATE_ISSUER) != 14) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_get_enum_string_index(KMIP_TAG_DIGITAL_SIGNATURE_ALGORITHM) != 15) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_get_enum_string_index(KMIP_TAG_DIGEST) != 16) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_get_enum_string_index(KMIP_TAG_OPERATION_POLICY_NAME) != 17) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_get_enum_string_index(KMIP_TAG_CRYPTOGRAPHIC_USAGE_MASK) != 18) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_get_enum_string_index(KMIP_TAG_LEASE_TIME) != 19) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_get_enum_string_index(KMIP_TAG_USAGE_LIMITS) != 20) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_get_enum_string_index(KMIP_TAG_STATE) != 21) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_get_enum_string_index(KMIP_TAG_INITIAL_DATE) != 22) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_get_enum_string_index(KMIP_TAG_ACTIVATION_DATE) != 23) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_get_enum_string_index(KMIP_TAG_PROCESS_START_DATE) != 24) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_get_enum_string_index(KMIP_TAG_PROTECT_STOP_DATE) != 25) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_get_enum_string_index(KMIP_TAG_DEACTIVATION_DATE) != 26) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_get_enum_string_index(KMIP_TAG_DESTROY_DATE) != 27) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_get_enum_string_index(KMIP_TAG_COMPROMISE_OCCURRENCE_DATE) != 28) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_get_enum_string_index(KMIP_TAG_COMPROMISE_DATE) != 29) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_get_enum_string_index(KMIP_TAG_REVOCATION_REASON) != 30) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_get_enum_string_index(KMIP_TAG_ARCHIVE_DATE) != 31) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_get_enum_string_index(KMIP_TAG_OBJECT_GROUP) != 32) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_get_enum_string_index(KMIP_TAG_FRESH) != 33) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_get_enum_string_index(KMIP_TAG_LINK) != 34) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_get_enum_string_index(KMIP_TAG_APPLICATION_SPECIFIC_INFORMATION) != 35) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_get_enum_string_index(KMIP_TAG_CONTACT_INFORMATION) != 36) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_get_enum_string_index(KMIP_TAG_LAST_CHANGE_DATE) != 37) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_get_enum_string_index(KMIP_TAG_ALTERNATIVE_NAME) != 38) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_get_enum_string_index(KMIP_TAG_KEY_VALUE_PRESENT) != 39) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_get_enum_string_index(KMIP_TAG_KEY_VALUE_LOCATION) != 40) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_get_enum_string_index(KMIP_TAG_ORIGINAL_CREATION_DATE) != 41) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_get_enum_string_index(KMIP_TAG_RANDOM_NUMBER_GENERATOR) != 42) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_get_enum_string_index(KMIP_TAG_PKCS_12_FRIENDLY_NAME) != 43) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_get_enum_string_index(KMIP_TAG_DESCRIPTION) != 44) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_get_enum_string_index(KMIP_TAG_COMMENT) != 45) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_get_enum_string_index(KMIP_TAG_SENSITIVE) != 46) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_get_enum_string_index(KMIP_TAG_ALWAYS_SENSITIVE) != 47) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_get_enum_string_index(KMIP_TAG_EXTRACTABLE) != 48) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_get_enum_string_index(KMIP_TAG_NEVER_EXTRACTABLE) != 49) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_get_enum_string_index(KMIP_TAG_KEY_FORMAT_TYPE) != 50) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_get_enum_string_index(-1) != 51) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + TEST_PASSED(tracker, __func__); +} + +int +test_check_enum_value_protection_storage_masks(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + enum kmip_version v = KMIP_2_0; + enum tag t = KMIP_TAG_PROTECTION_STORAGE_MASK; + + if(kmip_check_enum_value(v, t, KMIP_PROTECT_SOFTWARE) != KMIP_OK) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_check_enum_value(v, t, KMIP_PROTECT_HARDWARE) != KMIP_OK) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_check_enum_value(v, t, KMIP_PROTECT_ON_PROCESSOR) != KMIP_OK) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_check_enum_value(v, t, KMIP_PROTECT_ON_SYSTEM) != KMIP_OK) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_check_enum_value(v, t, KMIP_PROTECT_OFF_SYSTEM) != KMIP_OK) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_check_enum_value(v, t, KMIP_PROTECT_HYPERVISOR) != KMIP_OK) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_check_enum_value(v, t, KMIP_PROTECT_OPERATING_SYSTEM) != KMIP_OK) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_check_enum_value(v, t, KMIP_PROTECT_CONTAINER) != KMIP_OK) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_check_enum_value(v, t, KMIP_PROTECT_ON_PREMISES) != KMIP_OK) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_check_enum_value(v, t, KMIP_PROTECT_OFF_PREMISES) != KMIP_OK) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_check_enum_value(v, t, KMIP_PROTECT_SELF_MANAGED) != KMIP_OK) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_check_enum_value(v, t, KMIP_PROTECT_OUTSOURCED) != KMIP_OK) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_check_enum_value(v, t, KMIP_PROTECT_VALIDATED) != KMIP_OK) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_check_enum_value(v, t, KMIP_PROTECT_SAME_JURISDICTION) != KMIP_OK) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + v = KMIP_1_4; + + if(kmip_check_enum_value(v, t, KMIP_PROTECT_SOFTWARE) != KMIP_INVALID_FOR_VERSION) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_check_enum_value(v, t, KMIP_PROTECT_HARDWARE) != KMIP_INVALID_FOR_VERSION) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_check_enum_value(v, t, KMIP_PROTECT_ON_PROCESSOR) != KMIP_INVALID_FOR_VERSION) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_check_enum_value(v, t, KMIP_PROTECT_ON_SYSTEM) != KMIP_INVALID_FOR_VERSION) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_check_enum_value(v, t, KMIP_PROTECT_OFF_SYSTEM) != KMIP_INVALID_FOR_VERSION) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_check_enum_value(v, t, KMIP_PROTECT_HYPERVISOR) != KMIP_INVALID_FOR_VERSION) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_check_enum_value(v, t, KMIP_PROTECT_OPERATING_SYSTEM) != KMIP_INVALID_FOR_VERSION) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_check_enum_value(v, t, KMIP_PROTECT_CONTAINER) != KMIP_INVALID_FOR_VERSION) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_check_enum_value(v, t, KMIP_PROTECT_ON_PREMISES) != KMIP_INVALID_FOR_VERSION) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_check_enum_value(v, t, KMIP_PROTECT_OFF_PREMISES) != KMIP_INVALID_FOR_VERSION) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_check_enum_value(v, t, KMIP_PROTECT_SELF_MANAGED) != KMIP_INVALID_FOR_VERSION) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_check_enum_value(v, t, KMIP_PROTECT_OUTSOURCED) != KMIP_INVALID_FOR_VERSION) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_check_enum_value(v, t, KMIP_PROTECT_VALIDATED) != KMIP_INVALID_FOR_VERSION) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_check_enum_value(v, t, KMIP_PROTECT_SAME_JURISDICTION) != KMIP_INVALID_FOR_VERSION) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + if(kmip_check_enum_value(v, t, -1) != KMIP_ENUM_MISMATCH) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + TEST_PASSED(tracker, __func__); +} + +int +test_init_protocol_version(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + kmip_init_protocol_version(NULL, KMIP_1_0); + + ProtocolVersion pv = {0}; + + if(pv.major != 0) + TEST_FAILED(tracker, __func__, __LINE__); + if(pv.minor != 0) + TEST_FAILED(tracker, __func__, __LINE__); + + kmip_init_protocol_version(&pv, KMIP_1_0); + + if(pv.major != 1) + TEST_FAILED(tracker, __func__, __LINE__); + if(pv.minor != 0) + TEST_FAILED(tracker, __func__, __LINE__); + + kmip_init_protocol_version(&pv, KMIP_1_1); + + if(pv.major != 1) + TEST_FAILED(tracker, __func__, __LINE__); + if(pv.minor != 1) + TEST_FAILED(tracker, __func__, __LINE__); + + kmip_init_protocol_version(&pv, KMIP_1_2); + + if(pv.major != 1) + TEST_FAILED(tracker, __func__, __LINE__); + if(pv.minor != 2) + TEST_FAILED(tracker, __func__, __LINE__); + + kmip_init_protocol_version(&pv, KMIP_1_3); + + if(pv.major != 1) + TEST_FAILED(tracker, __func__, __LINE__); + if(pv.minor != 3) + TEST_FAILED(tracker, __func__, __LINE__); + + kmip_init_protocol_version(&pv, KMIP_1_4); + + if(pv.major != 1) + TEST_FAILED(tracker, __func__, __LINE__); + if(pv.minor != 4) + TEST_FAILED(tracker, __func__, __LINE__); + + kmip_init_protocol_version(&pv, KMIP_2_0); + + if(pv.major != 2) + TEST_FAILED(tracker, __func__, __LINE__); + if(pv.minor != 0) + TEST_FAILED(tracker, __func__, __LINE__); + + TEST_PASSED(tracker, __func__); +} + +int +test_init_request_batch_item(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + kmip_init_request_batch_item(NULL); + + RequestBatchItem rbi = {0}; + + if(rbi.operation != 0) + TEST_FAILED(tracker, __func__, __LINE__); + if(rbi.unique_batch_item_id != NULL) + TEST_FAILED(tracker, __func__, __LINE__); + if(rbi.request_payload != NULL) + TEST_FAILED(tracker, __func__, __LINE__); + if(rbi.ephemeral != 0) + TEST_FAILED(tracker, __func__, __LINE__); + + kmip_init_request_batch_item(&rbi); + + if(rbi.operation != 0) + TEST_FAILED(tracker, __func__, __LINE__); + if(rbi.unique_batch_item_id != NULL) + TEST_FAILED(tracker, __func__, __LINE__); + if(rbi.request_payload != NULL) + TEST_FAILED(tracker, __func__, __LINE__); + if(rbi.ephemeral != KMIP_UNSET) + TEST_FAILED(tracker, __func__, __LINE__); + + TEST_PASSED(tracker, __func__); +} + +int +test_print_attributes(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + /* For now this will probably be left as a placeholder for a + future test. Ideally the print functions would output to + an arbitrary buffer so that we can verify that they are + correctly displaying structure content and formatting. + Since they currently use printf directly, this may be hard + to do in the short term. + */ + TEST_FAILED(tracker, __func__, __LINE__); +} + +int +test_free_attributes(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + /* Build a dynamically allocated Attributes structure. Free it + with this function. Verify that all internal pointers and + fields are correctly nullified. + + Ideally, hook into the free function managed by the context + and use that hook to verify that the correct free calls are + made on the internal Attributes structure pointers. This + may require more infrastructure work than currently exists. + */ + TEST_FAILED(tracker, __func__, __LINE__); +} + +int +test_compare_attributes(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + /* Build two separate identical Attributes structures. Compare + them with this function and confirm they match. + + Build two separate different Attributes structures. Compare + them with this function and confirm they do not match. This + may require multiple rounds, changing different parts of the + underlying Attributes structure. It may make more sense to + split this into multiple test functions. + */ + TEST_FAILED(tracker, __func__, __LINE__); +} + +int +test_deep_copy_int32(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + int32 expected = 42; + int32 *observed = NULL; + + observed = kmip_deep_copy_int32(NULL, NULL); + if(observed != NULL) + TEST_FAILED(tracker, __func__, __LINE__); + + KMIP ctx = {0}; + kmip_init(&ctx, NULL, 0, KMIP_1_0); + + observed = kmip_deep_copy_int32(&ctx, NULL); + if(observed != NULL) + { + kmip_destroy(&ctx); + TEST_FAILED(tracker, __func__, __LINE__); + } + + observed = kmip_deep_copy_int32(&ctx, &expected); + if(observed == NULL) + { + kmip_destroy(&ctx); + TEST_FAILED(tracker, __func__, __LINE__); + } + if(*observed != expected) + { + kmip_print_integer(expected); + kmip_print_integer(*observed); + ctx.free_func(ctx.state, observed); + kmip_destroy(&ctx); + TEST_FAILED(tracker, __func__, __LINE__); + } + + ctx.free_func(ctx.state, observed); + kmip_destroy(&ctx); + + TEST_PASSED(tracker, __func__); +} + +int +test_deep_copy_text_string(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + TextString expected = {0}; + expected.value = "example"; + expected.size = 7; + TextString *observed = NULL; + + observed = kmip_deep_copy_text_string(NULL, NULL); + if(observed != NULL) + TEST_FAILED(tracker, __func__, __LINE__); + + KMIP ctx = {0}; + kmip_init(&ctx, NULL, 0, KMIP_1_0); + + observed = kmip_deep_copy_text_string(&ctx, NULL); + if(observed != NULL) + { + kmip_destroy(&ctx); + TEST_FAILED(tracker, __func__, __LINE__); + } + + observed = kmip_deep_copy_text_string(&ctx, &expected); + if(observed == NULL) + { + kmip_destroy(&ctx); + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_compare_text_string(&expected, observed)) + { + kmip_print_text_string(1, "Name Value", &expected); + kmip_print_text_string(1, "Name Value", observed); + kmip_free_text_string(&ctx, observed); + ctx.free_func(ctx.state, observed); + kmip_destroy(&ctx); + TEST_FAILED(tracker, __func__, __LINE__); + } + + kmip_free_text_string(&ctx, observed); + ctx.free_func(ctx.state, observed); + kmip_destroy(&ctx); + + TEST_PASSED(tracker, __func__); +} + +int +test_deep_copy_name(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + TextString value = {0}; + value.value = "example"; + value.size = 7; + Name expected = {0}; + expected.value = &value; + expected.type = KMIP_NAME_UNINTERPRETED_TEXT_STRING; + Name *observed = NULL; + + observed = kmip_deep_copy_name(NULL, NULL); + if(observed != NULL) + TEST_FAILED(tracker, __func__, __LINE__); + + KMIP ctx = {0}; + kmip_init(&ctx, NULL, 0, KMIP_1_0); + + observed = kmip_deep_copy_name(&ctx, NULL); + if(observed != NULL) + { + kmip_destroy(&ctx); + TEST_FAILED(tracker, __func__, __LINE__); + } + + observed = kmip_deep_copy_name(&ctx, &expected); + if(observed == NULL) + { + kmip_destroy(&ctx); + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_compare_name(&expected, observed)) + { + kmip_print_name(1, &expected); + kmip_print_name(1, observed); + kmip_free_name(&ctx, observed); + ctx.free_func(ctx.state, observed); + kmip_destroy(&ctx); + TEST_FAILED(tracker, __func__, __LINE__); + } + + kmip_free_name(&ctx, observed); + ctx.free_func(ctx.state, observed); + kmip_destroy(&ctx); + + TEST_PASSED(tracker, __func__); +} + +int +test_deep_copy_attribute(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + Attribute expected = {0}; + kmip_init_attribute(&expected); + Attribute *observed = NULL; + + observed = kmip_deep_copy_attribute(NULL, NULL); + if(observed != NULL) + TEST_FAILED(tracker, __func__, __LINE__); + + KMIP ctx = {0}; + kmip_init(&ctx, NULL, 0, KMIP_1_0); + + observed = kmip_deep_copy_attribute(&ctx, NULL); + if(observed != NULL) + { + kmip_destroy(&ctx); + TEST_FAILED(tracker, __func__, __LINE__); + } + + /* Test deep copying an "empty" attribute. */ + observed = kmip_deep_copy_attribute(&ctx, &expected); + if(observed == NULL) + { + kmip_destroy(&ctx); + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_compare_attribute(&expected, observed)) + { + kmip_print_attribute(1, &expected); + kmip_print_attribute(1, observed); + kmip_free_attribute(&ctx, observed); + ctx.free_func(ctx.state, observed); + kmip_destroy(&ctx); + TEST_FAILED(tracker, __func__, __LINE__); + } + + kmip_free_attribute(&ctx, observed); + ctx.free_func(ctx.state, observed); + + /* Test deep copying a Unique Identifier attribute. */ + TextString uuid = {0}; + uuid.value = "49a1ca88-6bea-4fb2-b450-7e58802c3038"; + uuid.size = 36; + expected.type = KMIP_ATTR_UNIQUE_IDENTIFIER; + expected.value = &uuid; + + observed = kmip_deep_copy_attribute(&ctx, &expected); + if(observed == NULL) + { + kmip_destroy(&ctx); + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_compare_attribute(&expected, observed)) + { + kmip_print_attribute(1, &expected); + kmip_print_attribute(1, observed); + kmip_free_attribute(&ctx, observed); + ctx.free_func(ctx.state, observed); + kmip_destroy(&ctx); + TEST_FAILED(tracker, __func__, __LINE__); + } + + kmip_free_attribute(&ctx, observed); + ctx.free_func(ctx.state, observed); + + /* Test deep copying an Operation Policy Name attribute. */ + TextString policy = {0}; + policy.value = "default"; + policy.size = 7; + expected.type = KMIP_ATTR_OPERATION_POLICY_NAME; + expected.value = &policy; + + observed = kmip_deep_copy_attribute(&ctx, &expected); + if(observed == NULL) + { + kmip_destroy(&ctx); + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_compare_attribute(&expected, observed)) + { + kmip_print_attribute(1, &expected); + kmip_print_attribute(1, observed); + kmip_free_attribute(&ctx, observed); + ctx.free_func(ctx.state, observed); + kmip_destroy(&ctx); + TEST_FAILED(tracker, __func__, __LINE__); + } + + kmip_free_attribute(&ctx, observed); + ctx.free_func(ctx.state, observed); + + /* Test deep copying a Name attribute. */ + TextString name_value = {0}; + name_value.value = "example"; + name_value.size = 7; + Name name = {0}; + name.value = &name_value; + name.type = KMIP_NAME_UNINTERPRETED_TEXT_STRING; + expected.type = KMIP_ATTR_NAME; + expected.value = &name; + + observed = kmip_deep_copy_attribute(&ctx, &expected); + if(observed == NULL) + { + kmip_destroy(&ctx); + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_compare_attribute(&expected, observed)) + { + kmip_print_attribute(1, &expected); + kmip_print_attribute(1, observed); + kmip_free_attribute(&ctx, observed); + ctx.free_func(ctx.state, observed); + kmip_destroy(&ctx); + TEST_FAILED(tracker, __func__, __LINE__); + } + + kmip_free_attribute(&ctx, observed); + ctx.free_func(ctx.state, observed); + + /* Test deep copying an Object Type attribute. */ + enum object_type object_type = KMIP_OBJTYPE_SYMMETRIC_KEY; + expected.type = KMIP_ATTR_OBJECT_TYPE; + expected.value = &object_type; + + observed = kmip_deep_copy_attribute(&ctx, &expected); + if(observed == NULL) + { + kmip_destroy(&ctx); + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_compare_attribute(&expected, observed)) + { + kmip_print_attribute(1, &expected); + kmip_print_attribute(1, observed); + kmip_free_attribute(&ctx, observed); + ctx.free_func(ctx.state, observed); + kmip_destroy(&ctx); + TEST_FAILED(tracker, __func__, __LINE__); + } + + kmip_free_attribute(&ctx, observed); + ctx.free_func(ctx.state, observed); + + /* Test deep copying a Cryptographic Algorithm attribute. */ + enum cryptographic_algorithm cryptographic_algorithm = KMIP_CRYPTOALG_AES; + expected.type = KMIP_ATTR_CRYPTOGRAPHIC_ALGORITHM; + expected.value = &cryptographic_algorithm; + + observed = kmip_deep_copy_attribute(&ctx, &expected); + if(observed == NULL) + { + kmip_destroy(&ctx); + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_compare_attribute(&expected, observed)) + { + kmip_print_attribute(1, &expected); + kmip_print_attribute(1, observed); + kmip_free_attribute(&ctx, observed); + ctx.free_func(ctx.state, observed); + kmip_destroy(&ctx); + TEST_FAILED(tracker, __func__, __LINE__); + } + + kmip_free_attribute(&ctx, observed); + ctx.free_func(ctx.state, observed); + + /* Test deep copying a Cryptographic Length attribute. */ + int32 cryptographic_length = 256; + expected.type = KMIP_ATTR_CRYPTOGRAPHIC_LENGTH; + expected.value = &cryptographic_length; + + observed = kmip_deep_copy_attribute(&ctx, &expected); + if(observed == NULL) + { + kmip_destroy(&ctx); + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_compare_attribute(&expected, observed)) + { + kmip_print_attribute(1, &expected); + kmip_print_attribute(1, observed); + kmip_free_attribute(&ctx, observed); + ctx.free_func(ctx.state, observed); + kmip_destroy(&ctx); + TEST_FAILED(tracker, __func__, __LINE__); + } + + kmip_free_attribute(&ctx, observed); + ctx.free_func(ctx.state, observed); + + /* Test deep copying a Cryptographic Usage Mask attribute. */ + int32 cryptographic_usage_mask = KMIP_CRYPTOMASK_ENCRYPT | KMIP_CRYPTOMASK_DECRYPT; + expected.type = KMIP_ATTR_CRYPTOGRAPHIC_USAGE_MASK; + expected.value = &cryptographic_usage_mask; + + observed = kmip_deep_copy_attribute(&ctx, &expected); + if(observed == NULL) + { + kmip_destroy(&ctx); + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_compare_attribute(&expected, observed)) + { + kmip_print_attribute(1, &expected); + kmip_print_attribute(1, observed); + kmip_free_attribute(&ctx, observed); + ctx.free_func(ctx.state, observed); + kmip_destroy(&ctx); + TEST_FAILED(tracker, __func__, __LINE__); + } + + kmip_free_attribute(&ctx, observed); + ctx.free_func(ctx.state, observed); + + /* Test deep copying a State attribute. */ + enum state state = KMIP_STATE_ACTIVE; + expected.type = KMIP_ATTR_STATE; + expected.value = &state; + + observed = kmip_deep_copy_attribute(&ctx, &expected); + if(observed == NULL) + { + kmip_destroy(&ctx); + TEST_FAILED(tracker, __func__, __LINE__); + } + if(!kmip_compare_attribute(&expected, observed)) + { + kmip_print_attribute(1, &expected); + kmip_print_attribute(1, observed); + kmip_free_attribute(&ctx, observed); + ctx.free_func(ctx.state, observed); + kmip_destroy(&ctx); + TEST_FAILED(tracker, __func__, __LINE__); + } + + kmip_free_attribute(&ctx, observed); + ctx.free_func(ctx.state, observed); + kmip_destroy(&ctx); + + TEST_PASSED(tracker, __func__); +} + +int +test_decode_int8_be(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[1] = {0x42}; + + struct kmip ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0); + + int8 value = 0; + + int result = kmip_decode_int8_be(&ctx, &value); + result = report_decoding_test_result( + tracker, + &ctx, + value == 0x42, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_decode_int32_be(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[4] = {0x11, 0x22, 0x33, 0x44}; + + struct kmip ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0); + + int32 expected = 0x11223344; + int32 observed = 0; + + int result = kmip_decode_int32_be(&ctx, &observed); + result = report_decoding_test_result( + tracker, + &ctx, + observed == expected, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_decode_int64_be(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[8] = { + 0x01, 0xB6, 0x9B, 0x4B, 0xA5, 0x74, 0x92, 0x00 + }; + + struct kmip ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0); + + int64 expected = 0x01B69B4BA5749200; + int64 observed = 0; + + int result = kmip_decode_int64_be(&ctx, &observed); + result = report_decoding_test_result( + tracker, + &ctx, + observed == expected, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_encode_integer(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[16] = { + 0x42, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 observed[16] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0); + + int result = kmip_encode_integer(&ctx, KMIP_TAG_DEFAULT, 8); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_decode_integer(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[16] = { + 0x42, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00 + }; + + struct kmip ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0); + + int32 expected = 8; + int32 observed = 0; + + int result = kmip_decode_integer(&ctx, KMIP_TAG_DEFAULT, &observed); + result = report_decoding_test_result( + tracker, + &ctx, + observed == expected, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_encode_long(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[16] = { + 0x42, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, + 0x01, 0xB6, 0x9B, 0x4B, 0xA5, 0x74, 0x92, 0x00 + }; + + uint8 observed[16] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0); + + int result = kmip_encode_long(&ctx, KMIP_TAG_DEFAULT, 123456789000000000); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_decode_long(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[16] = { + 0x42, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, + 0x01, 0xB6, 0x9B, 0x4B, 0xA5, 0x74, 0x92, 0x00 + }; + + struct kmip ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0); + + int64 expected = 0x01B69B4BA5749200; + int64 observed = 0; + + int result = kmip_decode_long(&ctx, KMIP_TAG_DEFAULT, &observed); + result = report_decoding_test_result( + tracker, + &ctx, + observed == expected, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_encode_enum(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[16] = { + 0x42, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 observed[16] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0); + + int result = kmip_encode_enum(&ctx, KMIP_TAG_DEFAULT, KMIP_CRYPTOALG_AES); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_decode_enum(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[16] = { + 0x42, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00 + }; + + struct kmip ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0); + + enum cryptographic_algorithm expected = KMIP_CRYPTOALG_AES; + enum cryptographic_algorithm observed = 0; + + int result = kmip_decode_enum(&ctx, KMIP_TAG_DEFAULT, &observed); + result = report_decoding_test_result( + tracker, + &ctx, + observed == expected, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_encode_bool(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[16] = { + 0x42, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 + }; + + uint8 observed[16] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0); + + int result = kmip_encode_bool(&ctx, KMIP_TAG_DEFAULT, KMIP_TRUE); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_decode_bool(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[16] = { + 0x42, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 + }; + + struct kmip ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0); + + bool32 expected = KMIP_TRUE; + bool32 observed = 0; + + int result = kmip_decode_bool(&ctx, KMIP_TAG_DEFAULT, &observed); + result = report_decoding_test_result( + tracker, + &ctx, + observed == expected, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_encode_text_string(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[24] = { + 0x42, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0B, + 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x57, 0x6F, + 0x72, 0x6C, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 observed[24] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0); + + struct text_string example = {0}; + example.value = "Hello World"; + example.size = 11; + + int result = kmip_encode_text_string(&ctx, KMIP_TAG_DEFAULT, &example); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_decode_text_string(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[24] = { + 0x42, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0B, + 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x57, 0x6F, + 0x72, 0x6C, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + struct kmip ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0); + + struct text_string expected = {0}; + expected.value = "Hello World"; + expected.size = 11; + struct text_string observed = {0}; + + int result = kmip_decode_text_string(&ctx, KMIP_TAG_DEFAULT, &observed); + result = report_decoding_test_result( + tracker, + &ctx, + kmip_compare_text_string(&expected, &observed), + result, + __func__); + kmip_free_text_string(&ctx, &observed); + kmip_destroy(&ctx); + return(result); +} + +int +test_encode_byte_string(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[16] = { + 0x42, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, + 0x01, 0x02, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 observed[16] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0); + uint8 str[3] = {0x01, 0x02, 0x03}; + + struct byte_string example = {0}; + example.value = str; + example.size = 3; + + int result = kmip_encode_byte_string(&ctx, KMIP_TAG_DEFAULT, &example); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_decode_byte_string(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[16] = { + 0x42, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, + 0x01, 0x02, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + struct kmip ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0); + + uint8 str[3] = {0x01, 0x02, 0x03}; + + struct byte_string expected = {0}; + expected.value = str; + expected.size = 3; + struct byte_string observed = {0}; + + int result = kmip_decode_byte_string(&ctx, KMIP_TAG_DEFAULT, &observed); + result = report_decoding_test_result( + tracker, + &ctx, + kmip_compare_byte_string(&expected, &observed), + result, + __func__); + kmip_free_byte_string(&ctx, &observed); + kmip_destroy(&ctx); + return(result); +} + +int +test_encode_date_time(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[16] = { + 0x42, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x47, 0xDA, 0x67, 0xF8 + }; + + uint8 observed[16] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0); + + int result = kmip_encode_date_time(&ctx, KMIP_TAG_DEFAULT, 1205495800); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_decode_date_time(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[16] = { + 0x42, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x47, 0xDA, 0x67, 0xF8 + }; + + struct kmip ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0); + + uint64 expected = 1205495800; + uint64 observed = 0; + + int result = kmip_decode_date_time(&ctx, KMIP_TAG_DEFAULT, &observed); + result = report_decoding_test_result( + tracker, + &ctx, + observed == expected, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_encode_interval(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[16] = { + 0x42, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x0D, 0x2F, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 observed[16] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0); + + int result = kmip_encode_interval(&ctx, KMIP_TAG_DEFAULT, 864000); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_decode_interval(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[16] = { + 0x42, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x0D, 0x2F, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + struct kmip ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0); + + uint32 expected = 864000; + uint32 observed = 0; + + int result = kmip_decode_interval(&ctx, KMIP_TAG_DEFAULT, &observed); + result = report_decoding_test_result( + tracker, + &ctx, + observed == expected, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_encode_name(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[48] = { + 0x42, 0x00, 0x53, 0x01, 0x00, 0x00, 0x00, 0x28, + 0x42, 0x00, 0x55, 0x07, 0x00, 0x00, 0x00, 0x09, + 0x54, 0x65, 0x6D, 0x70, 0x6C, 0x61, 0x74, 0x65, + 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x54, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 observed[48] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0); + + struct text_string value = {0}; + value.value = "Template1"; + value.size = 9; + + struct name n = {0}; + n.value = &value; + n.type = KMIP_NAME_UNINTERPRETED_TEXT_STRING; + + int result = kmip_encode_name(&ctx, &n); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_decode_name(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[48] = { + 0x42, 0x00, 0x53, 0x01, 0x00, 0x00, 0x00, 0x28, + 0x42, 0x00, 0x55, 0x07, 0x00, 0x00, 0x00, 0x09, + 0x54, 0x65, 0x6D, 0x70, 0x6C, 0x61, 0x74, 0x65, + 0x31, 0x00, 0x00, 0x00, 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_0); + + struct text_string value = {0}; + value.value = "Template1"; + value.size = 9; + + struct name expected = {0}; + expected.value = &value; + expected.type = KMIP_NAME_UNINTERPRETED_TEXT_STRING; + struct name observed = {0}; + + int result = kmip_decode_name(&ctx, &observed); + result = report_decoding_test_result( + tracker, + &ctx, + kmip_compare_name(&expected, &observed), + result, + __func__); + kmip_free_name(&ctx, &observed); + kmip_destroy(&ctx); + return(result); +} + +int +test_encode_protection_storage_masks(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + /* This encoding matches the following set of values: + * Protection Storage Masks + * Protection Storage Mask + * Software + * Hardware + * On Processor + * On System + * Off System + * Hypervisor + * Operating System + * Container + * On Premises + * Off Premises + * Self Managed + * Outsourced + * Validated + * Same Jurisdiction + * Protection Storage Mask + * Software + * Hardware + */ + uint8 expected[40] = { + 0x42, 0x01, 0x5F, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x42, 0x01, 0x5E, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x01, 0x5E, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 observed[40] = {0}; + KMIP ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_2_0); + + LinkedList list = {0}; + LinkedListItem item_1 = {0}; + int32 mask_1 = 0x3FFF; + item_1.data = &mask_1; + + LinkedListItem item_2 = {0}; + int32 mask_2 = 0x0003; + item_2.data = &mask_2; + + kmip_linked_list_enqueue(&list, &item_1); + kmip_linked_list_enqueue(&list, &item_2); + + ProtectionStorageMasks psm = {0}; + psm.masks = &list; + + int result = kmip_encode_protection_storage_masks(&ctx, &psm); + result = report_encoding_test_result(tracker, &ctx, expected, observed, result, __func__); + + kmip_destroy(&ctx); + + return(result); +} + +int +test_decode_protection_storage_masks(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + /* This encoding matches the following set of values: + * Protection Storage Masks + * Protection Storage Mask + * Software + * Hardware + * On Processor + * On System + * Off System + * Hypervisor + * Operating System + * Container + * On Premises + * Off Premises + * Self Managed + * Outsourced + * Validated + * Same Jurisdiction + * Protection Storage Mask + * Software + * Hardware + */ + uint8 encoding[40] = { + 0x42, 0x01, 0x5F, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x42, 0x01, 0x5E, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x01, 0x5E, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00 + }; + + KMIP ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_2_0); + + LinkedList list = {0}; + LinkedListItem item_1 = {0}; + int32 mask_1 = 0x3FFF; + item_1.data = &mask_1; + + LinkedListItem item_2 = {0}; + int32 mask_2 = 0x0003; + item_2.data = &mask_2; + + kmip_linked_list_enqueue(&list, &item_1); + kmip_linked_list_enqueue(&list, &item_2); + + ProtectionStorageMasks expected = {0}; + expected.masks = &list; + + ProtectionStorageMasks observed = {0}; + int result = kmip_decode_protection_storage_masks(&ctx, &observed); + int comparison = kmip_compare_protection_storage_masks(&expected, &observed); + if(!comparison) + { + kmip_print_protection_storage_masks(1, &expected); + kmip_print_protection_storage_masks(1, &observed); + } + result = report_decoding_test_result(tracker, &ctx, comparison, result, __func__); + + kmip_free_protection_storage_masks(&ctx, &observed); + kmip_destroy(&ctx); + + return(result); +} + +int +test_encode_attribute_unique_identifier(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[88] = { + 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[88] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0); + + struct text_string uuid = {0}; + uuid.value = "49a1ca88-6bea-4fb2-b450-7e58802c3038"; + uuid.size = 36; + + struct attribute attr = {0}; + kmip_init_attribute(&attr); + + attr.type = KMIP_ATTR_UNIQUE_IDENTIFIER; + attr.value = &uuid; + + 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_unique_identifier(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[88] = { + 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 + }; + + struct kmip ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0); + + struct text_string uuid = {0}; + uuid.value = "49a1ca88-6bea-4fb2-b450-7e58802c3038"; + uuid.size = 36; + + struct attribute expected = {0}; + kmip_init_attribute(&expected); + expected.type = KMIP_ATTR_UNIQUE_IDENTIFIER; + expected.value = &uuid; + 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_attribute_name(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[72] = { + 0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x40, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x04, + 0x4E, 0x61, 0x6D, 0x65, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x0B, 0x01, 0x00, 0x00, 0x00, 0x28, + 0x42, 0x00, 0x55, 0x07, 0x00, 0x00, 0x00, 0x09, + 0x54, 0x65, 0x6D, 0x70, 0x6C, 0x61, 0x74, 0x65, + 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x54, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 observed[72] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0); + + struct text_string value = {0}; + value.value = "Template1"; + value.size = 9; + + struct name n = {0}; + n.value = &value; + n.type = KMIP_NAME_UNINTERPRETED_TEXT_STRING; + + struct attribute attr = {0}; + kmip_init_attribute(&attr); + + attr.type = KMIP_ATTR_NAME; + attr.value = &n; + + 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_name(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[72] = { + 0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x40, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x04, + 0x4E, 0x61, 0x6D, 0x65, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x0B, 0x01, 0x00, 0x00, 0x00, 0x28, + 0x42, 0x00, 0x55, 0x07, 0x00, 0x00, 0x00, 0x09, + 0x54, 0x65, 0x6D, 0x70, 0x6C, 0x61, 0x74, 0x65, + 0x31, 0x00, 0x00, 0x00, 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_0); + + struct text_string value = {0}; + value.value = "Template1"; + value.size = 9; + + struct name n = {0}; + n.value = &value; + n.type = KMIP_NAME_UNINTERPRETED_TEXT_STRING; + + struct attribute expected = {0}; + kmip_init_attribute(&expected); + expected.type = KMIP_ATTR_NAME; + expected.value = &n; + 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_attribute_object_type(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[48] = { + 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 + }; + + uint8 observed[48] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0); + + enum object_type t = KMIP_OBJTYPE_SYMMETRIC_KEY; + struct attribute attr = {0}; + kmip_init_attribute(&attr); + + attr.type = KMIP_ATTR_OBJECT_TYPE; + attr.value = &t; + + 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_object_type(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[48] = { + 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 + }; + + struct kmip ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0); + + enum object_type t = KMIP_OBJTYPE_SYMMETRIC_KEY; + struct attribute expected = {0}; + kmip_init_attribute(&expected); + expected.type = KMIP_ATTR_OBJECT_TYPE; + expected.value = &t; + 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_attribute_cryptographic_algorithm(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[56] = { + 0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x17, + 0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x41, 0x6C, + 0x67, 0x6F, 0x72, 0x69, 0x74, 0x68, 0x6D, 0x00, + 0x42, 0x00, 0x0B, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 observed[56] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0); + + enum cryptographic_algorithm a = KMIP_CRYPTOALG_AES; + struct attribute attr = {0}; + kmip_init_attribute(&attr); + + attr.type = KMIP_ATTR_CRYPTOGRAPHIC_ALGORITHM; + attr.value = &a; + + 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_cryptographic_algorithm(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[56] = { + 0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x17, + 0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x41, 0x6C, + 0x67, 0x6F, 0x72, 0x69, 0x74, 0x68, 0x6D, 0x00, + 0x42, 0x00, 0x0B, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00 + }; + + struct kmip ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0); + + enum cryptographic_algorithm a = KMIP_CRYPTOALG_AES; + struct attribute expected = {0}; + kmip_init_attribute(&expected); + expected.type = KMIP_ATTR_CRYPTOGRAPHIC_ALGORITHM; + expected.value = &a; + 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_attribute_cryptographic_length(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[56] = { + 0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x14, + 0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x4C, 0x65, + 0x6E, 0x67, 0x74, 0x68, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 observed[56] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0); + + int32 length = 128; + struct attribute attr = {0}; + kmip_init_attribute(&attr); + + attr.type = KMIP_ATTR_CRYPTOGRAPHIC_LENGTH; + attr.value = &length; + + 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_cryptographic_length(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[56] = { + 0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x14, + 0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x4C, 0x65, + 0x6E, 0x67, 0x74, 0x68, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00 + }; + + struct kmip ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0); + + int32 length = 128; + struct attribute expected = {0}; + kmip_init_attribute(&expected); + expected.type = KMIP_ATTR_CRYPTOGRAPHIC_LENGTH; + expected.value = &length; + 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_attribute_operation_policy_name(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[56] = { + 0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x15, + 0x4F, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6F, + 0x6E, 0x20, 0x50, 0x6F, 0x6C, 0x69, 0x63, 0x79, + 0x20, 0x4E, 0x61, 0x6D, 0x65, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x0B, 0x07, 0x00, 0x00, 0x00, 0x07, + 0x64, 0x65, 0x66, 0x61, 0x75, 0x6C, 0x74, 0x00 + }; + + uint8 observed[56] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0); + + struct text_string policy = {0}; + policy.value = "default"; + policy.size = 7; + + struct attribute attr = {0}; + kmip_init_attribute(&attr); + + attr.type = KMIP_ATTR_OPERATION_POLICY_NAME; + attr.value = &policy; + + 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_operation_policy_name(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[56] = { + 0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x15, + 0x4F, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6F, + 0x6E, 0x20, 0x50, 0x6F, 0x6C, 0x69, 0x63, 0x79, + 0x20, 0x4E, 0x61, 0x6D, 0x65, 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_0); + + struct text_string policy = {0}; + policy.value = "default"; + policy.size = 7; + + struct attribute expected = {0}; + kmip_init_attribute(&expected); + expected.type = KMIP_ATTR_OPERATION_POLICY_NAME; + expected.value = &policy; + 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_attribute_cryptographic_usage_mask(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[56] = { + 0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x18, + 0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x55, 0x73, + 0x61, 0x67, 0x65, 0x20, 0x4D, 0x61, 0x73, 0x6B, + 0x42, 0x00, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 observed[56] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0); + + int32 mask = KMIP_CRYPTOMASK_ENCRYPT | KMIP_CRYPTOMASK_DECRYPT; + struct attribute attr = {0}; + kmip_init_attribute(&attr); + + attr.type = KMIP_ATTR_CRYPTOGRAPHIC_USAGE_MASK; + attr.value = &mask; + + 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_cryptographic_usage_mask(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[56] = { + 0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x18, + 0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x55, 0x73, + 0x61, 0x67, 0x65, 0x20, 0x4D, 0x61, 0x73, 0x6B, + 0x42, 0x00, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00 + }; + + struct kmip ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0); + + int32 mask = KMIP_CRYPTOMASK_ENCRYPT | KMIP_CRYPTOMASK_DECRYPT; + struct attribute expected = {0}; + kmip_init_attribute(&expected); + expected.type = KMIP_ATTR_CRYPTOGRAPHIC_USAGE_MASK; + expected.value = &mask; + 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_attribute_state(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[40] = { + 0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x05, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x0B, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 observed[40] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0); + + enum state s = KMIP_STATE_PRE_ACTIVE; + struct attribute attr = {0}; + kmip_init_attribute(&attr); + + attr.type = KMIP_ATTR_STATE; + attr.value = &s; + + 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_state(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[40] = { + 0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x05, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x0B, 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_0); + + enum state s = KMIP_STATE_PRE_ACTIVE; + struct attribute expected = {0}; + kmip_init_attribute(&expected); + expected.type = KMIP_ATTR_STATE; + expected.value = &s; + 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_protocol_version(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[40] = { + 0x42, 0x00, 0x69, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x42, 0x00, 0x6A, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x6B, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 observed[40] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0); + + struct protocol_version pv = {0}; + pv.major = 1; + pv.minor = 0; + + int result = kmip_encode_protocol_version(&ctx, &pv); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_decode_protocol_version(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[40] = { + 0x42, 0x00, 0x69, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x42, 0x00, 0x6A, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x6B, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + struct kmip ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0); + + struct protocol_version expected = {0}; + expected.major = 1; + expected.minor = 0; + struct protocol_version observed = {0}; + + int result = kmip_decode_protocol_version(&ctx, &observed); + result = report_decoding_test_result( + tracker, + &ctx, + kmip_compare_protocol_version(&expected, &observed), + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_encode_cryptographic_parameters(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[72] = { + 0x42, 0x00, 0x2B, 0x01, 0x00, 0x00, 0x00, 0x40, + 0x42, 0x00, 0x11, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x5F, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x38, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x83, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 observed[72] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0); + + struct cryptographic_parameters cp = {0}; + cp.block_cipher_mode = KMIP_BLOCK_CBC; + cp.padding_method = KMIP_PAD_PKCS5; + cp.hashing_algorithm = KMIP_HASH_SHA1; + cp.key_role_type = KMIP_ROLE_KEK; + + int result = kmip_encode_cryptographic_parameters(&ctx, &cp); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_decode_cryptographic_parameters(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[72] = { + 0x42, 0x00, 0x2B, 0x01, 0x00, 0x00, 0x00, 0x40, + 0x42, 0x00, 0x11, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x5F, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x38, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x83, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00 + }; + + struct kmip ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0); + + struct cryptographic_parameters expected = {0}; + kmip_init_cryptographic_parameters(&expected); + expected.block_cipher_mode = KMIP_BLOCK_CBC; + expected.padding_method = KMIP_PAD_PKCS5; + expected.hashing_algorithm = KMIP_HASH_SHA1; + expected.key_role_type = KMIP_ROLE_KEK; + struct cryptographic_parameters observed = {0}; + kmip_init_cryptographic_parameters(&observed); + + int result = kmip_decode_cryptographic_parameters(&ctx, &observed); + result = report_decoding_test_result( + tracker, + &ctx, + kmip_compare_cryptographic_parameters(&expected, &observed), + result, + __func__); + kmip_free_cryptographic_parameters(&ctx, &observed); + kmip_destroy(&ctx); + return(result); +} + +int +test_encode_encryption_key_information(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[80] = { + 0x42, 0x00, 0x36, 0x01, 0x00, 0x00, 0x00, 0x48, + 0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, + 0x31, 0x30, 0x30, 0x31, 0x38, 0x32, 0x64, 0x35, + 0x2D, 0x37, 0x32, 0x62, 0x38, 0x2D, 0x34, 0x37, + 0x61, 0x61, 0x2D, 0x38, 0x33, 0x38, 0x33, 0x2D, + 0x34, 0x64, 0x39, 0x37, 0x64, 0x35, 0x31, 0x32, + 0x65, 0x39, 0x38, 0x61, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x2B, 0x01, 0x00, 0x00, 0x00, 0x10, + 0x42, 0x00, 0x11, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 observed[80] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0); + + struct text_string uuid = {0}; + uuid.value = "100182d5-72b8-47aa-8383-4d97d512e98a"; + uuid.size = 36; + + struct cryptographic_parameters cp = {0}; + cp.block_cipher_mode = KMIP_BLOCK_NIST_KEY_WRAP; + + struct encryption_key_information eki = {0}; + eki.unique_identifier = &uuid; + eki.cryptographic_parameters = &cp; + + int result = kmip_encode_encryption_key_information(&ctx, &eki); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_decode_encryption_key_information(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[80] = { + 0x42, 0x00, 0x36, 0x01, 0x00, 0x00, 0x00, 0x48, + 0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, + 0x31, 0x30, 0x30, 0x31, 0x38, 0x32, 0x64, 0x35, + 0x2D, 0x37, 0x32, 0x62, 0x38, 0x2D, 0x34, 0x37, + 0x61, 0x61, 0x2D, 0x38, 0x33, 0x38, 0x33, 0x2D, + 0x34, 0x64, 0x39, 0x37, 0x64, 0x35, 0x31, 0x32, + 0x65, 0x39, 0x38, 0x61, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x2B, 0x01, 0x00, 0x00, 0x00, 0x10, + 0x42, 0x00, 0x11, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x0D, 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 = "100182d5-72b8-47aa-8383-4d97d512e98a"; + uuid.size = 36; + + struct cryptographic_parameters cp = {0}; + kmip_init_cryptographic_parameters(&cp); + + cp.block_cipher_mode = KMIP_BLOCK_NIST_KEY_WRAP; + + struct encryption_key_information expected = {0}; + expected.unique_identifier = &uuid; + expected.cryptographic_parameters = &cp; + + struct encryption_key_information observed = {0}; + + int result = kmip_decode_encryption_key_information(&ctx, &observed); + result = report_decoding_test_result( + tracker, + &ctx, + kmip_compare_encryption_key_information(&expected, &observed), + result, + __func__); + kmip_free_encryption_key_information(&ctx, &observed); + kmip_destroy(&ctx); + return(result); +} + +int +test_encode_mac_signature_key_information(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[80] = { + 0x42, 0x00, 0x4E, 0x01, 0x00, 0x00, 0x00, 0x48, + 0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, + 0x31, 0x30, 0x30, 0x31, 0x38, 0x32, 0x64, 0x35, + 0x2D, 0x37, 0x32, 0x62, 0x38, 0x2D, 0x34, 0x37, + 0x61, 0x61, 0x2D, 0x38, 0x33, 0x38, 0x33, 0x2D, + 0x34, 0x64, 0x39, 0x37, 0x64, 0x35, 0x31, 0x32, + 0x65, 0x39, 0x38, 0x61, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x2B, 0x01, 0x00, 0x00, 0x00, 0x10, + 0x42, 0x00, 0x11, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 observed[80] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0); + + struct text_string uuid = {0}; + uuid.value = "100182d5-72b8-47aa-8383-4d97d512e98a"; + uuid.size = 36; + + struct cryptographic_parameters cp = {0}; + cp.block_cipher_mode = KMIP_BLOCK_NIST_KEY_WRAP; + + struct mac_signature_key_information mski = {0}; + mski.unique_identifier = &uuid; + mski.cryptographic_parameters = &cp; + + int result = kmip_encode_mac_signature_key_information(&ctx, &mski); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_decode_mac_signature_key_information(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[80] = { + 0x42, 0x00, 0x4E, 0x01, 0x00, 0x00, 0x00, 0x48, + 0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, + 0x31, 0x30, 0x30, 0x31, 0x38, 0x32, 0x64, 0x35, + 0x2D, 0x37, 0x32, 0x62, 0x38, 0x2D, 0x34, 0x37, + 0x61, 0x61, 0x2D, 0x38, 0x33, 0x38, 0x33, 0x2D, + 0x34, 0x64, 0x39, 0x37, 0x64, 0x35, 0x31, 0x32, + 0x65, 0x39, 0x38, 0x61, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x2B, 0x01, 0x00, 0x00, 0x00, 0x10, + 0x42, 0x00, 0x11, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x0D, 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 = "100182d5-72b8-47aa-8383-4d97d512e98a"; + uuid.size = 36; + + struct cryptographic_parameters cp = {0}; + kmip_init_cryptographic_parameters(&cp); + + cp.block_cipher_mode = KMIP_BLOCK_NIST_KEY_WRAP; + + struct mac_signature_key_information expected = {0}; + expected.unique_identifier = &uuid; + expected.cryptographic_parameters = &cp; + + struct mac_signature_key_information observed = {0}; + + int result = kmip_decode_mac_signature_key_information(&ctx, &observed); + result = report_decoding_test_result( + tracker, + &ctx, + kmip_compare_mac_signature_key_information(&expected, &observed), + result, + __func__); + kmip_free_mac_signature_key_information(&ctx, &observed); + kmip_destroy(&ctx); + return(result); +} + +int +test_encode_key_wrapping_data(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[104] = { + 0x42, 0x00, 0x46, 0x01, 0x00, 0x00, 0x00, 0x60, + 0x42, 0x00, 0x9E, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x36, 0x01, 0x00, 0x00, 0x00, 0x48, + 0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, + 0x31, 0x30, 0x30, 0x31, 0x38, 0x32, 0x64, 0x35, + 0x2D, 0x37, 0x32, 0x62, 0x38, 0x2D, 0x34, 0x37, + 0x61, 0x61, 0x2D, 0x38, 0x33, 0x38, 0x33, 0x2D, + 0x34, 0x64, 0x39, 0x37, 0x64, 0x35, 0x31, 0x32, + 0x65, 0x39, 0x38, 0x61, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x2B, 0x01, 0x00, 0x00, 0x00, 0x10, + 0x42, 0x00, 0x11, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 observed[104] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0); + + struct text_string uuid = {0}; + uuid.value = "100182d5-72b8-47aa-8383-4d97d512e98a"; + uuid.size = 36; + + struct cryptographic_parameters cp = {0}; + cp.block_cipher_mode = KMIP_BLOCK_NIST_KEY_WRAP; + + struct encryption_key_information eki = {0}; + eki.unique_identifier = &uuid; + eki.cryptographic_parameters = &cp; + + struct key_wrapping_data kwd = {0}; + kwd.wrapping_method = KMIP_WRAP_ENCRYPT; + kwd.encryption_key_info = &eki; + + int result = kmip_encode_key_wrapping_data(&ctx, &kwd); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_decode_key_wrapping_data(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[104] = { + 0x42, 0x00, 0x46, 0x01, 0x00, 0x00, 0x00, 0x60, + 0x42, 0x00, 0x9E, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x36, 0x01, 0x00, 0x00, 0x00, 0x48, + 0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, + 0x31, 0x30, 0x30, 0x31, 0x38, 0x32, 0x64, 0x35, + 0x2D, 0x37, 0x32, 0x62, 0x38, 0x2D, 0x34, 0x37, + 0x61, 0x61, 0x2D, 0x38, 0x33, 0x38, 0x33, 0x2D, + 0x34, 0x64, 0x39, 0x37, 0x64, 0x35, 0x31, 0x32, + 0x65, 0x39, 0x38, 0x61, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x2B, 0x01, 0x00, 0x00, 0x00, 0x10, + 0x42, 0x00, 0x11, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x0D, 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 = "100182d5-72b8-47aa-8383-4d97d512e98a"; + uuid.size = 36; + + struct cryptographic_parameters cp = {0}; + kmip_init_cryptographic_parameters(&cp); + + cp.block_cipher_mode = KMIP_BLOCK_NIST_KEY_WRAP; + + struct encryption_key_information eki = {0}; + eki.unique_identifier = &uuid; + eki.cryptographic_parameters = &cp; + + struct key_wrapping_data expected = {0}; + expected.wrapping_method = KMIP_WRAP_ENCRYPT; + expected.encryption_key_info = &eki; + + struct key_wrapping_data observed = {0}; + + int result = kmip_decode_key_wrapping_data(&ctx, &observed); + result = report_decoding_test_result( + tracker, + &ctx, + kmip_compare_key_wrapping_data(&expected, &observed), + result, + __func__); + kmip_free_key_wrapping_data(&ctx, &observed); + kmip_destroy(&ctx); + return(result); +} + +int +test_encode_key_material_byte_string(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[24] = { + 0x42, 0x00, 0x43, 0x08, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF + }; + + uint8 observed[24] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0); + + uint8 value[16] = { + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF + }; + struct byte_string key = {0}; + key.value = value; + key.size = ARRAY_LENGTH(value); + + int result = kmip_encode_key_material(&ctx, KMIP_KEYFORMAT_RAW, &key); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_decode_key_material_byte_string(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[24] = { + 0x42, 0x00, 0x43, 0x08, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF + }; + + struct kmip ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0); + + uint8 value[16] = { + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF + }; + struct byte_string expected = {0}; + expected.value = value; + expected.size = ARRAY_LENGTH(value); + + struct byte_string *expected_ptr = &expected; + struct byte_string *observed_ptr = NULL; + + int result = kmip_decode_key_material( + &ctx, + KMIP_KEYFORMAT_RAW, + (void**)&observed_ptr); + result = report_decoding_test_result( + tracker, + &ctx, + kmip_compare_key_material(KMIP_KEYFORMAT_RAW, (void**)&expected_ptr, (void**)&observed_ptr), + result, + __func__); + kmip_free_key_material(&ctx, KMIP_KEYFORMAT_RAW, (void**)&observed_ptr); + kmip_destroy(&ctx); + return(result); +} + +int +test_encode_key_material_transparent_symmetric_key(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[48] = { + 0x42, 0x00, 0x43, 0x01, 0x00, 0x00, 0x00, 0x28, + 0x42, 0x00, 0x3F, 0x08, 0x00, 0x00, 0x00, 0x20, + 0x00, 0x00, 0x11, 0x11, 0x22, 0x22, 0x33, 0x33, + 0x44, 0x44, 0x55, 0x55, 0x66, 0x66, 0x77, 0x77, + 0x88, 0x88, 0x99, 0x99, 0xAA, 0xAA, 0xBB, 0xBB, + 0xCC, 0xCC, 0xDD, 0xDD, 0xEE, 0xEE, 0xFF, 0xFF + }; + + uint8 observed[48] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0); + + uint8 value[32] = { + 0x00, 0x00, 0x11, 0x11, 0x22, 0x22, 0x33, 0x33, + 0x44, 0x44, 0x55, 0x55, 0x66, 0x66, 0x77, 0x77, + 0x88, 0x88, 0x99, 0x99, 0xAA, 0xAA, 0xBB, 0xBB, + 0xCC, 0xCC, 0xDD, 0xDD, 0xEE, 0xEE, 0xFF, 0xFF + }; + struct byte_string key = {0}; + key.value = value; + key.size = ARRAY_LENGTH(value); + struct transparent_symmetric_key tsk = {0}; + tsk.key = &key; + + int result = kmip_encode_key_material(&ctx, KMIP_KEYFORMAT_TRANS_SYMMETRIC_KEY, &tsk); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_decode_key_material_transparent_symmetric_key(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[48] = { + 0x42, 0x00, 0x43, 0x01, 0x00, 0x00, 0x00, 0x28, + 0x42, 0x00, 0x3F, 0x08, 0x00, 0x00, 0x00, 0x20, + 0x00, 0x00, 0x11, 0x11, 0x22, 0x22, 0x33, 0x33, + 0x44, 0x44, 0x55, 0x55, 0x66, 0x66, 0x77, 0x77, + 0x88, 0x88, 0x99, 0x99, 0xAA, 0xAA, 0xBB, 0xBB, + 0xCC, 0xCC, 0xDD, 0xDD, 0xEE, 0xEE, 0xFF, 0xFF + }; + + struct kmip ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0); + + uint8 value[32] = { + 0x00, 0x00, 0x11, 0x11, 0x22, 0x22, 0x33, 0x33, + 0x44, 0x44, 0x55, 0x55, 0x66, 0x66, 0x77, 0x77, + 0x88, 0x88, 0x99, 0x99, 0xAA, 0xAA, 0xBB, 0xBB, + 0xCC, 0xCC, 0xDD, 0xDD, 0xEE, 0xEE, 0xFF, 0xFF + }; + struct byte_string key = {0}; + key.value = value; + key.size = ARRAY_LENGTH(value); + struct transparent_symmetric_key expected = {0}; + expected.key = &key; + + struct transparent_symmetric_key *expected_ptr = &expected; + struct transparent_symmetric_key *observed_ptr = NULL; + + int result = kmip_decode_key_material( + &ctx, + KMIP_KEYFORMAT_TRANS_SYMMETRIC_KEY, + (void**)&observed_ptr); + result = report_decoding_test_result( + tracker, + &ctx, + kmip_compare_key_material(KMIP_KEYFORMAT_TRANS_SYMMETRIC_KEY, (void**)&expected_ptr, (void**)&observed_ptr), + result, + __func__); + kmip_free_key_material( + &ctx, + KMIP_KEYFORMAT_TRANS_SYMMETRIC_KEY, + (void**)&observed_ptr); + kmip_destroy(&ctx); + return(result); +} + +int +test_encode_key_value(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[32] = { + 0x42, 0x00, 0x45, 0x01, 0x00, 0x00, 0x00, 0x18, + 0x42, 0x00, 0x43, 0x08, 0x00, 0x00, 0x00, 0x10, + 0xD3, 0x51, 0x91, 0x0F, 0x1D, 0x79, 0x34, 0xD6, + 0xE2, 0xAE, 0x17, 0x57, 0x65, 0x64, 0xE2, 0xBC + }; + + uint8 observed[32] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0); + + uint8 value[16] = { + 0xD3, 0x51, 0x91, 0x0F, 0x1D, 0x79, 0x34, 0xD6, + 0xE2, 0xAE, 0x17, 0x57, 0x65, 0x64, 0xE2, 0xBC + }; + struct byte_string key = {0}; + key.value = value; + key.size = ARRAY_LENGTH(value); + + struct key_value kv = {0}; + kv.key_material = &key; + + int result = kmip_encode_key_value(&ctx, KMIP_KEYFORMAT_RAW, &kv); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_decode_key_value(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[32] = { + 0x42, 0x00, 0x45, 0x01, 0x00, 0x00, 0x00, 0x18, + 0x42, 0x00, 0x43, 0x08, 0x00, 0x00, 0x00, 0x10, + 0xD3, 0x51, 0x91, 0x0F, 0x1D, 0x79, 0x34, 0xD6, + 0xE2, 0xAE, 0x17, 0x57, 0x65, 0x64, 0xE2, 0xBC + }; + + struct kmip ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0); + + uint8 value[16] = { + 0xD3, 0x51, 0x91, 0x0F, 0x1D, 0x79, 0x34, 0xD6, + 0xE2, 0xAE, 0x17, 0x57, 0x65, 0x64, 0xE2, 0xBC + }; + struct byte_string key = {0}; + key.value = value; + key.size = ARRAY_LENGTH(value); + + struct key_value expected = {0}; + expected.key_material = &key; + struct key_value observed = {0}; + + int result = kmip_decode_key_value(&ctx, KMIP_KEYFORMAT_RAW, &observed); + result = report_decoding_test_result( + tracker, + &ctx, + kmip_compare_key_value(KMIP_KEYFORMAT_RAW, &expected, &observed), + result, + __func__); + kmip_free_key_value(&ctx, KMIP_KEYFORMAT_RAW, &observed); + kmip_destroy(&ctx); + return(result); +} + +int +test_encode_key_value_with_attributes(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[144] = { + 0x42, 0x00, 0x45, 0x01, 0x00, 0x00, 0x00, 0x88, + 0x42, 0x00, 0x43, 0x08, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x17, + 0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x41, 0x6C, + 0x67, 0x6F, 0x72, 0x69, 0x74, 0x68, 0x6D, 0x00, + 0x42, 0x00, 0x0B, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x14, + 0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x4C, 0x65, + 0x6E, 0x67, 0x74, 0x68, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 observed[144] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0); + + uint8 value[16] = { + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF + }; + struct byte_string key = {0}; + key.value = value; + key.size = ARRAY_LENGTH(value); + + struct attribute attributes[2] = {0}; + for(int i = 0; i < 2; i++) + { + kmip_init_attribute(&attributes[i]); + } + + enum cryptographic_algorithm ca = KMIP_CRYPTOALG_AES; + int length = 128; + attributes[0].type = KMIP_ATTR_CRYPTOGRAPHIC_ALGORITHM; + attributes[0].value = &ca; + attributes[1].type = KMIP_ATTR_CRYPTOGRAPHIC_LENGTH; + attributes[1].value = &length; + + struct key_value kv = {0}; + kv.key_material = &key; + kv.attributes = attributes; + kv.attribute_count = ARRAY_LENGTH(attributes); + + int result = kmip_encode_key_value(&ctx, KMIP_KEYFORMAT_RAW, &kv); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_decode_key_value_with_attributes(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[144] = { + 0x42, 0x00, 0x45, 0x01, 0x00, 0x00, 0x00, 0x88, + 0x42, 0x00, 0x43, 0x08, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x17, + 0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x41, 0x6C, + 0x67, 0x6F, 0x72, 0x69, 0x74, 0x68, 0x6D, 0x00, + 0x42, 0x00, 0x0B, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x14, + 0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x4C, 0x65, + 0x6E, 0x67, 0x74, 0x68, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00 + }; + + struct kmip ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0); + + uint8 value[16] = { + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF + }; + struct byte_string key = {0}; + key.value = value; + key.size = ARRAY_LENGTH(value); + + struct attribute attributes[2] = {0}; + for(size_t i = 0; i < 2; i++) + { + kmip_init_attribute(&attributes[i]); + } + + enum cryptographic_algorithm ca = KMIP_CRYPTOALG_AES; + int length = 128; + attributes[0].type = KMIP_ATTR_CRYPTOGRAPHIC_ALGORITHM; + attributes[0].value = &ca; + attributes[1].type = KMIP_ATTR_CRYPTOGRAPHIC_LENGTH; + attributes[1].value = &length; + + struct key_value expected = {0}; + expected.key_material = &key; + expected.attributes = attributes; + expected.attribute_count = ARRAY_LENGTH(attributes); + struct key_value observed = {0}; + + int result = kmip_decode_key_value(&ctx, KMIP_KEYFORMAT_RAW, &observed); + result = report_decoding_test_result( + tracker, + &ctx, + kmip_compare_key_value(KMIP_KEYFORMAT_RAW, &expected, &observed), + result, + __func__); + kmip_free_key_value(&ctx, KMIP_KEYFORMAT_RAW, &observed); + kmip_destroy(&ctx); + return(result); +} + +int +test_encode_key_block_key_value_byte_string(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[192] = { + 0x42, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0xB8, + 0x42, 0x00, 0x42, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x45, 0x08, 0x00, 0x00, 0x00, 0x18, + 0x1F, 0xA6, 0x8B, 0x0A, 0x81, 0x12, 0xB4, 0x47, + 0xAE, 0xF3, 0x4B, 0xD8, 0xFB, 0x5A, 0x7B, 0x82, + 0x9D, 0x3E, 0x86, 0x23, 0x71, 0xD2, 0xCF, 0xE5, + 0x42, 0x00, 0x28, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x2A, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x46, 0x01, 0x00, 0x00, 0x00, 0x60, + 0x42, 0x00, 0x9E, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x36, 0x01, 0x00, 0x00, 0x00, 0x48, + 0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, + 0x31, 0x30, 0x30, 0x31, 0x38, 0x32, 0x64, 0x35, + 0x2D, 0x37, 0x32, 0x62, 0x38, 0x2D, 0x34, 0x37, + 0x61, 0x61, 0x2D, 0x38, 0x33, 0x38, 0x33, 0x2D, + 0x34, 0x64, 0x39, 0x37, 0x64, 0x35, 0x31, 0x32, + 0x65, 0x39, 0x38, 0x61, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x2B, 0x01, 0x00, 0x00, 0x00, 0x10, + 0x42, 0x00, 0x11, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 observed[192] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0); + + uint8 value[24] = { + 0x1F, 0xA6, 0x8B, 0x0A, 0x81, 0x12, 0xB4, 0x47, + 0xAE, 0xF3, 0x4B, 0xD8, 0xFB, 0x5A, 0x7B, 0x82, + 0x9D, 0x3E, 0x86, 0x23, 0x71, 0xD2, 0xCF, 0xE5 + }; + struct byte_string key = {0}; + key.value = value; + key.size = ARRAY_LENGTH(value); + + struct text_string uuid = {0}; + uuid.value = "100182d5-72b8-47aa-8383-4d97d512e98a"; + uuid.size = 36; + + struct cryptographic_parameters cp = {0}; + cp.block_cipher_mode = KMIP_BLOCK_NIST_KEY_WRAP; + + struct encryption_key_information eki = {0}; + eki.unique_identifier = &uuid; + eki.cryptographic_parameters = &cp; + + struct key_wrapping_data kwd = {0}; + kwd.wrapping_method = KMIP_WRAP_ENCRYPT; + kwd.encryption_key_info = &eki; + + struct key_block kb = {0}; + kb.key_format_type = KMIP_KEYFORMAT_RAW; + kb.key_value = &key; + kb.cryptographic_algorithm = KMIP_CRYPTOALG_AES; + kb.cryptographic_length = 128; + kb.key_wrapping_data = &kwd; + + int result = kmip_encode_key_block(&ctx, &kb); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_decode_key_block_key_value_byte_string(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[192] = { + 0x42, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0xB8, + 0x42, 0x00, 0x42, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x45, 0x08, 0x00, 0x00, 0x00, 0x18, + 0x1F, 0xA6, 0x8B, 0x0A, 0x81, 0x12, 0xB4, 0x47, + 0xAE, 0xF3, 0x4B, 0xD8, 0xFB, 0x5A, 0x7B, 0x82, + 0x9D, 0x3E, 0x86, 0x23, 0x71, 0xD2, 0xCF, 0xE5, + 0x42, 0x00, 0x28, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x2A, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x46, 0x01, 0x00, 0x00, 0x00, 0x60, + 0x42, 0x00, 0x9E, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x36, 0x01, 0x00, 0x00, 0x00, 0x48, + 0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, + 0x31, 0x30, 0x30, 0x31, 0x38, 0x32, 0x64, 0x35, + 0x2D, 0x37, 0x32, 0x62, 0x38, 0x2D, 0x34, 0x37, + 0x61, 0x61, 0x2D, 0x38, 0x33, 0x38, 0x33, 0x2D, + 0x34, 0x64, 0x39, 0x37, 0x64, 0x35, 0x31, 0x32, + 0x65, 0x39, 0x38, 0x61, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x2B, 0x01, 0x00, 0x00, 0x00, 0x10, + 0x42, 0x00, 0x11, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00 + }; + + struct kmip ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0); + + uint8 value[24] = { + 0x1F, 0xA6, 0x8B, 0x0A, 0x81, 0x12, 0xB4, 0x47, + 0xAE, 0xF3, 0x4B, 0xD8, 0xFB, 0x5A, 0x7B, 0x82, + 0x9D, 0x3E, 0x86, 0x23, 0x71, 0xD2, 0xCF, 0xE5 + }; + struct byte_string key = {0}; + key.value = value; + key.size = ARRAY_LENGTH(value); + + struct text_string uuid = {0}; + uuid.value = "100182d5-72b8-47aa-8383-4d97d512e98a"; + uuid.size = 36; + + struct cryptographic_parameters cp = {0}; + kmip_init_cryptographic_parameters(&cp); + + cp.block_cipher_mode = KMIP_BLOCK_NIST_KEY_WRAP; + + struct encryption_key_information eki = {0}; + eki.unique_identifier = &uuid; + eki.cryptographic_parameters = &cp; + + struct key_wrapping_data kwd = {0}; + kwd.wrapping_method = KMIP_WRAP_ENCRYPT; + kwd.encryption_key_info = &eki; + + struct key_block expected = {0}; + kmip_init_key_block(&expected); + + expected.key_format_type = KMIP_KEYFORMAT_RAW; + expected.key_value = &key; + expected.key_value_type = KMIP_TYPE_BYTE_STRING; + expected.cryptographic_algorithm = KMIP_CRYPTOALG_AES; + expected.cryptographic_length = 128; + expected.key_wrapping_data = &kwd; + + struct key_block observed = {0}; + kmip_init_key_block(&observed); + + int result = kmip_decode_key_block(&ctx, &observed); + result = report_decoding_test_result( + tracker, + &ctx, + kmip_compare_key_block(&expected, &observed), + result, + __func__); + kmip_free_key_block(&ctx, &observed); + kmip_destroy(&ctx); + return(result); +} + +int +test_encode_key_block_key_value_structure(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[88] = { + 0x42, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x50, + 0x42, 0x00, 0x42, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x45, 0x01, 0x00, 0x00, 0x00, 0x18, + 0x42, 0x00, 0x43, 0x08, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x42, 0x00, 0x28, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x2A, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 observed[88] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0); + + uint8 value[16] = { + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF + }; + struct byte_string key = {0}; + key.value = value; + key.size = ARRAY_LENGTH(value); + + struct key_value kv = {0}; + kv.key_material = &key; + + struct key_block kb = {0}; + kb.key_format_type = KMIP_KEYFORMAT_RAW; + kb.key_value = &kv; + kb.cryptographic_algorithm = KMIP_CRYPTOALG_AES; + kb.cryptographic_length = 128; + + int result = kmip_encode_key_block(&ctx, &kb); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_decode_key_block_key_value_structure(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[88] = { + 0x42, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x50, + 0x42, 0x00, 0x42, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x45, 0x01, 0x00, 0x00, 0x00, 0x18, + 0x42, 0x00, 0x43, 0x08, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x42, 0x00, 0x28, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x2A, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00 + }; + + struct kmip ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0); + + uint8 value[16] = { + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF + }; + struct byte_string key = {0}; + key.value = value; + key.size = ARRAY_LENGTH(value); + + struct key_value kv = {0}; + kv.key_material = &key; + + struct key_block expected = {0}; + kmip_init_key_block(&expected); + + expected.key_format_type = KMIP_KEYFORMAT_RAW; + expected.key_value = &kv; + expected.key_value_type = KMIP_TYPE_STRUCTURE; + expected.cryptographic_algorithm = KMIP_CRYPTOALG_AES; + expected.cryptographic_length = 128; + + struct key_block observed = {0}; + kmip_init_key_block(&observed); + + int result = kmip_decode_key_block(&ctx, &observed); + result = report_decoding_test_result( + tracker, + &ctx, + kmip_compare_key_block(&expected, &observed), + result, + __func__); + kmip_free_key_block(&ctx, &observed); + kmip_destroy(&ctx); + return(result); +} + +int +test_encode_symmetric_key(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[96] = { + 0x42, 0x00, 0x8F, 0x01, 0x00, 0x00, 0x00, 0x58, + 0x42, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x50, + 0x42, 0x00, 0x42, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x45, 0x01, 0x00, 0x00, 0x00, 0x18, + 0x42, 0x00, 0x43, 0x08, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x42, 0x00, 0x28, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x2A, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 observed[96] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0); + + uint8 value[16] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F + }; + struct byte_string key = {0}; + key.value = value; + key.size = ARRAY_LENGTH(value); + + struct key_value kv = {0}; + kv.key_material = &key; + + struct key_block kb = {0}; + kb.key_format_type = KMIP_KEYFORMAT_RAW; + kb.key_value = &kv; + kb.cryptographic_algorithm = KMIP_CRYPTOALG_AES; + kb.cryptographic_length = 128; + + struct symmetric_key sk = {0}; + sk.key_block = &kb; + + int result = kmip_encode_symmetric_key(&ctx, &sk); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_decode_symmetric_key(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[96] = { + 0x42, 0x00, 0x8F, 0x01, 0x00, 0x00, 0x00, 0x58, + 0x42, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x50, + 0x42, 0x00, 0x42, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x45, 0x01, 0x00, 0x00, 0x00, 0x18, + 0x42, 0x00, 0x43, 0x08, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x42, 0x00, 0x28, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x2A, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00 + }; + + struct kmip ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0); + + uint8 value[16] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F + }; + struct byte_string key = {0}; + key.value = value; + key.size = ARRAY_LENGTH(value); + + struct key_value kv = {0}; + kv.key_material = &key; + + struct key_block kb = {0}; + kb.key_format_type = KMIP_KEYFORMAT_RAW; + kb.key_value = &kv; + kb.key_value_type = KMIP_TYPE_STRUCTURE; + kb.cryptographic_algorithm = KMIP_CRYPTOALG_AES; + kb.cryptographic_length = 128; + + struct symmetric_key expected = {0}; + expected.key_block = &kb; + + struct symmetric_key observed = {0}; + + int result = kmip_decode_symmetric_key(&ctx, &observed); + result = report_decoding_test_result( + tracker, + &ctx, + kmip_compare_symmetric_key(&expected, &observed), + result, + __func__); + kmip_free_symmetric_key(&ctx, &observed); + kmip_destroy(&ctx); + return(result); +} + +int +test_encode_public_key(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[248] = { + 0x42, 0x00, 0x6D, 0x01, 0x00, 0x00, 0x00, 0xF0, + 0x42, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0xE8, + 0x42, 0x00, 0x42, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x45, 0x01, 0x00, 0x00, 0x00, 0xB0, + 0x42, 0x00, 0x43, 0x08, 0x00, 0x00, 0x00, 0xA2, + 0x30, 0x81, 0x9F, 0x30, 0x0D, 0x06, 0x09, 0x2A, + 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, + 0x05, 0x00, 0x03, 0x81, 0x8D, 0x00, 0x30, 0x81, + 0x89, 0x02, 0x81, 0x81, 0x00, 0x93, 0x04, 0x51, + 0xC9, 0xEC, 0xD9, 0x4F, 0x5B, 0xB9, 0xDA, 0x17, + 0xDD, 0x09, 0x38, 0x1B, 0xD2, 0x3B, 0xE4, 0x3E, + 0xCA, 0x8C, 0x75, 0x39, 0xF3, 0x01, 0xFC, 0x8A, + 0x8C, 0xD5, 0xD5, 0x27, 0x4C, 0x3E, 0x76, 0x99, + 0xDB, 0xDC, 0x71, 0x1C, 0x97, 0xA7, 0xAA, 0x91, + 0xE2, 0xC5, 0x0A, 0x82, 0xBD, 0x0B, 0x10, 0x34, + 0xF0, 0xDF, 0x49, 0x3D, 0xEC, 0x16, 0x36, 0x24, + 0x27, 0xE5, 0x8A, 0xCC, 0xE7, 0xF6, 0xCE, 0x0F, + 0x9B, 0xCC, 0x61, 0x7B, 0xBD, 0x8C, 0x90, 0xD0, + 0x09, 0x4A, 0x27, 0x03, 0xBA, 0x0D, 0x09, 0xEB, + 0x19, 0xD1, 0x00, 0x5F, 0x2F, 0xB2, 0x65, 0x52, + 0x6A, 0xAC, 0x75, 0xAF, 0x32, 0xF8, 0xBC, 0x78, + 0x2C, 0xDE, 0xD2, 0xA5, 0x7F, 0x81, 0x1E, 0x03, + 0xEA, 0xF6, 0x7A, 0x94, 0x4D, 0xE5, 0xE7, 0x84, + 0x13, 0xDC, 0xA8, 0xF2, 0x32, 0xD0, 0x74, 0xE6, + 0xDC, 0xEA, 0x4C, 0xEC, 0x9F, 0x02, 0x03, 0x01, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x28, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x2A, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 observed[248] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0); + + uint8 value[162] = { + 0x30, 0x81, 0x9F, 0x30, 0x0D, 0x06, 0x09, 0x2A, + 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, + 0x05, 0x00, 0x03, 0x81, 0x8D, 0x00, 0x30, 0x81, + 0x89, 0x02, 0x81, 0x81, 0x00, 0x93, 0x04, 0x51, + 0xC9, 0xEC, 0xD9, 0x4F, 0x5B, 0xB9, 0xDA, 0x17, + 0xDD, 0x09, 0x38, 0x1B, 0xD2, 0x3B, 0xE4, 0x3E, + 0xCA, 0x8C, 0x75, 0x39, 0xF3, 0x01, 0xFC, 0x8A, + 0x8C, 0xD5, 0xD5, 0x27, 0x4C, 0x3E, 0x76, 0x99, + 0xDB, 0xDC, 0x71, 0x1C, 0x97, 0xA7, 0xAA, 0x91, + 0xE2, 0xC5, 0x0A, 0x82, 0xBD, 0x0B, 0x10, 0x34, + 0xF0, 0xDF, 0x49, 0x3D, 0xEC, 0x16, 0x36, 0x24, + 0x27, 0xE5, 0x8A, 0xCC, 0xE7, 0xF6, 0xCE, 0x0F, + 0x9B, 0xCC, 0x61, 0x7B, 0xBD, 0x8C, 0x90, 0xD0, + 0x09, 0x4A, 0x27, 0x03, 0xBA, 0x0D, 0x09, 0xEB, + 0x19, 0xD1, 0x00, 0x5F, 0x2F, 0xB2, 0x65, 0x52, + 0x6A, 0xAC, 0x75, 0xAF, 0x32, 0xF8, 0xBC, 0x78, + 0x2C, 0xDE, 0xD2, 0xA5, 0x7F, 0x81, 0x1E, 0x03, + 0xEA, 0xF6, 0x7A, 0x94, 0x4D, 0xE5, 0xE7, 0x84, + 0x13, 0xDC, 0xA8, 0xF2, 0x32, 0xD0, 0x74, 0xE6, + 0xDC, 0xEA, 0x4C, 0xEC, 0x9F, 0x02, 0x03, 0x01, + 0x00, 0x01 + }; + struct byte_string key = {0}; + key.value = value; + key.size = ARRAY_LENGTH(value); + + struct key_value kv = {0}; + kv.key_material = &key; + + struct key_block kb = {0}; + kb.key_format_type = KMIP_KEYFORMAT_X509; + kb.key_value = &kv; + kb.cryptographic_algorithm = KMIP_CRYPTOALG_RSA; + kb.cryptographic_length = 1024; + + struct public_key pk = {0}; + pk.key_block = &kb; + + int result = kmip_encode_public_key(&ctx, &pk); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_decode_public_key(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[248] = { + 0x42, 0x00, 0x6D, 0x01, 0x00, 0x00, 0x00, 0xF0, + 0x42, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0xE8, + 0x42, 0x00, 0x42, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x45, 0x01, 0x00, 0x00, 0x00, 0xB0, + 0x42, 0x00, 0x43, 0x08, 0x00, 0x00, 0x00, 0xA2, + 0x30, 0x81, 0x9F, 0x30, 0x0D, 0x06, 0x09, 0x2A, + 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, + 0x05, 0x00, 0x03, 0x81, 0x8D, 0x00, 0x30, 0x81, + 0x89, 0x02, 0x81, 0x81, 0x00, 0x93, 0x04, 0x51, + 0xC9, 0xEC, 0xD9, 0x4F, 0x5B, 0xB9, 0xDA, 0x17, + 0xDD, 0x09, 0x38, 0x1B, 0xD2, 0x3B, 0xE4, 0x3E, + 0xCA, 0x8C, 0x75, 0x39, 0xF3, 0x01, 0xFC, 0x8A, + 0x8C, 0xD5, 0xD5, 0x27, 0x4C, 0x3E, 0x76, 0x99, + 0xDB, 0xDC, 0x71, 0x1C, 0x97, 0xA7, 0xAA, 0x91, + 0xE2, 0xC5, 0x0A, 0x82, 0xBD, 0x0B, 0x10, 0x34, + 0xF0, 0xDF, 0x49, 0x3D, 0xEC, 0x16, 0x36, 0x24, + 0x27, 0xE5, 0x8A, 0xCC, 0xE7, 0xF6, 0xCE, 0x0F, + 0x9B, 0xCC, 0x61, 0x7B, 0xBD, 0x8C, 0x90, 0xD0, + 0x09, 0x4A, 0x27, 0x03, 0xBA, 0x0D, 0x09, 0xEB, + 0x19, 0xD1, 0x00, 0x5F, 0x2F, 0xB2, 0x65, 0x52, + 0x6A, 0xAC, 0x75, 0xAF, 0x32, 0xF8, 0xBC, 0x78, + 0x2C, 0xDE, 0xD2, 0xA5, 0x7F, 0x81, 0x1E, 0x03, + 0xEA, 0xF6, 0x7A, 0x94, 0x4D, 0xE5, 0xE7, 0x84, + 0x13, 0xDC, 0xA8, 0xF2, 0x32, 0xD0, 0x74, 0xE6, + 0xDC, 0xEA, 0x4C, 0xEC, 0x9F, 0x02, 0x03, 0x01, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x28, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x2A, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + struct kmip ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0); + + uint8 value[162] = { + 0x30, 0x81, 0x9F, 0x30, 0x0D, 0x06, 0x09, 0x2A, + 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, + 0x05, 0x00, 0x03, 0x81, 0x8D, 0x00, 0x30, 0x81, + 0x89, 0x02, 0x81, 0x81, 0x00, 0x93, 0x04, 0x51, + 0xC9, 0xEC, 0xD9, 0x4F, 0x5B, 0xB9, 0xDA, 0x17, + 0xDD, 0x09, 0x38, 0x1B, 0xD2, 0x3B, 0xE4, 0x3E, + 0xCA, 0x8C, 0x75, 0x39, 0xF3, 0x01, 0xFC, 0x8A, + 0x8C, 0xD5, 0xD5, 0x27, 0x4C, 0x3E, 0x76, 0x99, + 0xDB, 0xDC, 0x71, 0x1C, 0x97, 0xA7, 0xAA, 0x91, + 0xE2, 0xC5, 0x0A, 0x82, 0xBD, 0x0B, 0x10, 0x34, + 0xF0, 0xDF, 0x49, 0x3D, 0xEC, 0x16, 0x36, 0x24, + 0x27, 0xE5, 0x8A, 0xCC, 0xE7, 0xF6, 0xCE, 0x0F, + 0x9B, 0xCC, 0x61, 0x7B, 0xBD, 0x8C, 0x90, 0xD0, + 0x09, 0x4A, 0x27, 0x03, 0xBA, 0x0D, 0x09, 0xEB, + 0x19, 0xD1, 0x00, 0x5F, 0x2F, 0xB2, 0x65, 0x52, + 0x6A, 0xAC, 0x75, 0xAF, 0x32, 0xF8, 0xBC, 0x78, + 0x2C, 0xDE, 0xD2, 0xA5, 0x7F, 0x81, 0x1E, 0x03, + 0xEA, 0xF6, 0x7A, 0x94, 0x4D, 0xE5, 0xE7, 0x84, + 0x13, 0xDC, 0xA8, 0xF2, 0x32, 0xD0, 0x74, 0xE6, + 0xDC, 0xEA, 0x4C, 0xEC, 0x9F, 0x02, 0x03, 0x01, + 0x00, 0x01 + }; + struct byte_string key = {0}; + key.value = value; + key.size = ARRAY_LENGTH(value); + + struct key_value kv = {0}; + kv.key_material = &key; + + struct key_block kb = {0}; + kb.key_format_type = KMIP_KEYFORMAT_X509; + kb.key_value = &kv; + kb.key_value_type = KMIP_TYPE_STRUCTURE; + kb.cryptographic_algorithm = KMIP_CRYPTOALG_RSA; + kb.cryptographic_length = 1024; + + struct public_key expected = {0}; + expected.key_block = &kb; + + struct public_key observed = {0}; + + int result = kmip_decode_public_key(&ctx, &observed); + result = report_decoding_test_result( + tracker, + &ctx, + kmip_compare_public_key(&expected, &observed), + result, + __func__); + kmip_free_public_key(&ctx, &observed); + kmip_destroy(&ctx); + return(result); +} + +int +test_encode_private_key(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[1280] = { + 0x42, 0x00, 0x64, 0x01, 0x00, 0x00, 0x04, 0xF8, + 0x42, 0x00, 0x40, 0x01, 0x00, 0x00, 0x04, 0xF0, + 0x42, 0x00, 0x42, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x45, 0x01, 0x00, 0x00, 0x04, 0xB8, + 0x42, 0x00, 0x43, 0x08, 0x00, 0x00, 0x04, 0xA9, + 0x30, 0x82, 0x04, 0xA5, 0x02, 0x01, 0x00, 0x02, + 0x82, 0x01, 0x01, 0x00, 0xAB, 0x7F, 0x16, 0x1C, + 0x00, 0x42, 0x49, 0x6C, 0xCD, 0x6C, 0x6D, 0x4D, + 0xAD, 0xB9, 0x19, 0x97, 0x34, 0x35, 0x35, 0x77, + 0x76, 0x00, 0x3A, 0xCF, 0x54, 0xB7, 0xAF, 0x1E, + 0x44, 0x0A, 0xFB, 0x80, 0xB6, 0x4A, 0x87, 0x55, + 0xF8, 0x00, 0x2C, 0xFE, 0xBA, 0x6B, 0x18, 0x45, + 0x40, 0xA2, 0xD6, 0x60, 0x86, 0xD7, 0x46, 0x48, + 0x34, 0x6D, 0x75, 0xB8, 0xD7, 0x18, 0x12, 0xB2, + 0x05, 0x38, 0x7C, 0x0F, 0x65, 0x83, 0xBC, 0x4D, + 0x7D, 0xC7, 0xEC, 0x11, 0x4F, 0x3B, 0x17, 0x6B, + 0x79, 0x57, 0xC4, 0x22, 0xE7, 0xD0, 0x3F, 0xC6, + 0x26, 0x7F, 0xA2, 0xA6, 0xF8, 0x9B, 0x9B, 0xEE, + 0x9E, 0x60, 0xA1, 0xD7, 0xC2, 0xD8, 0x33, 0xE5, + 0xA5, 0xF4, 0xBB, 0x0B, 0x14, 0x34, 0xF4, 0xE7, + 0x95, 0xA4, 0x11, 0x00, 0xF8, 0xAA, 0x21, 0x49, + 0x00, 0xDF, 0x8B, 0x65, 0x08, 0x9F, 0x98, 0x13, + 0x5B, 0x1C, 0x67, 0xB7, 0x01, 0x67, 0x5A, 0xBD, + 0xBC, 0x7D, 0x57, 0x21, 0xAA, 0xC9, 0xD1, 0x4A, + 0x7F, 0x08, 0x1F, 0xCE, 0xC8, 0x0B, 0x64, 0xE8, + 0xA0, 0xEC, 0xC8, 0x29, 0x53, 0x53, 0xC7, 0x95, + 0x32, 0x8A, 0xBF, 0x70, 0xE1, 0xB4, 0x2E, 0x7B, + 0xB8, 0xB7, 0xF4, 0xE8, 0xAC, 0x8C, 0x81, 0x0C, + 0xDB, 0x66, 0xE3, 0xD2, 0x11, 0x26, 0xEB, 0xA8, + 0xDA, 0x7D, 0x0C, 0xA3, 0x41, 0x42, 0xCB, 0x76, + 0xF9, 0x1F, 0x01, 0x3D, 0xA8, 0x09, 0xE9, 0xC1, + 0xB7, 0xAE, 0x64, 0xC5, 0x41, 0x30, 0xFB, 0xC2, + 0x1D, 0x80, 0xE9, 0xC2, 0xCB, 0x06, 0xC5, 0xC8, + 0xD7, 0xCC, 0xE8, 0x94, 0x6A, 0x9A, 0xC9, 0x9B, + 0x1C, 0x28, 0x15, 0xC3, 0x61, 0x2A, 0x29, 0xA8, + 0x2D, 0x73, 0xA1, 0xF9, 0x93, 0x74, 0xFE, 0x30, + 0xE5, 0x49, 0x51, 0x66, 0x2A, 0x6E, 0xDA, 0x29, + 0xC6, 0xFC, 0x41, 0x13, 0x35, 0xD5, 0xDC, 0x74, + 0x26, 0xB0, 0xF6, 0x05, 0x02, 0x03, 0x01, 0x00, + 0x01, 0x02, 0x82, 0x01, 0x00, 0x3B, 0x12, 0x45, + 0x5D, 0x53, 0xC1, 0x81, 0x65, 0x16, 0xC5, 0x18, + 0x49, 0x3F, 0x63, 0x98, 0xAA, 0xFA, 0x72, 0xB1, + 0x7D, 0xFA, 0x89, 0x4D, 0xB8, 0x88, 0xA7, 0xD4, + 0x8C, 0x0A, 0x47, 0xF6, 0x25, 0x79, 0xA4, 0xE6, + 0x44, 0xF8, 0x6D, 0xA7, 0x11, 0xFE, 0xC8, 0x50, + 0xCD, 0xD9, 0xDB, 0xBD, 0x17, 0xF6, 0x9A, 0x44, + 0x3D, 0x2E, 0xC1, 0xDD, 0x60, 0xD3, 0xC6, 0x18, + 0xFA, 0x74, 0xCD, 0xE5, 0xFD, 0xAF, 0xAB, 0xD6, + 0xBA, 0xA2, 0x6E, 0xB0, 0xA3, 0xAD, 0xB4, 0xDE, + 0xF6, 0x48, 0x0F, 0xB1, 0x21, 0x8C, 0xD3, 0xB0, + 0x83, 0xE2, 0x52, 0xE8, 0x85, 0xB6, 0xF0, 0x72, + 0x9F, 0x98, 0xB2, 0x14, 0x4D, 0x2B, 0x72, 0x29, + 0x3E, 0x1B, 0x11, 0xD7, 0x33, 0x93, 0xBC, 0x41, + 0xF7, 0x5B, 0x15, 0xEE, 0x3D, 0x75, 0x69, 0xB4, + 0x99, 0x5E, 0xD1, 0xA1, 0x44, 0x25, 0xDA, 0x43, + 0x19, 0xB7, 0xB2, 0x6B, 0x0E, 0x8F, 0xEF, 0x17, + 0xC3, 0x75, 0x42, 0xAE, 0x5C, 0x6D, 0x58, 0x49, + 0xF8, 0x72, 0x09, 0x56, 0x7F, 0x39, 0x25, 0xA4, + 0x7B, 0x01, 0x6D, 0x56, 0x48, 0x59, 0x71, 0x7B, + 0xC5, 0x7F, 0xCB, 0x45, 0x22, 0xD0, 0xAA, 0x49, + 0xCE, 0x81, 0x6E, 0x5B, 0xE7, 0xB3, 0x08, 0x81, + 0x93, 0x23, 0x6E, 0xC9, 0xEF, 0xFF, 0x14, 0x08, + 0x58, 0x04, 0x5B, 0x73, 0xC5, 0xD7, 0x9B, 0xAF, + 0x38, 0xF7, 0xC6, 0x7F, 0x04, 0xC5, 0xDC, 0xF0, + 0xE3, 0x80, 0x6A, 0xD9, 0x82, 0xD1, 0x25, 0x90, + 0x58, 0xC3, 0x47, 0x3E, 0x84, 0x71, 0x79, 0xA8, + 0x78, 0xF2, 0xC6, 0xB3, 0xBD, 0x96, 0x8F, 0xB9, + 0x9E, 0xA4, 0x6E, 0x91, 0x85, 0x89, 0x2F, 0x36, + 0x76, 0xE7, 0x89, 0x65, 0xC2, 0xAE, 0xD4, 0x87, + 0x7B, 0xA3, 0x91, 0x7D, 0xF0, 0x7C, 0x5E, 0x92, + 0x74, 0x74, 0xF1, 0x9E, 0x76, 0x4B, 0xA6, 0x1D, + 0xC3, 0x8D, 0x63, 0xBF, 0x29, 0x02, 0x81, 0x81, + 0x00, 0xD5, 0xC6, 0x9C, 0x8C, 0x3C, 0xDC, 0x24, + 0x64, 0x74, 0x4A, 0x79, 0x37, 0x13, 0xDA, 0xFB, + 0x9F, 0x1D, 0xBC, 0x79, 0x9F, 0xF9, 0x64, 0x23, + 0xFE, 0xCD, 0x3C, 0xBA, 0x79, 0x42, 0x86, 0xBC, + 0xE9, 0x20, 0xF4, 0xB5, 0xC1, 0x83, 0xF9, 0x9E, + 0xE9, 0x02, 0x8D, 0xB6, 0x21, 0x2C, 0x62, 0x77, + 0xC4, 0xC8, 0x29, 0x7F, 0xCF, 0xBC, 0xE7, 0xF7, + 0xC2, 0x4C, 0xA4, 0xC5, 0x1F, 0xC7, 0x18, 0x2F, + 0xB8, 0xF4, 0x01, 0x9F, 0xB1, 0xD5, 0x65, 0x96, + 0x74, 0xC5, 0xCB, 0xE6, 0xD5, 0xFA, 0x99, 0x20, + 0x51, 0x34, 0x17, 0x60, 0xCD, 0x00, 0x73, 0x57, + 0x29, 0xA0, 0x70, 0xA9, 0xE5, 0x4D, 0x34, 0x2B, + 0xEB, 0xA8, 0xEF, 0x47, 0xEE, 0x82, 0xD3, 0xA0, + 0x1B, 0x04, 0xCE, 0xC4, 0xA0, 0x0D, 0x4D, 0xDB, + 0x41, 0xE3, 0x51, 0x16, 0xFC, 0x22, 0x1E, 0x85, + 0x4B, 0x43, 0xA6, 0x96, 0xC0, 0xE6, 0x41, 0x9B, + 0x1B, 0x02, 0x81, 0x81, 0x00, 0xCD, 0x5E, 0xA7, + 0x70, 0x27, 0x89, 0x06, 0x4B, 0x67, 0x35, 0x40, + 0xCB, 0xFF, 0x09, 0x35, 0x6A, 0xD8, 0x0B, 0xC3, + 0xD5, 0x92, 0x81, 0x2E, 0xBA, 0x47, 0x61, 0x0B, + 0x9F, 0xAC, 0x6A, 0xEC, 0xEF, 0xE2, 0x2A, 0xCA, + 0xE4, 0x38, 0x45, 0x9C, 0xDA, 0x74, 0xE5, 0x96, + 0x53, 0xD8, 0x8C, 0x04, 0x18, 0x9D, 0x34, 0x39, + 0x9B, 0xF5, 0xB1, 0x4B, 0x92, 0x0E, 0x34, 0xEF, + 0x38, 0xA7, 0xD0, 0x9F, 0xE6, 0x95, 0x93, 0x39, + 0x6E, 0x8F, 0xE7, 0x35, 0xE6, 0xF0, 0xA6, 0xAE, + 0x49, 0x90, 0x40, 0x10, 0x41, 0xD8, 0xA4, 0x06, + 0xB6, 0xFD, 0x86, 0xA1, 0x16, 0x1E, 0x45, 0xF9, + 0x5A, 0x3E, 0xAA, 0x5C, 0x10, 0x12, 0xE6, 0x66, + 0x2E, 0x44, 0xF1, 0x5F, 0x33, 0x5A, 0xC9, 0x71, + 0xE1, 0x76, 0x6B, 0x2B, 0xB9, 0xC9, 0x85, 0x10, + 0x99, 0x74, 0x14, 0x1B, 0x44, 0xD3, 0x7E, 0x1E, + 0x31, 0x98, 0x20, 0xA5, 0x5F, 0x02, 0x81, 0x81, + 0x00, 0xB2, 0x87, 0x12, 0x37, 0xBF, 0x9F, 0xAD, + 0x38, 0xC3, 0x31, 0x6A, 0xB7, 0x87, 0x7A, 0x6A, + 0x86, 0x80, 0x63, 0xE5, 0x42, 0xA7, 0x18, 0x6D, + 0x43, 0x1E, 0x8D, 0x27, 0xC1, 0x9A, 0xC0, 0x41, + 0x45, 0x84, 0x03, 0x39, 0x42, 0xE9, 0xFF, 0x6E, + 0x29, 0x73, 0xBB, 0x7B, 0x2D, 0x8B, 0x0E, 0x94, + 0xAD, 0x1E, 0xE8, 0x21, 0x58, 0x10, 0x8F, 0xBC, + 0x86, 0x64, 0x51, 0x7A, 0x5A, 0x46, 0x7F, 0xB9, + 0x63, 0x01, 0x4B, 0xD5, 0xDC, 0xC2, 0xB4, 0xFB, + 0x08, 0x7C, 0x23, 0x03, 0x9D, 0x11, 0x92, 0x0D, + 0xBE, 0x22, 0xFD, 0x9F, 0x16, 0xB4, 0xD8, 0x9E, + 0x23, 0x22, 0x5C, 0xD4, 0x55, 0xAD, 0xBA, 0xF3, + 0x2E, 0xF4, 0x3F, 0x18, 0x58, 0x64, 0xA3, 0x6D, + 0x63, 0x03, 0x09, 0xD6, 0x85, 0x3F, 0x77, 0x14, + 0xB3, 0x9A, 0xAE, 0x1E, 0xBE, 0xE3, 0x93, 0x8F, + 0x87, 0xC2, 0x70, 0x7E, 0x17, 0x8C, 0x73, 0x9F, + 0x9F, 0x02, 0x81, 0x81, 0x00, 0x96, 0x90, 0xBE, + 0xD1, 0x4B, 0x2A, 0xFA, 0xA2, 0x6D, 0x98, 0x6D, + 0x59, 0x22, 0x31, 0xEE, 0x27, 0xD7, 0x1D, 0x49, + 0x06, 0x5B, 0xD2, 0xBA, 0x1F, 0x78, 0x15, 0x7E, + 0x20, 0x22, 0x98, 0x81, 0xFD, 0x9D, 0x23, 0x22, + 0x7D, 0x0F, 0x84, 0x79, 0xEA, 0xEF, 0xA9, 0x22, + 0xFD, 0x75, 0xD5, 0xB1, 0x6B, 0x1A, 0x56, 0x1F, + 0xA6, 0x68, 0x0B, 0x04, 0x0C, 0xA0, 0xBD, 0xCE, + 0x65, 0x0B, 0x23, 0xB9, 0x17, 0xA4, 0xB1, 0xBB, + 0x79, 0x83, 0xA7, 0x4F, 0xAD, 0x70, 0xE1, 0xC3, + 0x05, 0xCB, 0xEC, 0x2B, 0xFF, 0x1A, 0x85, 0xA7, + 0x26, 0xA1, 0xD9, 0x02, 0x60, 0xE4, 0xF1, 0x08, + 0x4F, 0x51, 0x82, 0x34, 0xDC, 0xD3, 0xFE, 0x77, + 0x0B, 0x95, 0x20, 0x21, 0x5B, 0xD5, 0x43, 0xBB, + 0x6A, 0x41, 0x17, 0x71, 0x87, 0x54, 0x67, 0x6A, + 0x34, 0x17, 0x16, 0x66, 0xA7, 0x9F, 0x26, 0xE7, + 0x9C, 0x14, 0x9C, 0x5A, 0xA1, 0x02, 0x81, 0x81, + 0x00, 0xA0, 0xC9, 0x85, 0xA0, 0xA0, 0xA7, 0x91, + 0xA6, 0x59, 0xF9, 0x97, 0x31, 0x13, 0x4C, 0x44, + 0xF3, 0x7B, 0x2E, 0x52, 0x0A, 0x2C, 0xEA, 0x35, + 0x80, 0x0A, 0xD2, 0x72, 0x41, 0xED, 0x36, 0x0D, + 0xFD, 0xE6, 0xE8, 0xCA, 0x61, 0x4F, 0x12, 0x04, + 0x7F, 0xD0, 0x8B, 0x76, 0xAC, 0x4D, 0x13, 0xC0, + 0x56, 0xA0, 0x69, 0x9E, 0x2F, 0x98, 0xA1, 0xCA, + 0xC9, 0x10, 0x11, 0x29, 0x4D, 0x71, 0x20, 0x8F, + 0x4A, 0xBA, 0xB3, 0x3B, 0xA8, 0x7A, 0xA0, 0x51, + 0x7F, 0x41, 0x5B, 0xAC, 0xA8, 0x8D, 0x6B, 0xAC, + 0x00, 0x60, 0x88, 0xFA, 0x60, 0x1D, 0x34, 0x94, + 0x17, 0xE1, 0xF0, 0xC9, 0xB2, 0x3A, 0xFF, 0xA4, + 0xD4, 0x96, 0x61, 0x8D, 0xBC, 0x02, 0x49, 0x86, + 0xED, 0x69, 0x0B, 0xBB, 0x7B, 0x02, 0x57, 0x68, + 0xFF, 0x9D, 0xF8, 0xAC, 0x15, 0x41, 0x6F, 0x48, + 0x9F, 0x81, 0x29, 0xC3, 0x23, 0x41, 0xA8, 0xB4, + 0x4F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x28, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x2A, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 observed[1280] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0); + + uint8 value[1193] = { + 0x30, 0x82, 0x04, 0xA5, 0x02, 0x01, 0x00, 0x02, + 0x82, 0x01, 0x01, 0x00, 0xAB, 0x7F, 0x16, 0x1C, + 0x00, 0x42, 0x49, 0x6C, 0xCD, 0x6C, 0x6D, 0x4D, + 0xAD, 0xB9, 0x19, 0x97, 0x34, 0x35, 0x35, 0x77, + 0x76, 0x00, 0x3A, 0xCF, 0x54, 0xB7, 0xAF, 0x1E, + 0x44, 0x0A, 0xFB, 0x80, 0xB6, 0x4A, 0x87, 0x55, + 0xF8, 0x00, 0x2C, 0xFE, 0xBA, 0x6B, 0x18, 0x45, + 0x40, 0xA2, 0xD6, 0x60, 0x86, 0xD7, 0x46, 0x48, + 0x34, 0x6D, 0x75, 0xB8, 0xD7, 0x18, 0x12, 0xB2, + 0x05, 0x38, 0x7C, 0x0F, 0x65, 0x83, 0xBC, 0x4D, + 0x7D, 0xC7, 0xEC, 0x11, 0x4F, 0x3B, 0x17, 0x6B, + 0x79, 0x57, 0xC4, 0x22, 0xE7, 0xD0, 0x3F, 0xC6, + 0x26, 0x7F, 0xA2, 0xA6, 0xF8, 0x9B, 0x9B, 0xEE, + 0x9E, 0x60, 0xA1, 0xD7, 0xC2, 0xD8, 0x33, 0xE5, + 0xA5, 0xF4, 0xBB, 0x0B, 0x14, 0x34, 0xF4, 0xE7, + 0x95, 0xA4, 0x11, 0x00, 0xF8, 0xAA, 0x21, 0x49, + 0x00, 0xDF, 0x8B, 0x65, 0x08, 0x9F, 0x98, 0x13, + 0x5B, 0x1C, 0x67, 0xB7, 0x01, 0x67, 0x5A, 0xBD, + 0xBC, 0x7D, 0x57, 0x21, 0xAA, 0xC9, 0xD1, 0x4A, + 0x7F, 0x08, 0x1F, 0xCE, 0xC8, 0x0B, 0x64, 0xE8, + 0xA0, 0xEC, 0xC8, 0x29, 0x53, 0x53, 0xC7, 0x95, + 0x32, 0x8A, 0xBF, 0x70, 0xE1, 0xB4, 0x2E, 0x7B, + 0xB8, 0xB7, 0xF4, 0xE8, 0xAC, 0x8C, 0x81, 0x0C, + 0xDB, 0x66, 0xE3, 0xD2, 0x11, 0x26, 0xEB, 0xA8, + 0xDA, 0x7D, 0x0C, 0xA3, 0x41, 0x42, 0xCB, 0x76, + 0xF9, 0x1F, 0x01, 0x3D, 0xA8, 0x09, 0xE9, 0xC1, + 0xB7, 0xAE, 0x64, 0xC5, 0x41, 0x30, 0xFB, 0xC2, + 0x1D, 0x80, 0xE9, 0xC2, 0xCB, 0x06, 0xC5, 0xC8, + 0xD7, 0xCC, 0xE8, 0x94, 0x6A, 0x9A, 0xC9, 0x9B, + 0x1C, 0x28, 0x15, 0xC3, 0x61, 0x2A, 0x29, 0xA8, + 0x2D, 0x73, 0xA1, 0xF9, 0x93, 0x74, 0xFE, 0x30, + 0xE5, 0x49, 0x51, 0x66, 0x2A, 0x6E, 0xDA, 0x29, + 0xC6, 0xFC, 0x41, 0x13, 0x35, 0xD5, 0xDC, 0x74, + 0x26, 0xB0, 0xF6, 0x05, 0x02, 0x03, 0x01, 0x00, + 0x01, 0x02, 0x82, 0x01, 0x00, 0x3B, 0x12, 0x45, + 0x5D, 0x53, 0xC1, 0x81, 0x65, 0x16, 0xC5, 0x18, + 0x49, 0x3F, 0x63, 0x98, 0xAA, 0xFA, 0x72, 0xB1, + 0x7D, 0xFA, 0x89, 0x4D, 0xB8, 0x88, 0xA7, 0xD4, + 0x8C, 0x0A, 0x47, 0xF6, 0x25, 0x79, 0xA4, 0xE6, + 0x44, 0xF8, 0x6D, 0xA7, 0x11, 0xFE, 0xC8, 0x50, + 0xCD, 0xD9, 0xDB, 0xBD, 0x17, 0xF6, 0x9A, 0x44, + 0x3D, 0x2E, 0xC1, 0xDD, 0x60, 0xD3, 0xC6, 0x18, + 0xFA, 0x74, 0xCD, 0xE5, 0xFD, 0xAF, 0xAB, 0xD6, + 0xBA, 0xA2, 0x6E, 0xB0, 0xA3, 0xAD, 0xB4, 0xDE, + 0xF6, 0x48, 0x0F, 0xB1, 0x21, 0x8C, 0xD3, 0xB0, + 0x83, 0xE2, 0x52, 0xE8, 0x85, 0xB6, 0xF0, 0x72, + 0x9F, 0x98, 0xB2, 0x14, 0x4D, 0x2B, 0x72, 0x29, + 0x3E, 0x1B, 0x11, 0xD7, 0x33, 0x93, 0xBC, 0x41, + 0xF7, 0x5B, 0x15, 0xEE, 0x3D, 0x75, 0x69, 0xB4, + 0x99, 0x5E, 0xD1, 0xA1, 0x44, 0x25, 0xDA, 0x43, + 0x19, 0xB7, 0xB2, 0x6B, 0x0E, 0x8F, 0xEF, 0x17, + 0xC3, 0x75, 0x42, 0xAE, 0x5C, 0x6D, 0x58, 0x49, + 0xF8, 0x72, 0x09, 0x56, 0x7F, 0x39, 0x25, 0xA4, + 0x7B, 0x01, 0x6D, 0x56, 0x48, 0x59, 0x71, 0x7B, + 0xC5, 0x7F, 0xCB, 0x45, 0x22, 0xD0, 0xAA, 0x49, + 0xCE, 0x81, 0x6E, 0x5B, 0xE7, 0xB3, 0x08, 0x81, + 0x93, 0x23, 0x6E, 0xC9, 0xEF, 0xFF, 0x14, 0x08, + 0x58, 0x04, 0x5B, 0x73, 0xC5, 0xD7, 0x9B, 0xAF, + 0x38, 0xF7, 0xC6, 0x7F, 0x04, 0xC5, 0xDC, 0xF0, + 0xE3, 0x80, 0x6A, 0xD9, 0x82, 0xD1, 0x25, 0x90, + 0x58, 0xC3, 0x47, 0x3E, 0x84, 0x71, 0x79, 0xA8, + 0x78, 0xF2, 0xC6, 0xB3, 0xBD, 0x96, 0x8F, 0xB9, + 0x9E, 0xA4, 0x6E, 0x91, 0x85, 0x89, 0x2F, 0x36, + 0x76, 0xE7, 0x89, 0x65, 0xC2, 0xAE, 0xD4, 0x87, + 0x7B, 0xA3, 0x91, 0x7D, 0xF0, 0x7C, 0x5E, 0x92, + 0x74, 0x74, 0xF1, 0x9E, 0x76, 0x4B, 0xA6, 0x1D, + 0xC3, 0x8D, 0x63, 0xBF, 0x29, 0x02, 0x81, 0x81, + 0x00, 0xD5, 0xC6, 0x9C, 0x8C, 0x3C, 0xDC, 0x24, + 0x64, 0x74, 0x4A, 0x79, 0x37, 0x13, 0xDA, 0xFB, + 0x9F, 0x1D, 0xBC, 0x79, 0x9F, 0xF9, 0x64, 0x23, + 0xFE, 0xCD, 0x3C, 0xBA, 0x79, 0x42, 0x86, 0xBC, + 0xE9, 0x20, 0xF4, 0xB5, 0xC1, 0x83, 0xF9, 0x9E, + 0xE9, 0x02, 0x8D, 0xB6, 0x21, 0x2C, 0x62, 0x77, + 0xC4, 0xC8, 0x29, 0x7F, 0xCF, 0xBC, 0xE7, 0xF7, + 0xC2, 0x4C, 0xA4, 0xC5, 0x1F, 0xC7, 0x18, 0x2F, + 0xB8, 0xF4, 0x01, 0x9F, 0xB1, 0xD5, 0x65, 0x96, + 0x74, 0xC5, 0xCB, 0xE6, 0xD5, 0xFA, 0x99, 0x20, + 0x51, 0x34, 0x17, 0x60, 0xCD, 0x00, 0x73, 0x57, + 0x29, 0xA0, 0x70, 0xA9, 0xE5, 0x4D, 0x34, 0x2B, + 0xEB, 0xA8, 0xEF, 0x47, 0xEE, 0x82, 0xD3, 0xA0, + 0x1B, 0x04, 0xCE, 0xC4, 0xA0, 0x0D, 0x4D, 0xDB, + 0x41, 0xE3, 0x51, 0x16, 0xFC, 0x22, 0x1E, 0x85, + 0x4B, 0x43, 0xA6, 0x96, 0xC0, 0xE6, 0x41, 0x9B, + 0x1B, 0x02, 0x81, 0x81, 0x00, 0xCD, 0x5E, 0xA7, + 0x70, 0x27, 0x89, 0x06, 0x4B, 0x67, 0x35, 0x40, + 0xCB, 0xFF, 0x09, 0x35, 0x6A, 0xD8, 0x0B, 0xC3, + 0xD5, 0x92, 0x81, 0x2E, 0xBA, 0x47, 0x61, 0x0B, + 0x9F, 0xAC, 0x6A, 0xEC, 0xEF, 0xE2, 0x2A, 0xCA, + 0xE4, 0x38, 0x45, 0x9C, 0xDA, 0x74, 0xE5, 0x96, + 0x53, 0xD8, 0x8C, 0x04, 0x18, 0x9D, 0x34, 0x39, + 0x9B, 0xF5, 0xB1, 0x4B, 0x92, 0x0E, 0x34, 0xEF, + 0x38, 0xA7, 0xD0, 0x9F, 0xE6, 0x95, 0x93, 0x39, + 0x6E, 0x8F, 0xE7, 0x35, 0xE6, 0xF0, 0xA6, 0xAE, + 0x49, 0x90, 0x40, 0x10, 0x41, 0xD8, 0xA4, 0x06, + 0xB6, 0xFD, 0x86, 0xA1, 0x16, 0x1E, 0x45, 0xF9, + 0x5A, 0x3E, 0xAA, 0x5C, 0x10, 0x12, 0xE6, 0x66, + 0x2E, 0x44, 0xF1, 0x5F, 0x33, 0x5A, 0xC9, 0x71, + 0xE1, 0x76, 0x6B, 0x2B, 0xB9, 0xC9, 0x85, 0x10, + 0x99, 0x74, 0x14, 0x1B, 0x44, 0xD3, 0x7E, 0x1E, + 0x31, 0x98, 0x20, 0xA5, 0x5F, 0x02, 0x81, 0x81, + 0x00, 0xB2, 0x87, 0x12, 0x37, 0xBF, 0x9F, 0xAD, + 0x38, 0xC3, 0x31, 0x6A, 0xB7, 0x87, 0x7A, 0x6A, + 0x86, 0x80, 0x63, 0xE5, 0x42, 0xA7, 0x18, 0x6D, + 0x43, 0x1E, 0x8D, 0x27, 0xC1, 0x9A, 0xC0, 0x41, + 0x45, 0x84, 0x03, 0x39, 0x42, 0xE9, 0xFF, 0x6E, + 0x29, 0x73, 0xBB, 0x7B, 0x2D, 0x8B, 0x0E, 0x94, + 0xAD, 0x1E, 0xE8, 0x21, 0x58, 0x10, 0x8F, 0xBC, + 0x86, 0x64, 0x51, 0x7A, 0x5A, 0x46, 0x7F, 0xB9, + 0x63, 0x01, 0x4B, 0xD5, 0xDC, 0xC2, 0xB4, 0xFB, + 0x08, 0x7C, 0x23, 0x03, 0x9D, 0x11, 0x92, 0x0D, + 0xBE, 0x22, 0xFD, 0x9F, 0x16, 0xB4, 0xD8, 0x9E, + 0x23, 0x22, 0x5C, 0xD4, 0x55, 0xAD, 0xBA, 0xF3, + 0x2E, 0xF4, 0x3F, 0x18, 0x58, 0x64, 0xA3, 0x6D, + 0x63, 0x03, 0x09, 0xD6, 0x85, 0x3F, 0x77, 0x14, + 0xB3, 0x9A, 0xAE, 0x1E, 0xBE, 0xE3, 0x93, 0x8F, + 0x87, 0xC2, 0x70, 0x7E, 0x17, 0x8C, 0x73, 0x9F, + 0x9F, 0x02, 0x81, 0x81, 0x00, 0x96, 0x90, 0xBE, + 0xD1, 0x4B, 0x2A, 0xFA, 0xA2, 0x6D, 0x98, 0x6D, + 0x59, 0x22, 0x31, 0xEE, 0x27, 0xD7, 0x1D, 0x49, + 0x06, 0x5B, 0xD2, 0xBA, 0x1F, 0x78, 0x15, 0x7E, + 0x20, 0x22, 0x98, 0x81, 0xFD, 0x9D, 0x23, 0x22, + 0x7D, 0x0F, 0x84, 0x79, 0xEA, 0xEF, 0xA9, 0x22, + 0xFD, 0x75, 0xD5, 0xB1, 0x6B, 0x1A, 0x56, 0x1F, + 0xA6, 0x68, 0x0B, 0x04, 0x0C, 0xA0, 0xBD, 0xCE, + 0x65, 0x0B, 0x23, 0xB9, 0x17, 0xA4, 0xB1, 0xBB, + 0x79, 0x83, 0xA7, 0x4F, 0xAD, 0x70, 0xE1, 0xC3, + 0x05, 0xCB, 0xEC, 0x2B, 0xFF, 0x1A, 0x85, 0xA7, + 0x26, 0xA1, 0xD9, 0x02, 0x60, 0xE4, 0xF1, 0x08, + 0x4F, 0x51, 0x82, 0x34, 0xDC, 0xD3, 0xFE, 0x77, + 0x0B, 0x95, 0x20, 0x21, 0x5B, 0xD5, 0x43, 0xBB, + 0x6A, 0x41, 0x17, 0x71, 0x87, 0x54, 0x67, 0x6A, + 0x34, 0x17, 0x16, 0x66, 0xA7, 0x9F, 0x26, 0xE7, + 0x9C, 0x14, 0x9C, 0x5A, 0xA1, 0x02, 0x81, 0x81, + 0x00, 0xA0, 0xC9, 0x85, 0xA0, 0xA0, 0xA7, 0x91, + 0xA6, 0x59, 0xF9, 0x97, 0x31, 0x13, 0x4C, 0x44, + 0xF3, 0x7B, 0x2E, 0x52, 0x0A, 0x2C, 0xEA, 0x35, + 0x80, 0x0A, 0xD2, 0x72, 0x41, 0xED, 0x36, 0x0D, + 0xFD, 0xE6, 0xE8, 0xCA, 0x61, 0x4F, 0x12, 0x04, + 0x7F, 0xD0, 0x8B, 0x76, 0xAC, 0x4D, 0x13, 0xC0, + 0x56, 0xA0, 0x69, 0x9E, 0x2F, 0x98, 0xA1, 0xCA, + 0xC9, 0x10, 0x11, 0x29, 0x4D, 0x71, 0x20, 0x8F, + 0x4A, 0xBA, 0xB3, 0x3B, 0xA8, 0x7A, 0xA0, 0x51, + 0x7F, 0x41, 0x5B, 0xAC, 0xA8, 0x8D, 0x6B, 0xAC, + 0x00, 0x60, 0x88, 0xFA, 0x60, 0x1D, 0x34, 0x94, + 0x17, 0xE1, 0xF0, 0xC9, 0xB2, 0x3A, 0xFF, 0xA4, + 0xD4, 0x96, 0x61, 0x8D, 0xBC, 0x02, 0x49, 0x86, + 0xED, 0x69, 0x0B, 0xBB, 0x7B, 0x02, 0x57, 0x68, + 0xFF, 0x9D, 0xF8, 0xAC, 0x15, 0x41, 0x6F, 0x48, + 0x9F, 0x81, 0x29, 0xC3, 0x23, 0x41, 0xA8, 0xB4, + 0x4F + }; + struct byte_string key = {0}; + key.value = value; + key.size = ARRAY_LENGTH(value); + + struct key_value kv = {0}; + kv.key_material = &key; + + struct key_block kb = {0}; + kb.key_format_type = KMIP_KEYFORMAT_PKCS1; + kb.key_value = &kv; + kb.cryptographic_algorithm = KMIP_CRYPTOALG_RSA; + kb.cryptographic_length = 2048; + + struct private_key pk = {0}; + pk.key_block = &kb; + + int result = kmip_encode_private_key(&ctx, &pk); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_decode_private_key(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[1280] = { + 0x42, 0x00, 0x64, 0x01, 0x00, 0x00, 0x04, 0xF8, + 0x42, 0x00, 0x40, 0x01, 0x00, 0x00, 0x04, 0xF0, + 0x42, 0x00, 0x42, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x45, 0x01, 0x00, 0x00, 0x04, 0xB8, + 0x42, 0x00, 0x43, 0x08, 0x00, 0x00, 0x04, 0xA9, + 0x30, 0x82, 0x04, 0xA5, 0x02, 0x01, 0x00, 0x02, + 0x82, 0x01, 0x01, 0x00, 0xAB, 0x7F, 0x16, 0x1C, + 0x00, 0x42, 0x49, 0x6C, 0xCD, 0x6C, 0x6D, 0x4D, + 0xAD, 0xB9, 0x19, 0x97, 0x34, 0x35, 0x35, 0x77, + 0x76, 0x00, 0x3A, 0xCF, 0x54, 0xB7, 0xAF, 0x1E, + 0x44, 0x0A, 0xFB, 0x80, 0xB6, 0x4A, 0x87, 0x55, + 0xF8, 0x00, 0x2C, 0xFE, 0xBA, 0x6B, 0x18, 0x45, + 0x40, 0xA2, 0xD6, 0x60, 0x86, 0xD7, 0x46, 0x48, + 0x34, 0x6D, 0x75, 0xB8, 0xD7, 0x18, 0x12, 0xB2, + 0x05, 0x38, 0x7C, 0x0F, 0x65, 0x83, 0xBC, 0x4D, + 0x7D, 0xC7, 0xEC, 0x11, 0x4F, 0x3B, 0x17, 0x6B, + 0x79, 0x57, 0xC4, 0x22, 0xE7, 0xD0, 0x3F, 0xC6, + 0x26, 0x7F, 0xA2, 0xA6, 0xF8, 0x9B, 0x9B, 0xEE, + 0x9E, 0x60, 0xA1, 0xD7, 0xC2, 0xD8, 0x33, 0xE5, + 0xA5, 0xF4, 0xBB, 0x0B, 0x14, 0x34, 0xF4, 0xE7, + 0x95, 0xA4, 0x11, 0x00, 0xF8, 0xAA, 0x21, 0x49, + 0x00, 0xDF, 0x8B, 0x65, 0x08, 0x9F, 0x98, 0x13, + 0x5B, 0x1C, 0x67, 0xB7, 0x01, 0x67, 0x5A, 0xBD, + 0xBC, 0x7D, 0x57, 0x21, 0xAA, 0xC9, 0xD1, 0x4A, + 0x7F, 0x08, 0x1F, 0xCE, 0xC8, 0x0B, 0x64, 0xE8, + 0xA0, 0xEC, 0xC8, 0x29, 0x53, 0x53, 0xC7, 0x95, + 0x32, 0x8A, 0xBF, 0x70, 0xE1, 0xB4, 0x2E, 0x7B, + 0xB8, 0xB7, 0xF4, 0xE8, 0xAC, 0x8C, 0x81, 0x0C, + 0xDB, 0x66, 0xE3, 0xD2, 0x11, 0x26, 0xEB, 0xA8, + 0xDA, 0x7D, 0x0C, 0xA3, 0x41, 0x42, 0xCB, 0x76, + 0xF9, 0x1F, 0x01, 0x3D, 0xA8, 0x09, 0xE9, 0xC1, + 0xB7, 0xAE, 0x64, 0xC5, 0x41, 0x30, 0xFB, 0xC2, + 0x1D, 0x80, 0xE9, 0xC2, 0xCB, 0x06, 0xC5, 0xC8, + 0xD7, 0xCC, 0xE8, 0x94, 0x6A, 0x9A, 0xC9, 0x9B, + 0x1C, 0x28, 0x15, 0xC3, 0x61, 0x2A, 0x29, 0xA8, + 0x2D, 0x73, 0xA1, 0xF9, 0x93, 0x74, 0xFE, 0x30, + 0xE5, 0x49, 0x51, 0x66, 0x2A, 0x6E, 0xDA, 0x29, + 0xC6, 0xFC, 0x41, 0x13, 0x35, 0xD5, 0xDC, 0x74, + 0x26, 0xB0, 0xF6, 0x05, 0x02, 0x03, 0x01, 0x00, + 0x01, 0x02, 0x82, 0x01, 0x00, 0x3B, 0x12, 0x45, + 0x5D, 0x53, 0xC1, 0x81, 0x65, 0x16, 0xC5, 0x18, + 0x49, 0x3F, 0x63, 0x98, 0xAA, 0xFA, 0x72, 0xB1, + 0x7D, 0xFA, 0x89, 0x4D, 0xB8, 0x88, 0xA7, 0xD4, + 0x8C, 0x0A, 0x47, 0xF6, 0x25, 0x79, 0xA4, 0xE6, + 0x44, 0xF8, 0x6D, 0xA7, 0x11, 0xFE, 0xC8, 0x50, + 0xCD, 0xD9, 0xDB, 0xBD, 0x17, 0xF6, 0x9A, 0x44, + 0x3D, 0x2E, 0xC1, 0xDD, 0x60, 0xD3, 0xC6, 0x18, + 0xFA, 0x74, 0xCD, 0xE5, 0xFD, 0xAF, 0xAB, 0xD6, + 0xBA, 0xA2, 0x6E, 0xB0, 0xA3, 0xAD, 0xB4, 0xDE, + 0xF6, 0x48, 0x0F, 0xB1, 0x21, 0x8C, 0xD3, 0xB0, + 0x83, 0xE2, 0x52, 0xE8, 0x85, 0xB6, 0xF0, 0x72, + 0x9F, 0x98, 0xB2, 0x14, 0x4D, 0x2B, 0x72, 0x29, + 0x3E, 0x1B, 0x11, 0xD7, 0x33, 0x93, 0xBC, 0x41, + 0xF7, 0x5B, 0x15, 0xEE, 0x3D, 0x75, 0x69, 0xB4, + 0x99, 0x5E, 0xD1, 0xA1, 0x44, 0x25, 0xDA, 0x43, + 0x19, 0xB7, 0xB2, 0x6B, 0x0E, 0x8F, 0xEF, 0x17, + 0xC3, 0x75, 0x42, 0xAE, 0x5C, 0x6D, 0x58, 0x49, + 0xF8, 0x72, 0x09, 0x56, 0x7F, 0x39, 0x25, 0xA4, + 0x7B, 0x01, 0x6D, 0x56, 0x48, 0x59, 0x71, 0x7B, + 0xC5, 0x7F, 0xCB, 0x45, 0x22, 0xD0, 0xAA, 0x49, + 0xCE, 0x81, 0x6E, 0x5B, 0xE7, 0xB3, 0x08, 0x81, + 0x93, 0x23, 0x6E, 0xC9, 0xEF, 0xFF, 0x14, 0x08, + 0x58, 0x04, 0x5B, 0x73, 0xC5, 0xD7, 0x9B, 0xAF, + 0x38, 0xF7, 0xC6, 0x7F, 0x04, 0xC5, 0xDC, 0xF0, + 0xE3, 0x80, 0x6A, 0xD9, 0x82, 0xD1, 0x25, 0x90, + 0x58, 0xC3, 0x47, 0x3E, 0x84, 0x71, 0x79, 0xA8, + 0x78, 0xF2, 0xC6, 0xB3, 0xBD, 0x96, 0x8F, 0xB9, + 0x9E, 0xA4, 0x6E, 0x91, 0x85, 0x89, 0x2F, 0x36, + 0x76, 0xE7, 0x89, 0x65, 0xC2, 0xAE, 0xD4, 0x87, + 0x7B, 0xA3, 0x91, 0x7D, 0xF0, 0x7C, 0x5E, 0x92, + 0x74, 0x74, 0xF1, 0x9E, 0x76, 0x4B, 0xA6, 0x1D, + 0xC3, 0x8D, 0x63, 0xBF, 0x29, 0x02, 0x81, 0x81, + 0x00, 0xD5, 0xC6, 0x9C, 0x8C, 0x3C, 0xDC, 0x24, + 0x64, 0x74, 0x4A, 0x79, 0x37, 0x13, 0xDA, 0xFB, + 0x9F, 0x1D, 0xBC, 0x79, 0x9F, 0xF9, 0x64, 0x23, + 0xFE, 0xCD, 0x3C, 0xBA, 0x79, 0x42, 0x86, 0xBC, + 0xE9, 0x20, 0xF4, 0xB5, 0xC1, 0x83, 0xF9, 0x9E, + 0xE9, 0x02, 0x8D, 0xB6, 0x21, 0x2C, 0x62, 0x77, + 0xC4, 0xC8, 0x29, 0x7F, 0xCF, 0xBC, 0xE7, 0xF7, + 0xC2, 0x4C, 0xA4, 0xC5, 0x1F, 0xC7, 0x18, 0x2F, + 0xB8, 0xF4, 0x01, 0x9F, 0xB1, 0xD5, 0x65, 0x96, + 0x74, 0xC5, 0xCB, 0xE6, 0xD5, 0xFA, 0x99, 0x20, + 0x51, 0x34, 0x17, 0x60, 0xCD, 0x00, 0x73, 0x57, + 0x29, 0xA0, 0x70, 0xA9, 0xE5, 0x4D, 0x34, 0x2B, + 0xEB, 0xA8, 0xEF, 0x47, 0xEE, 0x82, 0xD3, 0xA0, + 0x1B, 0x04, 0xCE, 0xC4, 0xA0, 0x0D, 0x4D, 0xDB, + 0x41, 0xE3, 0x51, 0x16, 0xFC, 0x22, 0x1E, 0x85, + 0x4B, 0x43, 0xA6, 0x96, 0xC0, 0xE6, 0x41, 0x9B, + 0x1B, 0x02, 0x81, 0x81, 0x00, 0xCD, 0x5E, 0xA7, + 0x70, 0x27, 0x89, 0x06, 0x4B, 0x67, 0x35, 0x40, + 0xCB, 0xFF, 0x09, 0x35, 0x6A, 0xD8, 0x0B, 0xC3, + 0xD5, 0x92, 0x81, 0x2E, 0xBA, 0x47, 0x61, 0x0B, + 0x9F, 0xAC, 0x6A, 0xEC, 0xEF, 0xE2, 0x2A, 0xCA, + 0xE4, 0x38, 0x45, 0x9C, 0xDA, 0x74, 0xE5, 0x96, + 0x53, 0xD8, 0x8C, 0x04, 0x18, 0x9D, 0x34, 0x39, + 0x9B, 0xF5, 0xB1, 0x4B, 0x92, 0x0E, 0x34, 0xEF, + 0x38, 0xA7, 0xD0, 0x9F, 0xE6, 0x95, 0x93, 0x39, + 0x6E, 0x8F, 0xE7, 0x35, 0xE6, 0xF0, 0xA6, 0xAE, + 0x49, 0x90, 0x40, 0x10, 0x41, 0xD8, 0xA4, 0x06, + 0xB6, 0xFD, 0x86, 0xA1, 0x16, 0x1E, 0x45, 0xF9, + 0x5A, 0x3E, 0xAA, 0x5C, 0x10, 0x12, 0xE6, 0x66, + 0x2E, 0x44, 0xF1, 0x5F, 0x33, 0x5A, 0xC9, 0x71, + 0xE1, 0x76, 0x6B, 0x2B, 0xB9, 0xC9, 0x85, 0x10, + 0x99, 0x74, 0x14, 0x1B, 0x44, 0xD3, 0x7E, 0x1E, + 0x31, 0x98, 0x20, 0xA5, 0x5F, 0x02, 0x81, 0x81, + 0x00, 0xB2, 0x87, 0x12, 0x37, 0xBF, 0x9F, 0xAD, + 0x38, 0xC3, 0x31, 0x6A, 0xB7, 0x87, 0x7A, 0x6A, + 0x86, 0x80, 0x63, 0xE5, 0x42, 0xA7, 0x18, 0x6D, + 0x43, 0x1E, 0x8D, 0x27, 0xC1, 0x9A, 0xC0, 0x41, + 0x45, 0x84, 0x03, 0x39, 0x42, 0xE9, 0xFF, 0x6E, + 0x29, 0x73, 0xBB, 0x7B, 0x2D, 0x8B, 0x0E, 0x94, + 0xAD, 0x1E, 0xE8, 0x21, 0x58, 0x10, 0x8F, 0xBC, + 0x86, 0x64, 0x51, 0x7A, 0x5A, 0x46, 0x7F, 0xB9, + 0x63, 0x01, 0x4B, 0xD5, 0xDC, 0xC2, 0xB4, 0xFB, + 0x08, 0x7C, 0x23, 0x03, 0x9D, 0x11, 0x92, 0x0D, + 0xBE, 0x22, 0xFD, 0x9F, 0x16, 0xB4, 0xD8, 0x9E, + 0x23, 0x22, 0x5C, 0xD4, 0x55, 0xAD, 0xBA, 0xF3, + 0x2E, 0xF4, 0x3F, 0x18, 0x58, 0x64, 0xA3, 0x6D, + 0x63, 0x03, 0x09, 0xD6, 0x85, 0x3F, 0x77, 0x14, + 0xB3, 0x9A, 0xAE, 0x1E, 0xBE, 0xE3, 0x93, 0x8F, + 0x87, 0xC2, 0x70, 0x7E, 0x17, 0x8C, 0x73, 0x9F, + 0x9F, 0x02, 0x81, 0x81, 0x00, 0x96, 0x90, 0xBE, + 0xD1, 0x4B, 0x2A, 0xFA, 0xA2, 0x6D, 0x98, 0x6D, + 0x59, 0x22, 0x31, 0xEE, 0x27, 0xD7, 0x1D, 0x49, + 0x06, 0x5B, 0xD2, 0xBA, 0x1F, 0x78, 0x15, 0x7E, + 0x20, 0x22, 0x98, 0x81, 0xFD, 0x9D, 0x23, 0x22, + 0x7D, 0x0F, 0x84, 0x79, 0xEA, 0xEF, 0xA9, 0x22, + 0xFD, 0x75, 0xD5, 0xB1, 0x6B, 0x1A, 0x56, 0x1F, + 0xA6, 0x68, 0x0B, 0x04, 0x0C, 0xA0, 0xBD, 0xCE, + 0x65, 0x0B, 0x23, 0xB9, 0x17, 0xA4, 0xB1, 0xBB, + 0x79, 0x83, 0xA7, 0x4F, 0xAD, 0x70, 0xE1, 0xC3, + 0x05, 0xCB, 0xEC, 0x2B, 0xFF, 0x1A, 0x85, 0xA7, + 0x26, 0xA1, 0xD9, 0x02, 0x60, 0xE4, 0xF1, 0x08, + 0x4F, 0x51, 0x82, 0x34, 0xDC, 0xD3, 0xFE, 0x77, + 0x0B, 0x95, 0x20, 0x21, 0x5B, 0xD5, 0x43, 0xBB, + 0x6A, 0x41, 0x17, 0x71, 0x87, 0x54, 0x67, 0x6A, + 0x34, 0x17, 0x16, 0x66, 0xA7, 0x9F, 0x26, 0xE7, + 0x9C, 0x14, 0x9C, 0x5A, 0xA1, 0x02, 0x81, 0x81, + 0x00, 0xA0, 0xC9, 0x85, 0xA0, 0xA0, 0xA7, 0x91, + 0xA6, 0x59, 0xF9, 0x97, 0x31, 0x13, 0x4C, 0x44, + 0xF3, 0x7B, 0x2E, 0x52, 0x0A, 0x2C, 0xEA, 0x35, + 0x80, 0x0A, 0xD2, 0x72, 0x41, 0xED, 0x36, 0x0D, + 0xFD, 0xE6, 0xE8, 0xCA, 0x61, 0x4F, 0x12, 0x04, + 0x7F, 0xD0, 0x8B, 0x76, 0xAC, 0x4D, 0x13, 0xC0, + 0x56, 0xA0, 0x69, 0x9E, 0x2F, 0x98, 0xA1, 0xCA, + 0xC9, 0x10, 0x11, 0x29, 0x4D, 0x71, 0x20, 0x8F, + 0x4A, 0xBA, 0xB3, 0x3B, 0xA8, 0x7A, 0xA0, 0x51, + 0x7F, 0x41, 0x5B, 0xAC, 0xA8, 0x8D, 0x6B, 0xAC, + 0x00, 0x60, 0x88, 0xFA, 0x60, 0x1D, 0x34, 0x94, + 0x17, 0xE1, 0xF0, 0xC9, 0xB2, 0x3A, 0xFF, 0xA4, + 0xD4, 0x96, 0x61, 0x8D, 0xBC, 0x02, 0x49, 0x86, + 0xED, 0x69, 0x0B, 0xBB, 0x7B, 0x02, 0x57, 0x68, + 0xFF, 0x9D, 0xF8, 0xAC, 0x15, 0x41, 0x6F, 0x48, + 0x9F, 0x81, 0x29, 0xC3, 0x23, 0x41, 0xA8, 0xB4, + 0x4F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x28, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x2A, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + struct kmip ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0); + + uint8 value[1193] = { + 0x30, 0x82, 0x04, 0xA5, 0x02, 0x01, 0x00, 0x02, + 0x82, 0x01, 0x01, 0x00, 0xAB, 0x7F, 0x16, 0x1C, + 0x00, 0x42, 0x49, 0x6C, 0xCD, 0x6C, 0x6D, 0x4D, + 0xAD, 0xB9, 0x19, 0x97, 0x34, 0x35, 0x35, 0x77, + 0x76, 0x00, 0x3A, 0xCF, 0x54, 0xB7, 0xAF, 0x1E, + 0x44, 0x0A, 0xFB, 0x80, 0xB6, 0x4A, 0x87, 0x55, + 0xF8, 0x00, 0x2C, 0xFE, 0xBA, 0x6B, 0x18, 0x45, + 0x40, 0xA2, 0xD6, 0x60, 0x86, 0xD7, 0x46, 0x48, + 0x34, 0x6D, 0x75, 0xB8, 0xD7, 0x18, 0x12, 0xB2, + 0x05, 0x38, 0x7C, 0x0F, 0x65, 0x83, 0xBC, 0x4D, + 0x7D, 0xC7, 0xEC, 0x11, 0x4F, 0x3B, 0x17, 0x6B, + 0x79, 0x57, 0xC4, 0x22, 0xE7, 0xD0, 0x3F, 0xC6, + 0x26, 0x7F, 0xA2, 0xA6, 0xF8, 0x9B, 0x9B, 0xEE, + 0x9E, 0x60, 0xA1, 0xD7, 0xC2, 0xD8, 0x33, 0xE5, + 0xA5, 0xF4, 0xBB, 0x0B, 0x14, 0x34, 0xF4, 0xE7, + 0x95, 0xA4, 0x11, 0x00, 0xF8, 0xAA, 0x21, 0x49, + 0x00, 0xDF, 0x8B, 0x65, 0x08, 0x9F, 0x98, 0x13, + 0x5B, 0x1C, 0x67, 0xB7, 0x01, 0x67, 0x5A, 0xBD, + 0xBC, 0x7D, 0x57, 0x21, 0xAA, 0xC9, 0xD1, 0x4A, + 0x7F, 0x08, 0x1F, 0xCE, 0xC8, 0x0B, 0x64, 0xE8, + 0xA0, 0xEC, 0xC8, 0x29, 0x53, 0x53, 0xC7, 0x95, + 0x32, 0x8A, 0xBF, 0x70, 0xE1, 0xB4, 0x2E, 0x7B, + 0xB8, 0xB7, 0xF4, 0xE8, 0xAC, 0x8C, 0x81, 0x0C, + 0xDB, 0x66, 0xE3, 0xD2, 0x11, 0x26, 0xEB, 0xA8, + 0xDA, 0x7D, 0x0C, 0xA3, 0x41, 0x42, 0xCB, 0x76, + 0xF9, 0x1F, 0x01, 0x3D, 0xA8, 0x09, 0xE9, 0xC1, + 0xB7, 0xAE, 0x64, 0xC5, 0x41, 0x30, 0xFB, 0xC2, + 0x1D, 0x80, 0xE9, 0xC2, 0xCB, 0x06, 0xC5, 0xC8, + 0xD7, 0xCC, 0xE8, 0x94, 0x6A, 0x9A, 0xC9, 0x9B, + 0x1C, 0x28, 0x15, 0xC3, 0x61, 0x2A, 0x29, 0xA8, + 0x2D, 0x73, 0xA1, 0xF9, 0x93, 0x74, 0xFE, 0x30, + 0xE5, 0x49, 0x51, 0x66, 0x2A, 0x6E, 0xDA, 0x29, + 0xC6, 0xFC, 0x41, 0x13, 0x35, 0xD5, 0xDC, 0x74, + 0x26, 0xB0, 0xF6, 0x05, 0x02, 0x03, 0x01, 0x00, + 0x01, 0x02, 0x82, 0x01, 0x00, 0x3B, 0x12, 0x45, + 0x5D, 0x53, 0xC1, 0x81, 0x65, 0x16, 0xC5, 0x18, + 0x49, 0x3F, 0x63, 0x98, 0xAA, 0xFA, 0x72, 0xB1, + 0x7D, 0xFA, 0x89, 0x4D, 0xB8, 0x88, 0xA7, 0xD4, + 0x8C, 0x0A, 0x47, 0xF6, 0x25, 0x79, 0xA4, 0xE6, + 0x44, 0xF8, 0x6D, 0xA7, 0x11, 0xFE, 0xC8, 0x50, + 0xCD, 0xD9, 0xDB, 0xBD, 0x17, 0xF6, 0x9A, 0x44, + 0x3D, 0x2E, 0xC1, 0xDD, 0x60, 0xD3, 0xC6, 0x18, + 0xFA, 0x74, 0xCD, 0xE5, 0xFD, 0xAF, 0xAB, 0xD6, + 0xBA, 0xA2, 0x6E, 0xB0, 0xA3, 0xAD, 0xB4, 0xDE, + 0xF6, 0x48, 0x0F, 0xB1, 0x21, 0x8C, 0xD3, 0xB0, + 0x83, 0xE2, 0x52, 0xE8, 0x85, 0xB6, 0xF0, 0x72, + 0x9F, 0x98, 0xB2, 0x14, 0x4D, 0x2B, 0x72, 0x29, + 0x3E, 0x1B, 0x11, 0xD7, 0x33, 0x93, 0xBC, 0x41, + 0xF7, 0x5B, 0x15, 0xEE, 0x3D, 0x75, 0x69, 0xB4, + 0x99, 0x5E, 0xD1, 0xA1, 0x44, 0x25, 0xDA, 0x43, + 0x19, 0xB7, 0xB2, 0x6B, 0x0E, 0x8F, 0xEF, 0x17, + 0xC3, 0x75, 0x42, 0xAE, 0x5C, 0x6D, 0x58, 0x49, + 0xF8, 0x72, 0x09, 0x56, 0x7F, 0x39, 0x25, 0xA4, + 0x7B, 0x01, 0x6D, 0x56, 0x48, 0x59, 0x71, 0x7B, + 0xC5, 0x7F, 0xCB, 0x45, 0x22, 0xD0, 0xAA, 0x49, + 0xCE, 0x81, 0x6E, 0x5B, 0xE7, 0xB3, 0x08, 0x81, + 0x93, 0x23, 0x6E, 0xC9, 0xEF, 0xFF, 0x14, 0x08, + 0x58, 0x04, 0x5B, 0x73, 0xC5, 0xD7, 0x9B, 0xAF, + 0x38, 0xF7, 0xC6, 0x7F, 0x04, 0xC5, 0xDC, 0xF0, + 0xE3, 0x80, 0x6A, 0xD9, 0x82, 0xD1, 0x25, 0x90, + 0x58, 0xC3, 0x47, 0x3E, 0x84, 0x71, 0x79, 0xA8, + 0x78, 0xF2, 0xC6, 0xB3, 0xBD, 0x96, 0x8F, 0xB9, + 0x9E, 0xA4, 0x6E, 0x91, 0x85, 0x89, 0x2F, 0x36, + 0x76, 0xE7, 0x89, 0x65, 0xC2, 0xAE, 0xD4, 0x87, + 0x7B, 0xA3, 0x91, 0x7D, 0xF0, 0x7C, 0x5E, 0x92, + 0x74, 0x74, 0xF1, 0x9E, 0x76, 0x4B, 0xA6, 0x1D, + 0xC3, 0x8D, 0x63, 0xBF, 0x29, 0x02, 0x81, 0x81, + 0x00, 0xD5, 0xC6, 0x9C, 0x8C, 0x3C, 0xDC, 0x24, + 0x64, 0x74, 0x4A, 0x79, 0x37, 0x13, 0xDA, 0xFB, + 0x9F, 0x1D, 0xBC, 0x79, 0x9F, 0xF9, 0x64, 0x23, + 0xFE, 0xCD, 0x3C, 0xBA, 0x79, 0x42, 0x86, 0xBC, + 0xE9, 0x20, 0xF4, 0xB5, 0xC1, 0x83, 0xF9, 0x9E, + 0xE9, 0x02, 0x8D, 0xB6, 0x21, 0x2C, 0x62, 0x77, + 0xC4, 0xC8, 0x29, 0x7F, 0xCF, 0xBC, 0xE7, 0xF7, + 0xC2, 0x4C, 0xA4, 0xC5, 0x1F, 0xC7, 0x18, 0x2F, + 0xB8, 0xF4, 0x01, 0x9F, 0xB1, 0xD5, 0x65, 0x96, + 0x74, 0xC5, 0xCB, 0xE6, 0xD5, 0xFA, 0x99, 0x20, + 0x51, 0x34, 0x17, 0x60, 0xCD, 0x00, 0x73, 0x57, + 0x29, 0xA0, 0x70, 0xA9, 0xE5, 0x4D, 0x34, 0x2B, + 0xEB, 0xA8, 0xEF, 0x47, 0xEE, 0x82, 0xD3, 0xA0, + 0x1B, 0x04, 0xCE, 0xC4, 0xA0, 0x0D, 0x4D, 0xDB, + 0x41, 0xE3, 0x51, 0x16, 0xFC, 0x22, 0x1E, 0x85, + 0x4B, 0x43, 0xA6, 0x96, 0xC0, 0xE6, 0x41, 0x9B, + 0x1B, 0x02, 0x81, 0x81, 0x00, 0xCD, 0x5E, 0xA7, + 0x70, 0x27, 0x89, 0x06, 0x4B, 0x67, 0x35, 0x40, + 0xCB, 0xFF, 0x09, 0x35, 0x6A, 0xD8, 0x0B, 0xC3, + 0xD5, 0x92, 0x81, 0x2E, 0xBA, 0x47, 0x61, 0x0B, + 0x9F, 0xAC, 0x6A, 0xEC, 0xEF, 0xE2, 0x2A, 0xCA, + 0xE4, 0x38, 0x45, 0x9C, 0xDA, 0x74, 0xE5, 0x96, + 0x53, 0xD8, 0x8C, 0x04, 0x18, 0x9D, 0x34, 0x39, + 0x9B, 0xF5, 0xB1, 0x4B, 0x92, 0x0E, 0x34, 0xEF, + 0x38, 0xA7, 0xD0, 0x9F, 0xE6, 0x95, 0x93, 0x39, + 0x6E, 0x8F, 0xE7, 0x35, 0xE6, 0xF0, 0xA6, 0xAE, + 0x49, 0x90, 0x40, 0x10, 0x41, 0xD8, 0xA4, 0x06, + 0xB6, 0xFD, 0x86, 0xA1, 0x16, 0x1E, 0x45, 0xF9, + 0x5A, 0x3E, 0xAA, 0x5C, 0x10, 0x12, 0xE6, 0x66, + 0x2E, 0x44, 0xF1, 0x5F, 0x33, 0x5A, 0xC9, 0x71, + 0xE1, 0x76, 0x6B, 0x2B, 0xB9, 0xC9, 0x85, 0x10, + 0x99, 0x74, 0x14, 0x1B, 0x44, 0xD3, 0x7E, 0x1E, + 0x31, 0x98, 0x20, 0xA5, 0x5F, 0x02, 0x81, 0x81, + 0x00, 0xB2, 0x87, 0x12, 0x37, 0xBF, 0x9F, 0xAD, + 0x38, 0xC3, 0x31, 0x6A, 0xB7, 0x87, 0x7A, 0x6A, + 0x86, 0x80, 0x63, 0xE5, 0x42, 0xA7, 0x18, 0x6D, + 0x43, 0x1E, 0x8D, 0x27, 0xC1, 0x9A, 0xC0, 0x41, + 0x45, 0x84, 0x03, 0x39, 0x42, 0xE9, 0xFF, 0x6E, + 0x29, 0x73, 0xBB, 0x7B, 0x2D, 0x8B, 0x0E, 0x94, + 0xAD, 0x1E, 0xE8, 0x21, 0x58, 0x10, 0x8F, 0xBC, + 0x86, 0x64, 0x51, 0x7A, 0x5A, 0x46, 0x7F, 0xB9, + 0x63, 0x01, 0x4B, 0xD5, 0xDC, 0xC2, 0xB4, 0xFB, + 0x08, 0x7C, 0x23, 0x03, 0x9D, 0x11, 0x92, 0x0D, + 0xBE, 0x22, 0xFD, 0x9F, 0x16, 0xB4, 0xD8, 0x9E, + 0x23, 0x22, 0x5C, 0xD4, 0x55, 0xAD, 0xBA, 0xF3, + 0x2E, 0xF4, 0x3F, 0x18, 0x58, 0x64, 0xA3, 0x6D, + 0x63, 0x03, 0x09, 0xD6, 0x85, 0x3F, 0x77, 0x14, + 0xB3, 0x9A, 0xAE, 0x1E, 0xBE, 0xE3, 0x93, 0x8F, + 0x87, 0xC2, 0x70, 0x7E, 0x17, 0x8C, 0x73, 0x9F, + 0x9F, 0x02, 0x81, 0x81, 0x00, 0x96, 0x90, 0xBE, + 0xD1, 0x4B, 0x2A, 0xFA, 0xA2, 0x6D, 0x98, 0x6D, + 0x59, 0x22, 0x31, 0xEE, 0x27, 0xD7, 0x1D, 0x49, + 0x06, 0x5B, 0xD2, 0xBA, 0x1F, 0x78, 0x15, 0x7E, + 0x20, 0x22, 0x98, 0x81, 0xFD, 0x9D, 0x23, 0x22, + 0x7D, 0x0F, 0x84, 0x79, 0xEA, 0xEF, 0xA9, 0x22, + 0xFD, 0x75, 0xD5, 0xB1, 0x6B, 0x1A, 0x56, 0x1F, + 0xA6, 0x68, 0x0B, 0x04, 0x0C, 0xA0, 0xBD, 0xCE, + 0x65, 0x0B, 0x23, 0xB9, 0x17, 0xA4, 0xB1, 0xBB, + 0x79, 0x83, 0xA7, 0x4F, 0xAD, 0x70, 0xE1, 0xC3, + 0x05, 0xCB, 0xEC, 0x2B, 0xFF, 0x1A, 0x85, 0xA7, + 0x26, 0xA1, 0xD9, 0x02, 0x60, 0xE4, 0xF1, 0x08, + 0x4F, 0x51, 0x82, 0x34, 0xDC, 0xD3, 0xFE, 0x77, + 0x0B, 0x95, 0x20, 0x21, 0x5B, 0xD5, 0x43, 0xBB, + 0x6A, 0x41, 0x17, 0x71, 0x87, 0x54, 0x67, 0x6A, + 0x34, 0x17, 0x16, 0x66, 0xA7, 0x9F, 0x26, 0xE7, + 0x9C, 0x14, 0x9C, 0x5A, 0xA1, 0x02, 0x81, 0x81, + 0x00, 0xA0, 0xC9, 0x85, 0xA0, 0xA0, 0xA7, 0x91, + 0xA6, 0x59, 0xF9, 0x97, 0x31, 0x13, 0x4C, 0x44, + 0xF3, 0x7B, 0x2E, 0x52, 0x0A, 0x2C, 0xEA, 0x35, + 0x80, 0x0A, 0xD2, 0x72, 0x41, 0xED, 0x36, 0x0D, + 0xFD, 0xE6, 0xE8, 0xCA, 0x61, 0x4F, 0x12, 0x04, + 0x7F, 0xD0, 0x8B, 0x76, 0xAC, 0x4D, 0x13, 0xC0, + 0x56, 0xA0, 0x69, 0x9E, 0x2F, 0x98, 0xA1, 0xCA, + 0xC9, 0x10, 0x11, 0x29, 0x4D, 0x71, 0x20, 0x8F, + 0x4A, 0xBA, 0xB3, 0x3B, 0xA8, 0x7A, 0xA0, 0x51, + 0x7F, 0x41, 0x5B, 0xAC, 0xA8, 0x8D, 0x6B, 0xAC, + 0x00, 0x60, 0x88, 0xFA, 0x60, 0x1D, 0x34, 0x94, + 0x17, 0xE1, 0xF0, 0xC9, 0xB2, 0x3A, 0xFF, 0xA4, + 0xD4, 0x96, 0x61, 0x8D, 0xBC, 0x02, 0x49, 0x86, + 0xED, 0x69, 0x0B, 0xBB, 0x7B, 0x02, 0x57, 0x68, + 0xFF, 0x9D, 0xF8, 0xAC, 0x15, 0x41, 0x6F, 0x48, + 0x9F, 0x81, 0x29, 0xC3, 0x23, 0x41, 0xA8, 0xB4, + 0x4F + }; + struct byte_string key = {0}; + key.value = value; + key.size = ARRAY_LENGTH(value); + + struct key_value kv = {0}; + kv.key_material = &key; + + struct key_block kb = {0}; + kb.key_format_type = KMIP_KEYFORMAT_PKCS1; + kb.key_value = &kv; + kb.key_value_type = KMIP_TYPE_STRUCTURE; + kb.cryptographic_algorithm = KMIP_CRYPTOALG_RSA; + kb.cryptographic_length = 2048; + + struct private_key expected = {0}; + expected.key_block = &kb; + + struct private_key observed = {0}; + + int result = kmip_decode_private_key(&ctx, &observed); + result = report_decoding_test_result( + tracker, + &ctx, + kmip_compare_private_key(&expected, &observed), + result, + __func__); + kmip_free_private_key(&ctx, &observed); + kmip_destroy(&ctx); + return(result); +} + +int +test_encode_key_wrapping_specification(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[136] = { + 0x42, 0x00, 0x47, 0x01, 0x00, 0x00, 0x00, 0x80, + 0x42, 0x00, 0x9E, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x36, 0x01, 0x00, 0x00, 0x00, 0x48, + 0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, + 0x66, 0x34, 0x62, 0x32, 0x62, 0x34, 0x63, 0x33, + 0x2D, 0x34, 0x63, 0x31, 0x39, 0x2D, 0x34, 0x65, + 0x63, 0x66, 0x2D, 0x38, 0x32, 0x37, 0x61, 0x2D, + 0x30, 0x31, 0x31, 0x63, 0x61, 0x36, 0x30, 0x35, + 0x37, 0x64, 0x33, 0x65, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x2B, 0x01, 0x00, 0x00, 0x00, 0x10, + 0x42, 0x00, 0x11, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x18, + 0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x55, 0x73, + 0x61, 0x67, 0x65, 0x20, 0x4D, 0x61, 0x73, 0x6B + }; + + uint8 observed[136] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0); + + struct text_string uuid = {0}; + uuid.value = "f4b2b4c3-4c19-4ecf-827a-011ca6057d3e"; + uuid.size = 36; + + struct cryptographic_parameters cp = {0}; + cp.block_cipher_mode = KMIP_BLOCK_NIST_KEY_WRAP; + + struct encryption_key_information eki = {0}; + eki.unique_identifier = &uuid; + eki.cryptographic_parameters = &cp; + + struct text_string attribute_name = {0}; + attribute_name.value = "Cryptographic Usage Mask"; + attribute_name.size = 24; + + struct key_wrapping_specification kws = {0}; + kws.wrapping_method = KMIP_WRAP_ENCRYPT; + kws.encryption_key_info = &eki; + kws.attribute_names = &attribute_name; + kws.attribute_name_count = 1; + + int result = kmip_encode_key_wrapping_specification(&ctx, &kws); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_decode_key_wrapping_specification(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[136] = { + 0x42, 0x00, 0x47, 0x01, 0x00, 0x00, 0x00, 0x80, + 0x42, 0x00, 0x9E, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x36, 0x01, 0x00, 0x00, 0x00, 0x48, + 0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, + 0x66, 0x34, 0x62, 0x32, 0x62, 0x34, 0x63, 0x33, + 0x2D, 0x34, 0x63, 0x31, 0x39, 0x2D, 0x34, 0x65, + 0x63, 0x66, 0x2D, 0x38, 0x32, 0x37, 0x61, 0x2D, + 0x30, 0x31, 0x31, 0x63, 0x61, 0x36, 0x30, 0x35, + 0x37, 0x64, 0x33, 0x65, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x2B, 0x01, 0x00, 0x00, 0x00, 0x10, + 0x42, 0x00, 0x11, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x18, + 0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x55, 0x73, + 0x61, 0x67, 0x65, 0x20, 0x4D, 0x61, 0x73, 0x6B + }; + + struct kmip ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0); + + struct text_string uuid = {0}; + uuid.value = "f4b2b4c3-4c19-4ecf-827a-011ca6057d3e"; + uuid.size = 36; + + struct cryptographic_parameters cp = {0}; + kmip_init_cryptographic_parameters(&cp); + + cp.block_cipher_mode = KMIP_BLOCK_NIST_KEY_WRAP; + + struct encryption_key_information eki = {0}; + eki.unique_identifier = &uuid; + eki.cryptographic_parameters = &cp; + + struct text_string attribute_name = {0}; + attribute_name.value = "Cryptographic Usage Mask"; + attribute_name.size = 24; + + struct key_wrapping_specification expected = {0}; + expected.wrapping_method = KMIP_WRAP_ENCRYPT; + expected.encryption_key_info = &eki; + expected.attribute_names = &attribute_name; + expected.attribute_name_count = 1; + + struct key_wrapping_specification observed = {0}; + + int result = kmip_decode_key_wrapping_specification(&ctx, &observed); + result = report_decoding_test_result( + tracker, + &ctx, + kmip_compare_key_wrapping_specification(&expected, &observed), + result, + __func__); + kmip_free_key_wrapping_specification(&ctx, &observed); + kmip_destroy(&ctx); + return(result); +} + +int +test_encode_create_request_payload(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + /* This encoding matches the following set of values: + * Request Payload + * Object Type - Symmetric Key + * Template Attribute + * Attribute + * Attribute Name - Cryptographic Algorithm + * Attribute Value - AES + * Attribute + * Attribute Name - Cryptographic Length + * Attribute Value - 128 + * Attribute + * Attribute Name - Cryptographic Usage Mask + * Attribute Value - Encrypt | Decrypt + */ + uint8 expected[200] = { + 0x42, 0x00, 0x79, 0x01, 0x00, 0x00, 0x00, 0xC0, + 0x42, 0x00, 0x57, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x91, 0x01, 0x00, 0x00, 0x00, 0xA8, + 0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x17, + 0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x41, 0x6C, + 0x67, 0x6F, 0x72, 0x69, 0x74, 0x68, 0x6D, 0x00, + 0x42, 0x00, 0x0B, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x14, + 0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x4C, 0x65, + 0x6E, 0x67, 0x74, 0x68, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x18, + 0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x55, 0x73, + 0x61, 0x67, 0x65, 0x20, 0x4D, 0x61, 0x73, 0x6B, + 0x42, 0x00, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 observed[200] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0); + + struct attribute a[3] = {0}; + for(int i = 0; i < 3; i++) + { + kmip_init_attribute(&a[i]); + } + + enum cryptographic_algorithm algorithm = KMIP_CRYPTOALG_AES; + a[0].type = KMIP_ATTR_CRYPTOGRAPHIC_ALGORITHM; + a[0].value = &algorithm; + + int32 length = 128; + a[1].type = KMIP_ATTR_CRYPTOGRAPHIC_LENGTH; + a[1].value = &length; + + int32 mask = KMIP_CRYPTOMASK_ENCRYPT | KMIP_CRYPTOMASK_DECRYPT; + a[2].type = KMIP_ATTR_CRYPTOGRAPHIC_USAGE_MASK; + a[2].value = &mask; + + struct template_attribute ta = {0}; + ta.attributes = a; + ta.attribute_count = ARRAY_LENGTH(a); + + struct create_request_payload crp = {0}; + crp.object_type = KMIP_OBJTYPE_SYMMETRIC_KEY; + crp.template_attribute = &ta; + + int result = kmip_encode_create_request_payload(&ctx, &crp); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_encode_create_request_payload_kmip_2_0(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + /* This encoding matches the following set of values: + * Request Payload + * Object Type - Symmetric Key + * Attributes + * Cryptographic Algorithm - AES + * Cryptographic Length - 128 + * Cryptographic Usage Mask - Encrypt | Decrypt + * Protection Storage Masks + * Protection Storage Mask - Software | On System + * Protection Storage Mask - Off System | Off Premises + */ + uint8 expected[120] = { + 0x42, 0x00, 0x79, 0x01, 0x00, 0x00, 0x00, 0x70, + 0x42, 0x00, 0x57, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x01, 0x25, 0x01, 0x00, 0x00, 0x00, 0x30, + 0x42, 0x00, 0x28, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x2A, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x2C, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x01, 0x5F, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x42, 0x01, 0x5E, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x01, 0x5E, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 observed[120] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_2_0); + + Attribute a[3] = {0}; + for(int i = 0; i < 3; i++) + { + kmip_init_attribute(&a[i]); + } + + enum cryptographic_algorithm algorithm = KMIP_CRYPTOALG_AES; + a[0].type = KMIP_ATTR_CRYPTOGRAPHIC_ALGORITHM; + a[0].value = &algorithm; + + int32 length = 128; + a[1].type = KMIP_ATTR_CRYPTOGRAPHIC_LENGTH; + a[1].value = &length; + + int32 mask = KMIP_CRYPTOMASK_ENCRYPT | KMIP_CRYPTOMASK_DECRYPT; + a[2].type = KMIP_ATTR_CRYPTOGRAPHIC_USAGE_MASK; + a[2].value = &mask; + + Attributes attributes = {0}; + LinkedList list = {0}; + LinkedListItem item_1, item_2, item_3 = {0}; + item_1.data = &a[0]; + item_2.data = &a[1]; + item_3.data = &a[2]; + kmip_linked_list_enqueue(&list, &item_1); + kmip_linked_list_enqueue(&list, &item_2); + kmip_linked_list_enqueue(&list, &item_3); + attributes.attribute_list = &list; + + ProtectionStorageMasks psm = {0}; + LinkedList masks = {0}; + LinkedListItem mask_1, mask_2 = {0}; + int32 m1 = KMIP_PROTECT_SOFTWARE | KMIP_PROTECT_ON_SYSTEM; + int32 m2 = KMIP_PROTECT_OFF_SYSTEM | KMIP_PROTECT_OFF_PREMISES; + mask_1.data = &m1; + mask_2.data = &m2; + kmip_linked_list_enqueue(&masks, &mask_1); + kmip_linked_list_enqueue(&masks, &mask_2); + psm.masks = &masks; + + CreateRequestPayload payload = {0}; + payload.object_type = KMIP_OBJTYPE_SYMMETRIC_KEY; + payload.attributes = &attributes; + payload.protection_storage_masks = &psm; + + int result = kmip_encode_create_request_payload(&ctx, &payload); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_decode_create_request_payload(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[200] = { + 0x42, 0x00, 0x79, 0x01, 0x00, 0x00, 0x00, 0xC0, + 0x42, 0x00, 0x57, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x91, 0x01, 0x00, 0x00, 0x00, 0xA8, + 0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x17, + 0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x41, 0x6C, + 0x67, 0x6F, 0x72, 0x69, 0x74, 0x68, 0x6D, 0x00, + 0x42, 0x00, 0x0B, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x14, + 0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x4C, 0x65, + 0x6E, 0x67, 0x74, 0x68, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x18, + 0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x55, 0x73, + 0x61, 0x67, 0x65, 0x20, 0x4D, 0x61, 0x73, 0x6B, + 0x42, 0x00, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00 + }; + + struct kmip ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0); + + struct attribute a[3] = {0}; + for(int i = 0; i < 3; i++) + { + kmip_init_attribute(&a[i]); + } + + enum cryptographic_algorithm algorithm = KMIP_CRYPTOALG_AES; + a[0].type = KMIP_ATTR_CRYPTOGRAPHIC_ALGORITHM; + a[0].value = &algorithm; + + int32 length = 128; + a[1].type = KMIP_ATTR_CRYPTOGRAPHIC_LENGTH; + a[1].value = &length; + + int32 mask = KMIP_CRYPTOMASK_ENCRYPT | KMIP_CRYPTOMASK_DECRYPT; + a[2].type = KMIP_ATTR_CRYPTOGRAPHIC_USAGE_MASK; + a[2].value = &mask; + + struct template_attribute ta = {0}; + ta.attributes = a; + ta.attribute_count = ARRAY_LENGTH(a); + + struct create_request_payload expected = {0}; + expected.object_type = KMIP_OBJTYPE_SYMMETRIC_KEY; + expected.template_attribute = &ta; + + struct create_request_payload observed = {0}; + + int result = kmip_decode_create_request_payload(&ctx, &observed); + result = report_decoding_test_result( + tracker, + &ctx, + kmip_compare_create_request_payload(&expected, &observed), + result, + __func__); + kmip_free_create_request_payload(&ctx, &observed); + kmip_destroy(&ctx); + return(result); +} + +int +test_decode_create_request_payload_kmip_2_0(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + /* This encoding matches the following set of values: + * Request Payload + * Object Type - Symmetric Key + * Attributes + * Cryptographic Algorithm - AES + * Cryptographic Length - 128 + * Cryptographic Usage Mask - Encrypt | Decrypt + * Protection Storage Masks + * Protection Storage Mask - Software | On System + * Protection Storage Mask - Off System | Off Premises + */ + uint8 encoding[120] = { + 0x42, 0x00, 0x79, 0x01, 0x00, 0x00, 0x00, 0x70, + 0x42, 0x00, 0x57, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x01, 0x25, 0x01, 0x00, 0x00, 0x00, 0x30, + 0x42, 0x00, 0x28, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x2A, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x2C, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x01, 0x5F, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x42, 0x01, 0x5E, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x01, 0x5E, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00 + }; + + struct kmip ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_2_0); + + Attribute a[3] = {0}; + for(int i = 0; i < 3; i++) + { + kmip_init_attribute(&a[i]); + } + + enum cryptographic_algorithm algorithm = KMIP_CRYPTOALG_AES; + a[0].type = KMIP_ATTR_CRYPTOGRAPHIC_ALGORITHM; + a[0].value = &algorithm; + + int32 length = 128; + a[1].type = KMIP_ATTR_CRYPTOGRAPHIC_LENGTH; + a[1].value = &length; + + int32 mask = KMIP_CRYPTOMASK_ENCRYPT | KMIP_CRYPTOMASK_DECRYPT; + a[2].type = KMIP_ATTR_CRYPTOGRAPHIC_USAGE_MASK; + a[2].value = &mask; + + Attributes attributes = {0}; + LinkedList list = {0}; + LinkedListItem item_1, item_2, item_3 = {0}; + item_1.data = &a[0]; + item_2.data = &a[1]; + item_3.data = &a[2]; + kmip_linked_list_enqueue(&list, &item_1); + kmip_linked_list_enqueue(&list, &item_2); + kmip_linked_list_enqueue(&list, &item_3); + attributes.attribute_list = &list; + + ProtectionStorageMasks psm = {0}; + LinkedList masks = {0}; + LinkedListItem mask_1, mask_2 = {0}; + int32 m1 = KMIP_PROTECT_SOFTWARE | KMIP_PROTECT_ON_SYSTEM; + int32 m2 = KMIP_PROTECT_OFF_SYSTEM | KMIP_PROTECT_OFF_PREMISES; + mask_1.data = &m1; + mask_2.data = &m2; + kmip_linked_list_enqueue(&masks, &mask_1); + kmip_linked_list_enqueue(&masks, &mask_2); + psm.masks = &masks; + + CreateRequestPayload expected = {0}; + expected.object_type = KMIP_OBJTYPE_SYMMETRIC_KEY; + expected.attributes = &attributes; + expected.protection_storage_masks = &psm; + + CreateRequestPayload observed = {0}; + + int result = kmip_decode_create_request_payload(&ctx, &observed); + result = report_decoding_test_result( + tracker, + &ctx, + kmip_compare_create_request_payload(&expected, &observed), + result, + __func__); + kmip_free_create_request_payload(&ctx, &observed); + kmip_destroy(&ctx); + return(result); +} + +int +test_encode_create_response_payload(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[72] = { + 0x42, 0x00, 0x7C, 0x01, 0x00, 0x00, 0x00, 0x40, + 0x42, 0x00, 0x57, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, + 0x66, 0x62, 0x34, 0x62, 0x35, 0x62, 0x39, 0x63, + 0x2D, 0x36, 0x31, 0x38, 0x38, 0x2D, 0x34, 0x63, + 0x36, 0x33, 0x2D, 0x38, 0x31, 0x34, 0x32, 0x2D, + 0x66, 0x65, 0x39, 0x63, 0x33, 0x32, 0x38, 0x31, + 0x32, 0x39, 0x66, 0x63, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 observed[72] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0); + + struct text_string uuid = {0}; + uuid.value = "fb4b5b9c-6188-4c63-8142-fe9c328129fc"; + uuid.size = 36; + + struct create_response_payload crp = {0}; + crp.object_type = KMIP_OBJTYPE_SYMMETRIC_KEY; + crp.unique_identifier = &uuid; + + int result = kmip_encode_create_response_payload(&ctx, &crp); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_decode_create_response_payload(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[72] = { + 0x42, 0x00, 0x7C, 0x01, 0x00, 0x00, 0x00, 0x40, + 0x42, 0x00, 0x57, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, + 0x66, 0x62, 0x34, 0x62, 0x35, 0x62, 0x39, 0x63, + 0x2D, 0x36, 0x31, 0x38, 0x38, 0x2D, 0x34, 0x63, + 0x36, 0x33, 0x2D, 0x38, 0x31, 0x34, 0x32, 0x2D, + 0x66, 0x65, 0x39, 0x63, 0x33, 0x32, 0x38, 0x31, + 0x32, 0x39, 0x66, 0x63, 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 = "fb4b5b9c-6188-4c63-8142-fe9c328129fc"; + uuid.size = 36; + + struct create_response_payload expected = {0}; + expected.object_type = KMIP_OBJTYPE_SYMMETRIC_KEY; + expected.unique_identifier = &uuid; + + struct create_response_payload observed = {0}; + + int result = kmip_decode_create_response_payload(&ctx, &observed); + result = report_decoding_test_result( + tracker, + &ctx, + kmip_compare_create_response_payload(&expected, &observed), + result, + __func__); + kmip_free_create_response_payload(&ctx, &observed); + kmip_destroy(&ctx); + return(result); +} + +int +test_encode_create_response_payload_with_template_attribute(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[136] = { + 0x42, 0x00, 0x7C, 0x01, 0x00, 0x00, 0x00, 0x80, + 0x42, 0x00, 0x57, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, + 0x66, 0x62, 0x34, 0x62, 0x35, 0x62, 0x39, 0x63, + 0x2D, 0x36, 0x31, 0x38, 0x38, 0x2D, 0x34, 0x63, + 0x36, 0x33, 0x2D, 0x38, 0x31, 0x34, 0x32, 0x2D, + 0x66, 0x65, 0x39, 0x63, 0x33, 0x32, 0x38, 0x31, + 0x32, 0x39, 0x66, 0x63, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x91, 0x01, 0x00, 0x00, 0x00, 0x38, + 0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x17, + 0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x41, 0x6C, + 0x67, 0x6F, 0x72, 0x69, 0x74, 0x68, 0x6D, 0x00, + 0x42, 0x00, 0x0B, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, + }; + + uint8 observed[136] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0); + + struct text_string uuid = {0}; + uuid.value = "fb4b5b9c-6188-4c63-8142-fe9c328129fc"; + uuid.size = 36; + + struct attribute a = {0}; + kmip_init_attribute(&a); + + enum cryptographic_algorithm algorithm = KMIP_CRYPTOALG_AES; + a.type = KMIP_ATTR_CRYPTOGRAPHIC_ALGORITHM; + a.value = &algorithm; + + struct template_attribute ta = {0}; + ta.attributes = &a; + ta.attribute_count = 1; + + struct create_response_payload crp = {0}; + crp.object_type = KMIP_OBJTYPE_SYMMETRIC_KEY; + crp.unique_identifier = &uuid; + crp.template_attribute = &ta; + + int result = kmip_encode_create_response_payload(&ctx, &crp); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_decode_create_response_payload_with_template_attribute(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[136] = { + 0x42, 0x00, 0x7C, 0x01, 0x00, 0x00, 0x00, 0x80, + 0x42, 0x00, 0x57, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, + 0x66, 0x62, 0x34, 0x62, 0x35, 0x62, 0x39, 0x63, + 0x2D, 0x36, 0x31, 0x38, 0x38, 0x2D, 0x34, 0x63, + 0x36, 0x33, 0x2D, 0x38, 0x31, 0x34, 0x32, 0x2D, + 0x66, 0x65, 0x39, 0x63, 0x33, 0x32, 0x38, 0x31, + 0x32, 0x39, 0x66, 0x63, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x91, 0x01, 0x00, 0x00, 0x00, 0x38, + 0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x17, + 0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x41, 0x6C, + 0x67, 0x6F, 0x72, 0x69, 0x74, 0x68, 0x6D, 0x00, + 0x42, 0x00, 0x0B, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x03, 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 = "fb4b5b9c-6188-4c63-8142-fe9c328129fc"; + uuid.size = 36; + + struct attribute a = {0}; + kmip_init_attribute(&a); + + enum cryptographic_algorithm algorithm = KMIP_CRYPTOALG_AES; + a.type = KMIP_ATTR_CRYPTOGRAPHIC_ALGORITHM; + a.value = &algorithm; + + struct template_attribute ta = {0}; + ta.attributes = &a; + ta.attribute_count = 1; + + struct create_response_payload expected = {0}; + expected.object_type = KMIP_OBJTYPE_SYMMETRIC_KEY; + expected.unique_identifier = &uuid; + expected.template_attribute = &ta; + + struct create_response_payload observed = {0}; + + int result = kmip_decode_create_response_payload(&ctx, &observed); + result = report_decoding_test_result( + tracker, + &ctx, + kmip_compare_create_response_payload(&expected, &observed), + result, + __func__); + kmip_free_create_response_payload(&ctx, &observed); + kmip_destroy(&ctx); + return(result); +} + +int +test_encode_get_request_payload(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[56] = { + 0x42, 0x00, 0x79, 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[56] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0); + + struct text_string uuid = {0}; + uuid.value = "49a1ca88-6bea-4fb2-b450-7e58802c3038"; + uuid.size = 36; + + struct get_request_payload grp = {0}; + grp.unique_identifier = &uuid; + + int result = kmip_encode_get_request_payload(&ctx, &grp); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_decode_get_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, + 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 + }; + + struct kmip ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0); + + struct text_string uuid = {0}; + uuid.value = "49a1ca88-6bea-4fb2-b450-7e58802c3038"; + uuid.size = 36; + + struct get_request_payload expected = {0}; + expected.unique_identifier = &uuid; + + struct get_request_payload observed = {0}; + + int result = kmip_decode_get_request_payload(&ctx, &observed); + result = report_decoding_test_result( + tracker, + &ctx, + kmip_compare_get_request_payload(&expected, &observed), + result, + __func__); + kmip_free_get_request_payload(&ctx, &observed); + kmip_destroy(&ctx); + return(result); +} + +int +test_encode_get_request_payload_with_format_compression(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[88] = { + 0x42, 0x00, 0x79, 0x01, 0x00, 0x00, 0x00, 0x50, + 0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, + 0x37, 0x63, 0x66, 0x35, 0x32, 0x30, 0x39, 0x62, + 0x2D, 0x36, 0x66, 0x66, 0x36, 0x2D, 0x34, 0x34, + 0x32, 0x36, 0x2D, 0x38, 0x39, 0x39, 0x65, 0x2D, + 0x32, 0x32, 0x62, 0x30, 0x36, 0x37, 0x38, 0x35, + 0x39, 0x33, 0x37, 0x32, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x42, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x41, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 observed[88] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0); + + struct text_string uuid = {0}; + uuid.value = "7cf5209b-6ff6-4426-899e-22b067859372"; + uuid.size = 36; + + struct get_request_payload grp = {0}; + grp.unique_identifier = &uuid; + grp.key_format_type = KMIP_KEYFORMAT_PKCS1; + grp.key_compression_type = KMIP_KEYCOMP_EC_PUB_UNCOMPRESSED; + + int result = kmip_encode_get_request_payload(&ctx, &grp); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_encode_get_request_payload_with_wrapping_spec(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[160] = { + 0x42, 0x00, 0x79, 0x01, 0x00, 0x00, 0x00, 0x98, + 0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, + 0x62, 0x66, 0x66, 0x37, 0x33, 0x34, 0x37, 0x62, + 0x2D, 0x33, 0x61, 0x33, 0x39, 0x2D, 0x34, 0x63, + 0x63, 0x62, 0x2D, 0x38, 0x32, 0x33, 0x34, 0x2D, + 0x62, 0x61, 0x32, 0x35, 0x36, 0x30, 0x63, 0x61, + 0x31, 0x35, 0x39, 0x38, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x47, 0x01, 0x00, 0x00, 0x00, 0x60, + 0x42, 0x00, 0x9E, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x36, 0x01, 0x00, 0x00, 0x00, 0x48, + 0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, + 0x31, 0x30, 0x30, 0x31, 0x38, 0x32, 0x64, 0x35, + 0x2D, 0x37, 0x32, 0x62, 0x38, 0x2D, 0x34, 0x37, + 0x61, 0x61, 0x2D, 0x38, 0x33, 0x38, 0x33, 0x2D, + 0x34, 0x64, 0x39, 0x37, 0x64, 0x35, 0x31, 0x32, + 0x65, 0x39, 0x38, 0x61, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x2B, 0x01, 0x00, 0x00, 0x00, 0x10, + 0x42, 0x00, 0x11, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 observed[160] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0); + + struct text_string wrapping_uuid = {0}; + wrapping_uuid.value = "100182d5-72b8-47aa-8383-4d97d512e98a"; + wrapping_uuid.size = 36; + struct text_string uuid = {0}; + uuid.value = "bff7347b-3a39-4ccb-8234-ba2560ca1598"; + uuid.size = 36; + + struct cryptographic_parameters cp = {0}; + cp.block_cipher_mode = KMIP_BLOCK_NIST_KEY_WRAP; + + struct encryption_key_information eki = {0}; + eki.unique_identifier = &wrapping_uuid; + eki.cryptographic_parameters = &cp; + + struct key_wrapping_specification kws = {0}; + kws.wrapping_method = KMIP_WRAP_ENCRYPT; + kws.encryption_key_info = &eki; + + struct get_request_payload grp = {0}; + grp.unique_identifier = &uuid; + grp.key_wrapping_spec = &kws; + + int result = kmip_encode_get_request_payload(&ctx, &grp); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_encode_get_response_payload(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[176] = { + 0x42, 0x00, 0x7C, 0x01, 0x00, 0x00, 0x00, 0xA8, + 0x42, 0x00, 0x57, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, + 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, + 0x42, 0x00, 0x8F, 0x01, 0x00, 0x00, 0x00, 0x60, + 0x42, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x58, + 0x42, 0x00, 0x42, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x45, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x42, 0x00, 0x43, 0x08, 0x00, 0x00, 0x00, 0x18, + 0x73, 0x67, 0x57, 0x80, 0x51, 0x01, 0x2A, 0x6D, + 0x13, 0x4A, 0x85, 0x5E, 0x25, 0xC8, 0xCD, 0x5E, + 0x4C, 0xA1, 0x31, 0x45, 0x57, 0x29, 0xD3, 0xC8, + 0x42, 0x00, 0x28, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x2A, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0xA8, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 observed[176] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0); + + struct text_string uuid = {0}; + uuid.value = "49a1ca88-6bea-4fb2-b450-7e58802c3038"; + uuid.size = 36; + + uint8 value[24] = { + 0x73, 0x67, 0x57, 0x80, 0x51, 0x01, 0x2A, 0x6D, + 0x13, 0x4A, 0x85, 0x5E, 0x25, 0xC8, 0xCD, 0x5E, + 0x4C, 0xA1, 0x31, 0x45, 0x57, 0x29, 0xD3, 0xC8 + }; + struct byte_string v = {0}; + v.value = value; + v.size = ARRAY_LENGTH(value); + + struct key_value kv = {0}; + kv.key_material = &v; + + struct key_block kb = {0}; + kb.key_format_type = KMIP_KEYFORMAT_RAW; + kb.key_value = &kv; + kb.cryptographic_algorithm = KMIP_CRYPTOALG_TRIPLE_DES; + kb.cryptographic_length = 168; + + struct symmetric_key key = {0}; + key.key_block = &kb; + + struct get_response_payload grp = {0}; + grp.object_type = KMIP_OBJTYPE_SYMMETRIC_KEY; + grp.unique_identifier = &uuid; + grp.object = &key; + + int result = kmip_encode_get_response_payload(&ctx, &grp); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_decode_get_response_payload(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[176] = { + 0x42, 0x00, 0x7C, 0x01, 0x00, 0x00, 0x00, 0xA8, + 0x42, 0x00, 0x57, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, + 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, + 0x42, 0x00, 0x8F, 0x01, 0x00, 0x00, 0x00, 0x60, + 0x42, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x58, + 0x42, 0x00, 0x42, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x45, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x42, 0x00, 0x43, 0x08, 0x00, 0x00, 0x00, 0x18, + 0x73, 0x67, 0x57, 0x80, 0x51, 0x01, 0x2A, 0x6D, + 0x13, 0x4A, 0x85, 0x5E, 0x25, 0xC8, 0xCD, 0x5E, + 0x4C, 0xA1, 0x31, 0x45, 0x57, 0x29, 0xD3, 0xC8, + 0x42, 0x00, 0x28, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x2A, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0xA8, 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 = "49a1ca88-6bea-4fb2-b450-7e58802c3038"; + uuid.size = 36; + + uint8 value[24] = { + 0x73, 0x67, 0x57, 0x80, 0x51, 0x01, 0x2A, 0x6D, + 0x13, 0x4A, 0x85, 0x5E, 0x25, 0xC8, 0xCD, 0x5E, + 0x4C, 0xA1, 0x31, 0x45, 0x57, 0x29, 0xD3, 0xC8 + }; + struct byte_string v = {0}; + v.value = value; + v.size = ARRAY_LENGTH(value); + + struct key_value kv = {0}; + kv.key_material = &v; + + struct key_block kb = {0}; + kb.key_format_type = KMIP_KEYFORMAT_RAW; + kb.key_value = &kv; + kb.key_value_type = KMIP_TYPE_STRUCTURE; + kb.cryptographic_algorithm = KMIP_CRYPTOALG_TRIPLE_DES; + kb.cryptographic_length = 168; + + struct symmetric_key key = {0}; + key.key_block = &kb; + + struct get_response_payload expected = {0}; + expected.object_type = KMIP_OBJTYPE_SYMMETRIC_KEY; + expected.unique_identifier = &uuid; + expected.object = &key; + + struct get_response_payload observed = {0}; + + int result = kmip_decode_get_response_payload(&ctx, &observed); + result = report_decoding_test_result( + tracker, + &ctx, + kmip_compare_get_response_payload(&expected, &observed), + result, + __func__); + kmip_free_get_response_payload(&ctx, &observed); + kmip_destroy(&ctx); + return(result); +} + +int +test_encode_destroy_request_payload(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[56] = { + 0x42, 0x00, 0x79, 0x01, 0x00, 0x00, 0x00, 0x30, + 0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, + 0x66, 0x62, 0x34, 0x62, 0x35, 0x62, 0x39, 0x63, + 0x2D, 0x36, 0x31, 0x38, 0x38, 0x2D, 0x34, 0x63, + 0x36, 0x33, 0x2D, 0x38, 0x31, 0x34, 0x32, 0x2D, + 0x66, 0x65, 0x39, 0x63, 0x33, 0x32, 0x38, 0x31, + 0x32, 0x39, 0x66, 0x63, 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 = "fb4b5b9c-6188-4c63-8142-fe9c328129fc"; + uuid.size = 36; + + struct destroy_request_payload drp = {0}; + drp.unique_identifier = &uuid; + + int result = kmip_encode_destroy_request_payload(&ctx, &drp); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_decode_destroy_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, + 0x66, 0x62, 0x34, 0x62, 0x35, 0x62, 0x39, 0x63, + 0x2D, 0x36, 0x31, 0x38, 0x38, 0x2D, 0x34, 0x63, + 0x36, 0x33, 0x2D, 0x38, 0x31, 0x34, 0x32, 0x2D, + 0x66, 0x65, 0x39, 0x63, 0x33, 0x32, 0x38, 0x31, + 0x32, 0x39, 0x66, 0x63, 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 = "fb4b5b9c-6188-4c63-8142-fe9c328129fc"; + uuid.size = 36; + + struct destroy_request_payload expected = {0}; + expected.unique_identifier = &uuid; + + struct destroy_request_payload observed = {0}; + + int result = kmip_decode_destroy_request_payload(&ctx, &observed); + result = report_decoding_test_result( + tracker, + &ctx, + kmip_compare_destroy_request_payload(&expected, &observed), + result, + __func__); + kmip_free_destroy_request_payload(&ctx, &observed); + kmip_destroy(&ctx); + return(result); +} + +int +test_encode_destroy_response_payload(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[56] = { + 0x42, 0x00, 0x7C, 0x01, 0x00, 0x00, 0x00, 0x30, + 0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, + 0x66, 0x62, 0x34, 0x62, 0x35, 0x62, 0x39, 0x63, + 0x2D, 0x36, 0x31, 0x38, 0x38, 0x2D, 0x34, 0x63, + 0x36, 0x33, 0x2D, 0x38, 0x31, 0x34, 0x32, 0x2D, + 0x66, 0x65, 0x39, 0x63, 0x33, 0x32, 0x38, 0x31, + 0x32, 0x39, 0x66, 0x63, 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 = "fb4b5b9c-6188-4c63-8142-fe9c328129fc"; + uuid.size = 36; + + struct destroy_response_payload drp = {0}; + drp.unique_identifier = &uuid; + + int result = kmip_encode_destroy_response_payload(&ctx, &drp); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_decode_destroy_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, + 0x66, 0x62, 0x34, 0x62, 0x35, 0x62, 0x39, 0x63, + 0x2D, 0x36, 0x31, 0x38, 0x38, 0x2D, 0x34, 0x63, + 0x36, 0x33, 0x2D, 0x38, 0x31, 0x34, 0x32, 0x2D, + 0x66, 0x65, 0x39, 0x63, 0x33, 0x32, 0x38, 0x31, + 0x32, 0x39, 0x66, 0x63, 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 = "fb4b5b9c-6188-4c63-8142-fe9c328129fc"; + uuid.size = 36; + + struct destroy_response_payload expected = {0}; + expected.unique_identifier = &uuid; + + struct destroy_response_payload observed = {0}; + + int result = kmip_decode_destroy_response_payload(&ctx, &observed); + result = report_decoding_test_result( + tracker, + &ctx, + kmip_compare_destroy_response_payload(&expected, &observed), + result, + __func__); + kmip_free_destroy_response_payload(&ctx, &observed); + kmip_destroy(&ctx); + return(result); +} + +int +test_encode_username_password_credential(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[48] = { + 0x42, 0x00, 0x25, 0x01, 0x00, 0x00, 0x00, 0x28, + 0x42, 0x00, 0x99, 0x07, 0x00, 0x00, 0x00, 0x04, + 0x46, 0x72, 0x65, 0x64, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xA1, 0x07, 0x00, 0x00, 0x00, 0x09, + 0x70, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, + 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 observed[48] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0); + + struct text_string username = {0}; + username.value = "Fred"; + username.size = 4; + struct text_string password = {0}; + password.value = "password1"; + password.size = 9; + + struct username_password_credential upc = {0}; + upc.username = &username; + upc.password = &password; + + int result = kmip_encode_username_password_credential(&ctx, &upc); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_decode_username_password_credential(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[48] = { + 0x42, 0x00, 0x25, 0x01, 0x00, 0x00, 0x00, 0x28, + 0x42, 0x00, 0x99, 0x07, 0x00, 0x00, 0x00, 0x04, + 0x46, 0x72, 0x65, 0x64, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xA1, 0x07, 0x00, 0x00, 0x00, 0x09, + 0x70, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, + 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + struct kmip ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0); + + struct text_string username = {0}; + username.value = "Fred"; + username.size = 4; + struct text_string password = {0}; + password.value = "password1"; + password.size = 9; + + struct username_password_credential expected = {0}; + expected.username = &username; + expected.password = &password; + + struct username_password_credential observed = {0}; + + int result = kmip_decode_username_password_credential(&ctx, &observed); + result = report_decoding_test_result( + tracker, + &ctx, + kmip_compare_username_password_credential(&expected, &observed), + result, + __func__); + kmip_free_username_password_credential(&ctx, &observed); + kmip_destroy(&ctx); + return(result); +} + +int +test_encode_credential_username_password_credential(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[64] = { + 0x42, 0x00, 0x23, 0x01, 0x00, 0x00, 0x00, 0x38, + 0x42, 0x00, 0x24, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x25, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x42, 0x00, 0x99, 0x07, 0x00, 0x00, 0x00, 0x06, + 0x42, 0x61, 0x72, 0x6E, 0x65, 0x79, 0x00, 0x00, + 0x42, 0x00, 0xA1, 0x07, 0x00, 0x00, 0x00, 0x07, + 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x32, 0x00 + }; + + uint8 observed[64] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0); + + struct text_string username = {0}; + username.value = "Barney"; + username.size = 6; + struct text_string password = {0}; + password.value = "secret2"; + password.size = 7; + + struct username_password_credential upc = {0}; + upc.username = &username; + upc.password = &password; + + struct credential c = {0}; + c.credential_type = KMIP_CRED_USERNAME_AND_PASSWORD; + c.credential_value = &upc; + + int result = kmip_encode_credential(&ctx, &c); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_decode_credential_username_password_credential(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[64] = { + 0x42, 0x00, 0x23, 0x01, 0x00, 0x00, 0x00, 0x38, + 0x42, 0x00, 0x24, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x25, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x42, 0x00, 0x99, 0x07, 0x00, 0x00, 0x00, 0x06, + 0x42, 0x61, 0x72, 0x6E, 0x65, 0x79, 0x00, 0x00, + 0x42, 0x00, 0xA1, 0x07, 0x00, 0x00, 0x00, 0x07, + 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x32, 0x00 + }; + + struct kmip ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0); + + struct text_string username = {0}; + username.value = "Barney"; + username.size = 6; + struct text_string password = {0}; + password.value = "secret2"; + password.size = 7; + + struct username_password_credential upc = {0}; + upc.username = &username; + upc.password = &password; + + struct credential expected = {0}; + expected.credential_type = KMIP_CRED_USERNAME_AND_PASSWORD; + expected.credential_value = &upc; + + struct credential observed = {0}; + + int result = kmip_decode_credential(&ctx, &observed); + result = report_decoding_test_result( + tracker, + &ctx, + kmip_compare_credential(&expected, &observed), + result, + __func__); + kmip_free_credential(&ctx, &observed); + kmip_destroy(&ctx); + return(result); +} + +int +test_encode_authentication_username_password_credential(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[80] = { + 0x42, 0x00, 0x0C, 0x01, 0x00, 0x00, 0x00, 0x48, + 0x42, 0x00, 0x23, 0x01, 0x00, 0x00, 0x00, 0x40, + 0x42, 0x00, 0x24, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x25, 0x01, 0x00, 0x00, 0x00, 0x28, + 0x42, 0x00, 0x99, 0x07, 0x00, 0x00, 0x00, 0x04, + 0x46, 0x72, 0x65, 0x64, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xA1, 0x07, 0x00, 0x00, 0x00, 0x09, + 0x70, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, + 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 observed[80] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0); + + struct text_string username = {0}; + username.value = "Fred"; + username.size = 4; + struct text_string password = {0}; + password.value = "password1"; + password.size = 9; + + struct username_password_credential upc = {0}; + upc.username = &username; + upc.password = &password; + + struct credential c = {0}; + c.credential_type = KMIP_CRED_USERNAME_AND_PASSWORD; + c.credential_value = &upc; + + struct authentication a = {0}; + a.credential = &c; + + int result = kmip_encode_authentication(&ctx, &a); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_decode_authentication_username_password_credential(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[80] = { + 0x42, 0x00, 0x0C, 0x01, 0x00, 0x00, 0x00, 0x48, + 0x42, 0x00, 0x23, 0x01, 0x00, 0x00, 0x00, 0x40, + 0x42, 0x00, 0x24, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x25, 0x01, 0x00, 0x00, 0x00, 0x28, + 0x42, 0x00, 0x99, 0x07, 0x00, 0x00, 0x00, 0x04, + 0x46, 0x72, 0x65, 0x64, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xA1, 0x07, 0x00, 0x00, 0x00, 0x09, + 0x70, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, + 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + struct kmip ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0); + + struct text_string username = {0}; + username.value = "Fred"; + username.size = 4; + struct text_string password = {0}; + password.value = "password1"; + password.size = 9; + + struct username_password_credential upc = {0}; + upc.username = &username; + upc.password = &password; + + struct credential c = {0}; + c.credential_type = KMIP_CRED_USERNAME_AND_PASSWORD; + c.credential_value = &upc; + + struct authentication expected = {0}; + expected.credential = &c; + + struct authentication observed = {0}; + + int result = kmip_decode_authentication(&ctx, &observed); + result = report_decoding_test_result( + tracker, + &ctx, + kmip_compare_authentication(&expected, &observed), + result, + __func__); + kmip_free_authentication(&ctx, &observed); + kmip_destroy(&ctx); + return(result); +} + +int +test_encode_request_header(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[168] = { + 0x42, 0x00, 0x77, 0x01, 0x00, 0x00, 0x00, 0xA0, + 0x42, 0x00, 0x69, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x42, 0x00, 0x6A, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x6B, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x0C, 0x01, 0x00, 0x00, 0x00, 0x40, + 0x42, 0x00, 0x23, 0x01, 0x00, 0x00, 0x00, 0x38, + 0x42, 0x00, 0x24, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x25, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x42, 0x00, 0x99, 0x07, 0x00, 0x00, 0x00, 0x06, + 0x42, 0x61, 0x72, 0x6E, 0x65, 0x79, 0x00, 0x00, + 0x42, 0x00, 0xA1, 0x07, 0x00, 0x00, 0x00, 0x07, + 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x32, 0x00, + 0x42, 0x00, 0x0E, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x10, 0x06, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x42, 0x00, 0x0D, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 observed[168] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0); + + struct protocol_version pv = {0}; + pv.major = 1; + pv.minor = 0; + + struct text_string username = {0}; + username.value = "Barney"; + username.size = 6; + struct text_string password = {0}; + password.value = "secret2"; + password.size = 7; + + struct username_password_credential upc = {0}; + upc.username = &username; + upc.password = &password; + + struct credential c = {0}; + c.credential_type = KMIP_CRED_USERNAME_AND_PASSWORD; + c.credential_value = &upc; + + struct authentication a = {0}; + a.credential = &c; + + struct request_header rh = {0}; + kmip_init_request_header(&rh); + + rh.protocol_version = &pv; + rh.authentication = &a; + rh.batch_error_continuation_option = KMIP_BATCH_CONTINUE; + rh.batch_order_option = KMIP_TRUE; + rh.batch_count = 2; + + int result = kmip_encode_request_header(&ctx, &rh); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_decode_request_header(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[168] = { + 0x42, 0x00, 0x77, 0x01, 0x00, 0x00, 0x00, 0xA0, + 0x42, 0x00, 0x69, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x42, 0x00, 0x6A, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x6B, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x0C, 0x01, 0x00, 0x00, 0x00, 0x40, + 0x42, 0x00, 0x23, 0x01, 0x00, 0x00, 0x00, 0x38, + 0x42, 0x00, 0x24, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x25, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x42, 0x00, 0x99, 0x07, 0x00, 0x00, 0x00, 0x06, + 0x42, 0x61, 0x72, 0x6E, 0x65, 0x79, 0x00, 0x00, + 0x42, 0x00, 0xA1, 0x07, 0x00, 0x00, 0x00, 0x07, + 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x32, 0x00, + 0x42, 0x00, 0x0E, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x10, 0x06, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x42, 0x00, 0x0D, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00 + }; + + struct kmip ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0); + + struct protocol_version pv = {0}; + pv.major = 1; + pv.minor = 0; + + struct text_string username = {0}; + username.value = "Barney"; + username.size = 6; + struct text_string password = {0}; + password.value = "secret2"; + password.size = 7; + + struct username_password_credential upc = {0}; + upc.username = &username; + upc.password = &password; + + struct credential c = {0}; + c.credential_type = KMIP_CRED_USERNAME_AND_PASSWORD; + c.credential_value = &upc; + + struct authentication a = {0}; + a.credential = &c; + + struct request_header expected = {0}; + kmip_init_request_header(&expected); + + expected.protocol_version = &pv; + expected.authentication = &a; + expected.batch_error_continuation_option = KMIP_BATCH_CONTINUE; + expected.batch_order_option = KMIP_TRUE; + expected.batch_count = 2; + + struct request_header observed = {0}; + kmip_init_request_header(&observed); + + int result = kmip_decode_request_header(&ctx, &observed); + result = report_decoding_test_result( + tracker, + &ctx, + kmip_compare_request_header(&expected, &observed), + result, + __func__); + kmip_free_request_header(&ctx, &observed); + kmip_destroy(&ctx); + return(result); +} + +int +test_encode_response_header(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[80] = { + 0x42, 0x00, 0x7A, 0x01, 0x00, 0x00, 0x00, 0x48, + 0x42, 0x00, 0x69, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x42, 0x00, 0x6A, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x6B, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x92, 0x09, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x4F, 0x9A, 0x54, 0xE5, + 0x42, 0x00, 0x0D, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 observed[80] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0); + + struct protocol_version pv = {0}; + pv.major = 1; + pv.minor = 0; + + struct response_header rh = {0}; + kmip_init_response_header(&rh); + + rh.protocol_version = &pv; + rh.time_stamp = 1335514341; + rh.batch_count = 1; + + int result = kmip_encode_response_header(&ctx, &rh); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_decode_response_header(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[80] = { + 0x42, 0x00, 0x7A, 0x01, 0x00, 0x00, 0x00, 0x48, + 0x42, 0x00, 0x69, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x42, 0x00, 0x6A, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x6B, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x92, 0x09, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x4F, 0x9A, 0x54, 0xE5, + 0x42, 0x00, 0x0D, 0x02, 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_0); + + struct protocol_version pv = {0}; + pv.major = 1; + pv.minor = 0; + + struct response_header expected = {0}; + kmip_init_response_header(&expected); + + expected.protocol_version = &pv; + expected.time_stamp = 1335514341; + expected.batch_count = 1; + + struct response_header observed = {0}; + kmip_init_response_header(&observed); + + int result = kmip_decode_response_header(&ctx, &observed); + result = report_decoding_test_result( + tracker, + &ctx, + kmip_compare_response_header(&expected, &observed), + result, + __func__); + kmip_free_response_header(&ctx, &observed); + kmip_destroy(&ctx); + return(result); +} + +int +test_encode_request_batch_item_get_payload(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[80] = { + 0x42, 0x00, 0x0F, 0x01, 0x00, 0x00, 0x00, 0x48, + 0x42, 0x00, 0x5C, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x79, 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[80] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0); + + struct text_string uuid = {0}; + uuid.value = "49a1ca88-6bea-4fb2-b450-7e58802c3038"; + uuid.size = 36; + + struct get_request_payload grp = {0}; + grp.unique_identifier = &uuid; + + struct request_batch_item rbi = {0}; + kmip_init_request_batch_item(&rbi); + rbi.operation = KMIP_OP_GET; + rbi.request_payload = &grp; + + int result = kmip_encode_request_batch_item(&ctx, &rbi); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_encode_request_batch_item_get_payload_kmip_2_0(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + /* This encoding matches the following set of values: + * Batch Item + * Operation - Get + * Ephemeral - False + * Request Payload + * Unique Identifier - 49a1ca88-6bea-4fb2-b450-7e58802c3038 + */ + uint8 expected[96] = { + 0x42, 0x00, 0x0F, 0x01, 0x00, 0x00, 0x00, 0x58, + 0x42, 0x00, 0x5C, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x01, 0x54, 0x06, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x79, 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[96] = {0}; + KMIP ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_2_0); + + TextString uuid = {0}; + uuid.value = "49a1ca88-6bea-4fb2-b450-7e58802c3038"; + uuid.size = 36; + + GetRequestPayload grp = {0}; + grp.unique_identifier = &uuid; + + RequestBatchItem rbi = {0}; + kmip_init_request_batch_item(&rbi); + rbi.operation = KMIP_OP_GET; + rbi.ephemeral = KMIP_FALSE; + rbi.request_payload = &grp; + + int result = kmip_encode_request_batch_item(&ctx, &rbi); + result = report_encoding_test_result(tracker, &ctx, expected, observed, result, __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_decode_request_batch_item_get_payload(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[80] = { + 0x42, 0x00, 0x0F, 0x01, 0x00, 0x00, 0x00, 0x48, + 0x42, 0x00, 0x5C, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x79, 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 + }; + + struct kmip ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0); + + struct text_string uuid = {0}; + uuid.value = "49a1ca88-6bea-4fb2-b450-7e58802c3038"; + uuid.size = 36; + + struct get_request_payload grp = {0}; + grp.unique_identifier = &uuid; + + struct request_batch_item expected = {0}; + kmip_init_request_batch_item(&expected); + expected.operation = KMIP_OP_GET; + expected.request_payload = &grp; + + struct request_batch_item observed = {0}; + kmip_init_request_batch_item(&observed); + + int result = kmip_decode_request_batch_item(&ctx, &observed); + result = report_decoding_test_result( + tracker, + &ctx, + kmip_compare_request_batch_item(&expected, &observed), + result, + __func__); + kmip_free_request_batch_item(&ctx, &observed); + kmip_destroy(&ctx); + return(result); +} + +int +test_decode_request_batch_item_get_payload_kmip_2_0(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + /* This encoding matches the following set of values: + * Batch Item + * Operation - Get + * Ephemeral - False + * Request Payload + * Unique Identifier - 49a1ca88-6bea-4fb2-b450-7e58802c3038 + */ + uint8 encoding[96] = { + 0x42, 0x00, 0x0F, 0x01, 0x00, 0x00, 0x00, 0x58, + 0x42, 0x00, 0x5C, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x01, 0x54, 0x06, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x79, 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 + }; + + KMIP ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_2_0); + + TextString uuid = {0}; + uuid.value = "49a1ca88-6bea-4fb2-b450-7e58802c3038"; + uuid.size = 36; + + GetRequestPayload grp = {0}; + grp.unique_identifier = &uuid; + + RequestBatchItem expected = {0}; + kmip_init_request_batch_item(&expected); + expected.operation = KMIP_OP_GET; + expected.ephemeral = KMIP_FALSE; + expected.request_payload = &grp; + + RequestBatchItem observed = {0}; + kmip_init_request_batch_item(&observed); + + int result = kmip_decode_request_batch_item(&ctx, &observed); + int comparison = kmip_compare_request_batch_item(&expected, &observed); + if(!comparison) + { + kmip_print_request_batch_item(1, &expected); + kmip_print_request_batch_item(1, &observed); + } + result = report_decoding_test_result(tracker, &ctx, comparison, result, __func__); + + kmip_free_request_batch_item(&ctx, &observed); + kmip_destroy(&ctx); + return(result); +} + +int +test_encode_response_batch_item_get_payload(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[216] = { + 0x42, 0x00, 0x0F, 0x01, 0x00, 0x00, 0x00, 0xD0, + 0x42, 0x00, 0x5C, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x7F, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x7C, 0x01, 0x00, 0x00, 0x00, 0xA8, + 0x42, 0x00, 0x57, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, + 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, + 0x42, 0x00, 0x8F, 0x01, 0x00, 0x00, 0x00, 0x60, + 0x42, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x58, + 0x42, 0x00, 0x42, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x45, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x42, 0x00, 0x43, 0x08, 0x00, 0x00, 0x00, 0x18, + 0x73, 0x67, 0x57, 0x80, 0x51, 0x01, 0x2A, 0x6D, + 0x13, 0x4A, 0x85, 0x5E, 0x25, 0xC8, 0xCD, 0x5E, + 0x4C, 0xA1, 0x31, 0x45, 0x57, 0x29, 0xD3, 0xC8, + 0x42, 0x00, 0x28, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x2A, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0xA8, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 observed[216] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0); + + struct text_string uuid = {0}; + uuid.value = "49a1ca88-6bea-4fb2-b450-7e58802c3038"; + uuid.size = 36; + + uint8 value[24] = { + 0x73, 0x67, 0x57, 0x80, 0x51, 0x01, 0x2A, 0x6D, + 0x13, 0x4A, 0x85, 0x5E, 0x25, 0xC8, 0xCD, 0x5E, + 0x4C, 0xA1, 0x31, 0x45, 0x57, 0x29, 0xD3, 0xC8 + }; + + struct byte_string v = {0}; + v.value = value; + v.size = ARRAY_LENGTH(value); + + struct key_value kv = {0}; + kv.key_material = &v; + + struct key_block kb = {0}; + kb.key_format_type = KMIP_KEYFORMAT_RAW; + kb.key_value = &kv; + kb.cryptographic_algorithm = KMIP_CRYPTOALG_TRIPLE_DES; + kb.cryptographic_length = 168; + + struct symmetric_key key = {0}; + key.key_block = &kb; + + struct get_response_payload grp = {0}; + grp.object_type = KMIP_OBJTYPE_SYMMETRIC_KEY; + grp.unique_identifier = &uuid; + grp.object = &key; + + struct response_batch_item rbi = {0}; + rbi.operation = KMIP_OP_GET; + rbi.result_status = KMIP_STATUS_SUCCESS; + rbi.response_payload = &grp; + + int result = kmip_encode_response_batch_item(&ctx, &rbi); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_decode_response_batch_item_get_payload(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[216] = { + 0x42, 0x00, 0x0F, 0x01, 0x00, 0x00, 0x00, 0xD0, + 0x42, 0x00, 0x5C, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x7F, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x7C, 0x01, 0x00, 0x00, 0x00, 0xA8, + 0x42, 0x00, 0x57, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, + 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, + 0x42, 0x00, 0x8F, 0x01, 0x00, 0x00, 0x00, 0x60, + 0x42, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x58, + 0x42, 0x00, 0x42, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x45, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x42, 0x00, 0x43, 0x08, 0x00, 0x00, 0x00, 0x18, + 0x73, 0x67, 0x57, 0x80, 0x51, 0x01, 0x2A, 0x6D, + 0x13, 0x4A, 0x85, 0x5E, 0x25, 0xC8, 0xCD, 0x5E, + 0x4C, 0xA1, 0x31, 0x45, 0x57, 0x29, 0xD3, 0xC8, + 0x42, 0x00, 0x28, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x2A, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0xA8, 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 = "49a1ca88-6bea-4fb2-b450-7e58802c3038"; + uuid.size = 36; + + uint8 value[24] = { + 0x73, 0x67, 0x57, 0x80, 0x51, 0x01, 0x2A, 0x6D, + 0x13, 0x4A, 0x85, 0x5E, 0x25, 0xC8, 0xCD, 0x5E, + 0x4C, 0xA1, 0x31, 0x45, 0x57, 0x29, 0xD3, 0xC8 + }; + + struct byte_string v = {0}; + v.value = value; + v.size = ARRAY_LENGTH(value); + + struct key_value kv = {0}; + kv.key_material = &v; + + struct key_block kb = {0}; + kb.key_format_type = KMIP_KEYFORMAT_RAW; + kb.key_value = &kv; + kb.key_value_type = KMIP_TYPE_STRUCTURE; + kb.cryptographic_algorithm = KMIP_CRYPTOALG_TRIPLE_DES; + kb.cryptographic_length = 168; + + struct symmetric_key key = {0}; + key.key_block = &kb; + + struct get_response_payload grp = {0}; + grp.object_type = KMIP_OBJTYPE_SYMMETRIC_KEY; + grp.unique_identifier = &uuid; + grp.object = &key; + + struct response_batch_item expected = {0}; + expected.operation = KMIP_OP_GET; + expected.result_status = KMIP_STATUS_SUCCESS; + expected.response_payload = &grp; + + struct response_batch_item observed = {0}; + + int result = kmip_decode_response_batch_item(&ctx, &observed); + result = report_decoding_test_result( + tracker, + &ctx, + kmip_compare_response_batch_item(&expected, &observed), + result, + __func__); + kmip_free_response_batch_item(&ctx, &observed); + kmip_destroy(&ctx); + return(result); +} + +int +test_encode_request_message_get(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[152] = { + 0x42, 0x00, 0x78, 0x01, 0x00, 0x00, 0x00, 0x90, + 0x42, 0x00, 0x77, 0x01, 0x00, 0x00, 0x00, 0x38, + 0x42, 0x00, 0x69, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x42, 0x00, 0x6A, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x6B, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x0D, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x0F, 0x01, 0x00, 0x00, 0x00, 0x48, + 0x42, 0x00, 0x5C, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x79, 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[152] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0); + + struct protocol_version pv = {0}; + pv.major = 1; + pv.minor = 0; + + struct request_header rh = {0}; + kmip_init_request_header(&rh); + + rh.protocol_version = &pv; + rh.batch_count = 1; + + struct text_string uuid = {0}; + uuid.value = "49a1ca88-6bea-4fb2-b450-7e58802c3038"; + uuid.size = 36; + + struct get_request_payload grp = {0}; + grp.unique_identifier = &uuid; + + struct request_batch_item rbi = {0}; + kmip_init_request_batch_item(&rbi); + rbi.operation = KMIP_OP_GET; + rbi.request_payload = &grp; + + struct request_message rm = {0}; + rm.request_header = &rh; + rm.batch_items = &rbi; + rm.batch_count = 1; + + int result = kmip_encode_request_message(&ctx, &rm); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_decode_request_message_get(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[152] = { + 0x42, 0x00, 0x78, 0x01, 0x00, 0x00, 0x00, 0x90, + 0x42, 0x00, 0x77, 0x01, 0x00, 0x00, 0x00, 0x38, + 0x42, 0x00, 0x69, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x42, 0x00, 0x6A, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x6B, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x0D, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x0F, 0x01, 0x00, 0x00, 0x00, 0x48, + 0x42, 0x00, 0x5C, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x79, 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 + }; + + struct kmip ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0); + + struct protocol_version pv = {0}; + pv.major = 1; + pv.minor = 0; + + struct request_header rh = {0}; + kmip_init_request_header(&rh); + + rh.protocol_version = &pv; + rh.batch_count = 1; + + struct text_string uuid = {0}; + uuid.value = "49a1ca88-6bea-4fb2-b450-7e58802c3038"; + uuid.size = 36; + + struct get_request_payload grp = {0}; + grp.unique_identifier = &uuid; + + struct request_batch_item rbi = {0}; + kmip_init_request_batch_item(&rbi); + rbi.operation = KMIP_OP_GET; + rbi.request_payload = &grp; + + struct request_message expected = {0}; + expected.request_header = &rh; + expected.batch_items = &rbi; + expected.batch_count = 1; + + struct request_message observed = {0}; + + int result = kmip_decode_request_message(&ctx, &observed); + int comparison = kmip_compare_request_message(&expected, &observed); + if(!comparison) + { + kmip_print_request_message(&expected); + kmip_print_request_message(&observed); + } + result = report_decoding_test_result(tracker, &ctx, comparison, result, __func__); + + kmip_free_request_message(&ctx, &observed); + kmip_destroy(&ctx); + return(result); +} + +int +test_encode_response_message_get(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[304] = { + 0x42, 0x00, 0x7B, 0x01, 0x00, 0x00, 0x01, 0x28, + 0x42, 0x00, 0x7A, 0x01, 0x00, 0x00, 0x00, 0x48, + 0x42, 0x00, 0x69, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x42, 0x00, 0x6A, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x6B, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x92, 0x09, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x4F, 0x9A, 0x54, 0xE7, + 0x42, 0x00, 0x0D, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x0F, 0x01, 0x00, 0x00, 0x00, 0xD0, + 0x42, 0x00, 0x5C, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x7F, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x7C, 0x01, 0x00, 0x00, 0x00, 0xA8, + 0x42, 0x00, 0x57, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, + 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, + 0x42, 0x00, 0x8F, 0x01, 0x00, 0x00, 0x00, 0x60, + 0x42, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x58, + 0x42, 0x00, 0x42, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x45, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x42, 0x00, 0x43, 0x08, 0x00, 0x00, 0x00, 0x18, + 0x73, 0x67, 0x57, 0x80, 0x51, 0x01, 0x2A, 0x6D, + 0x13, 0x4A, 0x85, 0x5E, 0x25, 0xC8, 0xCD, 0x5E, + 0x4C, 0xA1, 0x31, 0x45, 0x57, 0x29, 0xD3, 0xC8, + 0x42, 0x00, 0x28, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x2A, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0xA8, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 observed[304] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0); + + struct protocol_version pv = {0}; + pv.major = 1; + pv.minor = 0; + + struct response_header rh = {0}; + kmip_init_response_header(&rh); + + rh.protocol_version = &pv; + rh.time_stamp = 1335514343; + rh.batch_count = 1; + + struct text_string uuid = {0}; + uuid.value = "49a1ca88-6bea-4fb2-b450-7e58802c3038"; + uuid.size = 36; + + uint8 value[24] = { + 0x73, 0x67, 0x57, 0x80, 0x51, 0x01, 0x2A, 0x6D, + 0x13, 0x4A, 0x85, 0x5E, 0x25, 0xC8, 0xCD, 0x5E, + 0x4C, 0xA1, 0x31, 0x45, 0x57, 0x29, 0xD3, 0xC8 + }; + + struct byte_string v = {0}; + v.value = value; + v.size = ARRAY_LENGTH(value); + + struct key_value kv = {0}; + kv.key_material = &v; + + struct key_block kb = {0}; + kb.key_format_type = KMIP_KEYFORMAT_RAW; + kb.key_value = &kv; + kb.cryptographic_algorithm = KMIP_CRYPTOALG_TRIPLE_DES; + kb.cryptographic_length = 168; + + struct symmetric_key key = {0}; + key.key_block = &kb; + + struct get_response_payload grp = {0}; + grp.object_type = KMIP_OBJTYPE_SYMMETRIC_KEY; + grp.unique_identifier = &uuid; + grp.object = &key; + + struct response_batch_item rbi = {0}; + rbi.operation = KMIP_OP_GET; + rbi.result_status = KMIP_STATUS_SUCCESS; + rbi.response_payload = &grp; + + struct response_message rm = {0}; + rm.response_header = &rh; + rm.batch_items = &rbi; + rm.batch_count = 1; + + int result = kmip_encode_response_message(&ctx, &rm); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_decode_response_message_get(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[304] = { + 0x42, 0x00, 0x7B, 0x01, 0x00, 0x00, 0x01, 0x28, + 0x42, 0x00, 0x7A, 0x01, 0x00, 0x00, 0x00, 0x48, + 0x42, 0x00, 0x69, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x42, 0x00, 0x6A, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x6B, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x92, 0x09, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x4F, 0x9A, 0x54, 0xE7, + 0x42, 0x00, 0x0D, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x0F, 0x01, 0x00, 0x00, 0x00, 0xD0, + 0x42, 0x00, 0x5C, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x7F, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x7C, 0x01, 0x00, 0x00, 0x00, 0xA8, + 0x42, 0x00, 0x57, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, + 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, + 0x42, 0x00, 0x8F, 0x01, 0x00, 0x00, 0x00, 0x60, + 0x42, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x58, + 0x42, 0x00, 0x42, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x45, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x42, 0x00, 0x43, 0x08, 0x00, 0x00, 0x00, 0x18, + 0x73, 0x67, 0x57, 0x80, 0x51, 0x01, 0x2A, 0x6D, + 0x13, 0x4A, 0x85, 0x5E, 0x25, 0xC8, 0xCD, 0x5E, + 0x4C, 0xA1, 0x31, 0x45, 0x57, 0x29, 0xD3, 0xC8, + 0x42, 0x00, 0x28, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x2A, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0xA8, 0x00, 0x00, 0x00, 0x00 + }; + + struct kmip ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0); + + struct protocol_version pv = {0}; + pv.major = 1; + pv.minor = 0; + + struct response_header rh = {0}; + kmip_init_response_header(&rh); + + rh.protocol_version = &pv; + rh.time_stamp = 1335514343; + rh.batch_count = 1; + + struct text_string uuid = {0}; + uuid.value = "49a1ca88-6bea-4fb2-b450-7e58802c3038"; + uuid.size = 36; + + uint8 value[24] = { + 0x73, 0x67, 0x57, 0x80, 0x51, 0x01, 0x2A, 0x6D, + 0x13, 0x4A, 0x85, 0x5E, 0x25, 0xC8, 0xCD, 0x5E, + 0x4C, 0xA1, 0x31, 0x45, 0x57, 0x29, 0xD3, 0xC8 + }; + + struct byte_string v = {0}; + v.value = value; + v.size = ARRAY_LENGTH(value); + + struct key_value kv = {0}; + kv.key_material = &v; + + struct key_block kb = {0}; + kb.key_format_type = KMIP_KEYFORMAT_RAW; + kb.key_value = &kv; + kb.key_value_type = KMIP_TYPE_STRUCTURE; + kb.cryptographic_algorithm = KMIP_CRYPTOALG_TRIPLE_DES; + kb.cryptographic_length = 168; + + struct symmetric_key key = {0}; + key.key_block = &kb; + + struct get_response_payload grp = {0}; + grp.object_type = KMIP_OBJTYPE_SYMMETRIC_KEY; + grp.unique_identifier = &uuid; + grp.object = &key; + + struct response_batch_item rbi = {0}; + rbi.operation = KMIP_OP_GET; + rbi.result_status = KMIP_STATUS_SUCCESS; + rbi.response_payload = &grp; + + struct response_message expected = {0}; + expected.response_header = &rh; + expected.batch_items = &rbi; + expected.batch_count = 1; + + struct response_message observed = {0}; + + int result = kmip_decode_response_message(&ctx, &observed); + result = report_decoding_test_result( + tracker, + &ctx, + kmip_compare_response_message(&expected, &observed), + result, + __func__); + kmip_free_response_message(&ctx, &observed); + kmip_destroy(&ctx); + return(result); +} + +int +test_encode_attributes(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + /* This encoding matches the following set of values: + * Attributes + * Cryptographic Algorithm - AES + * Cryptographic Length - 128 + */ + uint8 expected[40] = { + 0x42, 0x01, 0x25, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x42, 0x00, 0x28, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x2A, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 observed[40] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_2_0); + + LinkedList attribute_list = {0}; + + LinkedListItem item_1 = {0}; + Attribute attr_1 = {0}; + kmip_init_attribute(&attr_1); + enum cryptographic_algorithm algorithm = KMIP_CRYPTOALG_AES; + attr_1.type = KMIP_ATTR_CRYPTOGRAPHIC_ALGORITHM; + attr_1.value = &algorithm; + item_1.data = &attr_1; + + LinkedListItem item_2 = {0}; + Attribute attr_2 = {0}; + kmip_init_attribute(&attr_2); + int32 length = 128; + attr_2.type = KMIP_ATTR_CRYPTOGRAPHIC_LENGTH; + attr_2.value = &length; + item_2.data = &attr_2; + + kmip_linked_list_enqueue(&attribute_list, &item_1); + kmip_linked_list_enqueue(&attribute_list, &item_2); + + Attributes attributes = {0}; + attributes.attribute_list = &attribute_list; + + int result = kmip_encode_attributes(&ctx, &attributes); + result = report_encoding_test_result(tracker, &ctx, expected, observed, result, __func__); + + kmip_destroy(&ctx); + + return(result); +} + +int +test_encode_attributes_with_invalid_kmip_version(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 observed[40] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_4); + + Attributes attributes = {0}; + + int result = kmip_encode_attributes(&ctx, &attributes); + kmip_destroy(&ctx); + + result = report_result(tracker, result, KMIP_INVALID_FOR_VERSION, __func__); + return(result); +} + +int +test_encode_attribute_v2_unique_identifier(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + /* This encoding matches the following value: + * Unique Identifier - fb4b5b9c-6188-4c63-8142-fe9c328129fc + */ + uint8 expected[48] = { + 0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, + 0x66, 0x62, 0x34, 0x62, 0x35, 0x62, 0x39, 0x63, + 0x2D, 0x36, 0x31, 0x38, 0x38, 0x2D, 0x34, 0x63, + 0x36, 0x33, 0x2D, 0x38, 0x31, 0x34, 0x32, 0x2D, + 0x66, 0x65, 0x39, 0x63, 0x33, 0x32, 0x38, 0x31, + 0x32, 0x39, 0x66, 0x63, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 observed[48] = {0}; + KMIP ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_2_0); + + Attribute attribute = {0}; + kmip_init_attribute(&attribute); + TextString unique_identifier = {0}; + unique_identifier.value = "fb4b5b9c-6188-4c63-8142-fe9c328129fc"; + unique_identifier.size = 36; + attribute.type = KMIP_ATTR_UNIQUE_IDENTIFIER; + attribute.value = &unique_identifier; + + int result = kmip_encode_attribute_v2(&ctx, &attribute); + result = report_encoding_test_result(tracker, &ctx, expected, observed, result, __func__); + + kmip_destroy(&ctx); + + return(result); +} + +int +test_encode_attribute_v2_name(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + /* This encoding matches the following value: + * Name + * Value - Template1 + * Type - Uninterpreted Text String + */ + uint8 expected[48] = { + 0x42, 0x00, 0x53, 0x01, 0x00, 0x00, 0x00, 0x28, + 0x42, 0x00, 0x55, 0x07, 0x00, 0x00, 0x00, 0x09, + 0x54, 0x65, 0x6D, 0x70, 0x6C, 0x61, 0x74, 0x65, + 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x54, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 observed[48] = {0}; + KMIP ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_2_0); + + Attribute attribute = {0}; + kmip_init_attribute(&attribute); + TextString name_value = {0}; + name_value.value = "Template1"; + name_value.size = 9; + Name name = {0}; + name.value = &name_value; + name.type = KMIP_NAME_UNINTERPRETED_TEXT_STRING; + + attribute.type = KMIP_ATTR_NAME; + attribute.value = &name; + + int result = kmip_encode_attribute_v2(&ctx, &attribute); + result = report_encoding_test_result(tracker, &ctx, expected, observed, result, __func__); + + kmip_destroy(&ctx); + + return(result); +} + +int +test_encode_attribute_v2_object_type(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + /* This encoding matches the following value: + * Object Type - Symmetric Key + */ + uint8 expected[16] = { + 0x42, 0x00, 0x57, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 observed[16] = {0}; + KMIP ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_2_0); + + Attribute attribute = {0}; + kmip_init_attribute(&attribute); + enum object_type object_type = KMIP_OBJTYPE_SYMMETRIC_KEY; + attribute.type = KMIP_ATTR_OBJECT_TYPE; + attribute.value = &object_type; + + int result = kmip_encode_attribute_v2(&ctx, &attribute); + result = report_encoding_test_result(tracker, &ctx, expected, observed, result, __func__); + + kmip_destroy(&ctx); + + return(result); +} + +int +test_encode_attribute_v2_cryptographic_algorithm(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + /* This encoding matches the following value: + * Cryptographic Algorithm - AES + */ + uint8 expected[16] = { + 0x42, 0x00, 0x28, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 observed[16] = {0}; + KMIP ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_2_0); + + Attribute attribute = {0}; + kmip_init_attribute(&attribute); + enum cryptographic_algorithm algorithm = KMIP_CRYPTOALG_AES; + attribute.type = KMIP_ATTR_CRYPTOGRAPHIC_ALGORITHM; + attribute.value = &algorithm; + + int result = kmip_encode_attribute_v2(&ctx, &attribute); + result = report_encoding_test_result(tracker, &ctx, expected, observed, result, __func__); + + kmip_destroy(&ctx); + + return(result); +} + +int +test_encode_attribute_v2_cryptographic_length(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + /* This encoding matches the following value: + * Cryptographic Length - 128 + */ + uint8 expected[16] = { + 0x42, 0x00, 0x2A, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 observed[16] = {0}; + KMIP ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_2_0); + + Attribute attribute = {0}; + kmip_init_attribute(&attribute); + int32 length = 128; + attribute.type = KMIP_ATTR_CRYPTOGRAPHIC_LENGTH; + attribute.value = &length; + + int result = kmip_encode_attribute_v2(&ctx, &attribute); + result = report_encoding_test_result(tracker, &ctx, expected, observed, result, __func__); + + kmip_destroy(&ctx); + + return(result); +} + +int +test_encode_attribute_v2_cryptographic_usage_mask(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + /* This encoding matches the following value: + * Cryptographic Usage Mask - Encrypt | Decrypt + */ + uint8 expected[16] = { + 0x42, 0x00, 0x2C, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 observed[16] = {0}; + KMIP ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_2_0); + + Attribute attribute = {0}; + kmip_init_attribute(&attribute); + int32 mask = KMIP_CRYPTOMASK_ENCRYPT | KMIP_CRYPTOMASK_DECRYPT; + attribute.type = KMIP_ATTR_CRYPTOGRAPHIC_USAGE_MASK; + attribute.value = &mask; + + int result = kmip_encode_attribute_v2(&ctx, &attribute); + result = report_encoding_test_result(tracker, &ctx, expected, observed, result, __func__); + + kmip_destroy(&ctx); + + return(result); +} + +int +test_encode_attribute_v2_state(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + /* This encoding matches the following value: + * State - Active + */ + uint8 expected[16] = { + 0x42, 0x00, 0x8D, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 observed[16] = {0}; + KMIP ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_2_0); + + Attribute attribute = {0}; + kmip_init_attribute(&attribute); + enum state state = KMIP_STATE_ACTIVE; + attribute.type = KMIP_ATTR_STATE; + attribute.value = &state; + + int result = kmip_encode_attribute_v2(&ctx, &attribute); + result = report_encoding_test_result(tracker, &ctx, expected, observed, result, __func__); + + kmip_destroy(&ctx); + + return(result); +} + +int +test_encode_attribute_v2_unsupported_attribute(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[16] = {0}; + + KMIP ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_2_0); + + Attribute attribute = {0}; + attribute.type = -1; + int result = kmip_encode_attribute_v2(&ctx, &attribute); + if(result != KMIP_ERROR_ATTR_UNSUPPORTED) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + kmip_destroy(&ctx); + + TEST_PASSED(tracker, __func__); +} + +int +test_decode_attributes(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + /* This encoding matches the following set of values: + * Attributes + * Cryptographic Algorithm - AES + * Cryptographic Length - 128 + */ + uint8 encoding[40] = { + 0x42, 0x01, 0x25, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x42, 0x00, 0x28, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x2A, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00 + }; + + KMIP ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_2_0); + + LinkedList attribute_list = {0}; + + LinkedListItem item_1 = {0}; + Attribute attr_1 = {0}; + kmip_init_attribute(&attr_1); + enum cryptographic_algorithm algorithm = KMIP_CRYPTOALG_AES; + attr_1.type = KMIP_ATTR_CRYPTOGRAPHIC_ALGORITHM; + attr_1.value = &algorithm; + item_1.data = &attr_1; + + LinkedListItem item_2 = {0}; + Attribute attr_2 = {0}; + kmip_init_attribute(&attr_2); + int32 length = 128; + attr_2.type = KMIP_ATTR_CRYPTOGRAPHIC_LENGTH; + attr_2.value = &length; + item_2.data = &attr_2; + + kmip_linked_list_enqueue(&attribute_list, &item_1); + kmip_linked_list_enqueue(&attribute_list, &item_2); + + Attributes expected = {0}; + expected.attribute_list = &attribute_list; + + Attributes observed = {0}; + int result = kmip_decode_attributes(&ctx, &observed); + int comparison = kmip_compare_attributes(&expected, &observed); + if(!comparison) + { + kmip_print_attributes(1, &expected); + kmip_print_attributes(1, &observed); + } + result = report_decoding_test_result(tracker, &ctx, comparison, result, __func__); + + kmip_free_attributes(&ctx, &observed); + kmip_destroy(&ctx); + + return(result); +} + +int +test_decode_attributes_with_invalid_kmip_version(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[] = {0}; + + KMIP ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_4); + + Attributes observed = {0}; + int result = kmip_decode_attributes(&ctx, &observed); + + kmip_free_attributes(&ctx, &observed); + kmip_destroy(&ctx); + + result = report_result(tracker, result, KMIP_INVALID_FOR_VERSION, __func__); + return(result); +} + +int +test_decode_attribute_v2_unique_identifier(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + /* This encoding matches the following value: + * Unique Identifier - fb4b5b9c-6188-4c63-8142-fe9c328129fc + */ + uint8 encoding[48] = { + 0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, + 0x66, 0x62, 0x34, 0x62, 0x35, 0x62, 0x39, 0x63, + 0x2D, 0x36, 0x31, 0x38, 0x38, 0x2D, 0x34, 0x63, + 0x36, 0x33, 0x2D, 0x38, 0x31, 0x34, 0x32, 0x2D, + 0x66, 0x65, 0x39, 0x63, 0x33, 0x32, 0x38, 0x31, + 0x32, 0x39, 0x66, 0x63, 0x00, 0x00, 0x00, 0x00 + }; + + KMIP ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_2_0); + + Attribute expected = {0}; + kmip_init_attribute(&expected); + TextString unique_identifier = {0}; + unique_identifier.value = "fb4b5b9c-6188-4c63-8142-fe9c328129fc"; + unique_identifier.size = 36; + expected.type = KMIP_ATTR_UNIQUE_IDENTIFIER; + expected.value = &unique_identifier; + + Attribute observed = {0}; + int result = kmip_decode_attribute_v2(&ctx, &observed); + int comparison = kmip_compare_attribute(&expected, &observed); + if(!comparison) + { + kmip_print_attribute(1, &expected); + kmip_print_attribute(1, &observed); + } + result = report_decoding_test_result(tracker, &ctx, comparison, result, __func__); + + kmip_free_attribute(&ctx, &observed); + kmip_destroy(&ctx); + + return(result); +} + +int +test_decode_attribute_v2_name(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + /* This encoding matches the following value: + * Name + * Value - Template1 + * Type - Uninterpreted Text String + */ + uint8 encoding[48] = { + 0x42, 0x00, 0x53, 0x01, 0x00, 0x00, 0x00, 0x28, + 0x42, 0x00, 0x55, 0x07, 0x00, 0x00, 0x00, 0x09, + 0x54, 0x65, 0x6D, 0x70, 0x6C, 0x61, 0x74, 0x65, + 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x54, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 + }; + + KMIP ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_2_0); + + Attribute expected = {0}; + kmip_init_attribute(&expected); + TextString name_value = {0}; + name_value.value = "Template1"; + name_value.size = 9; + Name name = {0}; + name.value = &name_value; + name.type = KMIP_NAME_UNINTERPRETED_TEXT_STRING; + + expected.type = KMIP_ATTR_NAME; + expected.value = &name; + + Attribute observed = {0}; + int result = kmip_decode_attribute_v2(&ctx, &observed); + int comparison = kmip_compare_attribute(&expected, &observed); + if(!comparison) + { + kmip_print_attribute(1, &expected); + kmip_print_attribute(1, &observed); + } + result = report_decoding_test_result(tracker, &ctx, comparison, result, __func__); + + kmip_free_attribute(&ctx, &observed); + kmip_destroy(&ctx); + + return(result); +} + +int +test_decode_attribute_v2_object_type(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + /* This encoding matches the following value: + * Object Type - Symmetric Key + */ + uint8 encoding[16] = { + 0x42, 0x00, 0x57, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00 + }; + + KMIP ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_2_0); + + Attribute expected = {0}; + kmip_init_attribute(&expected); + enum object_type object_type = KMIP_OBJTYPE_SYMMETRIC_KEY; + expected.type = KMIP_ATTR_OBJECT_TYPE; + expected.value = &object_type; + + Attribute observed = {0}; + int result = kmip_decode_attribute_v2(&ctx, &observed); + int comparison = kmip_compare_attribute(&expected, &observed); + if(!comparison) + { + kmip_print_attribute(1, &expected); + kmip_print_attribute(1, &observed); + } + result = report_decoding_test_result(tracker, &ctx, comparison, result, __func__); + + kmip_free_attribute(&ctx, &observed); + kmip_destroy(&ctx); + + return(result); +} + +int +test_decode_attribute_v2_cryptographic_algorithm(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + /* This encoding matches the following value: + * Cryptographic Algorithm - AES + */ + uint8 encoding[16] = { + 0x42, 0x00, 0x28, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00 + }; + + KMIP ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_2_0); + + Attribute expected = {0}; + kmip_init_attribute(&expected); + enum cryptographic_algorithm algorithm = KMIP_CRYPTOALG_AES; + expected.type = KMIP_ATTR_CRYPTOGRAPHIC_ALGORITHM; + expected.value = &algorithm; + + Attribute observed = {0}; + int result = kmip_decode_attribute_v2(&ctx, &observed); + int comparison = kmip_compare_attribute(&expected, &observed); + if(!comparison) + { + kmip_print_attribute(1, &expected); + kmip_print_attribute(1, &observed); + } + result = report_decoding_test_result(tracker, &ctx, comparison, result, __func__); + + kmip_free_attribute(&ctx, &observed); + kmip_destroy(&ctx); + + return(result); +} + +int +test_decode_attribute_v2_cryptographic_length(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + /* This encoding matches the following value: + * Cryptographic Length - 128 + */ + uint8 encoding[16] = { + 0x42, 0x00, 0x2A, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00 + }; + + KMIP ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_2_0); + + Attribute expected = {0}; + kmip_init_attribute(&expected); + int32 length = 128; + expected.type = KMIP_ATTR_CRYPTOGRAPHIC_LENGTH; + expected.value = &length; + + Attribute observed = {0}; + int result = kmip_decode_attribute_v2(&ctx, &observed); + int comparison = kmip_compare_attribute(&expected, &observed); + if(!comparison) + { + kmip_print_attribute(1, &expected); + kmip_print_attribute(1, &observed); + } + result = report_decoding_test_result(tracker, &ctx, comparison, result, __func__); + + kmip_free_attribute(&ctx, &observed); + kmip_destroy(&ctx); + + return(result); +} + +int +test_decode_attribute_v2_cryptographic_usage_mask(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + /* This encoding matches the following value: + * Cryptographic Usage Mask - Encrypt | Decrypt + */ + uint8 encoding[16] = { + 0x42, 0x00, 0x2C, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00 + }; + + KMIP ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_2_0); + + Attribute expected = {0}; + kmip_init_attribute(&expected); + int32 mask = KMIP_CRYPTOMASK_ENCRYPT | KMIP_CRYPTOMASK_DECRYPT; + expected.type = KMIP_ATTR_CRYPTOGRAPHIC_USAGE_MASK; + expected.value = &mask; + + Attribute observed = {0}; + int result = kmip_decode_attribute_v2(&ctx, &observed); + int comparison = kmip_compare_attribute(&expected, &observed); + if(!comparison) + { + kmip_print_attribute(1, &expected); + kmip_print_attribute(1, &observed); + } + result = report_decoding_test_result(tracker, &ctx, comparison, result, __func__); + + kmip_free_attribute(&ctx, &observed); + kmip_destroy(&ctx); + + return(result); +} + +int +test_decode_attribute_v2_state(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + /* This encoding matches the following value: + * State - Active + */ + uint8 encoding[16] = { + 0x42, 0x00, 0x8D, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00 + }; + + KMIP ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_2_0); + + Attribute expected = {0}; + kmip_init_attribute(&expected); + enum state state = KMIP_STATE_ACTIVE; + expected.type = KMIP_ATTR_STATE; + expected.value = &state; + + Attribute observed = {0}; + int result = kmip_decode_attribute_v2(&ctx, &observed); + int comparison = kmip_compare_attribute(&expected, &observed); + if(!comparison) + { + kmip_print_attribute(1, &expected); + kmip_print_attribute(1, &observed); + } + result = report_decoding_test_result(tracker, &ctx, comparison, result, __func__); + + kmip_free_attribute(&ctx, &observed); + kmip_destroy(&ctx); + + return(result); +} + +int +test_decode_attribute_v2_unsupported_attribute(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[3] = {0x42, 0x00, 0x00}; + + KMIP ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_2_0); + + Attribute observed = {0}; + int result = kmip_decode_attribute_v2(&ctx, &observed); + if(result != KMIP_ERROR_ATTR_UNSUPPORTED) + { + TEST_FAILED(tracker, __func__, __LINE__); + } + + kmip_free_attribute(&ctx, &observed); + kmip_destroy(&ctx); + + TEST_PASSED(tracker, __func__); +} + +int +test_encode_template_attribute(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[288] = { + 0x42, 0x00, 0x91, 0x01, 0x00, 0x00, 0x01, 0x18, + 0x42, 0x00, 0x53, 0x01, 0x00, 0x00, 0x00, 0x28, + 0x42, 0x00, 0x55, 0x07, 0x00, 0x00, 0x00, 0x09, + 0x54, 0x65, 0x6D, 0x70, 0x6C, 0x61, 0x74, 0x65, + 0x31, 0x00, 0x00, 0x00, 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, 0x17, + 0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x41, 0x6C, + 0x67, 0x6F, 0x72, 0x69, 0x74, 0x68, 0x6D, 0x00, + 0x42, 0x00, 0x0B, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x14, + 0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x4C, 0x65, + 0x6E, 0x67, 0x74, 0x68, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x18, + 0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x55, 0x73, + 0x61, 0x67, 0x65, 0x20, 0x4D, 0x61, 0x73, 0x6B, + 0x42, 0x00, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x0C, 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[288] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0); + + struct text_string v = {0}; + v.value = "Template1"; + v.size = 9; + + struct name n = {0}; + n.value = &v; + n.type = KMIP_NAME_UNINTERPRETED_TEXT_STRING; + + struct attribute a[4] = {0}; + for(int i = 0; i < 4; i++) + { + kmip_init_attribute(&a[i]); + } + + enum cryptographic_algorithm algorithm = KMIP_CRYPTOALG_AES; + a[0].type = KMIP_ATTR_CRYPTOGRAPHIC_ALGORITHM; + a[0].value = &algorithm; + + int32 length = 128; + a[1].type = KMIP_ATTR_CRYPTOGRAPHIC_LENGTH; + a[1].value = &length; + + int32 mask = KMIP_CRYPTOMASK_ENCRYPT | KMIP_CRYPTOMASK_DECRYPT; + a[2].type = KMIP_ATTR_CRYPTOGRAPHIC_USAGE_MASK; + a[2].value = &mask; + + 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[3].type = KMIP_ATTR_NAME; + a[3].value = &name; + + struct template_attribute ta = {0}; + ta.names = &n; + ta.name_count = 1; + ta.attributes = a; + ta.attribute_count = ARRAY_LENGTH(a); + + int result = kmip_encode_template_attribute(&ctx, &ta); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_decode_template_attribute(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[288] = { + 0x42, 0x00, 0x91, 0x01, 0x00, 0x00, 0x01, 0x18, + 0x42, 0x00, 0x53, 0x01, 0x00, 0x00, 0x00, 0x28, + 0x42, 0x00, 0x55, 0x07, 0x00, 0x00, 0x00, 0x09, + 0x54, 0x65, 0x6D, 0x70, 0x6C, 0x61, 0x74, 0x65, + 0x31, 0x00, 0x00, 0x00, 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, 0x17, + 0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x41, 0x6C, + 0x67, 0x6F, 0x72, 0x69, 0x74, 0x68, 0x6D, 0x00, + 0x42, 0x00, 0x0B, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x14, + 0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x4C, 0x65, + 0x6E, 0x67, 0x74, 0x68, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x18, + 0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x55, 0x73, + 0x61, 0x67, 0x65, 0x20, 0x4D, 0x61, 0x73, 0x6B, + 0x42, 0x00, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x0C, 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_0); + + struct text_string v = {0}; + v.value = "Template1"; + v.size = 9; + + struct name n = {0}; + n.value = &v; + n.type = KMIP_NAME_UNINTERPRETED_TEXT_STRING; + + struct attribute a[4] = {0}; + for(int i = 0; i < 4; i++) + { + kmip_init_attribute(&a[i]); + } + + enum cryptographic_algorithm algorithm = KMIP_CRYPTOALG_AES; + a[0].type = KMIP_ATTR_CRYPTOGRAPHIC_ALGORITHM; + a[0].value = &algorithm; + + int32 length = 128; + a[1].type = KMIP_ATTR_CRYPTOGRAPHIC_LENGTH; + a[1].value = &length; + + int32 mask = KMIP_CRYPTOMASK_ENCRYPT | KMIP_CRYPTOMASK_DECRYPT; + a[2].type = KMIP_ATTR_CRYPTOGRAPHIC_USAGE_MASK; + a[2].value = &mask; + + 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[3].type = KMIP_ATTR_NAME; + a[3].value = &name; + + struct template_attribute expected = {0}; + expected.names = &n; + expected.name_count = 1; + expected.attributes = a; + expected.attribute_count = ARRAY_LENGTH(a); + struct template_attribute observed = {0}; + + int result = kmip_decode_template_attribute(&ctx, &observed); + result = report_decoding_test_result( + tracker, + &ctx, + kmip_compare_template_attribute(&expected, &observed), + result, + __func__); + kmip_free_template_attribute(&ctx, &observed); + kmip_destroy(&ctx); + return(result); +} + +/* +The following tests cover features added in KMIP 1.1. +*/ + +int +test_encode_device_credential(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[144] = { + 0x42, 0x00, 0x25, 0x01, 0x00, 0x00, 0x00, 0x88, + 0x42, 0x00, 0xB0, 0x07, 0x00, 0x00, 0x00, 0x0C, + 0x73, 0x65, 0x72, 0x4E, 0x75, 0x6D, 0x31, 0x32, + 0x33, 0x34, 0x35, 0x36, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xA1, 0x07, 0x00, 0x00, 0x00, 0x06, + 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x00, 0x00, + 0x42, 0x00, 0xA2, 0x07, 0x00, 0x00, 0x00, 0x09, + 0x64, 0x65, 0x76, 0x49, 0x44, 0x32, 0x32, 0x33, + 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xAB, 0x07, 0x00, 0x00, 0x00, 0x09, + 0x6E, 0x65, 0x74, 0x49, 0x44, 0x39, 0x30, 0x30, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xA9, 0x07, 0x00, 0x00, 0x00, 0x0A, + 0x6D, 0x61, 0x63, 0x68, 0x69, 0x6E, 0x65, 0x49, + 0x44, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xAA, 0x07, 0x00, 0x00, 0x00, 0x0A, + 0x6D, 0x65, 0x64, 0x69, 0x61, 0x49, 0x44, 0x33, + 0x31, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 observed[144] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_1); + + struct text_string dsn = {0}; + dsn.value = "serNum123456"; + dsn.size = 12; + + struct text_string p = {0}; + p.value = "secret"; + p.size = 6; + + struct text_string di = {0}; + di.value = "devID2233"; + di.size = 9; + + struct text_string ni = {0}; + ni.value = "netID9000"; + ni.size = 9; + + struct text_string mac = {0}; + mac.value = "machineID1"; + mac.size = 10; + + struct text_string med = {0}; + med.value = "mediaID313"; + med.size = 10; + + struct device_credential dc = {0}; + dc.device_serial_number = &dsn; + dc.password = &p; + dc.device_identifier = &di; + dc.network_identifier = ∋ + dc.machine_identifier = &mac; + dc.media_identifier = &med; + + int result = kmip_encode_device_credential(&ctx, &dc); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_decode_device_credential(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[144] = { + 0x42, 0x00, 0x25, 0x01, 0x00, 0x00, 0x00, 0x88, + 0x42, 0x00, 0xB0, 0x07, 0x00, 0x00, 0x00, 0x0C, + 0x73, 0x65, 0x72, 0x4E, 0x75, 0x6D, 0x31, 0x32, + 0x33, 0x34, 0x35, 0x36, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xA1, 0x07, 0x00, 0x00, 0x00, 0x06, + 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x00, 0x00, + 0x42, 0x00, 0xA2, 0x07, 0x00, 0x00, 0x00, 0x09, + 0x64, 0x65, 0x76, 0x49, 0x44, 0x32, 0x32, 0x33, + 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xAB, 0x07, 0x00, 0x00, 0x00, 0x09, + 0x6E, 0x65, 0x74, 0x49, 0x44, 0x39, 0x30, 0x30, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xA9, 0x07, 0x00, 0x00, 0x00, 0x0A, + 0x6D, 0x61, 0x63, 0x68, 0x69, 0x6E, 0x65, 0x49, + 0x44, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xAA, 0x07, 0x00, 0x00, 0x00, 0x0A, + 0x6D, 0x65, 0x64, 0x69, 0x61, 0x49, 0x44, 0x33, + 0x31, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + struct kmip ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_1); + + struct text_string dsn = {0}; + dsn.value = "serNum123456"; + dsn.size = 12; + + struct text_string p = {0}; + p.value = "secret"; + p.size = 6; + + struct text_string di = {0}; + di.value = "devID2233"; + di.size = 9; + + struct text_string ni = {0}; + ni.value = "netID9000"; + ni.size = 9; + + struct text_string mac = {0}; + mac.value = "machineID1"; + mac.size = 10; + + struct text_string med = {0}; + med.value = "mediaID313"; + med.size = 10; + + struct device_credential expected = {0}; + expected.device_serial_number = &dsn; + expected.password = &p; + expected.device_identifier = &di; + expected.network_identifier = ∋ + expected.machine_identifier = &mac; + expected.media_identifier = &med; + + struct device_credential observed = {0}; + + int result = kmip_decode_device_credential(&ctx, &observed); + result = report_decoding_test_result( + tracker, + &ctx, + kmip_compare_device_credential(&expected, &observed), + result, + __func__); + kmip_free_device_credential(&ctx, &observed); + kmip_destroy(&ctx); + return(result); +} + +int +test_encode_key_wrapping_data_with_encoding_option(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[120] = { + 0x42, 0x00, 0x46, 0x01, 0x00, 0x00, 0x00, 0x70, + 0x42, 0x00, 0x9E, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x36, 0x01, 0x00, 0x00, 0x00, 0x48, + 0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, + 0x31, 0x30, 0x30, 0x31, 0x38, 0x32, 0x64, 0x35, + 0x2D, 0x37, 0x32, 0x62, 0x38, 0x2D, 0x34, 0x37, + 0x61, 0x61, 0x2D, 0x38, 0x33, 0x38, 0x33, 0x2D, + 0x34, 0x64, 0x39, 0x37, 0x64, 0x35, 0x31, 0x32, + 0x65, 0x39, 0x38, 0x61, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x2B, 0x01, 0x00, 0x00, 0x00, 0x10, + 0x42, 0x00, 0x11, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xA3, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 observed[120] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_1); + + struct text_string uuid = {0}; + uuid.value = "100182d5-72b8-47aa-8383-4d97d512e98a"; + uuid.size = 36; + + struct cryptographic_parameters cp = {0}; + cp.block_cipher_mode = KMIP_BLOCK_NIST_KEY_WRAP; + + struct encryption_key_information eki = {0}; + eki.unique_identifier = &uuid; + eki.cryptographic_parameters = &cp; + + struct key_wrapping_data kwd = {0}; + kwd.wrapping_method = KMIP_WRAP_ENCRYPT; + kwd.encryption_key_info = &eki; + kwd.encoding_option = KMIP_ENCODE_NO_ENCODING; + + int result = kmip_encode_key_wrapping_data(&ctx, &kwd); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_decode_key_wrapping_data_with_encoding_option(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[120] = { + 0x42, 0x00, 0x46, 0x01, 0x00, 0x00, 0x00, 0x70, + 0x42, 0x00, 0x9E, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x36, 0x01, 0x00, 0x00, 0x00, 0x48, + 0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, + 0x31, 0x30, 0x30, 0x31, 0x38, 0x32, 0x64, 0x35, + 0x2D, 0x37, 0x32, 0x62, 0x38, 0x2D, 0x34, 0x37, + 0x61, 0x61, 0x2D, 0x38, 0x33, 0x38, 0x33, 0x2D, + 0x34, 0x64, 0x39, 0x37, 0x64, 0x35, 0x31, 0x32, + 0x65, 0x39, 0x38, 0x61, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x2B, 0x01, 0x00, 0x00, 0x00, 0x10, + 0x42, 0x00, 0x11, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xA3, 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); + + struct text_string uuid = {0}; + uuid.value = "100182d5-72b8-47aa-8383-4d97d512e98a"; + uuid.size = 36; + + struct cryptographic_parameters cp = {0}; + kmip_init_cryptographic_parameters(&cp); + cp.block_cipher_mode = KMIP_BLOCK_NIST_KEY_WRAP; + + struct encryption_key_information eki = {0}; + eki.unique_identifier = &uuid; + eki.cryptographic_parameters = &cp; + + struct key_wrapping_data expected = {0}; + expected.wrapping_method = KMIP_WRAP_ENCRYPT; + expected.encryption_key_info = &eki; + expected.encoding_option = KMIP_ENCODE_NO_ENCODING; + + struct key_wrapping_data observed = {0}; + + int result = kmip_decode_key_wrapping_data(&ctx, &observed); + result = report_decoding_test_result( + tracker, + &ctx, + kmip_compare_key_wrapping_data(&expected, &observed), + result, + __func__); + kmip_free_key_wrapping_data(&ctx, &observed); + kmip_destroy(&ctx); + return(result); +} + +int +test_encode_key_wrapping_specification_with_encoding_option(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[120] = { + 0x42, 0x00, 0x47, 0x01, 0x00, 0x00, 0x00, 0x70, + 0x42, 0x00, 0x9E, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x36, 0x01, 0x00, 0x00, 0x00, 0x48, + 0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, + 0x31, 0x30, 0x30, 0x31, 0x38, 0x32, 0x64, 0x35, + 0x2D, 0x37, 0x32, 0x62, 0x38, 0x2D, 0x34, 0x37, + 0x61, 0x61, 0x2D, 0x38, 0x33, 0x38, 0x33, 0x2D, + 0x34, 0x64, 0x39, 0x37, 0x64, 0x35, 0x31, 0x32, + 0x65, 0x39, 0x38, 0x61, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x2B, 0x01, 0x00, 0x00, 0x00, 0x10, + 0x42, 0x00, 0x11, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xA3, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 observed[120] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_1); + + struct text_string uuid = {0}; + uuid.value = "100182d5-72b8-47aa-8383-4d97d512e98a"; + uuid.size = 36; + + struct cryptographic_parameters cp = {0}; + cp.block_cipher_mode = KMIP_BLOCK_NIST_KEY_WRAP; + + struct encryption_key_information eki = {0}; + eki.unique_identifier = &uuid; + eki.cryptographic_parameters = &cp; + + struct key_wrapping_specification kws = {0}; + kws.wrapping_method = KMIP_WRAP_ENCRYPT; + kws.encryption_key_info = &eki; + kws.encoding_option = KMIP_ENCODE_NO_ENCODING; + + int result = kmip_encode_key_wrapping_specification(&ctx, &kws); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +/* +The following tests cover features added in KMIP 1.2. +*/ + +int +test_encode_nonce(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[40] = { + 0x42, 0x00, 0xC8, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x42, 0x00, 0xC9, 0x08, 0x00, 0x00, 0x00, 0x04, + 0x01, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xCA, 0x08, 0x00, 0x00, 0x00, 0x06, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00 + }; + + uint8 observed[40] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_2); + + uint8 id[4] = {0x01, 0x02, 0x03, 0x04}; + struct byte_string ni = {0}; + ni.value = id; + ni.size = ARRAY_LENGTH(id); + + uint8 value[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + struct byte_string nv = {0}; + nv.value = value; + nv.size = ARRAY_LENGTH(value); + + struct nonce n = {0}; + n.nonce_id = ∋ + n.nonce_value = &nv; + + int result = kmip_encode_nonce(&ctx, &n); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_decode_nonce(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[40] = { + 0x42, 0x00, 0xC8, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x42, 0x00, 0xC9, 0x08, 0x00, 0x00, 0x00, 0x04, + 0x01, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xCA, 0x08, 0x00, 0x00, 0x00, 0x06, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00 + }; + + struct kmip ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_2); + + uint8 id[4] = {0x01, 0x02, 0x03, 0x04}; + struct byte_string ni = {0}; + ni.value = id; + ni.size = ARRAY_LENGTH(id); + + uint8 value[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + struct byte_string nv = {0}; + nv.value = value; + nv.size = ARRAY_LENGTH(value); + + struct nonce expected = {0}; + expected.nonce_id = ∋ + expected.nonce_value = &nv; + + struct nonce observed = {0}; + + int result = kmip_decode_nonce(&ctx, &observed); + result = report_decoding_test_result( + tracker, + &ctx, + kmip_compare_nonce(&expected, &observed), + result, + __func__); + kmip_free_nonce(&ctx, &observed); + kmip_destroy(&ctx); + return(result); +} + +int +test_encode_attestation_credential(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[128] = { + 0x42, 0x00, 0x25, 0x01, 0x00, 0x00, 0x00, 0x70, + 0x42, 0x00, 0xC8, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x42, 0x00, 0xC9, 0x08, 0x00, 0x00, 0x00, 0x04, + 0x01, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xCA, 0x08, 0x00, 0x00, 0x00, 0x06, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, + 0x42, 0x00, 0xC7, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xCB, 0x08, 0x00, 0x00, 0x00, 0x10, + 0x22, 0x22, 0x22, 0x22, 0x44, 0x44, 0x44, 0x44, + 0x66, 0x66, 0x66, 0x66, 0x88, 0x88, 0x88, 0x88, + 0x42, 0x00, 0xCC, 0x08, 0x00, 0x00, 0x00, 0x14, + 0x11, 0x11, 0x11, 0x11, 0x33, 0x33, 0x33, 0x33, + 0x55, 0x55, 0x55, 0x55, 0x77, 0x77, 0x77, 0x77, + 0x99, 0x99, 0x99, 0x99, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 observed[128] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_2); + + uint8 nonce_id[4] = {0x01, 0x02, 0x03, 0x04}; + struct byte_string ni = {0}; + ni.value = nonce_id; + ni.size = ARRAY_LENGTH(nonce_id); + + uint8 nonce_value[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + struct byte_string nv = {0}; + nv.value = nonce_value; + nv.size = ARRAY_LENGTH(nonce_value); + + struct nonce n = {0}; + n.nonce_id = ∋ + n.nonce_value = &nv; + + uint8 measurement[16] = { + 0x22, 0x22, 0x22, 0x22, 0x44, 0x44, 0x44, 0x44, + 0x66, 0x66, 0x66, 0x66, 0x88, 0x88, 0x88, 0x88 + }; + struct byte_string am = {0}; + am.value = measurement; + am.size = ARRAY_LENGTH(measurement); + + uint8 assertion[20] = { + 0x11, 0x11, 0x11, 0x11, 0x33, 0x33, 0x33, 0x33, + 0x55, 0x55, 0x55, 0x55, 0x77, 0x77, 0x77, 0x77, + 0x99, 0x99, 0x99, 0x99 + }; + struct byte_string aa = {0}; + aa.value = assertion; + aa.size = ARRAY_LENGTH(assertion); + + struct attestation_credential ac = {0}; + ac.nonce = &n; + ac.attestation_type = KMIP_ATTEST_TPM_QUOTE; + ac.attestation_measurement = &am; + ac.attestation_assertion = &aa; + + int result = kmip_encode_attestation_credential(&ctx, &ac); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_decode_attestation_credential(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[128] = { + 0x42, 0x00, 0x25, 0x01, 0x00, 0x00, 0x00, 0x70, + 0x42, 0x00, 0xC8, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x42, 0x00, 0xC9, 0x08, 0x00, 0x00, 0x00, 0x04, + 0x01, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xCA, 0x08, 0x00, 0x00, 0x00, 0x06, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, + 0x42, 0x00, 0xC7, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xCB, 0x08, 0x00, 0x00, 0x00, 0x10, + 0x22, 0x22, 0x22, 0x22, 0x44, 0x44, 0x44, 0x44, + 0x66, 0x66, 0x66, 0x66, 0x88, 0x88, 0x88, 0x88, + 0x42, 0x00, 0xCC, 0x08, 0x00, 0x00, 0x00, 0x14, + 0x11, 0x11, 0x11, 0x11, 0x33, 0x33, 0x33, 0x33, + 0x55, 0x55, 0x55, 0x55, 0x77, 0x77, 0x77, 0x77, + 0x99, 0x99, 0x99, 0x99, 0x00, 0x00, 0x00, 0x00 + }; + + struct kmip ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_2); + + uint8 nonce_id[4] = {0x01, 0x02, 0x03, 0x04}; + struct byte_string ni = {0}; + ni.value = nonce_id; + ni.size = ARRAY_LENGTH(nonce_id); + + uint8 nonce_value[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + struct byte_string nv = {0}; + nv.value = nonce_value; + nv.size = ARRAY_LENGTH(nonce_value); + + struct nonce n = {0}; + n.nonce_id = ∋ + n.nonce_value = &nv; + + uint8 measurement[16] = { + 0x22, 0x22, 0x22, 0x22, 0x44, 0x44, 0x44, 0x44, + 0x66, 0x66, 0x66, 0x66, 0x88, 0x88, 0x88, 0x88 + }; + struct byte_string am = {0}; + am.value = measurement; + am.size = ARRAY_LENGTH(measurement); + + uint8 assertion[20] = { + 0x11, 0x11, 0x11, 0x11, 0x33, 0x33, 0x33, 0x33, + 0x55, 0x55, 0x55, 0x55, 0x77, 0x77, 0x77, 0x77, + 0x99, 0x99, 0x99, 0x99 + }; + struct byte_string aa = {0}; + aa.value = assertion; + aa.size = ARRAY_LENGTH(assertion); + + struct attestation_credential expected = {0}; + expected.nonce = &n; + expected.attestation_type = KMIP_ATTEST_TPM_QUOTE; + expected.attestation_measurement = &am; + expected.attestation_assertion = &aa; + + struct attestation_credential observed = {0}; + + int result = kmip_decode_attestation_credential(&ctx, &observed); + result = report_decoding_test_result( + tracker, + &ctx, + kmip_compare_attestation_credential(&expected, &observed), + result, + __func__); + kmip_free_attestation_credential(&ctx, &observed); + kmip_destroy(&ctx); + return(result); +} + +int +test_encode_request_header_with_attestation_details(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[216] = { + 0x42, 0x00, 0x77, 0x01, 0x00, 0x00, 0x00, 0xD0, + 0x42, 0x00, 0x69, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x42, 0x00, 0x6A, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x6B, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xD3, 0x06, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x42, 0x00, 0xC7, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xC7, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x0C, 0x01, 0x00, 0x00, 0x00, 0x40, + 0x42, 0x00, 0x23, 0x01, 0x00, 0x00, 0x00, 0x38, + 0x42, 0x00, 0x24, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x25, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x42, 0x00, 0x99, 0x07, 0x00, 0x00, 0x00, 0x06, + 0x42, 0x61, 0x72, 0x6E, 0x65, 0x79, 0x00, 0x00, + 0x42, 0x00, 0xA1, 0x07, 0x00, 0x00, 0x00, 0x07, + 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x32, 0x00, + 0x42, 0x00, 0x0E, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x10, 0x06, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x42, 0x00, 0x0D, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 observed[216] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_2); + + struct protocol_version pv = {0}; + pv.major = 1; + pv.minor = 0; + + struct text_string username = {0}; + username.value = "Barney"; + username.size = 6; + struct text_string password = {0}; + password.value = "secret2"; + password.size = 7; + + struct username_password_credential upc = {0}; + upc.username = &username; + upc.password = &password; + + struct credential c = {0}; + c.credential_type = KMIP_CRED_USERNAME_AND_PASSWORD; + c.credential_value = &upc; + + struct authentication a = {0}; + a.credential = &c; + + enum attestation_type types[2] = { + KMIP_ATTEST_TPM_QUOTE, + KMIP_ATTEST_SAML_ASSERTION + }; + + struct request_header rh = {0}; + kmip_init_request_header(&rh); + + rh.protocol_version = &pv; + rh.attestation_capable_indicator = KMIP_TRUE; + rh.attestation_types = types; + rh.attestation_type_count = ARRAY_LENGTH(types); + rh.authentication = &a; + rh.batch_error_continuation_option = KMIP_BATCH_CONTINUE; + rh.batch_order_option = KMIP_TRUE; + rh.batch_count = 2; + + int result = kmip_encode_request_header(&ctx, &rh); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_encode_response_header_with_attestation_details(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[152] = { + 0x42, 0x00, 0x7A, 0x01, 0x00, 0x00, 0x00, 0x90, + 0x42, 0x00, 0x69, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x42, 0x00, 0x6A, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x6B, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x92, 0x09, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x4F, 0x9A, 0x54, 0xE5, + 0x42, 0x00, 0xC8, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x42, 0x00, 0xC9, 0x08, 0x00, 0x00, 0x00, 0x04, + 0x01, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xCA, 0x08, 0x00, 0x00, 0x00, 0x06, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, + 0x42, 0x00, 0xC7, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xC7, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x0D, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 observed[152] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_2); + + struct protocol_version pv = {0}; + pv.major = 1; + pv.minor = 0; + + uint8 id[4] = {0x01, 0x02, 0x03, 0x04}; + struct byte_string ni = {0}; + ni.value = id; + ni.size = ARRAY_LENGTH(id); + + uint8 value[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + struct byte_string nv = {0}; + nv.value = value; + nv.size = ARRAY_LENGTH(value); + + struct nonce n = {0}; + n.nonce_id = ∋ + n.nonce_value = &nv; + + enum attestation_type types[2] = { + KMIP_ATTEST_TPM_QUOTE, + KMIP_ATTEST_SAML_ASSERTION + }; + + struct response_header rh = {0}; + kmip_init_response_header(&rh); + + rh.protocol_version = &pv; + rh.time_stamp = 1335514341; + rh.nonce = &n; + rh.attestation_types = types; + rh.attestation_type_count = ARRAY_LENGTH(types); + rh.batch_count = 1; + + int result = kmip_encode_response_header(&ctx, &rh); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_decode_response_header_with_attestation_details(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[152] = { + 0x42, 0x00, 0x7A, 0x01, 0x00, 0x00, 0x00, 0x90, + 0x42, 0x00, 0x69, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x42, 0x00, 0x6A, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x6B, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x92, 0x09, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x4F, 0x9A, 0x54, 0xE5, + 0x42, 0x00, 0xC8, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x42, 0x00, 0xC9, 0x08, 0x00, 0x00, 0x00, 0x04, + 0x01, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xCA, 0x08, 0x00, 0x00, 0x00, 0x06, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, + 0x42, 0x00, 0xC7, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xC7, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x0D, 0x02, 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_2); + + struct protocol_version pv = {0}; + pv.major = 1; + pv.minor = 0; + + uint8 id[4] = {0x01, 0x02, 0x03, 0x04}; + struct byte_string ni = {0}; + ni.value = id; + ni.size = ARRAY_LENGTH(id); + + uint8 value[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + struct byte_string nv = {0}; + nv.value = value; + nv.size = ARRAY_LENGTH(value); + + struct nonce n = {0}; + n.nonce_id = ∋ + n.nonce_value = &nv; + + enum attestation_type types[2] = { + KMIP_ATTEST_TPM_QUOTE, + KMIP_ATTEST_SAML_ASSERTION + }; + + struct response_header expected = {0}; + kmip_init_response_header(&expected); + + expected.protocol_version = &pv; + expected.time_stamp = 1335514341; + expected.nonce = &n; + expected.attestation_types = types; + expected.attestation_type_count = ARRAY_LENGTH(types); + expected.batch_count = 1; + + struct response_header observed = {0}; + kmip_init_response_header(&observed); + + int result = kmip_decode_response_header(&ctx, &observed); + result = report_decoding_test_result( + tracker, + &ctx, + kmip_compare_response_header(&expected, &observed), + result, + __func__); + kmip_free_response_header(&ctx, &observed); + kmip_destroy(&ctx); + return(result); +} + +int +test_encode_cryptographic_parameters_with_digital_signature_fields(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[216] = { + 0x42, 0x00, 0x2B, 0x01, 0x00, 0x00, 0x00, 0xD0, + 0x42, 0x00, 0x11, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x5F, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x38, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x83, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xAE, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x28, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xC5, 0x06, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x42, 0x00, 0xCD, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xCE, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xCF, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xD2, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xD0, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xD1, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 observed[216] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_2); + + struct cryptographic_parameters cp = {0}; + cp.block_cipher_mode = KMIP_BLOCK_CBC; + cp.padding_method = KMIP_PAD_PKCS5; + cp.hashing_algorithm = KMIP_HASH_SHA1; + cp.key_role_type = KMIP_ROLE_KEK; + + cp.digital_signature_algorithm = KMIP_DIGITAL_SHA256_WITH_RSA; + cp.cryptographic_algorithm = KMIP_CRYPTOALG_RSA; + cp.random_iv = KMIP_TRUE; + cp.iv_length = 128; + cp.tag_length = 64; + cp.fixed_field_length = 64; + cp.invocation_field_length = 64; + cp.counter_length = 256; + cp.initial_counter_value = 0; + + int result = kmip_encode_cryptographic_parameters(&ctx, &cp); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_decode_cryptographic_parameters_with_digital_signature_fields(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[216] = { + 0x42, 0x00, 0x2B, 0x01, 0x00, 0x00, 0x00, 0xD0, + 0x42, 0x00, 0x11, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x5F, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x38, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x83, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xAE, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00 ,0x00, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x28, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xC5, 0x06, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x42, 0x00, 0xCD, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xCE, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xCF, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xD2, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xD0, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xD1, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + struct kmip ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_2); + + struct cryptographic_parameters expected = {0}; + kmip_init_cryptographic_parameters(&expected); + expected.block_cipher_mode = KMIP_BLOCK_CBC; + expected.padding_method = KMIP_PAD_PKCS5; + expected.hashing_algorithm = KMIP_HASH_SHA1; + expected.key_role_type = KMIP_ROLE_KEK; + + expected.digital_signature_algorithm = KMIP_DIGITAL_SHA256_WITH_RSA; + expected.cryptographic_algorithm = KMIP_CRYPTOALG_RSA; + expected.random_iv = KMIP_TRUE; + expected.iv_length = 128; + expected.tag_length = 64; + expected.fixed_field_length = 64; + expected.invocation_field_length = 64; + expected.counter_length = 256; + expected.initial_counter_value = 0; + + struct cryptographic_parameters observed = {0}; + kmip_init_cryptographic_parameters(&observed); + + int result = kmip_decode_cryptographic_parameters(&ctx, &observed); + result = report_decoding_test_result( + tracker, + &ctx, + kmip_compare_cryptographic_parameters(&expected, &observed), + result, + __func__); + kmip_free_cryptographic_parameters(&ctx, &observed); + kmip_destroy(&ctx); + return(result); +} + +/* +The following tests cover features added in KMIP 1.4. +*/ + +int +test_encode_cryptographic_parameters_with_mask_fields(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[312] = { + 0x42, 0x00, 0x2B, 0x01, 0x00, 0x00, 0x01, 0x30, + 0x42, 0x00, 0x11, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x5F, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x38, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x83, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xAE, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x28, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xC5, 0x06, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x42, 0x00, 0xCD, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xCE, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xCF, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xD2, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xD0, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xD1, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x01, 0x01, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x01, 0x02, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x01, 0x03, 0x08, 0x00, 0x00, 0x00, 0x18, + 0x73, 0x67, 0x57, 0x80, 0x51, 0x01, 0x2A, 0x6D, + 0x13, 0x4A, 0x85, 0x5E, 0x25, 0xC8, 0xCD, 0x5E, + 0x4C, 0xA1, 0x31, 0x45, 0x57, 0x29, 0xD3, 0xC8, + 0x42, 0x01, 0x04, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 observed[312] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_4); + + uint8 value[24] = { + 0x73, 0x67, 0x57, 0x80, 0x51, 0x01, 0x2A, 0x6D, + 0x13, 0x4A, 0x85, 0x5E, 0x25, 0xC8, 0xCD, 0x5E, + 0x4C, 0xA1, 0x31, 0x45, 0x57, 0x29, 0xD3, 0xC8 + }; + struct byte_string ps = {0}; + ps.value = value; + ps.size = ARRAY_LENGTH(value); + + struct cryptographic_parameters cp = {0}; + cp.block_cipher_mode = KMIP_BLOCK_CBC; + cp.padding_method = KMIP_PAD_PKCS5; + cp.hashing_algorithm = KMIP_HASH_SHA1; + cp.key_role_type = KMIP_ROLE_KEK; + + cp.digital_signature_algorithm = KMIP_DIGITAL_SHA256_WITH_RSA; + cp.cryptographic_algorithm = KMIP_CRYPTOALG_RSA; + cp.random_iv = KMIP_TRUE; + cp.iv_length = 128; + cp.tag_length = 64; + cp.fixed_field_length = 64; + cp.invocation_field_length = 64; + cp.counter_length = 256; + cp.initial_counter_value = 0; + + cp.salt_length = 32; + cp.mask_generator = KMIP_MASKGEN_MGF1; + cp.mask_generator_hashing_algorithm = KMIP_HASH_SHA256; + cp.p_source = &ps; + cp.trailer_field = 1; + + int result = kmip_encode_cryptographic_parameters(&ctx, &cp); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_decode_cryptographic_parameters_with_mask_fields(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[312] = { + 0x42, 0x00, 0x2B, 0x01, 0x00, 0x00, 0x01, 0x30, + 0x42, 0x00, 0x11, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x5F, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x38, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x83, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xAE, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x28, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xC5, 0x06, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x42, 0x00, 0xCD, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xCE, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xCF, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xD2, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xD0, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xD1, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x01, 0x01, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x01, 0x02, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x01, 0x03, 0x08, 0x00, 0x00, 0x00, 0x18, + 0x73, 0x67, 0x57, 0x80, 0x51, 0x01, 0x2A, 0x6D, + 0x13, 0x4A, 0x85, 0x5E, 0x25, 0xC8, 0xCD, 0x5E, + 0x4C, 0xA1, 0x31, 0x45, 0x57, 0x29, 0xD3, 0xC8, + 0x42, 0x01, 0x04, 0x02, 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_4); + + uint8 value[24] = { + 0x73, 0x67, 0x57, 0x80, 0x51, 0x01, 0x2A, 0x6D, + 0x13, 0x4A, 0x85, 0x5E, 0x25, 0xC8, 0xCD, 0x5E, + 0x4C, 0xA1, 0x31, 0x45, 0x57, 0x29, 0xD3, 0xC8 + }; + struct byte_string ps = {0}; + ps.value = value; + ps.size = ARRAY_LENGTH(value); + + struct cryptographic_parameters expected = {0}; + kmip_init_cryptographic_parameters(&expected); + + expected.block_cipher_mode = KMIP_BLOCK_CBC; + expected.padding_method = KMIP_PAD_PKCS5; + expected.hashing_algorithm = KMIP_HASH_SHA1; + expected.key_role_type = KMIP_ROLE_KEK; + + expected.digital_signature_algorithm = KMIP_DIGITAL_SHA256_WITH_RSA; + expected.cryptographic_algorithm = KMIP_CRYPTOALG_RSA; + expected.random_iv = KMIP_TRUE; + expected.iv_length = 128; + expected.tag_length = 64; + expected.fixed_field_length = 64; + expected.invocation_field_length = 64; + expected.counter_length = 256; + expected.initial_counter_value = 0; + + expected.salt_length = 32; + expected.mask_generator = KMIP_MASKGEN_MGF1; + expected.mask_generator_hashing_algorithm = KMIP_HASH_SHA256; + expected.p_source = &ps; + expected.trailer_field = 1; + + struct cryptographic_parameters observed = {0}; + kmip_init_cryptographic_parameters(&observed); + + int result = kmip_decode_cryptographic_parameters(&ctx, &observed); + result = report_decoding_test_result( + tracker, + &ctx, + kmip_compare_cryptographic_parameters(&expected, &observed), + result, + __func__); + kmip_free_cryptographic_parameters(&ctx, &observed); + kmip_destroy(&ctx); + return(result); +} + +int +test_encode_get_request_payload_with_wrap_type(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[104] = { + 0x42, 0x00, 0x79, 0x01, 0x00, 0x00, 0x00, 0x60, + 0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, + 0x37, 0x63, 0x66, 0x35, 0x32, 0x30, 0x39, 0x62, + 0x2D, 0x36, 0x66, 0x66, 0x36, 0x2D, 0x34, 0x34, + 0x32, 0x36, 0x2D, 0x38, 0x39, 0x39, 0x65, 0x2D, + 0x32, 0x32, 0x62, 0x30, 0x36, 0x37, 0x38, 0x35, + 0x39, 0x33, 0x37, 0x32, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x42, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xF8, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x41, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 observed[104] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_4); + + struct text_string uuid = {0}; + uuid.value = "7cf5209b-6ff6-4426-899e-22b067859372"; + uuid.size = 36; + + struct get_request_payload grp = {0}; + grp.unique_identifier = &uuid; + grp.key_format_type = KMIP_KEYFORMAT_PKCS1; + grp.key_compression_type = KMIP_KEYCOMP_EC_PUB_UNCOMPRESSED; + + grp.key_wrap_type = KMIP_WRAPTYPE_NOT_WRAPPED; + + int result = kmip_encode_get_request_payload(&ctx, &grp); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_encode_request_header_with_correlation_values(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[280] = { + 0x42, 0x00, 0x77, 0x01, 0x00, 0x00, 0x01, 0x10, + 0x42, 0x00, 0x69, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x42, 0x00, 0x6A, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x6B, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x50, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x01, 0x05, 0x07, 0x00, 0x00, 0x00, 0x08, + 0x63, 0x6C, 0x69, 0x65, 0x6E, 0x74, 0x20, 0x31, + 0x42, 0x01, 0x06, 0x07, 0x00, 0x00, 0x00, 0x08, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x31, + 0x42, 0x00, 0x07, 0x06, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x42, 0x00, 0xD3, 0x06, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x42, 0x00, 0xC7, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xC7, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x0C, 0x01, 0x00, 0x00, 0x00, 0x40, + 0x42, 0x00, 0x23, 0x01, 0x00, 0x00, 0x00, 0x38, + 0x42, 0x00, 0x24, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x25, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x42, 0x00, 0x99, 0x07, 0x00, 0x00, 0x00, 0x06, + 0x42, 0x61, 0x72, 0x6E, 0x65, 0x79, 0x00, 0x00, + 0x42, 0x00, 0xA1, 0x07, 0x00, 0x00, 0x00, 0x07, + 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x32, 0x00, + 0x42, 0x00, 0x0E, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x10, 0x06, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x42, 0x00, 0x0D, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 observed[280] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_4); + + struct protocol_version pv = {0}; + pv.major = 1; + pv.minor = 0; + + struct text_string username = {0}; + username.value = "Barney"; + username.size = 6; + struct text_string password = {0}; + password.value = "secret2"; + password.size = 7; + + struct username_password_credential upc = {0}; + upc.username = &username; + upc.password = &password; + + struct credential c = {0}; + c.credential_type = KMIP_CRED_USERNAME_AND_PASSWORD; + c.credential_value = &upc; + + struct authentication a = {0}; + a.credential = &c; + + enum attestation_type types[2] = { + KMIP_ATTEST_TPM_QUOTE, + KMIP_ATTEST_SAML_ASSERTION + }; + + struct text_string ccv = {0}; + ccv.value = "client 1"; + ccv.size = 8; + + struct text_string scv = {0}; + scv.value = "server 1"; + scv.size = 8; + + struct request_header rh = {0}; + kmip_init_request_header(&rh); + + rh.protocol_version = &pv; + rh.maximum_response_size = 4096; + rh.asynchronous_indicator = KMIP_TRUE; + rh.attestation_capable_indicator = KMIP_TRUE; + rh.attestation_types = types; + rh.attestation_type_count = ARRAY_LENGTH(types); + rh.authentication = &a; + rh.batch_error_continuation_option = KMIP_BATCH_CONTINUE; + rh.batch_order_option = KMIP_TRUE; + rh.batch_count = 2; + + rh.client_correlation_value = &ccv; + rh.server_correlation_value = &scv; + + int result = kmip_encode_request_header(&ctx, &rh); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_encode_response_header_with_correlation_values(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[184] = { + 0x42, 0x00, 0x7A, 0x01, 0x00, 0x00, 0x00, 0xB0, + 0x42, 0x00, 0x69, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x42, 0x00, 0x6A, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x6B, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x92, 0x09, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x4F, 0x9A, 0x54, 0xE5, + 0x42, 0x00, 0xC8, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x42, 0x00, 0xC9, 0x08, 0x00, 0x00, 0x00, 0x04, + 0x01, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xCA, 0x08, 0x00, 0x00, 0x00, 0x06, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, + 0x42, 0x00, 0xC7, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xC7, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x01, 0x05, 0x07, 0x00, 0x00, 0x00, 0x08, + 0x63, 0x6C, 0x69, 0x65, 0x6E, 0x74, 0x20, 0x31, + 0x42, 0x01, 0x06, 0x07, 0x00, 0x00, 0x00, 0x08, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x31, + 0x42, 0x00, 0x0D, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 observed[184] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_4); + + struct protocol_version pv = {0}; + pv.major = 1; + pv.minor = 0; + + uint8 id[4] = {0x01, 0x02, 0x03, 0x04}; + struct byte_string ni = {0}; + ni.value = id; + ni.size = ARRAY_LENGTH(id); + + uint8 value[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + struct byte_string nv = {0}; + nv.value = value; + nv.size = ARRAY_LENGTH(value); + + struct nonce n = {0}; + n.nonce_id = ∋ + n.nonce_value = &nv; + + enum attestation_type types[2] = { + KMIP_ATTEST_TPM_QUOTE, + KMIP_ATTEST_SAML_ASSERTION + }; + + struct text_string ccv = {0}; + ccv.value = "client 1"; + ccv.size = 8; + + struct text_string scv = {0}; + scv.value = "server 1"; + scv.size = 8; + + struct response_header rh = {0}; + kmip_init_response_header(&rh); + + rh.protocol_version = &pv; + rh.time_stamp = 1335514341; + rh.nonce = &n; + rh.attestation_types = types; + rh.attestation_type_count = ARRAY_LENGTH(types); + rh.batch_count = 1; + + rh.client_correlation_value = &ccv; + rh.server_correlation_value = &scv; + + int result = kmip_encode_response_header(&ctx, &rh); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_decode_response_header_with_correlation_values(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 encoding[184] = { + 0x42, 0x00, 0x7A, 0x01, 0x00, 0x00, 0x00, 0xB0, + 0x42, 0x00, 0x69, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x42, 0x00, 0x6A, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x6B, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x92, 0x09, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x4F, 0x9A, 0x54, 0xE5, + 0x42, 0x00, 0xC8, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x42, 0x00, 0xC9, 0x08, 0x00, 0x00, 0x00, 0x04, + 0x01, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xCA, 0x08, 0x00, 0x00, 0x00, 0x06, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, + 0x42, 0x00, 0xC7, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xC7, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x01, 0x05, 0x07, 0x00, 0x00, 0x00, 0x08, + 0x63, 0x6C, 0x69, 0x65, 0x6E, 0x74, 0x20, 0x31, + 0x42, 0x01, 0x06, 0x07, 0x00, 0x00, 0x00, 0x08, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x31, + 0x42, 0x00, 0x0D, 0x02, 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_4); + + struct protocol_version pv = {0}; + pv.major = 1; + pv.minor = 0; + + uint8 id[4] = {0x01, 0x02, 0x03, 0x04}; + struct byte_string ni = {0}; + ni.value = id; + ni.size = ARRAY_LENGTH(id); + + uint8 value[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + struct byte_string nv = {0}; + nv.value = value; + nv.size = ARRAY_LENGTH(value); + + struct nonce n = {0}; + n.nonce_id = ∋ + n.nonce_value = &nv; + + enum attestation_type types[2] = { + KMIP_ATTEST_TPM_QUOTE, + KMIP_ATTEST_SAML_ASSERTION + }; + + struct text_string ccv = {0}; + ccv.value = "client 1"; + ccv.size = 8; + + struct text_string scv = {0}; + scv.value = "server 1"; + scv.size = 8; + + struct response_header expected = {0}; + kmip_init_response_header(&expected); + + expected.protocol_version = &pv; + expected.time_stamp = 1335514341; + expected.nonce = &n; + expected.attestation_types = types; + expected.attestation_type_count = ARRAY_LENGTH(types); + expected.batch_count = 1; + + expected.client_correlation_value = &ccv; + expected.server_correlation_value = &scv; + + struct response_header observed = {0}; + kmip_init_response_header(&observed); + + int result = kmip_decode_response_header(&ctx, &observed); + result = report_decoding_test_result( + tracker, + &ctx, + kmip_compare_response_header(&expected, &observed), + result, + __func__); + kmip_free_response_header(&ctx, &observed); + kmip_destroy(&ctx); + return(result); +} + +int +test_encode_response_header_kmip_2_0(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + /* This encoding matches the following set of values: + * Response Header + * Protocol Version + * Protocol Version Major - 2 + * Protocol Version Minor - 0 + * Time Stamp - 1335514341 + * Nonce + * Nonce ID - 0x01020304 + * Nonce Value - 0xFFFFFFFFFFFF + * Server Hashed Password - 301EC144E9C6C4F64C29C01C3E11839C97D6E7D2BC0C5DBC68377B679AE51D4D + * Attestation Type - TPM Quote + * Attestation Type - SAML Assertion + * Client Correlation Value - client 1 + * Server Correlation Value - server 1 + * Batch Count - 1 + */ + uint8 expected[224] = { + 0x42, 0x00, 0x7A, 0x01, 0x00, 0x00, 0x00, 0xD8, + 0x42, 0x00, 0x69, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x42, 0x00, 0x6A, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x6B, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x92, 0x09, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x4F, 0x9A, 0x54, 0xE5, + 0x42, 0x00, 0xC8, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x42, 0x00, 0xC9, 0x08, 0x00, 0x00, 0x00, 0x04, + 0x01, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xCA, 0x08, 0x00, 0x00, 0x00, 0x06, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, + 0x42, 0x01, 0x55, 0x08, 0x00, 0x00, 0x00, 0x20, + 0x30, 0x1E, 0xC1, 0x44, 0xE9, 0xC6, 0xC4, 0xF6, + 0x4C, 0x29, 0xC0, 0x1C, 0x3E, 0x11, 0x83, 0x9C, + 0x97, 0xD6, 0xE7, 0xD2, 0xBC, 0x0C, 0x5D, 0xBC, + 0x68, 0x37, 0x7B, 0x67, 0x9A, 0xE5, 0x1D, 0x4D, + 0x42, 0x00, 0xC7, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xC7, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x01, 0x05, 0x07, 0x00, 0x00, 0x00, 0x08, + 0x63, 0x6C, 0x69, 0x65, 0x6E, 0x74, 0x20, 0x31, + 0x42, 0x01, 0x06, 0x07, 0x00, 0x00, 0x00, 0x08, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x31, + 0x42, 0x00, 0x0D, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 observed[224] = {0}; + KMIP ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_2_0); + + ProtocolVersion pv = {0}; + pv.major = 2; + pv.minor = 0; + + uint8 id[4] = {0x01, 0x02, 0x03, 0x04}; + ByteString ni = {0}; + ni.value = id; + ni.size = ARRAY_LENGTH(id); + + uint8 value[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + ByteString nv = {0}; + nv.value = value; + nv.size = ARRAY_LENGTH(value); + + Nonce n = {0}; + n.nonce_id = ∋ + n.nonce_value = &nv; + + uint8 hash[32] = { + 0x30, 0x1E, 0xC1, 0x44, 0xE9, 0xC6, 0xC4, 0xF6, + 0x4C, 0x29, 0xC0, 0x1C, 0x3E, 0x11, 0x83, 0x9C, + 0x97, 0xD6, 0xE7, 0xD2, 0xBC, 0x0C, 0x5D, 0xBC, + 0x68, 0x37, 0x7B, 0x67, 0x9A, 0xE5, 0x1D, 0x4D + }; + ByteString shp = {0}; + shp.value = hash; + shp.size = ARRAY_LENGTH(hash); + + enum attestation_type types[2] = { + KMIP_ATTEST_TPM_QUOTE, + KMIP_ATTEST_SAML_ASSERTION + }; + + TextString ccv = {0}; + ccv.value = "client 1"; + ccv.size = 8; + + TextString scv = {0}; + scv.value = "server 1"; + scv.size = 8; + + ResponseHeader rh = {0}; + kmip_init_response_header(&rh); + + rh.protocol_version = &pv; + rh.time_stamp = 1335514341; + rh.nonce = &n; + rh.server_hashed_password = &shp; + rh.attestation_types = types; + rh.attestation_type_count = ARRAY_LENGTH(types); + rh.batch_count = 1; + + rh.client_correlation_value = &ccv; + rh.server_correlation_value = &scv; + + int result = kmip_encode_response_header(&ctx, &rh); + result = report_encoding_test_result(tracker, &ctx, expected, observed, result, __func__); + + kmip_destroy(&ctx); + return(result); +} + +int +test_decode_response_header_kmip_2_0(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + /* This encoding matches the following set of values: + * Response Header + * Protocol Version + * Protocol Version Major - 2 + * Protocol Version Minor - 0 + * Time Stamp - 1335514341 + * Nonce + * Nonce ID - 0x01020304 + * Nonce Value - 0xFFFFFFFFFFFF + * Server Hashed Password - 301EC144E9C6C4F64C29C01C3E11839C97D6E7D2BC0C5DBC68377B679AE51D4D + * Attestation Type - TPM Quote + * Attestation Type - SAML Assertion + * Client Correlation Value - client 1 + * Server Correlation Value - server 1 + * Batch Count - 1 + */ + uint8 encoding[224] = { + 0x42, 0x00, 0x7A, 0x01, 0x00, 0x00, 0x00, 0xD8, + 0x42, 0x00, 0x69, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x42, 0x00, 0x6A, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x6B, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x92, 0x09, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x4F, 0x9A, 0x54, 0xE5, + 0x42, 0x00, 0xC8, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x42, 0x00, 0xC9, 0x08, 0x00, 0x00, 0x00, 0x04, + 0x01, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xCA, 0x08, 0x00, 0x00, 0x00, 0x06, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, + 0x42, 0x01, 0x55, 0x08, 0x00, 0x00, 0x00, 0x20, + 0x30, 0x1E, 0xC1, 0x44, 0xE9, 0xC6, 0xC4, 0xF6, + 0x4C, 0x29, 0xC0, 0x1C, 0x3E, 0x11, 0x83, 0x9C, + 0x97, 0xD6, 0xE7, 0xD2, 0xBC, 0x0C, 0x5D, 0xBC, + 0x68, 0x37, 0x7B, 0x67, 0x9A, 0xE5, 0x1D, 0x4D, + 0x42, 0x00, 0xC7, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xC7, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x01, 0x05, 0x07, 0x00, 0x00, 0x00, 0x08, + 0x63, 0x6C, 0x69, 0x65, 0x6E, 0x74, 0x20, 0x31, + 0x42, 0x01, 0x06, 0x07, 0x00, 0x00, 0x00, 0x08, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x31, + 0x42, 0x00, 0x0D, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 + }; + + KMIP ctx = {0}; + kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_2_0); + + ProtocolVersion pv = {0}; + pv.major = 2; + pv.minor = 0; + + uint8 id[4] = {0x01, 0x02, 0x03, 0x04}; + ByteString ni = {0}; + ni.value = id; + ni.size = ARRAY_LENGTH(id); + + uint8 value[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + ByteString nv = {0}; + nv.value = value; + nv.size = ARRAY_LENGTH(value); + + Nonce n = {0}; + n.nonce_id = ∋ + n.nonce_value = &nv; + + uint8 hash[32] = { + 0x30, 0x1E, 0xC1, 0x44, 0xE9, 0xC6, 0xC4, 0xF6, + 0x4C, 0x29, 0xC0, 0x1C, 0x3E, 0x11, 0x83, 0x9C, + 0x97, 0xD6, 0xE7, 0xD2, 0xBC, 0x0C, 0x5D, 0xBC, + 0x68, 0x37, 0x7B, 0x67, 0x9A, 0xE5, 0x1D, 0x4D + }; + ByteString shp = {0}; + shp.value = hash; + shp.size = ARRAY_LENGTH(hash); + + enum attestation_type types[2] = { + KMIP_ATTEST_TPM_QUOTE, + KMIP_ATTEST_SAML_ASSERTION + }; + + TextString ccv = {0}; + ccv.value = "client 1"; + ccv.size = 8; + + TextString scv = {0}; + scv.value = "server 1"; + scv.size = 8; + + ResponseHeader expected = {0}; + kmip_init_response_header(&expected); + + expected.protocol_version = &pv; + expected.time_stamp = 1335514341; + expected.nonce = &n; + expected.server_hashed_password = &shp; + expected.attestation_types = types; + expected.attestation_type_count = ARRAY_LENGTH(types); + expected.batch_count = 1; + + expected.client_correlation_value = &ccv; + expected.server_correlation_value = &scv; + + ResponseHeader observed = {0}; + kmip_init_response_header(&observed); + + int result = kmip_decode_response_header(&ctx, &observed); + int comparison = kmip_compare_response_header(&expected, &observed); + if(!comparison) + { + /* TODO (ph) Reorder these with printing result so that objects are + below function name. + */ + kmip_print_response_header(1, &expected); + kmip_print_response_header(1, &observed); + } + result = report_decoding_test_result(tracker, &ctx, comparison, result, __func__); + + kmip_free_response_header(&ctx, &observed); + kmip_destroy(&ctx); + return(result); +} + +/* +The following tests are taken verbatim from the KMIP 1.1 Test Cases +documentation, available here: + +http://docs.oasis-open.org/kmip/testcases/v1.1/kmip-testcases-v1.1.html +*/ + +int +test_kmip_1_1_test_suite_3_1_1_0_a(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + /* KMIP 1.1 Test Suite - Test 3.1.1.0a */ + uint8 expected[296] = { + 0x42, 0x00, 0x78, 0x01, 0x00, 0x00, 0x01, 0x20, + 0x42, 0x00, 0x77, 0x01, 0x00, 0x00, 0x00, 0x38, + 0x42, 0x00, 0x69, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x42, 0x00, 0x6A, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x6B, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x0D, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x0F, 0x01, 0x00, 0x00, 0x00, 0xD8, + 0x42, 0x00, 0x5C, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x79, 0x01, 0x00, 0x00, 0x00, 0xC0, + 0x42, 0x00, 0x57, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x91, 0x01, 0x00, 0x00, 0x00, 0xA8, + 0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x17, + 0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x41, 0x6C, + 0x67, 0x6F, 0x72, 0x69, 0x74, 0x68, 0x6D, 0x00, + 0x42, 0x00, 0x0B, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x14, + 0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x4C, 0x65, + 0x6E, 0x67, 0x74, 0x68, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, + 0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x18, + 0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x55, 0x73, + 0x61, 0x67, 0x65, 0x20, 0x4D, 0x61, 0x73, 0x6B, + 0x42, 0x00, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 observed[296] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_1); + + /* TODO (ph) If protocol version omitted, pull from context? */ + struct protocol_version pv = {0}; + pv.major = 1; + pv.minor = 1; + + struct request_header rh = {0}; + kmip_init_request_header(&rh); + + rh.protocol_version = &pv; + rh.batch_count = 1; + + struct attribute a[3] = {0}; + for(int i = 0; i < 3; i++) + { + kmip_init_attribute(&a[i]); + } + + enum cryptographic_algorithm algorithm = KMIP_CRYPTOALG_AES; + a[0].type = KMIP_ATTR_CRYPTOGRAPHIC_ALGORITHM; + a[0].value = &algorithm; + + int32 length = 128; + a[1].type = KMIP_ATTR_CRYPTOGRAPHIC_LENGTH; + a[1].value = &length; + + int32 mask = KMIP_CRYPTOMASK_ENCRYPT | KMIP_CRYPTOMASK_DECRYPT; + a[2].type = KMIP_ATTR_CRYPTOGRAPHIC_USAGE_MASK; + a[2].value = &mask; + + struct template_attribute ta = {0}; + ta.attributes = a; + ta.attribute_count = ARRAY_LENGTH(a); + + struct create_request_payload crp = {0}; + crp.object_type = KMIP_OBJTYPE_SYMMETRIC_KEY; + crp.template_attribute = &ta; + + struct request_batch_item rbi = {0}; + kmip_init_request_batch_item(&rbi); + rbi.operation = KMIP_OP_CREATE; + rbi.request_payload = &crp; + + struct request_message rm = {0}; + rm.request_header = &rh; + rm.batch_items = &rbi; + rm.batch_count = 1; + + int result = kmip_encode_request_message(&ctx, &rm); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_kmip_1_1_test_suite_3_1_1_0_b(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + /* KMIP 1.1 Test Suite - Test 3.1.1.0b */ + uint8 expected[200] = { + 0x42, 0x00, 0x7B, 0x01, 0x00, 0x00, 0x00, 0xC0, + 0x42, 0x00, 0x7A, 0x01, 0x00, 0x00, 0x00, 0x48, + 0x42, 0x00, 0x69, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x42, 0x00, 0x6A, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x6B, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x92, 0x09, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x4F, 0x9A, 0x54, 0xE5, + 0x42, 0x00, 0x0D, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x0F, 0x01, 0x00, 0x00, 0x00, 0x68, + 0x42, 0x00, 0x5C, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x7F, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x7C, 0x01, 0x00, 0x00, 0x00, 0x40, + 0x42, 0x00, 0x57, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, + 0x66, 0x62, 0x34, 0x62, 0x35, 0x62, 0x39, 0x63, + 0x2D, 0x36, 0x31, 0x38, 0x38, 0x2D, 0x34, 0x63, + 0x36, 0x33, 0x2D, 0x38, 0x31, 0x34, 0x32, 0x2D, + 0x66, 0x65, 0x39, 0x63, 0x33, 0x32, 0x38, 0x31, + 0x32, 0x39, 0x66, 0x63, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 observed[200] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0); + + struct protocol_version pv = {0}; + pv.major = 1; + pv.minor = 1; + + struct response_header rh = {0}; + kmip_init_response_header(&rh); + + rh.protocol_version = &pv; + rh.time_stamp = 1335514341; + rh.batch_count = 1; + + struct text_string uuid = {0}; + uuid.value = "fb4b5b9c-6188-4c63-8142-fe9c328129fc"; + uuid.size = 36; + + struct create_response_payload crp = {0}; + crp.object_type = KMIP_OBJTYPE_SYMMETRIC_KEY; + crp.unique_identifier = &uuid; + + struct response_batch_item rbi = {0}; + rbi.operation = KMIP_OP_CREATE; + rbi.result_status = KMIP_STATUS_SUCCESS; + rbi.response_payload = &crp; + + struct response_message rm = {0}; + rm.response_header = &rh; + rm.batch_items = &rbi; + rm.batch_count = 1; + + int result = kmip_encode_response_message(&ctx, &rm); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_kmip_1_1_test_suite_3_1_1_1_a(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + /* KMIP 1.1 Test Suite - Test 3.1.1.1a */ + uint8 expected[152] = { + 0x42, 0x00, 0x78, 0x01, 0x00, 0x00, 0x00, 0x90, + 0x42, 0x00, 0x77, 0x01, 0x00, 0x00, 0x00, 0x38, + 0x42, 0x00, 0x69, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x42, 0x00, 0x6A, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x6B, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x0D, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x0F, 0x01, 0x00, 0x00, 0x00, 0x48, + 0x42, 0x00, 0x5C, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x79, 0x01, 0x00, 0x00, 0x00, 0x30, + 0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, + 0x66, 0x62, 0x34, 0x62, 0x35, 0x62, 0x39, 0x63, + 0x2D, 0x36, 0x31, 0x38, 0x38, 0x2D, 0x34, 0x63, + 0x36, 0x33, 0x2D, 0x38, 0x31, 0x34, 0x32, 0x2D, + 0x66, 0x65, 0x39, 0x63, 0x33, 0x32, 0x38, 0x31, + 0x32, 0x39, 0x66, 0x63, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 observed[152] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_1); + + struct protocol_version pv = {0}; + pv.major = 1; + pv.minor = 1; + + struct request_header rh = {0}; + kmip_init_request_header(&rh); + + rh.protocol_version = &pv; + rh.batch_count = 1; + + struct text_string uuid = {0}; + uuid.value = "fb4b5b9c-6188-4c63-8142-fe9c328129fc"; + uuid.size = 36; + + struct destroy_request_payload drp = {0}; + drp.unique_identifier = &uuid; + + struct request_batch_item rbi = {0}; + kmip_init_request_batch_item(&rbi); + rbi.operation = KMIP_OP_DESTROY; + rbi.request_payload = &drp; + + struct request_message rm = {0}; + rm.request_header = &rh; + rm.batch_items = &rbi; + rm.batch_count = 1; + + int result = kmip_encode_request_message(&ctx, &rm); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_kmip_1_1_test_suite_3_1_1_1_b(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + /* KMIP 1.1 Test Suite - Test 3.1.1.1b */ + uint8 expected[184] = { + 0x42, 0x00, 0x7B, 0x01, 0x00, 0x00, 0x00, 0xB0, + 0x42, 0x00, 0x7A, 0x01, 0x00, 0x00, 0x00, 0x48, + 0x42, 0x00, 0x69, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x42, 0x00, 0x6A, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x6B, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x92, 0x09, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x4F, 0x9A, 0x54, 0xE5, + 0x42, 0x00, 0x0D, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x0F, 0x01, 0x00, 0x00, 0x00, 0x58, + 0x42, 0x00, 0x5C, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x7F, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x7C, 0x01, 0x00, 0x00, 0x00, 0x30, + 0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, + 0x66, 0x62, 0x34, 0x62, 0x35, 0x62, 0x39, 0x63, + 0x2D, 0x36, 0x31, 0x38, 0x38, 0x2D, 0x34, 0x63, + 0x36, 0x33, 0x2D, 0x38, 0x31, 0x34, 0x32, 0x2D, + 0x66, 0x65, 0x39, 0x63, 0x33, 0x32, 0x38, 0x31, + 0x32, 0x39, 0x66, 0x63, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 observed[184] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_1); + + struct protocol_version pv = {0}; + pv.major = 1; + pv.minor = 1; + + struct response_header rh = {0}; + kmip_init_response_header(&rh); + + rh.protocol_version = &pv; + rh.time_stamp = 1335514341; + rh.batch_count = 1; + + struct text_string uuid = {0}; + uuid.value = "fb4b5b9c-6188-4c63-8142-fe9c328129fc"; + uuid.size = 36; + + struct destroy_response_payload drp = {0}; + drp.unique_identifier = &uuid; + + struct response_batch_item rbi = {0}; + rbi.operation = KMIP_OP_DESTROY; + rbi.result_status = KMIP_STATUS_SUCCESS; + rbi.response_payload = &drp; + + struct response_message rm = {0}; + rm.response_header = &rh; + rm.batch_items = &rbi; + rm.batch_count = 1; + + int result = kmip_encode_response_message(&ctx, &rm); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_kmip_1_1_test_suite_3_1_3_2_a(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + /* KMIP 1.1 Test Suite - Test 3.1.3.2a */ + uint8 expected[152] = { + 0x42, 0x00, 0x78, 0x01, 0x00, 0x00, 0x00, 0x90, + 0x42, 0x00, 0x77, 0x01, 0x00, 0x00, 0x00, 0x38, + 0x42, 0x00, 0x69, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x42, 0x00, 0x6A, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x6B, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x0D, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x0F, 0x01, 0x00, 0x00, 0x00, 0x48, + 0x42, 0x00, 0x5C, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x79, 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[152] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_1); + + struct protocol_version pv = {0}; + pv.major = 1; + pv.minor = 1; + + struct request_header rh = {0}; + kmip_init_request_header(&rh); + + rh.protocol_version = &pv; + rh.batch_count = 1; + + struct text_string uuid = {0}; + uuid.value = "49a1ca88-6bea-4fb2-b450-7e58802c3038"; + uuid.size = 36; + + struct get_request_payload grp = {0}; + grp.unique_identifier = &uuid; + + struct request_batch_item rbi = {0}; + kmip_init_request_batch_item(&rbi); + rbi.operation = KMIP_OP_GET; + rbi.request_payload = &grp; + + struct request_message rm = {0}; + rm.request_header = &rh; + rm.batch_items = &rbi; + rm.batch_count = 1; + + int result = kmip_encode_request_message(&ctx, &rm); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +int +test_kmip_1_1_test_suite_3_1_3_2_b(TestTracker *tracker) +{ + TRACK_TEST(tracker); + + uint8 expected[304] = { + 0x42, 0x00, 0x7B, 0x01, 0x00, 0x00, 0x01, 0x28, + 0x42, 0x00, 0x7A, 0x01, 0x00, 0x00, 0x00, 0x48, + 0x42, 0x00, 0x69, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x42, 0x00, 0x6A, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x6B, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x92, 0x09, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x4F, 0x9A, 0x54, 0xE7, + 0x42, 0x00, 0x0D, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x0F, 0x01, 0x00, 0x00, 0x00, 0xD0, + 0x42, 0x00, 0x5C, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x7F, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x7C, 0x01, 0x00, 0x00, 0x00, 0xA8, + 0x42, 0x00, 0x57, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, + 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, + 0x42, 0x00, 0x8F, 0x01, 0x00, 0x00, 0x00, 0x60, + 0x42, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x58, + 0x42, 0x00, 0x42, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x45, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x42, 0x00, 0x43, 0x08, 0x00, 0x00, 0x00, 0x18, + 0x73, 0x67, 0x57, 0x80, 0x51, 0x01, 0x2A, 0x6D, + 0x13, 0x4A, 0x85, 0x5E, 0x25, 0xC8, 0xCD, 0x5E, + 0x4C, 0xA1, 0x31, 0x45, 0x57, 0x29, 0xD3, 0xC8, + 0x42, 0x00, 0x28, 0x05, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x2A, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0xA8, 0x00, 0x00, 0x00, 0x00 + }; + + uint8 observed[304] = {0}; + struct kmip ctx = {0}; + kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_1); + + struct protocol_version pv = {0}; + pv.major = 1; + pv.minor = 1; + + struct response_header rh = {0}; + kmip_init_response_header(&rh); + + rh.protocol_version = &pv; + rh.time_stamp = 1335514343; + rh.batch_count = 1; + + struct text_string uuid = {0}; + uuid.value = "49a1ca88-6bea-4fb2-b450-7e58802c3038"; + uuid.size = 36; + + uint8 value[24] = { + 0x73, 0x67, 0x57, 0x80, 0x51, 0x01, 0x2A, 0x6D, + 0x13, 0x4A, 0x85, 0x5E, 0x25, 0xC8, 0xCD, 0x5E, + 0x4C, 0xA1, 0x31, 0x45, 0x57, 0x29, 0xD3, 0xC8 + }; + + struct byte_string v = {0}; + v.value = value; + v.size = ARRAY_LENGTH(value); + + struct key_value kv = {0}; + kv.key_material = &v; + + struct key_block kb = {0}; + kb.key_format_type = KMIP_KEYFORMAT_RAW; + kb.key_value = &kv; + kb.cryptographic_algorithm = KMIP_CRYPTOALG_TRIPLE_DES; + kb.cryptographic_length = 168; + + struct symmetric_key key = {0}; + key.key_block = &kb; + + struct get_response_payload grp = {0}; + grp.object_type = KMIP_OBJTYPE_SYMMETRIC_KEY; + grp.unique_identifier = &uuid; + grp.object = &key; + + struct response_batch_item rbi = {0}; + rbi.operation = KMIP_OP_GET; + rbi.result_status = KMIP_STATUS_SUCCESS; + rbi.response_payload = &grp; + + struct response_message rm = {0}; + rm.response_header = &rh; + rm.batch_items = &rbi; + rm.batch_count = 1; + + int result = kmip_encode_response_message(&ctx, &rm); + result = report_encoding_test_result( + tracker, + &ctx, + expected, + observed, + result, + __func__); + kmip_destroy(&ctx); + return(result); +} + +/* Test Harness */ + +int +run_tests(void) +{ + TestTracker tracker = {0}; + + printf("Tests\n"); + printf("=====\n"); + + printf("\nUtility Tests\n"); + printf("-------------\n"); + test_linked_list_pop(&tracker); + test_linked_list_push(&tracker); + test_linked_list_enqueue(&tracker); + test_buffer_bytes_left(&tracker); + test_peek_tag(&tracker); + test_is_attribute_tag(&tracker); + test_get_enum_string_index(&tracker); + test_check_enum_value_protection_storage_masks(&tracker); + test_init_protocol_version(&tracker); + test_init_request_batch_item(&tracker); + test_deep_copy_int32(&tracker); + test_deep_copy_text_string(&tracker); + test_deep_copy_name(&tracker); + test_deep_copy_attribute(&tracker); + + printf("\nKMIP 1.0 Feature Tests\n"); + printf("----------------------\n"); + test_buffer_full_and_resize(&tracker); + test_is_tag_next(&tracker); + test_get_num_items_next(&tracker); + test_get_num_items_next_with_partial_item(&tracker); + test_get_num_items_next_with_mismatch_item(&tracker); + test_get_num_items_next_with_no_matches(&tracker); + test_get_num_items_next_with_non_structures(&tracker); + + printf("\n"); + test_decode_int8_be(&tracker); + test_decode_int32_be(&tracker); + test_decode_int64_be(&tracker); + test_decode_integer(&tracker); + test_decode_long(&tracker); + test_decode_enum(&tracker); + test_decode_bool(&tracker); + test_decode_text_string(&tracker); + test_decode_byte_string(&tracker); + test_decode_date_time(&tracker); + test_decode_interval(&tracker); + test_decode_name(&tracker); + test_decode_attribute_unique_identifier(&tracker); + test_decode_attribute_name(&tracker); + test_decode_attribute_object_type(&tracker); + test_decode_attribute_cryptographic_algorithm(&tracker); + test_decode_attribute_cryptographic_length(&tracker); + test_decode_attribute_operation_policy_name(&tracker); + test_decode_attribute_cryptographic_usage_mask(&tracker); + test_decode_attribute_state(&tracker); + test_decode_template_attribute(&tracker); + test_decode_protocol_version(&tracker); + test_decode_key_material_byte_string(&tracker); + test_decode_key_material_transparent_symmetric_key(&tracker); + test_decode_key_value(&tracker); + test_decode_key_value_with_attributes(&tracker); + test_decode_cryptographic_parameters(&tracker); + test_decode_encryption_key_information(&tracker); + test_decode_mac_signature_key_information(&tracker); + test_decode_key_wrapping_data(&tracker); + test_decode_key_block_key_value_byte_string(&tracker); + test_decode_key_block_key_value_structure(&tracker); + test_decode_symmetric_key(&tracker); + test_decode_public_key(&tracker); + test_decode_private_key(&tracker); + test_decode_key_wrapping_specification(&tracker); + test_decode_create_request_payload(&tracker); + test_decode_create_response_payload(&tracker); + test_decode_create_response_payload_with_template_attribute(&tracker); + test_decode_get_request_payload(&tracker); + test_decode_get_response_payload(&tracker); + test_decode_destroy_request_payload(&tracker); + test_decode_destroy_response_payload(&tracker); + test_decode_response_batch_item_get_payload(&tracker); + test_decode_username_password_credential(&tracker); + test_decode_credential_username_password_credential(&tracker); + test_decode_authentication_username_password_credential(&tracker); + test_decode_request_header(&tracker); + test_decode_response_header(&tracker); + test_decode_request_batch_item_get_payload(&tracker); + test_decode_request_message_get(&tracker); + test_decode_response_message_get(&tracker); + + printf("\n"); + test_encode_integer(&tracker); + test_encode_long(&tracker); + test_encode_enum(&tracker); + test_encode_bool(&tracker); + test_encode_text_string(&tracker); + test_encode_byte_string(&tracker); + test_encode_date_time(&tracker); + test_encode_interval(&tracker); + test_encode_name(&tracker); + test_encode_attribute_unique_identifier(&tracker); + test_encode_attribute_name(&tracker); + test_encode_attribute_object_type(&tracker); + test_encode_attribute_cryptographic_algorithm(&tracker); + test_encode_attribute_cryptographic_length(&tracker); + test_encode_attribute_operation_policy_name(&tracker); + test_encode_attribute_cryptographic_usage_mask(&tracker); + test_encode_attribute_state(&tracker); + test_encode_protocol_version(&tracker); + test_encode_cryptographic_parameters(&tracker); + test_encode_encryption_key_information(&tracker); + test_encode_mac_signature_key_information(&tracker); + test_encode_key_wrapping_data(&tracker); + test_encode_key_material_byte_string(&tracker); + test_encode_key_material_transparent_symmetric_key(&tracker); + test_encode_key_value(&tracker); + test_encode_key_value_with_attributes(&tracker); + test_encode_key_block_key_value_byte_string(&tracker); + test_encode_key_block_key_value_structure(&tracker); + test_encode_symmetric_key(&tracker); + test_encode_public_key(&tracker); + test_encode_private_key(&tracker); + test_encode_key_wrapping_specification(&tracker); + test_encode_create_request_payload(&tracker); + test_encode_create_response_payload(&tracker); + test_encode_create_response_payload_with_template_attribute(&tracker); + test_encode_get_request_payload(&tracker); + 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_destroy_request_payload(&tracker); + test_encode_destroy_response_payload(&tracker); + test_encode_username_password_credential(&tracker); + test_encode_credential_username_password_credential(&tracker); + test_encode_authentication_username_password_credential(&tracker); + test_encode_request_header(&tracker); + test_encode_response_header(&tracker); + test_encode_request_batch_item_get_payload(&tracker); + test_encode_response_batch_item_get_payload(&tracker); + test_encode_request_message_get(&tracker); + test_encode_response_message_get(&tracker); + test_encode_template_attribute(&tracker); + + printf("\nKMIP 1.1 Feature Tests\n"); + printf("----------------------\n"); + test_decode_device_credential(&tracker); + test_decode_key_wrapping_data_with_encoding_option(&tracker); + + printf("\n"); + test_encode_device_credential(&tracker); + test_encode_key_wrapping_data_with_encoding_option(&tracker); + test_encode_key_wrapping_specification_with_encoding_option(&tracker); + + printf("\nKMIP 1.1 Test Suite Test Cases\n"); + printf("------------------------------\n"); + test_kmip_1_1_test_suite_3_1_1_0_a(&tracker); + test_kmip_1_1_test_suite_3_1_1_0_b(&tracker); + test_kmip_1_1_test_suite_3_1_1_1_a(&tracker); + test_kmip_1_1_test_suite_3_1_1_1_b(&tracker); + test_kmip_1_1_test_suite_3_1_3_2_a(&tracker); + test_kmip_1_1_test_suite_3_1_3_2_b(&tracker); + + printf("\nKMIP 1.2 Feature Tests\n"); + printf("----------------------\n"); + test_decode_nonce(&tracker); + test_decode_attestation_credential(&tracker); + test_decode_response_header_with_attestation_details(&tracker); + test_decode_cryptographic_parameters_with_digital_signature_fields(&tracker); + + printf("\n"); + test_encode_nonce(&tracker); + test_encode_attestation_credential(&tracker); + test_encode_request_header_with_attestation_details(&tracker); + test_encode_response_header_with_attestation_details(&tracker); + test_encode_cryptographic_parameters_with_digital_signature_fields(&tracker); + + printf("\nKMIP 1.4 Feature Tests\n"); + printf("----------------------\n"); + test_decode_cryptographic_parameters_with_mask_fields(&tracker); + test_decode_response_header_with_correlation_values(&tracker); + + printf("\n"); + test_encode_cryptographic_parameters_with_mask_fields(&tracker); + test_encode_get_request_payload_with_wrap_type(&tracker); + test_encode_request_header_with_correlation_values(&tracker); + test_encode_response_header_with_correlation_values(&tracker); + + printf("\nKMIP 2.0 Feature Tests\n"); + printf("----------------------\n"); + test_decode_protection_storage_masks(&tracker); + test_decode_attributes(&tracker); + test_decode_attributes_with_invalid_kmip_version(&tracker); + test_decode_attribute_v2_unique_identifier(&tracker); + test_decode_attribute_v2_name(&tracker); + test_decode_attribute_v2_object_type(&tracker); + test_decode_attribute_v2_cryptographic_algorithm(&tracker); + test_decode_attribute_v2_cryptographic_length(&tracker); + test_decode_attribute_v2_cryptographic_usage_mask(&tracker); + test_decode_attribute_v2_state(&tracker); + test_decode_attribute_v2_unsupported_attribute(&tracker); + test_decode_create_request_payload_kmip_2_0(&tracker); + test_decode_request_batch_item_get_payload_kmip_2_0(&tracker); + test_decode_response_header_kmip_2_0(&tracker); + + printf("\n"); + test_encode_protection_storage_masks(&tracker); + test_encode_attributes(&tracker); + test_encode_attributes_with_invalid_kmip_version(&tracker); + test_encode_attribute_v2_unique_identifier(&tracker); + test_encode_attribute_v2_name(&tracker); + test_encode_attribute_v2_object_type(&tracker); + test_encode_attribute_v2_cryptographic_algorithm(&tracker); + test_encode_attribute_v2_cryptographic_length(&tracker); + test_encode_attribute_v2_cryptographic_usage_mask(&tracker); + test_encode_attribute_v2_state(&tracker); + test_encode_attribute_v2_unsupported_attribute(&tracker); + test_encode_create_request_payload_kmip_2_0(&tracker); + test_encode_request_batch_item_get_payload_kmip_2_0(&tracker); + test_encode_response_header_kmip_2_0(&tracker); + + printf("\nSummary\n"); + printf("================\n"); + printf("Total tests: %u\n", tracker.test_count); + printf(" PASS: %u\n", tracker.tests_passed); + printf(" FAILURE: %u\n", tracker.tests_failed); + + return(tracker.tests_failed); +} + +void +print_help(const char *app) +{ + printf("Usage: %s [flag] ...\n\n", app); + printf("Flags:\n"); + printf("-h : print this help info\n"); + printf("-i : run the test suite forever\n"); +} + +int +parse_arguments(int argc, + char **argv, + int *print_usage, + int *run_forever) +{ + for(int i = 1; i < argc; i++) + { + if(strncmp(argv[i], "-h", 2) == 0) + { + *print_usage = 1; + } + else if(strncmp(argv[i], "-i", 2) == 0) + { + *run_forever = 1; + } + else + { + printf("Invalid option: '%s'\n", argv[i]); + print_help(argv[0]); + return(-1); + } + } + + return(0); +} + +int +main(int argc, char **argv) +{ + int print_usage = 0; + int run_forever = 0; + + int error = parse_arguments(argc, argv, &print_usage, &run_forever); + if(error) + { + return(error); + } + if(print_usage) + { + print_help(argv[0]); + return(0); + } + + int results = 0; + if(run_forever) + { + while(1) + { + run_tests(); + } + } + else + { + results = run_tests(); + } + + return(results); +} |