summaryrefslogtreecommitdiffstats
path: root/src/libkmip
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 18:45:59 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 18:45:59 +0000
commit19fcec84d8d7d21e796c7624e521b60d28ee21ed (patch)
tree42d26aa27d1e3f7c0b8bd3fd14e7d7082f5008dc /src/libkmip
parentInitial commit. (diff)
downloadceph-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')
-rw-r--r--src/libkmip/.gitignore8
-rw-r--r--src/libkmip/.travis.yml23
-rw-r--r--src/libkmip/CHANGELOG.rst36
-rw-r--r--src/libkmip/CMakeLists.txt10
-rw-r--r--src/libkmip/LICENSE3
-rw-r--r--src/libkmip/LICENSE.APACHE201
-rw-r--r--src/libkmip/LICENSE.BSD27
-rw-r--r--src/libkmip/Makefile117
-rw-r--r--src/libkmip/README.md35
-rw-r--r--src/libkmip/demo_create.c371
-rw-r--r--src/libkmip/demo_destroy.c199
-rw-r--r--src/libkmip/demo_get.c303
-rw-r--r--src/libkmip/doc-requirements.txt4
-rw-r--r--src/libkmip/docs/Makefile20
-rw-r--r--src/libkmip/docs/source/_static/.keep0
-rw-r--r--src/libkmip/docs/source/api.rst1187
-rw-r--r--src/libkmip/docs/source/changelog.rst1
-rw-r--r--src/libkmip/docs/source/conf.py173
-rw-r--r--src/libkmip/docs/source/development.rst105
-rw-r--r--src/libkmip/docs/source/docs.txt9
-rw-r--r--src/libkmip/docs/source/examples.rst76
-rw-r--r--src/libkmip/docs/source/faq.rst19
-rw-r--r--src/libkmip/docs/source/index.rst46
-rw-r--r--src/libkmip/docs/source/installation.rst101
-rw-r--r--src/libkmip/docs/source/security.rst44
-rw-r--r--src/libkmip/kmip.c15958
-rw-r--r--src/libkmip/kmip.h1956
-rw-r--r--src/libkmip/kmip_bio.c1613
-rw-r--r--src/libkmip/kmip_bio.h31
-rw-r--r--src/libkmip/kmip_memset.c59
-rw-r--r--src/libkmip/kmip_memset.h15
-rw-r--r--src/libkmip/tests.c11400
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 = &ni;
+ 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 = &ni;
+ 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 = &ni;
+ 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 = &ni;
+ 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 = &ni;
+ 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 = &ni;
+ 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 = &ni;
+ 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 = &ni;
+ 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 = &ni;
+ 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 = &ni;
+ 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 = &ni;
+ 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 = &ni;
+ 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);
+}