Files
s390-tools/libkmipclient/attribute.c
Ingo Franzki 486882a4df libkmipclient: Fix findings from static code checker
The Coverity static code checker found a few bugs in the libkmipclient
code, fix those.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Joerg Schmidbauer <jschmidb@de.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-05-21 15:50:31 +02:00

4012 lines
121 KiB
C

/*
* libkmipclient - KMIP client library
*
* Copyright IBM Corp. 2021
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#define _XOPEN_SOURCE
#define _DEFAULT_SOURCE
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include "kmip.h"
#include "names.h"
/**
* Constructs a Template Attribute node (KMIP v1.x):
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Template-Attribute Yes Structure v1.x only
* Name No Structure v1.x only
* ... may be repeated
* Attribute No Structure v1.x only
* ... may be repeated
*
* Also applies to Common Template-Attribute, Private Key Template-Attribute,
* Public Key Template-Attribute.
*
* @param tag the template-attribute tag
* @param num_names the number of names in the array (can be 0)
* @param names array of name nodes
* @param num_attrs the number of attributes in the array (can be 0)
* @param attrs array of attribute nodes
*
* @returns the allocated node, or NULL in case of an error.
* The reference counts of the nodes specified as parameters which are added to
* the newly allocated node are increased. The caller must free its reference
* via kmip_node_free() if no longer needed.
*/
static struct kmip_node *kmip_new_template_attribute_v1(
enum kmip_tag tag,
unsigned int num_names,
struct kmip_node **names,
unsigned int num_attrs,
struct kmip_node **attrs)
{
struct kmip_node *tmpl;
unsigned int i;
int rc;
if (num_names > 0 && names == NULL)
return NULL;
if (num_attrs > 0 && attrs == NULL)
return NULL;
switch (tag) {
case KMIP_TAG_TEMPLATE_ATTRIBUTE:
case KMIP_TAG_COMMON_TEMPLATE_ATTRIBUTE:
case KMIP_TAG_PRIVATE_KEY_TEMPLATE_ATTRIBUTE:
case KMIP_TAG_PUBLIC_KEY_TEMPLATE_ATTRIBUTE:
break;
default:
return NULL;
}
tmpl = kmip_node_new_structure_va(KMIP_TAG_TEMPLATE_ATTRIBUTE, NULL, 0);
if (tmpl == NULL)
return NULL;
for (i = 0; i < num_names; i++) {
rc = kmip_node_add_structure_element(tmpl, names[i]);
if (rc != 0)
goto error;
}
for (i = 0; i < num_attrs; i++) {
rc = kmip_node_add_structure_element(tmpl, attrs[i]);
if (rc != 0)
goto error;
}
return tmpl;
error:
kmip_node_free(tmpl);
return NULL;
}
/**
* Gets information from a Template Attribute node (KMIP v1.x):
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Template-Attribute Yes Structure v1.x only
* Name No Structure v1.x only
* ... may be repeated
* Attribute No Structure v1.x only
* ... may be repeated
*
* Also applies to Common Template-Attribute, Private Key Template-Attribute,
* Public Key Template-Attribute.
*
* @param node the KMIP node
* @param num_names On return: The number of names (can be NULL)
* @param name_index the index of the name item to return
* @param name On return: the name item of the specified index.
* Function returns -ENOENT if no name is available.
* Can be NULL, then no name entry is returned.
* @param num_attrs On return: The number of attributes (can be NULL)
* @param attr_index the index of the attribute item to return
* @param attr On return: the attribute item of the specified
* index. Function returns -ENOENT if no attribute is
* available. Can be NULL, then no attribute entry is
* returned.
*
* @returns 0 on success, or a negative errno in case of an error.
* The reference count of the returned nodes is increased. The caller must
* free the node via kmip_node_free() when no longer needed.
*/
static int kmip_get_template_attribute_v1(const struct kmip_node *node,
unsigned int *num_names,
unsigned int name_index,
struct kmip_node **name,
unsigned int *num_attrs,
unsigned int attr_index,
struct kmip_node **attr)
{
if (node == NULL)
return -EINVAL;
switch (kmip_node_get_tag(node)) {
case KMIP_TAG_TEMPLATE_ATTRIBUTE:
case KMIP_TAG_COMMON_TEMPLATE_ATTRIBUTE:
case KMIP_TAG_PRIVATE_KEY_TEMPLATE_ATTRIBUTE:
case KMIP_TAG_PUBLIC_KEY_TEMPLATE_ATTRIBUTE:
break;
default:
return -EBADMSG;
}
if (num_names != NULL)
*num_names = kmip_node_get_structure_element_by_tag_count(
node, KMIP_TAG_NAME);
if (name != NULL) {
*name = kmip_node_get_structure_element_by_tag(node,
KMIP_TAG_NAME, name_index);
if (*name == NULL)
return -ENOENT;
}
if (num_attrs != NULL)
*num_attrs = kmip_node_get_structure_element_by_tag_count(
node, KMIP_TAG_ATTRIBUTE);
if (attr != NULL) {
*attr = kmip_node_get_structure_element_by_tag(node,
KMIP_TAG_ATTRIBUTE, attr_index);
if (*attr == NULL) {
if (name != NULL && *name != NULL) {
kmip_node_free(*name);
*name = NULL;
}
return -ENOENT;
}
}
return 0;
}
/**
* Constructs an Attribute node (KMIP v1.x):
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Attribute Yes Structure v1.x only
* Attribute Name Yes Text String v1.x only
* Attribute Index No Integer v1.x only
* Attribute Value Yes <varies> v1.x only
*
* @param name the name of the attribute
* @param index the index of the attribute. If < 0 then this field
* is omitted
* @param value the attribute value node
*
* @returns the allocated node, or NULL in case of an error.
* The reference counts of the nodes specified as parameters which are added to
* the newly allocated node are increased. The caller must free its reference
* via kmip_node_free() if no longer needed.
*/
static struct kmip_node *kmip_new_attribute_v1(const char *name, int32_t index,
struct kmip_node *value)
{
struct kmip_node *attr = NULL, *nam, *idx = NULL;
if (name == NULL || value == NULL)
return NULL;
nam = kmip_node_new_text_string(KMIP_TAG_ATTRIBUTE_NAME, NULL, name);
if (index >= 0)
idx = kmip_node_new_integer(KMIP_TAG_ATTRIBUTE_INDEX, NULL,
index);
if (nam == NULL || (index >= 0 && idx == NULL))
goto out;
attr = kmip_node_new_structure_va(KMIP_TAG_ATTRIBUTE, NULL, 3, nam, idx,
value);
out:
kmip_node_free(nam);
kmip_node_free(idx);
return attr;
}
/**
* Gets the information from an Attribute node (KMIP v1.x):
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Attribute Yes Structure v1.x only
* Attribute Name Yes Text String v1.x only
* Attribute Index No Integer v1.x only
* Attribute Value Yes <varies> v1.x only
*
* @param node the KMIP node
* @param name On return: the attribute name (can be NULL)
* @param index On return: the attribute index (can be NULL)
* @param value On return: the attribute value (can be NULL)
*
* @returns 0 on success, or a negative errno in case of an error
* The reference count of the returned nodes is increased. The caller must
* free the node via kmip_node_free() when no longer needed.
*/
static int kmip_get_attribute_v1(const struct kmip_node *node,
const char **name, int32_t *index,
struct kmip_node **value)
{
struct kmip_node *nam, *idx, *val;
int rc = 0;
if (node == NULL)
return -EINVAL;
if (kmip_node_get_tag(node) != KMIP_TAG_ATTRIBUTE)
return -EBADMSG;
nam = kmip_node_get_structure_element_by_tag(node,
KMIP_TAG_ATTRIBUTE_NAME,
0);
idx = kmip_node_get_structure_element_by_tag(node,
KMIP_TAG_ATTRIBUTE_INDEX,
0);
val = kmip_node_get_structure_element_by_tag(node,
KMIP_TAG_ATTRIBUTE_VALUE,
0);
if (nam == NULL || val == NULL) {
rc = -EBADMSG;
goto out;
}
if (name != NULL)
*name = kmip_node_get_text_string(nam);
if (index != NULL)
*index = (idx != NULL ? kmip_node_get_integer(idx) : 0);
if (value != NULL)
*value = val;
out:
kmip_node_free(nam);
kmip_node_free(idx);
if (value == NULL || rc != 0)
kmip_node_free(val);
return rc;
}
/**
* Constructs a (Vendor) Attribute node (KMIP v2.x):
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Attribute Yes Structure v2.x only
* Vendor Identification Yes Text String v2.x only
* Attribute Name Yes Text String v2.x only
* Attribute Value Yes <varies> v2.x only
*
* @param vendor_id the vendor identification of the attribute
* @param name the name of the attribute
* @param value the attribute value node
*
* @returns the allocated node, or NULL in case of an error.
* The reference counts of the nodes specified as parameters which are added to
* the newly allocated node are increased. The caller must free its reference
* via kmip_node_free() if no longer needed.
*/
struct kmip_node *kmip_new_vendor_attribute(const char *vendor_id,
const char *name,
struct kmip_node *value)
{
struct kmip_node *attr = NULL, *nam, *vend = NULL;
if (vendor_id == NULL || name == NULL || value == NULL)
return NULL;
vend = kmip_node_new_text_string(KMIP_TAG_VENDOR_IDENTIFICATION, NULL,
vendor_id);
nam = kmip_node_new_text_string(KMIP_TAG_ATTRIBUTE_NAME, NULL, name);
if (nam == NULL || vend == NULL)
goto out;
attr = kmip_node_new_structure_va(KMIP_TAG_ATTRIBUTE, NULL, 3, vend,
nam, value);
out:
kmip_node_free(nam);
kmip_node_free(vend);
return attr;
}
/**
* Gets the information from a (Vendor) Attribute node (KMIP v2.x):
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Attribute Yes Structure v2.x only
* Vendor Identification Yes Text String v2.x only
* Attribute Name Yes Text String v2.x only
* Attribute Value Yes <varies> v2.x only
*
* @param node the KMIP node
* @param vendor_id On return: the vendor identification (can be NULL)
* @param name On return: the attribute name (can be NULL)
* @param value On return: the attribute value (can be NULL)
*
* @returns 0 on success, or a negative errno in case of an error
* The reference count of the returned nodes is increased. The caller must
* free the node via kmip_node_free() when no longer needed.
*/
int kmip_get_vendor_attribute(const struct kmip_node *node,
const char **vendor_id, const char **name,
struct kmip_node **value)
{
struct kmip_node *vend, *nam, *val;
int rc = 0;
if (node == NULL)
return -EINVAL;
if (kmip_node_get_tag(node) != KMIP_TAG_ATTRIBUTE)
return -EBADMSG;
vend = kmip_node_get_structure_element_by_tag(node,
KMIP_TAG_VENDOR_IDENTIFICATION, 0);
nam = kmip_node_get_structure_element_by_tag(node,
KMIP_TAG_ATTRIBUTE_NAME,
0);
val = kmip_node_get_structure_element_by_tag(node,
KMIP_TAG_ATTRIBUTE_VALUE,
0);
if (vend == NULL || nam == NULL || val == NULL) {
rc = -EBADMSG;
goto out;
}
if (vendor_id != NULL)
*vendor_id = kmip_node_get_text_string(vend);
if (name != NULL)
*name = kmip_node_get_text_string(nam);
if (value != NULL)
*value = val;
out:
kmip_node_free(vend);
kmip_node_free(nam);
if (value == NULL || rc != 0)
kmip_node_free(val);
return rc;
}
/**
* Constructs an Attributes node (KMIP v2.x):
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Attributes Yes Structure v2.x only
* <any attribute> No <varies> v2.x only
* ... may be repeated
*
* Also applies to Common Attributes, Private Key Attributes,
* Public Key Attributes
*
* @param tag the attributes tag
* @param attrs_count the number of attributes following (can be 0)
* @param attrs the array of attributes
*
* @returns the allocated node, or NULL in case of an error.
* The reference counts of the nodes specified as parameters which are added to
* the newly allocated node are increased. The caller must free its reference
* via kmip_node_free() if no longer needed.
*/
static struct kmip_node *kmip_new_attributes_v2(enum kmip_tag tag,
unsigned int attrs_count,
struct kmip_node **attrs)
{
switch (tag) {
case KMIP_TAG_ATTRIBUTES:
case KMIP_TAG_COMMON_ATTRIBUTES:
case KMIP_TAG_PRIVATE_KEY_ATTRIBUTES:
case KMIP_TAG_PUBLIC_KEY_ATTRIBUTES:
break;
default:
return NULL;
}
return kmip_node_new_structure(KMIP_TAG_ATTRIBUTES, NULL, attrs_count,
attrs);
}
/**
* Gets the information from an Attributes node (KMIP v2.x):
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Attributes Yes Structure v2.x only
* <any attribute> No <varies> v2.x only
* ... may be repeated
*
* Also applies to Common Attributes, Private Key Attributes,
* Public Key Attributes
*
* @param node the KMIP node
* @param num_attrs On return: The number of attributes (can be NULL)
* @param attr_index the index of the attribute to return
* @param value On return: the attribute item of the specified
* index. Function returns -ENOENT if no attribute is
* available. Can be NULL, then no attribute entry is
* returned.
*
* @returns 0 on success, or a negative errno in case of an error
* The reference count of the returned nodes is increased. The caller must
* free the node via kmip_node_free() when no longer needed.
*/
static int kmip_get_attributes_v2(const struct kmip_node *node,
unsigned int *num_attrs,
unsigned int attr_index,
struct kmip_node **attr)
{
if (node == NULL)
return -EINVAL;
switch (kmip_node_get_tag(node)) {
case KMIP_TAG_ATTRIBUTES:
case KMIP_TAG_COMMON_ATTRIBUTES:
case KMIP_TAG_PRIVATE_KEY_ATTRIBUTES:
case KMIP_TAG_PUBLIC_KEY_ATTRIBUTES:
break;
default:
return -EBADMSG;
}
if (num_attrs != NULL)
*num_attrs = kmip_node_get_structure_element_count(node);
if (attr == NULL)
return 0;
*attr = kmip_node_get_structure_element_by_index(node, attr_index);
if (*attr == NULL)
return -ENOENT;
return 0;
}
/**
* Split a KMIP v1.x custom attribute name into a vendor-id and attribute
* name for a KMIP v2.x vendor attribute.
*
* @param name the custom attribute name. This string is being
* modified during splitting. If the contents is still
* needed, the caller should copy it first.
* @param vendor_id On return: the vendor-ID string. This point to
* inside the passed name string from the 1st argument.
* @param attr_name On return: the vendor attribute name string.
* This point to inside the passed name string from
* the 1st argument.
*
* @returns 0 on success, or a negative errno in case of an error
*/
static int kmip_split_v1_custom_attr_name(char *name, char **vendor_id,
char **attr_name)
{
char *tok;
if (name == NULL || vendor_id == NULL || attr_name == NULL)
return -EINVAL;
/*
* KMIP v1.x custom attribute names in the form 'x|y-<vendor>-<name>'
* are transformed into a KMIP v2.x vendor attribute with vendor id
* <vendor> and name <name>. If no vendor id is found, then the vendor
* id is set to 'x' or 'y', and the name is the remaining name string.
*/
if (strncmp(name, "x-", 2) != 0 && strncmp(name, "y-", 2) != 0)
return -EBADMSG;
name[1] = 0;
tok = strchr(name + 2, '-');
if (tok != NULL) {
*tok = 0;
*vendor_id = name + 2;
*attr_name = tok + 1;
} else {
*vendor_id = name;
*attr_name = name + 2;
}
return 0;
}
/**
* Builds a KMIP v1.x custom attribute name from a KMIP v2.x vendor-id and
* attribute name.
*
* @param vendor_id the vendor-ID string
* @param attr_name the vendor attribute name string
*
* @returns a newly allocated custom attribute name string, or NULL in case of
* an error. The returned string must be freed by the caller.
*/
char *kmip_build_v1_custom_attr_name(const char *vendor_id,
const char *attr_name)
{
char *custom_name = NULL;
int rc;
if (vendor_id == NULL || attr_name == NULL)
return NULL;
if (strcmp(vendor_id, "x") == 0 ||
strcmp(vendor_id, "y") == 0)
rc = asprintf(&custom_name, "%s-%s",
vendor_id, attr_name);
else
rc = asprintf(&custom_name, "x-%s-%s",
vendor_id, attr_name);
if (rc <= 0 || custom_name == NULL)
return NULL;
return custom_name;
}
/**
* Converts a KMIP v1.x Attribute into a KMIP v2.x Attribute
*
* @param v1_attr the KMIP v1.x attribute to convert
* @param v2_attr On return: the KMIP v2.x attribute
*
* @returns 0 on success, or a negative errno in case of an error
*/
int kmip_v2_attr_from_v1_attr(struct kmip_node *v1_attr,
struct kmip_node **v2_attr)
{
char *copy, *vendor_id, *attr_name;
struct kmip_node *value, *cloned_value;
enum kmip_tag v2_tag;
const char *name;
int rc;
if (v1_attr == NULL || v2_attr == NULL)
return -EINVAL;
rc = kmip_get_attribute_v1(v1_attr, &name, NULL, &value);
if (rc != 0)
return rc;
if (strncmp(name, "x-", 2) == 0 ||
strncmp(name, "y-", 2) == 0) {
/* Special handling for Custom Attribute */
copy = strdup(name);
if (copy == NULL) {
kmip_node_free(value);
return -ENOMEM;
}
rc = kmip_split_v1_custom_attr_name(copy, &vendor_id,
&attr_name);
if (rc != 0) {
kmip_node_free(value);
free(copy);
return rc;
}
cloned_value = kmip_node_clone(value);
kmip_node_free(value);
if (cloned_value == NULL) {
free(copy);
return -ENOMEM;
}
*v2_attr = kmip_new_vendor_attribute(vendor_id, attr_name,
cloned_value);
free(copy);
kmip_node_free(cloned_value);
return 0;
}
v2_tag = kmip_attr_tag_by_v1_attr_name(name);
if (v2_tag == 0) {
kmip_node_free(value);
return -EBADMSG;
}
cloned_value = kmip_node_clone(value);
kmip_node_free(value);
if (cloned_value == NULL)
return -ENOMEM;
cloned_value->tag = v2_tag;
*v2_attr = cloned_value;
return 0;
}
/**
* Converts a KMIP v2.x Attribute into a KMIP v1.x Attribute
*
* @param v2_attr the KMIP v2.x attribute to convert
* @param v1_attr On return: the KMIP v1.x attribute
*
* @returns 0 on success, or a negative errno in case of an error
*/
int kmip_v1_attr_from_v2_attr(struct kmip_node *v2_attr,
struct kmip_node **v1_attr)
{
struct kmip_node *attr_value, *cloned_value;
const char *attr_name, *vendor_id;
char *custom_name;
int rc;
if (v2_attr == NULL || v1_attr == NULL)
return -EINVAL;
if (v2_attr->tag == KMIP_TAG_ATTRIBUTE) {
/* Special handling for v2.x Vendor Attribute */
rc = kmip_get_vendor_attribute(v2_attr, &vendor_id,
&attr_name, &attr_value);
if (rc != 0)
return rc;
custom_name = kmip_build_v1_custom_attr_name(vendor_id,
attr_name);
if (custom_name == NULL) {
kmip_node_free(attr_value);
return -EBADMSG;
}
cloned_value = kmip_node_clone(attr_value);
kmip_node_free(attr_value);
if (cloned_value == NULL) {
free(custom_name);
return -ENOMEM;
}
*v1_attr = kmip_new_attribute_v1(custom_name, -1, cloned_value);
kmip_node_free(cloned_value);
free(custom_name);
if (*v1_attr == NULL)
return -ENOMEM;
return 0;
}
attr_name = kmip_v1_attr_name_by_tag(v2_attr->tag);
if (attr_name == NULL)
return -EBADMSG;
cloned_value = kmip_node_clone(v2_attr);
if (cloned_value == NULL)
return -ENOMEM;
/* Modify the cloned v2 attr and use it as value of the v1 attr */
cloned_value->tag = KMIP_TAG_ATTRIBUTE_VALUE;
*v1_attr = kmip_new_attribute_v1(attr_name, -1, cloned_value);
kmip_node_free(cloned_value);
if (*v1_attr == NULL)
return -ENOMEM;
return 0;
}
/**
* Constructs an Attributes node (KMIP v2.x) or a Template Attribute node
* (KMIP v1.x) from a list of attributes in KMIP v2.x style, dependent on the
* protocol version specified:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Attributes Yes Structure v2.x only
* <any attribute> No <varies> v2.x only
* ... may be repeated
*
* Also applies to Common Attributes, Private Key Attributes,
* Public Key Attributes
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Template-Attribute Yes Structure v1.x only
* Name No Structure v1.x only
* ... may be repeated
* Attribute No Structure v1.x only
* ... may be repeated
*
* Also applies to Common Template-Attribute, Private Key Template-Attribute,
* Public Key Template-Attribute.
*
* @param version the protocol version. If null, the current default
* protocol version is used.
* @param v2_tag the attributes tag
* @param attrs_count the number of attributes following
* @param v2_attrs the array of attributes (as KMIP v2.x attributes)
*
* @returns the allocated node, or NULL in case of an error.
* The reference counts of the nodes specified as parameters which are added to
* the newly allocated node are increased. The caller must free its reference
* via kmip_node_free() if no longer needed.
*/
struct kmip_node *kmip_new_attributes(const struct kmip_version *version,
enum kmip_tag v2_tag,
unsigned int attrs_count,
struct kmip_node **v2_attrs)
{
struct kmip_node *attrs = NULL, *attr;
struct kmip_node **v1_attrs = NULL;
enum kmip_tag v1_tag = 0;
unsigned int i;
int rc;
if (version == NULL)
version = kmip_get_default_protocol_version();
if (version->major == 1) {
/* KMIP v1.x: translate v1-tag to v2-tag */
switch (v2_tag) {
case KMIP_TAG_ATTRIBUTES:
v1_tag = KMIP_TAG_TEMPLATE_ATTRIBUTE;
break;
case KMIP_TAG_COMMON_ATTRIBUTES:
v1_tag = KMIP_TAG_COMMON_TEMPLATE_ATTRIBUTE;
break;
case KMIP_TAG_PRIVATE_KEY_ATTRIBUTES:
v1_tag = KMIP_TAG_PRIVATE_KEY_TEMPLATE_ATTRIBUTE;
break;
case KMIP_TAG_PUBLIC_KEY_ATTRIBUTES:
v1_tag = KMIP_TAG_PUBLIC_KEY_TEMPLATE_ATTRIBUTE;
break;
default:
return NULL;
}
if (attrs_count > 0) {
v1_attrs = calloc(attrs_count,
sizeof(struct kmip_node *));
if (v1_attrs == NULL)
return NULL;
}
for (i = 0; i < attrs_count; i++) {
attr = v2_attrs[i];
if (attr == NULL)
goto error;
rc = kmip_v1_attr_from_v2_attr(attr, &v1_attrs[i]);
if (rc != 0)
goto error;
}
attrs = kmip_new_template_attribute_v1(v1_tag, 0, NULL,
attrs_count, v1_attrs);
error:
for (i = 0; i < attrs_count; i++) {
if (v1_attrs[i] == NULL)
continue;
kmip_node_free(v1_attrs[i]);
}
if (v1_attrs != NULL)
free(v1_attrs);
} else {
/* KMIP >= v2.0 */
attrs = kmip_new_attributes_v2(v2_tag, attrs_count, v2_attrs);
}
return attrs;
}
/**
* Constructs an Attributes node (KMIP v2.x) or a Template Attribute node
* (KMIP v1.x) from a list of attributes in KMIP v2.x style, dependent on the
* protocol version specified:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Attributes Yes Structure v2.x only
* <any attribute> No <varies> v2.x only
* ... may be repeated
*
* Also applies to Common Attributes, Private Key Attributes,
* Public Key Attributes
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Template-Attribute Yes Structure v1.x only
* Name No Structure v1.x only
* ... may be repeated
* Attribute No Structure v1.x only
* ... may be repeated
*
* Also applies to Common Template-Attribute, Private Key Template-Attribute,
* Public Key Template-Attribute.
*
* @param version the protocol version. If null, the current default
* protocol version is used.
* @param v2_tag the attributes tag
* @param attrs_count the number of attributes following
* @param <attributes> the attributes (as KMIP v2.x attribute)
*
* @returns the allocated node, or NULL in case of an error.
* The reference counts of the nodes specified as parameters which are added to
* the newly allocated node are increased. The caller must free its reference
* via kmip_node_free() if no longer needed.
*/
struct kmip_node *kmip_new_attributes_va(const struct kmip_version *version,
enum kmip_tag v2_tag,
unsigned int attrs_count, ...)
{
struct kmip_node *ret, **attrs = NULL;
unsigned int i, k;
va_list ap;
if (attrs_count > 0) {
attrs = calloc(attrs_count, sizeof(struct kmip_node *));
if (attrs == NULL)
return NULL;
}
va_start(ap, attrs_count);
for (i = 0, k = 0; i < attrs_count; i++) {
attrs[k] = va_arg(ap, struct kmip_node *);
if (attrs[k] != NULL)
k++;
}
va_end(ap);
ret = kmip_new_attributes(version, v2_tag, k, attrs);
if (attrs != NULL)
free(attrs);
return ret;
}
/**
* Gets the information from an Attributes node (KMIP v2.x) or a Template
* Attribute node (KMIP v1.x). The returned attribute is always in KMIP v2.x
* style.
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Attributes Yes Structure v2.x only
* <any attribute> No <varies> v2.x only
* ... may be repeated
*
* Also applies to Common Attributes, Private Key Attributes,
* Public Key Attributes
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Template-Attribute Yes Structure v1.x only
* Name No Structure v1.x only
* ... may be repeated
* Attribute No Structure v1.x only
* ... may be repeated
*
* Also applies to Common Template-Attribute, Private Key Template-Attribute,
* Public Key Template-Attribute.
*
* @param node the KMIP node
* @param num_attrs On return: the number of attributes (can be NULL).
* @param attr_index the index of the attribute to return
* @param value On return: the attribute item of the specified index
* (as a KMIP v2.x attribute).
* Function returns -ENOENT if no attribute is
* available. Can be NULL, then no attribute entry is
* returned.
*
* @returns 0 on success, or a negative errno in case of an error
* The reference count of the returned nodes is increased. The caller must
* free the node via kmip_node_free() when no longer needed.
*/
int kmip_get_attributes(const struct kmip_node *node, unsigned int *num_attrs,
unsigned int attr_index, struct kmip_node **attr)
{
struct kmip_node *v1_attr, *v2_attr;
int rc;
if (node == NULL)
return -EINVAL;
switch (kmip_node_get_tag(node)) {
case KMIP_TAG_TEMPLATE_ATTRIBUTE:
case KMIP_TAG_COMMON_TEMPLATE_ATTRIBUTE:
case KMIP_TAG_PRIVATE_KEY_TEMPLATE_ATTRIBUTE:
case KMIP_TAG_PUBLIC_KEY_TEMPLATE_ATTRIBUTE:
/* KMIP v1.x template attributes */
if (attr == NULL) {
rc = kmip_get_template_attribute_v1(node, NULL, 0, NULL,
num_attrs, 0, NULL);
return rc;
}
rc = kmip_get_template_attribute_v1(node, NULL, 0, NULL,
num_attrs, attr_index,
&v1_attr);
if (rc != 0)
return rc;
rc = kmip_v2_attr_from_v1_attr(v1_attr, &v2_attr);
kmip_node_free(v1_attr);
if (rc != 0)
return rc;
*attr = v2_attr;
break;
case KMIP_TAG_ATTRIBUTES:
case KMIP_TAG_COMMON_ATTRIBUTES:
case KMIP_TAG_PRIVATE_KEY_ATTRIBUTES:
case KMIP_TAG_PUBLIC_KEY_ATTRIBUTES:
/* KMIP v2.x attributes */
rc = kmip_get_attributes_v2(node, num_attrs, attr_index, attr);
if (rc != 0)
return rc;
break;
default:
return -EBADMSG;
}
return 0;
}
/**
* Constructs an Attribute Reference node (KMIP v2.x):
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Attribute Reference Yes Enumeration v2.x only
* or
* Attribute Reference Yes Structure v2.x only
* Vendor Identification Yes Text String v2.x only
* Attribute Name Yes Text String v2.x only
*
* @param attr_tag the attribute tag
* @param vendor_id the vendor identification of the attribute
* @param name the name of the attribute
*
* Either the attr_tag or the vendor_id and name can be specified, but not both.
*
* @returns the allocated node, or NULL in case of an error.
*/
struct kmip_node *kmip_new_attribute_reference(enum kmip_tag attr_tag,
const char *vendor_id,
const char *name)
{
struct kmip_node *ref = NULL, *nam, *vend = NULL;
if (attr_tag == 0 && (vendor_id == NULL || name == NULL))
return NULL;
if (attr_tag != 0 && (vendor_id != NULL || name != NULL))
return NULL;
if (attr_tag != 0)
return kmip_node_new_enumeration(KMIP_TAG_ATTRIBUTE_REFERENCE,
NULL, attr_tag);
vend = kmip_node_new_text_string(KMIP_TAG_VENDOR_IDENTIFICATION, NULL,
vendor_id);
nam = kmip_node_new_text_string(KMIP_TAG_ATTRIBUTE_NAME, NULL, name);
if (nam == NULL || vend == NULL)
goto out;
ref = kmip_node_new_structure_va(KMIP_TAG_ATTRIBUTE_REFERENCE, NULL,
2, vend, nam);
out:
kmip_node_free(nam);
kmip_node_free(vend);
return ref;
}
/**
* Gets the information from a Attribute Reference node (KMIP v2.x):
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Attribute Reference Yes Enumeration v2.x only
* or
* Attribute Reference Yes Structure v2.x only
* Vendor Identification Yes Text String v2.x only
* Attribute Name Yes Text String v2.x only
*
* @param node the KMIP node
* @param attr_tag On return: The attribute tag (can be NULL)
* @param vendor_id On return: the vendor identification (can be NULL)
* @param name On return: the attribute name (can be NULL)
*
* @returns 0 on success, or a negative errno in case of an error
*/
int kmip_get_attribute_reference(const struct kmip_node *node,
enum kmip_tag *attr_tag,
const char **vendor_id, const char **name)
{
struct kmip_node *vend, *nam;
int rc = 0;
if (node == NULL)
return -EINVAL;
if (kmip_node_get_tag(node) != KMIP_TAG_ATTRIBUTE_REFERENCE)
return -EBADMSG;
if (kmip_node_get_type(node) == KMIP_TYPE_ENUMERATION) {
if (attr_tag != NULL)
*attr_tag = kmip_node_get_enumeration(node);
if (vendor_id != NULL)
vendor_id = NULL;
if (name != NULL)
*name = NULL;
return 0;
}
if (kmip_node_get_type(node) != KMIP_TYPE_STRUCTURE)
return -EBADMSG;
if (attr_tag != NULL)
*attr_tag = 0;
vend = kmip_node_get_structure_element_by_tag(node,
KMIP_TAG_VENDOR_IDENTIFICATION, 0);
nam = kmip_node_get_structure_element_by_tag(node,
KMIP_TAG_ATTRIBUTE_NAME, 0);
if (vend == NULL || nam == NULL) {
rc = -EBADMSG;
goto out;
}
if (vendor_id != NULL)
*vendor_id = kmip_node_get_text_string(vend);
if (name != NULL)
*name = kmip_node_get_text_string(nam);
out:
kmip_node_free(vend);
kmip_node_free(nam);
return rc;
}
/**
* Constructs an Current or New Attribute node (KMIP v2.x):
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Current Attribute Yes Structure v2.x only
* or
* New Attribute Yes Structure v2.x only
*
* @param new_attr if true a New Attribute structure, if false a
* Current Attribute structure is created
* @param attr the KMIP v2.x attribute
*
* @returns the allocated node, or NULL in case of an error.
*/
struct kmip_node *kmip_new_current_new_attribute(bool new_attr,
struct kmip_node *attr)
{
enum kmip_tag tag;
if (attr == NULL)
return NULL;
tag = (new_attr ? KMIP_TAG_NEW_ATTRIBUTE : KMIP_TAG_CURRENT_ATTRIBUTE);
return kmip_node_new_structure_va(tag, NULL, 1, attr);
}
/**
* Constructs an Attribute Name node (KMIP v1.x) from a KMIP v2.x Attribute
* Reference:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Attribute Name Yes Text String v1.x only
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Attribute Reference Yes Enumeration v2.x only
* or
* Attribute Reference Yes Structure v2.x only
* Vendor Identification Yes Text String v2.x only
* Attribute Name Yes Text String v2.x only
*
* @param v2_attr_ref the attribute reference node (as of KMIP v2.x)
*
* @returns the allocated node, or NULL in case of an error.
*/
struct kmip_node *kmip_new_attribute_name_v1(
const struct kmip_node *v2_attr_ref)
{
const char *vendor_id = NULL, *attr_name = NULL;
enum kmip_tag attr_tag = 0;
struct kmip_node *ret;
char *name = NULL;
int rc;
rc = kmip_get_attribute_reference(v2_attr_ref, &attr_tag, &vendor_id,
&attr_name);
if (rc != 0)
return NULL;
if (attr_tag != 0) {
attr_name = kmip_v1_attr_name_by_tag(attr_tag);
if (attr_name == NULL)
return NULL;
return kmip_node_new_text_string(KMIP_TAG_ATTRIBUTE_NAME, NULL,
attr_name);
}
if (vendor_id == NULL || attr_name == NULL)
return NULL;
/* Special handling for v2.x Vendor Attribute */
name = kmip_build_v1_custom_attr_name(vendor_id, attr_name);
if (name == NULL)
return NULL;
ret = kmip_node_new_text_string(KMIP_TAG_ATTRIBUTE_NAME, NULL, name);
free(name);
return ret;
}
/**
* Gets the information from an Attribute Name node (KMIP v1.x) and returns
* a KMIP v2.x Attribute Reference:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Attribute Name Yes Text String v1.x only
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Attribute Reference Yes Enumeration v2.x only
* or
* Attribute Reference Yes Structure v2.x only
* Vendor Identification Yes Text String v2.x only
* Attribute Name Yes Text String v2.x only
*
* @param node the KMIP node
* @param v2_attr_ref On return: the attribute reference node (as of
* KMIP v2.x)
*
* @returns 0 on success, or a negative errno in case of an error.
* The reference count of the returned nodes is increased. The caller must
* free the node via kmip_node_free() when no longer needed.
*/
int kmip_get_attribute_name_v1(const struct kmip_node *node,
struct kmip_node **v2_attr_ref)
{
char *copy, *vendor_id, *attr_name;
enum kmip_tag attr_tag;
const char *name;
int rc;
if (node == NULL || v2_attr_ref == NULL)
return -EINVAL;
if (kmip_node_get_tag(node) != KMIP_TAG_ATTRIBUTE_NAME)
return -EBADMSG;
name = kmip_node_get_text_string(node);
if (name == NULL)
return -EBADMSG;
if (strncmp(name, "x-", 2) == 0 || strncmp(name, "y-", 2) == 0) {
/* Special handling for Custom Attribute */
copy = strdup(name);
if (copy == NULL)
return -ENOMEM;
rc = kmip_split_v1_custom_attr_name(copy, &vendor_id,
&attr_name);
if (rc != 0) {
free(copy);
return rc;
}
*v2_attr_ref = kmip_new_attribute_reference(0, vendor_id,
attr_name);
free(copy);
if (*v2_attr_ref == NULL)
return -ENOMEM;
return 0;
}
attr_tag = kmip_attr_tag_by_v1_attr_name(name);
if (attr_tag == 0)
return -EBADMSG;
*v2_attr_ref = kmip_new_attribute_reference(attr_tag, NULL, NULL);
if (*v2_attr_ref == NULL)
return -ENOMEM;
return 0;
}
/**
* Constructs a Unique Identifier attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Unique Identifier Yes Text String v1.0
* Enumeration v2.0
* Integer v2.0
*
* @param text_id the unique identifier as text string (or NULL)
* @param enum_id the unique identifier as enumeration (or 0)
* @param int_id the unique identifier as integer
*
* @returns the allocated node, or NULL in case of an error.
*/
struct kmip_node *kmip_new_unique_identifier(const char *text_id,
enum kmip_unique_identifier enum_id,
int32_t int_id)
{
if (text_id != NULL && enum_id != 0)
return NULL;
if (text_id != NULL)
return kmip_node_new_text_string(KMIP_TAG_UNIQUE_IDENTIFIER,
NULL, text_id);
if (enum_id != 0)
return kmip_node_new_enumeration(KMIP_TAG_UNIQUE_IDENTIFIER,
NULL, enum_id);
return kmip_node_new_integer(KMIP_TAG_UNIQUE_IDENTIFIER, NULL, int_id);
}
/**
* Gets the information from a Unique Identifier attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Unique Identifier Yes Text String v1.0
* Enumeration v2.0
* Integer v2.0
*
* @param node the KMIP node
* @param text_id the unique identifier as text string (can be NULL)
* @param enum_id the unique identifier as enumeration (can be NULL)
* @param int_id the unique identifier as integer (can be NULL)
*
* @returns 0 on success, or a negative errno in case of an error
*/
int kmip_get_unique_identifier(const struct kmip_node *node,
const char **text_id,
enum kmip_unique_identifier *enum_id,
int32_t *int_id)
{
if (node == NULL)
return -EBADMSG;
if (kmip_node_get_tag(node) != KMIP_TAG_UNIQUE_IDENTIFIER)
return -EBADMSG;
if (text_id != NULL) {
if (kmip_node_get_type(node) == KMIP_TYPE_TEXT_STRING)
*text_id = kmip_node_get_text_string(node);
else
*text_id = NULL;
}
if (enum_id != NULL) {
if (kmip_node_get_type(node) == KMIP_TYPE_ENUMERATION)
*enum_id = kmip_node_get_enumeration(node);
else
*enum_id = 0;
}
if (int_id != NULL) {
if (kmip_node_get_type(node) == KMIP_TYPE_INTEGER)
*int_id = kmip_node_get_integer(node);
else
*int_id = 0;
}
return 0;
}
/**
* Constructs a Name attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Name Yes Structure v1.0
* Name Value Yes Text String v1.0
* Name Type Yes Enumeration v1.0
*
* @param value the value of the name
* @param type the type of the name
*
* @returns the allocated node, or NULL in case of an error.
*/
struct kmip_node *kmip_new_name(const char *value, enum kmip_name_type type)
{
struct kmip_node *name = NULL, *val, *typ;
if (value == NULL)
return NULL;
val = kmip_node_new_text_string(KMIP_TAG_NAME_VALUE, NULL, value);
typ = kmip_node_new_enumeration(KMIP_TAG_NAME_TYPE, NULL, type);
if (val == NULL || typ == NULL)
goto out;
name = kmip_node_new_structure_va(KMIP_TAG_NAME, NULL, 2, val, typ);
out:
kmip_node_free(val);
kmip_node_free(typ);
return name;
}
/**
* Gets the information from a Name attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Name Yes Structure v1.0
* Name Value Yes Text String v1.0
* Name Type Yes Enumeration v1.0
*
* @param node the KMIP node
* @param value On return: the name value (can be NULL)
* @param type On return: the name type (can be NULL)
*
* @returns 0 on success, or a negative errno in case of an error
* The reference count of the returned nodes is increased. The caller must
* free the node via kmip_node_free() when no longer needed.
*/
int kmip_get_name(const struct kmip_node *node,
const char **value, enum kmip_name_type *type)
{
struct kmip_node *val, *typ;
int rc = 0;
if (node == NULL)
return -EINVAL;
if (kmip_node_get_tag(node) != KMIP_TAG_NAME)
return -EBADMSG;
val = kmip_node_get_structure_element_by_tag(node, KMIP_TAG_NAME_VALUE,
0);
typ = kmip_node_get_structure_element_by_tag(node, KMIP_TAG_NAME_TYPE,
0);
if (val == NULL || typ == NULL) {
rc = -EBADMSG;
goto out;
}
if (value != NULL)
*value = kmip_node_get_text_string(val);
if (type != NULL)
*type = kmip_node_get_enumeration(typ);
out:
kmip_node_free(val);
kmip_node_free(typ);
return rc;
}
/**
* Constructs a Alternative Name attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Alternative Name Yes Structure v1.2
* Alternative Name Value Yes Text String v1.2
* Alternative Name Type Yes Enumeration v1.2
*
* @param value the value of the alternative name
* @param type the type of the alternative name
*
* @returns the allocated node, or NULL in case of an error.
*/
struct kmip_node *kmip_new_alternative_name(const char *value,
enum kmip_alternative_name_type type)
{
struct kmip_node *name = NULL, *val, *typ;
if (value == NULL)
return NULL;
val = kmip_node_new_text_string(KMIP_TAG_ALTERNATE_NAME_VALUE, NULL,
value);
typ = kmip_node_new_enumeration(KMIP_TAG_ALTERNATE_NAME_TYPE, NULL,
type);
if (val == NULL || typ == NULL)
goto out;
name = kmip_node_new_structure_va(KMIP_TAG_ALTERNATE_NAME, NULL, 2, val,
typ);
out:
kmip_node_free(val);
kmip_node_free(typ);
return name;
}
/**
* Gets the information from an Alternative Name attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Alternative Name Yes Structure v1.2
* Alternative Name Value Yes Text String v1.2
* Alternative Name Type Yes Enumeration v1.2
*
* @param node the KMIP node
* @param value On return: the alternative name value (can be NULL)
* @param type On return: the alternative name type (can be NULL)
*
* @returns 0 on success, or a negative errno in case of an error
* The reference count of the returned nodes is increased. The caller must
* free the node via kmip_node_free() when no longer needed.
*/
int kmip_get_alternative_name(const struct kmip_node *node,
const char **value,
enum kmip_alternative_name_type *type)
{
struct kmip_node *val, *typ;
int rc = 0;
if (node == NULL)
return -EINVAL;
if (kmip_node_get_tag(node) != KMIP_TAG_ALTERNATE_NAME)
return -EBADMSG;
val = kmip_node_get_structure_element_by_tag(node,
KMIP_TAG_ALTERNATE_NAME_VALUE, 0);
typ = kmip_node_get_structure_element_by_tag(node,
KMIP_TAG_ALTERNATE_NAME_TYPE, 0);
if (val == NULL || typ == NULL) {
rc = -EBADMSG;
goto out;
}
if (value != NULL)
*value = kmip_node_get_text_string(val);
if (type != NULL)
*type = kmip_node_get_enumeration(typ);
out:
kmip_node_free(val);
kmip_node_free(typ);
return rc;
}
/**
* Constructs a Object Type attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Object Type Yes Enumeration v1.0
*
* @param obj_type the object type
*
* @returns the allocated node, or NULL in case of an error.
*/
struct kmip_node *kmip_new_object_type(enum kmip_object_type obj_type)
{
return kmip_node_new_enumeration(KMIP_TAG_OBJECT_TYPE, NULL, obj_type);
}
/**
* Gets the information from a Object Type attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Object Type Yes Enumeration v1.0
*
*
* @param node the KMIP node
* @param obj_type the object type
*
* @returns 0 on success, or a negative errno in case of an error
*/
int kmip_get_object_type(const struct kmip_node *node,
enum kmip_object_type *obj_type)
{
if (node == NULL || obj_type == NULL)
return -EBADMSG;
if (kmip_node_get_tag(node) != KMIP_TAG_OBJECT_TYPE)
return -EBADMSG;
*obj_type = kmip_node_get_enumeration(node);
return 0;
}
/**
* Constructs a Cryptographic Algorithm attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Cryptographic Algorithm Yes Enumeration v1.0
*
* @param algo the cryptographic algorithm
*
* @returns the allocated node, or NULL in case of an error.
*/
struct kmip_node *kmip_new_cryptographic_algorithm(enum kmip_crypto_algo algo)
{
return kmip_node_new_enumeration(KMIP_TAG_CRYPTOGRAPHIC_ALGORITHM, NULL,
algo);
}
/**
* Gets the information from a Cryptographic Algorithm attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Cryptographic Algorithm Yes Enumeration v1.0
*
*
* @param node the KMIP node
* @param algo the cryptographic algorithm
*
* @returns 0 on success, or a negative errno in case of an error
*/
int kmip_get_cryptographic_algorithm(const struct kmip_node *node,
enum kmip_crypto_algo *algo)
{
if (node == NULL || algo == NULL)
return -EBADMSG;
if (kmip_node_get_tag(node) != KMIP_TAG_CRYPTOGRAPHIC_ALGORITHM)
return -EBADMSG;
*algo = kmip_node_get_enumeration(node);
return 0;
}
/**
* Constructs a Cryptographic Length attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Cryptographic Length Yes Integer v1.0
*
* @param length the cryptographic length
*
* @returns the allocated node, or NULL in case of an error.
*/
struct kmip_node *kmip_new_cryptographic_length(int32_t length)
{
return kmip_node_new_integer(KMIP_TAG_CRYPTOGRAPHIC_LENGTH, NULL,
length);
}
/**
* Gets the information from a Cryptographic Length attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Cryptographic Length Yes Integer v1.0
*
*
* @param node the KMIP node
* @param length the cryptographic length
*
* @returns 0 on success, or a negative errno in case of an error
*/
int kmip_get_cryptographic_length(const struct kmip_node *node,
int32_t *length)
{
if (node == NULL || length == NULL)
return -EBADMSG;
if (kmip_node_get_tag(node) != KMIP_TAG_CRYPTOGRAPHIC_LENGTH)
return -EBADMSG;
*length = kmip_node_get_integer(node);
return 0;
}
/**
* Constructs a Certificate Type attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Certificate Type Yes Enumeration v1.0
*
* @param type the certificate type
*
* @returns the allocated node, or NULL in case of an error.
*/
struct kmip_node *kmip_new_certificate_type(enum kmip_certificate_type type)
{
return kmip_node_new_enumeration(KMIP_TAG_CERTIFICATE_TYPE, NULL, type);
}
/**
* Gets the information from a Certificate Type attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Certificate Type Yes Enumeration v1.0
*
*
* @param node the KMIP node
* @param type the certificate type
*
* @returns 0 on success, or a negative errno in case of an error
*/
int kmip_get_certificate_type(const struct kmip_node *node,
enum kmip_certificate_type *type)
{
if (node == NULL || type == NULL)
return -EBADMSG;
if (kmip_node_get_tag(node) != KMIP_TAG_CERTIFICATE_TYPE)
return -EBADMSG;
*type = kmip_node_get_enumeration(node);
return 0;
}
/**
* Constructs a Cryptographic Usage Mask attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Cryptographic Usage Mask Yes Integer v1.0
*
* @param usage_mask the cryptographic usage mask
*
* @returns the allocated node, or NULL in case of an error.
*/
struct kmip_node *kmip_new_cryptographic_usage_mask(int32_t usage_mask)
{
return kmip_node_new_integer(KMIP_TAG_CRYPTOGRAPHIC_USAGE_MASK, NULL,
usage_mask);
}
/**
* Gets the information from a Cryptographic Usage Mask attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Cryptographic Usage Mask Yes Integer v1.0
*
*
* @param node the KMIP node
* @param usage_mask the cryptographic usage mask
*
* @returns 0 on success, or a negative errno in case of an error
*/
int kmip_get_cryptographic_usage_mask(const struct kmip_node *node,
int32_t *usage_mask)
{
if (node == NULL || usage_mask == NULL)
return -EBADMSG;
if (kmip_node_get_tag(node) != KMIP_TAG_CRYPTOGRAPHIC_USAGE_MASK)
return -EBADMSG;
*usage_mask = kmip_node_get_integer(node);
return 0;
}
/**
* Constructs a State attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* State Yes Enumeration v1.0
*
* @param state the state
*
* @returns the allocated node, or NULL in case of an error.
*/
struct kmip_node *kmip_new_state(enum kmip_state state)
{
return kmip_node_new_enumeration(KMIP_TAG_STATE, NULL, state);
}
/**
* Gets the information from a State attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* State Yes Enumeration v1.0
*
*
* @param node the KMIP node
* @param state the state
*
* @returns 0 on success, or a negative errno in case of an error
*/
int kmip_get_state(const struct kmip_node *node, enum kmip_state *state)
{
if (node == NULL || state == NULL)
return -EBADMSG;
if (kmip_node_get_tag(node) != KMIP_TAG_STATE)
return -EBADMSG;
*state = kmip_node_get_enumeration(node);
return 0;
}
/**
* Constructs a Initial Date attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Initial Date Yes Date-Time v1.0
*
* @param date the date
*
* @returns the allocated node, or NULL in case of an error.
*/
struct kmip_node *kmip_new_initial_date(int64_t date)
{
return kmip_node_new_enumeration(KMIP_TAG_INITIAL_DATE, NULL, date);
}
/**
* Gets the information from a Initial Date attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Initial Date Yes Date-Time v1.0
*
*
* @param node the KMIP node
* @param date the date
*
* @returns 0 on success, or a negative errno in case of an error
*/
int kmip_get_initial_date(const struct kmip_node *node, int64_t *date)
{
if (node == NULL || date == NULL)
return -EBADMSG;
if (kmip_node_get_tag(node) != KMIP_TAG_INITIAL_DATE)
return -EBADMSG;
*date = kmip_node_get_date_time(node);
return 0;
}
/**
* Constructs a Activation Date attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Activation Date Yes Date-Time v1.0
*
* @param date the date
*
* @returns the allocated node, or NULL in case of an error.
*/
struct kmip_node *kmip_new_activation_date(int64_t date)
{
return kmip_node_new_enumeration(KMIP_TAG_ACTIVATION_DATE, NULL, date);
}
/**
* Gets the information from a Activation Date attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Activation Date Yes Date-Time v1.0
*
*
* @param node the KMIP node
* @param date the date
*
* @returns 0 on success, or a negative errno in case of an error
*/
int kmip_get_activation_date(const struct kmip_node *node, int64_t *date)
{
if (node == NULL || date == NULL)
return -EBADMSG;
if (kmip_node_get_tag(node) != KMIP_TAG_ACTIVATION_DATE)
return -EBADMSG;
*date = kmip_node_get_date_time(node);
return 0;
}
/**
* Constructs a Deactivation Date attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Deactivation Date Yes Date-Time v1.0
*
* @param date the date
*
* @returns the allocated node, or NULL in case of an error.
*/
struct kmip_node *kmip_new_deactivation_date(int64_t date)
{
return kmip_node_new_enumeration(KMIP_TAG_DEACTIVATION_DATE, NULL,
date);
}
/**
* Gets the information from a Deactivation Date attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Deactivation Date Yes Date-Time v1.0
*
*
* @param node the KMIP node
* @param date the date
*
* @returns 0 on success, or a negative errno in case of an error
*/
int kmip_get_deactivation_date(const struct kmip_node *node, int64_t *date)
{
if (node == NULL || date == NULL)
return -EBADMSG;
if (kmip_node_get_tag(node) != KMIP_TAG_DEACTIVATION_DATE)
return -EBADMSG;
*date = kmip_node_get_date_time(node);
return 0;
}
/**
* Constructs a Destroy Date attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Destroy Date Yes Date-Time v1.0
*
* @param date the date
*
* @returns the allocated node, or NULL in case of an error.
*/
struct kmip_node *kmip_new_destroy_date(int64_t date)
{
return kmip_node_new_enumeration(KMIP_TAG_DESTROY_DATE, NULL, date);
}
/**
* Gets the information from a Destroy Date attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Destroy Date Yes Date-Time v1.0
*
*
* @param node the KMIP node
* @param date the date
*
* @returns 0 on success, or a negative errno in case of an error
*/
int kmip_get_destroy_date(const struct kmip_node *node, int64_t *date)
{
if (node == NULL || date == NULL)
return -EBADMSG;
if (kmip_node_get_tag(node) != KMIP_TAG_DESTROY_DATE)
return -EBADMSG;
*date = kmip_node_get_date_time(node);
return 0;
}
/**
* Constructs a Compromise Date attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Compromise Date Yes Date-Time v1.0
*
* @param date the date
*
* @returns the allocated node, or NULL in case of an error.
*/
struct kmip_node *kmip_new_compromise_date(int64_t date)
{
return kmip_node_new_enumeration(KMIP_TAG_COMPROMIZE_DATE, NULL, date);
}
/**
* Gets the information from a Compromise Date attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Compromise Date Yes Date-Time v1.0
*
*
* @param node the KMIP node
* @param date the date
*
* @returns 0 on success, or a negative errno in case of an error
*/
int kmip_get_compromise_date(const struct kmip_node *node, int64_t *date)
{
if (node == NULL || date == NULL)
return -EBADMSG;
if (kmip_node_get_tag(node) != KMIP_TAG_COMPROMIZE_DATE)
return -EBADMSG;
*date = kmip_node_get_date_time(node);
return 0;
}
/**
* Constructs a Compromise Occurrence Date attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Compromise Occurrence Date Yes Date-Time v1.0
*
* @param date the date
*
* @returns the allocated node, or NULL in case of an error.
*/
struct kmip_node *kmip_new_compromise_occurrence_date(int64_t date)
{
return kmip_node_new_enumeration(KMIP_TAG_COMPROMISE_OCCURRENCE_DATE,
NULL, date);
}
/**
* Gets the information from a Compromise Occurrence Date attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Compromise Occurrence Date Yes Date-Time v1.0
*
*
* @param node the KMIP node
* @param date the date
*
* @returns 0 on success, or a negative errno in case of an error
*/
int kmip_get_compromise_occurrence_date(const struct kmip_node *node,
int64_t *date)
{
if (node == NULL || date == NULL)
return -EBADMSG;
if (kmip_node_get_tag(node) != KMIP_TAG_COMPROMISE_OCCURRENCE_DATE)
return -EBADMSG;
*date = kmip_node_get_date_time(node);
return 0;
}
/**
* Constructs a Last Change Date attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Last Change Date Yes Date-Time v1.0
*
* @param date the date
*
* @returns the allocated node, or NULL in case of an error.
*/
struct kmip_node *kmip_new_last_change_date(int64_t date)
{
return kmip_node_new_enumeration(KMIP_TAG_LAST_CHANGE_DATE, NULL, date);
}
/**
* Gets the information from a Last Change Date attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Last Change Date Yes Date-Time v1.0
*
*
* @param node the KMIP node
* @param date the date
*
* @returns 0 on success, or a negative errno in case of an error
*/
int kmip_get_last_change_date(const struct kmip_node *node, int64_t *date)
{
if (node == NULL || date == NULL)
return -EBADMSG;
if (kmip_node_get_tag(node) != KMIP_TAG_LAST_CHANGE_DATE)
return -EBADMSG;
*date = kmip_node_get_date_time(node);
return 0;
}
/**
* Constructs a Original Creation Date attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Original Creation Date Yes Date-Time v1.0
*
* @param date the date
*
* @returns the allocated node, or NULL in case of an error.
*/
struct kmip_node *kmip_new_original_creation_date(int64_t date)
{
return kmip_node_new_enumeration(KMIP_TAG_ORIGINAL_CREATION_DATE, NULL,
date);
}
/**
* Gets the information from a Original Creation Date attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Original Creation Date Yes Date-Time v1.0
*
*
* @param node the KMIP node
* @param date the date
*
* @returns 0 on success, or a negative errno in case of an error
*/
int kmip_get_original_creation_date(const struct kmip_node *node, int64_t *date)
{
if (node == NULL || date == NULL)
return -EBADMSG;
if (kmip_node_get_tag(node) != KMIP_TAG_ORIGINAL_CREATION_DATE)
return -EBADMSG;
*date = kmip_node_get_date_time(node);
return 0;
}
/**
* Constructs a Archive Date attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Archive Date Yes Date-Time v1.0
*
* @param date the date
*
* @returns the allocated node, or NULL in case of an error.
*/
struct kmip_node *kmip_new_archive_date(int64_t date)
{
return kmip_node_new_enumeration(KMIP_TAG_ARCHIVE_DATE, NULL, date);
}
/**
* Gets the information from a Archive Date attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Archive Date Yes Date-Time v1.0
*
*
* @param node the KMIP node
* @param date the date
*
* @returns 0 on success, or a negative errno in case of an error
*/
int kmip_get_archive_date(const struct kmip_node *node, int64_t *date)
{
if (node == NULL || date == NULL)
return -EBADMSG;
if (kmip_node_get_tag(node) != KMIP_TAG_ARCHIVE_DATE)
return -EBADMSG;
*date = kmip_node_get_date_time(node);
return 0;
}
/**
* Constructs a Process Start Date attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Process Start Date Yes Date-Time v1.0
*
* @param date the date
*
* @returns the allocated node, or NULL in case of an error.
*/
struct kmip_node *kmip_new_process_start_date(int64_t date)
{
return kmip_node_new_enumeration(KMIP_TAG_PROCESS_START_DATE, NULL,
date);
}
/**
* Gets the information from a Process Start Date attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Process Start Date Yes Date-Time v1.0
*
*
* @param node the KMIP node
* @param date the date
*
* @returns 0 on success, or a negative errno in case of an error
*/
int kmip_get_process_start_date(const struct kmip_node *node, int64_t *date)
{
if (node == NULL || date == NULL)
return -EBADMSG;
if (kmip_node_get_tag(node) != KMIP_TAG_PROCESS_START_DATE)
return -EBADMSG;
*date = kmip_node_get_date_time(node);
return 0;
}
/**
* Constructs a Protect Stop Date attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Protect Stop Date Yes Date-Time v1.0
*
* @param date the date
*
* @returns the allocated node, or NULL in case of an error.
*/
struct kmip_node *kmip_new_protect_stop_date(int64_t date)
{
return kmip_node_new_enumeration(KMIP_TAG_PROTECT_STOP_DATE, NULL,
date);
}
/**
* Gets the information from a Protect Stop Date attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Protect Stop Date Yes Date-Time v1.0
*
* @param node the KMIP node
* @param date the date
*
* @returns 0 on success, or a negative errno in case of an error
*/
int kmip_get_protect_stop_date(const struct kmip_node *node, int64_t *date)
{
if (node == NULL || date == NULL)
return -EBADMSG;
if (kmip_node_get_tag(node) != KMIP_TAG_PROTECT_STOP_DATE)
return -EBADMSG;
*date = kmip_node_get_date_time(node);
return 0;
}
/**
* Constructs a Cryptographic Parameters attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Cryptographic Parameters Structure v1.0
* Block Cipher Mode No Enumeration v1.0
* Padding Method No Enumeration v1.0
* Hashing Algorithm No Enumeration v1.0
* Key Role Type No Enumeration v1.0
* Digital Signature Algorithm No Enumeration v1.2
* Cryptographic Algorithm No Enumeration v1.2
* Random IV No Boolean v1.2
* IV Length No Integer v1.2
* Tag Length No Integer v1.2
* Fixed Field Length No Integer v1.2
* Invocation Field Length No Integer v1.2
* Counter Length No Integer v1.2
* Initial Counter Value No Integer v1.2
* Salt Length No Integer v1.4
* Mask Generator No Enumeration v1.4
* Mask Generator Hashing Alg No Enumeration v1.4
* P Source No Byte String v1.4
* Trailer Field No Integer v1.4
*
* @param version the protocol version. If null, the current default
* protocol version is used.
* @param mode the block cipher mode (ignored if 0)
* @param padding the padding method (ignored if 0)
* @param hash_algo the hashing algorithm (ignored if 0)
* @param key_role the key role type (ignored if 0)
* @param signature_algo the signature algorithm (ignored if 0)
* @param crypto_algo the cryptographic algorithm (ignored if 0)
* @param random_iv true if a random IV is used (ignored if NULL)
* @param iv_length the IV length (ignored if NULL)
* @param tag_length the tag length (ignored if NULL)
* @param fixed_field_length the fixed field length (ignored if NULL)
* @param invoc_field_length the invocation field length (ignored if NULL)
* @param counter_length the counter length (ignored if NULL)
* @param init_counter_value the initial counter value (ignored if NULL)
* @param salt_length the salt length (ignored if NULL)
* @param mgf the mask generator (ignored if 0)
* @param mgf_hash_algo the mask generator hash algorithm (ignored if 0)
* @param trailer_field the trailer field (ignored if NULL)
*
* @returns the allocated node, or NULL in case of an error.
*/
struct kmip_node *kmip_new_cryptographic_parameters(
const struct kmip_version *version,
enum kmip_block_cipher_mode mode,
enum kmip_padding_method padding,
enum kmip_hashing_algo hash_algo,
enum kmip_key_role_type key_role,
enum kmip_signature_algo signature_algo,
enum kmip_crypto_algo crypto_algo,
bool *random_iv,
int32_t *iv_length,
int32_t *tag_length,
int32_t *fixed_field_length,
int32_t *invoc_field_length,
int32_t *counter_length,
int32_t *init_counter_value,
int32_t *salt_length,
enum kmip_mask_generator mgf,
enum kmip_hashing_algo mgf_hash_algo,
int32_t *trailer_field)
{
struct kmip_node *icv = NULL, *salt = NULL, *mg = NULL, *mghash = NULL;
struct kmip_node *ret = NULL, *cmod = NULL, *pad = NULL, *hash = NULL;
struct kmip_node *krl = NULL, *sig = NULL, *algo = NULL, *riv = NULL;
struct kmip_node *iv = NULL, *tag = NULL, *ffl = NULL, *ifl = NULL;
struct kmip_node *cnt = NULL, *trl = NULL;
if (version == NULL)
version = kmip_get_default_protocol_version();
if (mode != 0) {
cmod = kmip_node_new_enumeration(KMIP_TAG_BLOCK_CIPHER_MODE,
NULL, mode);
if (cmod == NULL)
goto out;
}
if (padding != 0) {
pad = kmip_node_new_enumeration(KMIP_TAG_PADDING_METHOD,
NULL, padding);
if (pad == NULL)
goto out;
}
if (hash_algo != 0) {
hash = kmip_node_new_enumeration(KMIP_TAG_HASHING_ALGORITHM,
NULL, hash_algo);
if (hash == NULL)
goto out;
}
if (key_role != 0) {
krl = kmip_node_new_enumeration(KMIP_TAG_KEY_ROLE_TYPE,
NULL, key_role);
if (krl == NULL)
goto out;
}
if (version->major == 1 && version->minor < 2)
goto create;
if (signature_algo != 0) {
sig = kmip_node_new_enumeration(
KMIP_TAG_DIGITAL_SIGNATURE_ALGORITHM,
NULL, signature_algo);
if (sig == NULL)
goto out;
}
if (crypto_algo != 0) {
algo = kmip_node_new_enumeration(
KMIP_TAG_CRYPTOGRAPHIC_ALGORITHM,
NULL, crypto_algo);
if (algo == NULL)
goto out;
}
if (random_iv != NULL) {
riv = kmip_node_new_boolean(KMIP_TAG_RANDOM_IV, NULL,
*random_iv);
if (riv == NULL)
goto out;
}
if (iv_length != NULL) {
iv = kmip_node_new_integer(KMIP_TAG_IV_LENGTH, NULL,
*iv_length);
if (iv == NULL)
goto out;
}
if (tag_length != NULL) {
tag = kmip_node_new_integer(KMIP_TAG_TAG_LENGTH, NULL,
*tag_length);
if (tag == NULL)
goto out;
}
if (fixed_field_length != NULL) {
ffl = kmip_node_new_integer(KMIP_TAG_FIXED_FIELD_LENGTH, NULL,
*fixed_field_length);
if (ffl == NULL)
goto out;
}
if (invoc_field_length != NULL) {
ifl = kmip_node_new_integer(KMIP_TAG_INVOCATION_FIELD_LENGTH,
NULL, *invoc_field_length);
if (ifl == NULL)
goto out;
}
if (counter_length != NULL) {
cnt = kmip_node_new_integer(KMIP_TAG_COUNTER_LENGTH, NULL,
*counter_length);
if (cnt == NULL)
goto out;
}
if (init_counter_value != NULL) {
icv = kmip_node_new_integer(KMIP_TAG_INITIAL_COUNTER_VALUE,
NULL, *init_counter_value);
if (icv == NULL)
goto out;
}
if (version->major == 1 && version->minor < 4)
goto create;
if (salt_length != NULL) {
salt = kmip_node_new_integer(KMIP_TAG_SALT_LENGTH, NULL,
*salt_length);
if (salt == NULL)
goto out;
}
if (mgf != 0) {
mg = kmip_node_new_enumeration(KMIP_TAG_MASK_GENERATOR,
NULL, mgf);
if (mg == NULL)
goto out;
}
if (mgf_hash_algo != 0) {
mghash = kmip_node_new_enumeration(
KMIP_TAG_MASK_GENERATOR_HASHING_ALGORITHM,
NULL, mgf_hash_algo);
if (mghash == NULL)
goto out;
}
if (trailer_field != NULL) {
trl = kmip_node_new_integer(KMIP_TAG_TRAILER_FIELD, NULL,
*trailer_field);
if (trl == NULL)
goto out;
}
create:
ret = kmip_node_new_structure_va(KMIP_TAG_CRYPTOGRAPHIC_PARAMETERS,
NULL, 17, cmod, pad, hash, krl, sig,
algo, riv, iv, tag, ffl, ifl, cnt, icv,
salt, mg, mghash, trl);
out:
kmip_node_free(cmod);
kmip_node_free(pad);
kmip_node_free(hash);
kmip_node_free(krl);
kmip_node_free(sig);
kmip_node_free(algo);
kmip_node_free(riv);
kmip_node_free(iv);
kmip_node_free(tag);
kmip_node_free(ffl);
kmip_node_free(ifl);
kmip_node_free(cnt);
kmip_node_free(icv);
kmip_node_free(salt);
kmip_node_free(mg);
kmip_node_free(mghash);
kmip_node_free(trl);
return ret;
}
/**
* Gets information from a Cryptographic Parameter attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Cryptographic Parameters Structure v1.0
* Block Cipher Mode No Enumeration v1.0
* Padding Method No Enumeration v1.0
* Hashing Algorithm No Enumeration v1.0
* Key Role Type No Enumeration v1.0
* Digital Signature Algorithm No Enumeration v1.2
* Cryptographic Algorithm No Enumeration v1.2
* Random IV No Boolean v1.2
* IV Length No Integer v1.2
* Tag Length No Integer v1.2
* Fixed Field Length No Integer v1.2
* Invocation Field Length No Integer v1.2
* Counter Length No Integer v1.2
* Initial Counter Value No Integer v1.2
* Salt Length No Integer v1.4
* Mask Generator No Enumeration v1.4
* Mask Generator Hashing Alg No Enumeration v1.4
* P Source No Byte String v1.4
* Trailer Field No Integer v1.4
*
* @param node the KMIP node
* @param mode On return: the block cipher mode (0 if not avail,
* can be NULL)
* @param padding On return: the padding method (0 if not avail,
* can be NULL)
* @param hash_algo On return: the hashing algorithm (0 if not avail,
* can be NULL)
* @param key_role On return: the key role type (0 if not avail,
* can be NULL)
* @param signature_algo On return: the signature algorithm (0 if not avail,
* can be NULL)
* @param crypto_algo On return: the cryptographic algorithm (0 if not
* avail, can be NULL)
* @param random_iv On return: true if a random IV is used (false if
* not avail, can be NULL)
* @param iv_length On return: the IV length (-1 if not avail, can be
* NULL)
* @param tag_length On return: the tag length (-1 if not avail, can be
* NULL)
* @param fixed_field_length On return: the fixed field length (-1 if not avail,
* can be NULL)
* @param invoc_field_length On return: the invocation field length (-1 if not
* avail, can be NULL)
* @param counter_length On return: the counter length (-1 if not avail,
* can be NULL)
* @param init_counter_value On return: the initial counter value (0 if not
* avail, can be NULL)
* @param salt_length On return: the salt length (-1 if not avail,
* can be NULL)
* @param mgf On return: the mask generator (0 if not avail,
* can be NULL)
* @param mgf_hash_algo On return: the mask generator hash algorithm (0 if
* not avail, can be NULL)
* @param trailer_field On return: the trailer field (0 if not avail,
* can be NULL)
*
* @returns 0 on success, or a negative errno in case of an error.
* The reference count of the returned nodes is increased. The caller must
* free the node via kmip_node_free() when no longer needed.
*/
int kmip_get_cryptographic_parameter(const struct kmip_node *node,
enum kmip_block_cipher_mode *mode,
enum kmip_padding_method *padding,
enum kmip_hashing_algo *hash_algo,
enum kmip_key_role_type *key_role,
enum kmip_signature_algo *signature_algo,
enum kmip_crypto_algo *crypto_algo,
bool *random_iv,
int32_t *iv_length,
int32_t *tag_length,
int32_t *fixed_field_length,
int32_t *invoc_field_length,
int32_t *counter_length,
int32_t *init_counter_value,
int32_t *salt_length,
enum kmip_mask_generator *mgf,
enum kmip_hashing_algo *mgf_hash_algo,
int32_t *trailer_field)
{
struct kmip_node *n;
if (node == NULL)
return -EINVAL;
if (kmip_node_get_tag(node) != KMIP_TAG_CRYPTOGRAPHIC_PARAMETERS)
return -EBADMSG;
if (mode != NULL) {
n = kmip_node_get_structure_element_by_tag(node,
KMIP_TAG_BLOCK_CIPHER_MODE, 0);
*mode = (n != NULL ? kmip_node_get_enumeration(n) : 0);
kmip_node_free(n);
}
if (padding != NULL) {
n = kmip_node_get_structure_element_by_tag(node,
KMIP_TAG_PADDING_METHOD, 0);
*padding = (n != NULL ? kmip_node_get_enumeration(n) : 0);
kmip_node_free(n);
}
if (hash_algo != NULL) {
n = kmip_node_get_structure_element_by_tag(node,
KMIP_TAG_HASHING_ALGORITHM, 0);
*hash_algo = (n != NULL ? kmip_node_get_enumeration(n) : 0);
kmip_node_free(n);
}
if (key_role != NULL) {
n = kmip_node_get_structure_element_by_tag(node,
KMIP_TAG_KEY_ROLE_TYPE, 0);
*key_role = (n != NULL ? kmip_node_get_enumeration(n) : 0);
kmip_node_free(n);
}
if (signature_algo != NULL) {
n = kmip_node_get_structure_element_by_tag(node,
KMIP_TAG_DIGITAL_SIGNATURE_ALGORITHM, 0);
*signature_algo =
(n != NULL ? kmip_node_get_enumeration(n) : 0);
kmip_node_free(n);
}
if (crypto_algo != NULL) {
n = kmip_node_get_structure_element_by_tag(node,
KMIP_TAG_CRYPTOGRAPHIC_ALGORITHM, 0);
*crypto_algo = (n != NULL ? kmip_node_get_enumeration(n) : 0);
kmip_node_free(n);
}
if (random_iv != NULL) {
n = kmip_node_get_structure_element_by_tag(node,
KMIP_TAG_RANDOM_IV, 0);
*random_iv = (n != NULL ? kmip_node_get_boolean(n) : false);
kmip_node_free(n);
}
if (iv_length != NULL) {
n = kmip_node_get_structure_element_by_tag(node,
KMIP_TAG_IV_LENGTH, 0);
*iv_length = (n != NULL ? kmip_node_get_integer(n) : -1);
kmip_node_free(n);
}
if (tag_length != NULL) {
n = kmip_node_get_structure_element_by_tag(node,
KMIP_TAG_TAG_LENGTH, 0);
*tag_length = (n != NULL ? kmip_node_get_integer(n) : -1);
kmip_node_free(n);
}
if (fixed_field_length != NULL) {
n = kmip_node_get_structure_element_by_tag(node,
KMIP_TAG_FIXED_FIELD_LENGTH, 0);
*fixed_field_length =
(n != NULL ? kmip_node_get_integer(n) : -1);
kmip_node_free(n);
}
if (invoc_field_length != NULL) {
n = kmip_node_get_structure_element_by_tag(node,
KMIP_TAG_INVOCATION_FIELD_LENGTH, 0);
*invoc_field_length =
(n != NULL ? kmip_node_get_integer(n) : -1);
kmip_node_free(n);
}
if (counter_length != NULL) {
n = kmip_node_get_structure_element_by_tag(node,
KMIP_TAG_COUNTER_LENGTH, 0);
*counter_length = (n != NULL ? kmip_node_get_integer(n) : -1);
kmip_node_free(n);
}
if (init_counter_value != NULL) {
n = kmip_node_get_structure_element_by_tag(node,
KMIP_TAG_INITIAL_COUNTER_VALUE, 0);
*init_counter_value =
(n != NULL ? kmip_node_get_integer(n) : 0);
kmip_node_free(n);
}
if (salt_length != NULL) {
n = kmip_node_get_structure_element_by_tag(node,
KMIP_TAG_SALT_LENGTH, 0);
*salt_length = (n != NULL ? kmip_node_get_integer(n) : -1);
kmip_node_free(n);
}
if (mgf != NULL) {
n = kmip_node_get_structure_element_by_tag(node,
KMIP_TAG_MASK_GENERATOR, 0);
*mgf = (n != NULL ? kmip_node_get_enumeration(n) : 0);
kmip_node_free(n);
}
if (mgf_hash_algo != NULL) {
n = kmip_node_get_structure_element_by_tag(node,
KMIP_TAG_MASK_GENERATOR_HASHING_ALGORITHM, 0);
*mgf_hash_algo = (n != NULL ? kmip_node_get_enumeration(n) : 0);
kmip_node_free(n);
}
if (trailer_field != NULL) {
n = kmip_node_get_structure_element_by_tag(node,
KMIP_TAG_TRAILER_FIELD, 0);
*trailer_field = (n != NULL ? kmip_node_get_integer(n) : 0);
kmip_node_free(n);
}
return 0;
}
/**
* Constructs a Cryptographic Domain Parameters attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Cryptographic Domain Params Yes Structure v1.0
* Qlength No Integer v1.0
* Recommended Curve No Enumeration v1.0
*
* @param qlength the Q length (ignored of <= 0)
* @param curve the curve (ignored if 0)
*
* @returns the allocated node, or NULL in case of an error.
*/
struct kmip_node *kmip_new_cryptographic_domain_parameters(
int32_t qlength,
enum kmip_recommended_curve curve)
{
struct kmip_node *ret = NULL, *qlen = NULL, *crv = NULL;
if (qlength > 0) {
qlen = kmip_node_new_integer(KMIP_TAG_Q_LENGTH, NULL, qlength);
if (qlen == NULL)
goto out;
}
if (curve != 0) {
crv = kmip_node_new_enumeration(KMIP_TAG_RECOMMENDED_CURVE,
NULL, curve);
if (crv == NULL)
goto out;
}
ret = kmip_node_new_structure_va(
KMIP_TAG_CRYPTOGRAPHIC_DOMAIN_PARAMETERS, NULL, 2,
qlen, crv);
out:
kmip_node_free(qlen);
kmip_node_free(crv);
return ret;
}
/**
* Gets the information from a Cryptographic Domain Parameters attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Cryptographic Domain Params Yes Structure v1.0
* Qlength No Integer v1.0
* Recommended Curve No Enumeration v1.0
*
* @param node the KMIP node
* @param qlength On return: the Q length (-1 if not avail, can be
* NULL)
* @param curve On return: the curve (0 if not avail, can be NULL)
*
* @returns 0 on success, or a negative errno in case of an error
*/
int kmip_get_cryptographic_domain_parameters(const struct kmip_node *node,
int32_t *qlength,
enum kmip_recommended_curve *curve)
{
struct kmip_node *n;
if (node == NULL)
return -EINVAL;
if (kmip_node_get_tag(node) != KMIP_TAG_CRYPTOGRAPHIC_DOMAIN_PARAMETERS)
return -EBADMSG;
if (qlength != NULL) {
n = kmip_node_get_structure_element_by_tag(node,
KMIP_TAG_Q_LENGTH, 0);
*qlength = (n != NULL ? kmip_node_get_integer(n) : -1);
kmip_node_free(n);
}
if (curve != NULL) {
n = kmip_node_get_structure_element_by_tag(node,
KMIP_TAG_RECOMMENDED_CURVE, 0);
*curve = (n != NULL ? kmip_node_get_enumeration(n) : 0);
kmip_node_free(n);
}
return 0;
}
/**
* Constructs a Digital Signature Algorithm attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Digital Signature Algorithm Yes Enumeration v1.2
*
* @param signature_algo the signature algorithm
*
* @returns the allocated node, or NULL in case of an error.
*/
struct kmip_node *kmip_new_digital_signature_algorithm(
enum kmip_signature_algo signature_algo)
{
return kmip_node_new_enumeration(KMIP_TAG_DIGITAL_SIGNATURE_ALGORITHM,
NULL, signature_algo);
}
/**
* Gets the information from a Digital Signature Algorithm attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Digital Signature Algorithm Yes Enumeration v1.2
*
* @param node the KMIP node
* @param signature_algo the signature algorithm
*
* @returns 0 on success, or a negative errno in case of an error
*/
int kmip_get_digital_signature_algorithm(const struct kmip_node *node,
enum kmip_signature_algo *signature_algo)
{
if (node == NULL || signature_algo == NULL)
return -EBADMSG;
if (kmip_node_get_tag(node) != KMIP_TAG_DIGITAL_SIGNATURE_ALGORITHM)
return -EBADMSG;
*signature_algo = kmip_node_get_enumeration(node);
return 0;
}
/**
* Constructs a Object Group attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Object Group Yes Text String v1.0
*
* @param group the object group
*
* @returns the allocated node, or NULL in case of an error.
*/
struct kmip_node *kmip_new_object_group(const char *group)
{
return kmip_node_new_text_string(KMIP_TAG_OBJECT_GROUP, NULL, group);
}
/**
* Gets the information from a Object Group attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Object Group Yes Text String v1.0
*
* @param node the KMIP node
* @param group the object group
*
* @returns 0 on success, or a negative errno in case of an error
*/
int kmip_get_object_group(const struct kmip_node *node, const char **group)
{
if (node == NULL || group == NULL)
return -EBADMSG;
if (kmip_node_get_tag(node) != KMIP_TAG_OBJECT_GROUP)
return -EBADMSG;
*group = kmip_node_get_text_string(node);
return 0;
}
/**
* Constructs a Revocation Reason attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Revocation Reason Yes Structure v1.0
* Revocation Reason Code Yes Enumeration v1.0
* Revocation Message No Text String v1.0
*
* @param reason the revocation reason code
* @param message the revocation message (can be NULL)
*
* @returns the allocated node, or NULL in case of an error.
*/
struct kmip_node *kmip_new_revocation_reason(enum kmip_revoke_reason reason,
const char *message)
{
struct kmip_node *ret = NULL, *rsn, *msg = NULL;
rsn = kmip_node_new_enumeration(KMIP_TAG_REVOCATION_REASON_CODE, NULL,
reason);
if (rsn == NULL)
goto out;
if (message != NULL) {
msg = kmip_node_new_text_string(KMIP_TAG_REVOCATION_MESSAGE,
NULL, message);
if (msg == NULL)
goto out;
}
ret = kmip_node_new_structure_va(KMIP_TAG_REVOCATION_REASON, NULL, 2,
rsn, msg);
out:
kmip_node_free(rsn);
kmip_node_free(msg);
return ret;
}
/**
* Gets the information from a Revocation Reason attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Revocation Reason Yes Structure v1.0
* Revocation Reason Code Yes Enumeration v1.0
* Revocation Message No Text String v1.0
*
* @param node the KMIP node
* @param reason the revocation reason code
* @param message the revocation message (can be NULL)
*
* @returns 0 on success, or a negative errno in case of an error
*/
int kmip_get_revocation_reason(const struct kmip_node *node,
enum kmip_revoke_reason *reason,
const char **message)
{
struct kmip_node *n;
if (node == NULL || reason == NULL)
return -EINVAL;
if (kmip_node_get_tag(node) != KMIP_TAG_REVOCATION_REASON)
return -EBADMSG;
n = kmip_node_get_structure_element_by_tag(node,
KMIP_TAG_REVOCATION_REASON_CODE, 0);
if (n == NULL)
return -EBADMSG;
*reason = kmip_node_get_enumeration(n);
kmip_node_free(n);
if (message != NULL) {
n = kmip_node_get_structure_element_by_tag(node,
KMIP_TAG_REVOCATION_MESSAGE, 0);
*message = (n != NULL ? kmip_node_get_text_string(n) : NULL);
kmip_node_free(n);
}
return 0;
}
/**
* Constructs a Contact Information attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Contact Information Yes Text String v1.0
*
* @param contact the contact information
*
* @returns the allocated node, or NULL in case of an error.
*/
struct kmip_node *kmip_new_contact_information(const char *contact)
{
return kmip_node_new_text_string(KMIP_TAG_CONTACT_INFORMATION, NULL,
contact);
}
/**
* Gets the information from a Contact Information attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Contact Information Yes Text String v1.0
*
* @param node the KMIP node
* @param contact the contact information
*
* @returns 0 on success, or a negative errno in case of an error
*/
int kmip_get_contact_information(const struct kmip_node *node,
const char **contact)
{
if (node == NULL || contact == NULL)
return -EBADMSG;
if (kmip_node_get_tag(node) != KMIP_TAG_CONTACT_INFORMATION)
return -EBADMSG;
*contact = kmip_node_get_text_string(node);
return 0;
}
/**
* Constructs a Description attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Description Yes Text String v1.4
*
* @param description the description
*
* @returns the allocated node, or NULL in case of an error.
*/
struct kmip_node *kmip_new_description(const char *description)
{
return kmip_node_new_text_string(KMIP_TAG_DESCRIPTION, NULL,
description);
}
/**
* Gets the information from a Description attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Description Yes Text String v1.4
*
* @param node the KMIP node
* @param description the description
*
* @returns 0 on success, or a negative errno in case of an error
*/
int kmip_get_description(const struct kmip_node *node, const char **description)
{
if (node == NULL || description == NULL)
return -EBADMSG;
if (kmip_node_get_tag(node) != KMIP_TAG_DESCRIPTION)
return -EBADMSG;
*description = kmip_node_get_text_string(node);
return 0;
}
/**
* Constructs a Comment attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Comment Yes Text String v1.4
*
* @param comment the comment
*
* @returns the allocated node, or NULL in case of an error.
*/
struct kmip_node *kmip_new_comment(const char *comment)
{
return kmip_node_new_text_string(KMIP_TAG_COMMENT, NULL, comment);
}
/**
* Gets the information from a Comment attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Comment Yes Text String v1.4
*
* @param node the KMIP node
* @param comment the comment
*
* @returns 0 on success, or a negative errno in case of an error
*/
int kmip_get_comment(const struct kmip_node *node, const char **comment)
{
if (node == NULL || comment == NULL)
return -EBADMSG;
if (kmip_node_get_tag(node) != KMIP_TAG_COMMENT)
return -EBADMSG;
*comment = kmip_node_get_text_string(node);
return 0;
}
/**
* Constructs a Key Format Type attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Key Format Type Yes Enumeration v2.0
*
* @param type the key format type
*
* @returns the allocated node, or NULL in case of an error.
*/
struct kmip_node *kmip_new_key_format_type(enum kmip_key_format_type type)
{
return kmip_node_new_enumeration(KMIP_TAG_KEY_FORMAT_TYPE, NULL, type);
}
/**
* Gets the information from a Key Format Type attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Key Format Type Yes Enumeration v2.0
*
* @param node the KMIP node
* @param type the key format type
*
* @returns 0 on success, or a negative errno in case of an error
*/
int kmip_get_key_format_type(const struct kmip_node *node,
enum kmip_key_format_type *type)
{
if (node == NULL || type == NULL)
return -EBADMSG;
if (kmip_node_get_tag(node) != KMIP_TAG_KEY_FORMAT_TYPE)
return -EBADMSG;
*type = kmip_node_get_enumeration(node);
return 0;
}
/**
* Constructs a Protection Level attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Protection Level Yes Enumeration v2.0
*
* @param level the protection level
*
* @returns the allocated node, or NULL in case of an error.
*/
struct kmip_node *kmip_new_protection_level(enum kmip_protection_level level)
{
return kmip_node_new_enumeration(KMIP_TAG_PROTECTION_LEVEL, NULL,
level);
}
/**
* Gets the information from a Protection Level attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Protection Level Yes Enumeration v2.0
*
* @param node the KMIP node
* @param level the protection level
*
* @returns 0 on success, or a negative errno in case of an error
*/
int kmip_get_protection_level(const struct kmip_node *node,
enum kmip_protection_level *level)
{
if (node == NULL || level == NULL)
return -EBADMSG;
if (kmip_node_get_tag(node) != KMIP_TAG_PROTECTION_LEVEL)
return -EBADMSG;
*level = kmip_node_get_enumeration(node);
return 0;
}
/**
* Constructs a Protection Period attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Protection Period Yes Interval v2.0
*
* @param period the protection period
*
* @returns the allocated node, or NULL in case of an error.
*/
struct kmip_node *kmip_new_protection_period(uint32_t period)
{
return kmip_node_new_interval(KMIP_TAG_PROTECTION_PERIOD, NULL, period);
}
/**
* Gets the information from a Protection Period attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Protection Period Yes Interval v2.0
*
* @param node the KMIP node
* @param period the protection period
*
* @returns 0 on success, or a negative errno in case of an error
*/
int kmip_get_protection_period(const struct kmip_node *node, uint32_t *period)
{
if (node == NULL || period == NULL)
return -EBADMSG;
if (kmip_node_get_tag(node) != KMIP_TAG_PROTECTION_PERIOD)
return -EBADMSG;
*period = kmip_node_get_interval(node);
return 0;
}
/**
* Constructs a Protection Storage Mask attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Protection Storage Mask Yes Integer v2.0
*
* @param protection_mask the protection mask
*
* @returns the allocated node, or NULL in case of an error.
*/
struct kmip_node *kmip_new_protection_storage_mask(int32_t protection_mask)
{
return kmip_node_new_integer(KMIP_TAG_PROTECTION_STORAGE_MASK, NULL,
protection_mask);
}
/**
* Gets the information from a Protection Storage Mask attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Protection Storage Mask Yes Integer v2.0
*
* @param node the KMIP node
* @param protection_mask the protection mask
*
* @returns 0 on success, or a negative errno in case of an error
*/
int kmip_get_protection_storage_mask(const struct kmip_node *node,
int32_t *protection_mask)
{
if (node == NULL || protection_mask == NULL)
return -EBADMSG;
if (kmip_node_get_tag(node) != KMIP_TAG_PROTECTION_STORAGE_MASK)
return -EBADMSG;
*protection_mask = kmip_node_get_integer(node);
return 0;
}
/**
* Constructs a Fresh attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Fresh Yes Boolean v1.2
*
* @param fresh the fresh value
*
* @returns the allocated node, or NULL in case of an error.
*/
struct kmip_node *kmip_new_fresh(bool fresh)
{
return kmip_node_new_boolean(KMIP_TAG_FRESH, NULL, fresh);
}
/**
* Gets the information from a Fresh attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Fresh Yes Boolean v1.2
*
* @param node the KMIP node
* @param fresh the fresh value
*
* @returns 0 on success, or a negative errno in case of an error
*/
int kmip_get_fresh(const struct kmip_node *node, bool *fresh)
{
if (node == NULL || fresh == NULL)
return -EBADMSG;
if (kmip_node_get_tag(node) != KMIP_TAG_FRESH)
return -EBADMSG;
*fresh = kmip_node_get_boolean(node);
return 0;
}
/**
* Constructs a Key Value Present attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Key Value Present Yes Boolean v1.2
*
* @param present the present value
*
* @returns the allocated node, or NULL in case of an error.
*/
struct kmip_node *kmip_new_key_value_present(bool present)
{
return kmip_node_new_boolean(KMIP_TAG_KEY_VALUE_PRESENT, NULL, present);
}
/**
* Gets the information from a Key Value Present attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Key Value Present Yes Boolean v1.2
*
* @param node the KMIP node
* @param present the present value
*
* @returns 0 on success, or a negative errno in case of an error
*/
int kmip_get_key_value_present(const struct kmip_node *node, bool *present)
{
if (node == NULL || present == NULL)
return -EBADMSG;
if (kmip_node_get_tag(node) != KMIP_TAG_KEY_VALUE_PRESENT)
return -EBADMSG;
*present = kmip_node_get_boolean(node);
return 0;
}
/**
* Constructs a Short Unique Identifier attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Short Unique Identifier Yes Byte String v2.0
*
* @param short_uid the short unique identifier
* @param short_uid_len the length of the short unique identifier
*
* @returns the allocated node, or NULL in case of an error.
*/
struct kmip_node *kmip_new_short_unique_identifier(
const unsigned char *short_uid,
uint32_t short_uid_len)
{
return kmip_node_new_byte_string(KMIP_TAG_SHORT_UNIQUE_IDENTIFIER, NULL,
short_uid, short_uid_len);
}
/**
* Gets the information from a Short Unique Identifier attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Short Unique Identifier Yes Byte String v2.0
*
* @param node the KMIP node
* @param short_uid the short unique identifier
* @param short_uid_len the length of the short unique identifier
*
* @returns 0 on success, or a negative errno in case of an error
*/
int kmip_get_short_unique_identifier(const struct kmip_node *node,
const unsigned char **short_uid,
uint32_t *short_uid_len)
{
if (node == NULL || short_uid == NULL || short_uid_len == NULL)
return -EBADMSG;
if (kmip_node_get_tag(node) != KMIP_TAG_SHORT_UNIQUE_IDENTIFIER)
return -EBADMSG;
*short_uid = kmip_node_get_byte_string(node, short_uid_len);
return 0;
}
/**
* Constructs a Application Specific Information attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Application Specific Info. Yes Structure v1.0
* Application Namespace Yes Text String v1.0
* Application Data Yes/No Text String v1.0
*
* @param name_space the application namespace
* @param data the application data
*
* @returns the allocated node, or NULL in case of an error.
*/
struct kmip_node *kmip_new_application_specific_information(
const char *name_space, const char *data)
{
struct kmip_node *ret = NULL, *ns, *d = NULL;
if (name_space == NULL)
return NULL;
ns = kmip_node_new_text_string(KMIP_TAG_APPLICATION_NAMESPACE, NULL,
name_space);
if (ns == NULL)
goto out;
if (data != NULL) {
d = kmip_node_new_text_string(KMIP_TAG_APPLICATION_DATA, NULL,
data);
if (d == NULL)
goto out;
}
ret = kmip_node_new_structure_va(KMIP_TAG_APPLICATION_DATA, NULL, 2,
ns, d);
out:
kmip_node_free(ns);
kmip_node_free(d);
return ret;
}
/**
* Gets the information from a Application Specific Information attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Application Specific Info. Yes Structure v1.0
* Application Namespace Yes Text String v1.0
* Application Data Yes/No Text String v1.0
*
* @param node the KMIP node
* @param name_space the application namespace
* @param data the application data (can be NULL)
*
* @returns 0 on success, or a negative errno in case of an error
* The reference count of the returned nodes is increased. The caller must
* free the node via kmip_node_free() when no longer needed.
*/
int kmip_get_application_specific_information(const struct kmip_node *node,
const char **name_space,
const char **data)
{
struct kmip_node *n;
if (node == NULL || name_space == NULL)
return -EINVAL;
if (kmip_node_get_tag(node) != KMIP_TAG_APPLICATION_DATA)
return -EBADMSG;
n = kmip_node_get_structure_element_by_tag(node,
KMIP_TAG_APPLICATION_NAMESPACE, 0);
if (n == NULL)
return -EBADMSG;
*name_space = kmip_node_get_text_string(n);
kmip_node_free(n);
if (data != NULL) {
n = kmip_node_get_structure_element_by_tag(node,
KMIP_TAG_APPLICATION_DATA, 0);
if (n == NULL)
return -EBADMSG;
*data = kmip_node_get_text_string(n);
kmip_node_free(n);
}
return 0;
}
/**
* Constructs a Key Value Location attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Key Value Location Yes Structure v1.2
* Key Value Location Value Yes Text String v1.2
* Key Value Location Type Yes Enumeration v1.2
*
* @param value the value of the key value location
* @param type the type of the key value location
*
* @returns the allocated node, or NULL in case of an error.
*/
struct kmip_node *kmip_new_key_value_location(const char *value,
enum kmip_key_value_location_type type)
{
struct kmip_node *name = NULL, *val, *typ;
if (value == NULL)
return NULL;
val = kmip_node_new_text_string(KMIP_TAG_KEY_VALUE_LOCATION_VALUE, NULL,
value);
typ = kmip_node_new_enumeration(KMIP_TAG_KEY_VALUE_LOCATION_TYPE, NULL,
type);
if (val == NULL || typ == NULL)
goto out;
name = kmip_node_new_structure_va(KMIP_TAG_KEY_VALUE_LOCATION, NULL, 2,
val, typ);
out:
kmip_node_free(val);
kmip_node_free(typ);
return name;
}
/**
* Gets the information from a Key Value Location attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Key Value Location Yes Structure v1.2
* Key Value Location Value Yes Text String v1.2
* Key Value Location Type Yes Enumeration v1.2
*
* @param node the KMIP node
* @param value the value of the key value location
* @param type the type of the key value location
*
* @returns 0 on success, or a negative errno in case of an error
*/
int kmip_get_key_value_location(const struct kmip_node *node,
const char **value, enum kmip_key_value_location_type *type)
{
struct kmip_node *val, *typ;
int rc = 0;
if (node == NULL)
return -EINVAL;
if (kmip_node_get_tag(node) != KMIP_TAG_KEY_VALUE_LOCATION)
return -EBADMSG;
val = kmip_node_get_structure_element_by_tag(node,
KMIP_TAG_KEY_VALUE_LOCATION_VALUE, 0);
typ = kmip_node_get_structure_element_by_tag(node,
KMIP_TAG_KEY_VALUE_LOCATION_TYPE, 0);
if (val == NULL || typ == NULL) {
rc = -EBADMSG;
goto out;
}
if (value != NULL)
*value = kmip_node_get_text_string(val);
if (type != NULL)
*type = kmip_node_get_enumeration(typ);
out:
kmip_node_free(val);
kmip_node_free(typ);
return rc;
}
/**
* Constructs a Digest attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Digest Yes Structure v1.0
* Hashing Algorithm Yes Enumeration v1.0
* Digest Value Yes Byte String v1.0
*
* @param hash_algo the hashing algorithm
* @param digest the digest value
* @param digest_len the digest length
*
* @returns the allocated node, or NULL in case of an error.
*/
struct kmip_node *kmip_new_digest(enum kmip_hashing_algo hash_algo,
const unsigned char *digest,
uint32_t digest_len)
{
struct kmip_node *ret = NULL, *algo, *val;
if (digest == NULL || digest_len == 0)
return NULL;
algo = kmip_node_new_enumeration(KMIP_TAG_HASHING_ALGORITHM, NULL,
hash_algo);
val = kmip_node_new_byte_string(KMIP_TAG_DIGEST_VALUE, NULL,
digest, digest_len);
if (algo == NULL || val == NULL)
goto out;
ret = kmip_node_new_structure_va(KMIP_TAG_DIGEST, NULL, 2, algo, val);
out:
kmip_node_free(algo);
kmip_node_free(val);
return ret;
}
/**
* Gets the information from a Digest attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Digest Yes Structure v1.0
* Hashing Algorithm Yes Enumeration v1.0
* Digest Value Yes Byte String v1.0
*
* @param node the KMIP node
* @param hash_algo the hashing algorithm (can be NULL)
* @param digest the digest value (can be NULL)
* @param digest_len the digest length (can be NULL)
*
* @returns 0 on success, or a negative errno in case of an error
*/
int kmip_get_digest(const struct kmip_node *node,
enum kmip_hashing_algo *hash_algo,
const unsigned char **digest, uint32_t *digest_len)
{
struct kmip_node *algo, *val;
int rc = 0;
if (node == NULL)
return -EINVAL;
if (kmip_node_get_tag(node) != KMIP_TAG_DIGEST)
return -EBADMSG;
algo = kmip_node_get_structure_element_by_tag(node,
KMIP_TAG_HASHING_ALGORITHM, 0);
val = kmip_node_get_structure_element_by_tag(node,
KMIP_TAG_DIGEST_VALUE, 0);
if (algo == NULL || val == NULL) {
rc = -EBADMSG;
goto out;
}
if (hash_algo != NULL)
*hash_algo = kmip_node_get_enumeration(algo);
if (digest != NULL)
*digest = kmip_node_get_byte_string(val, digest_len);
out:
kmip_node_free(algo);
kmip_node_free(val);
return rc;
}
/**
* Constructs a Sensitive attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Sensitive Yes Boolean v1.4
*
* @param sensitive the sensitive value
*
* @returns the allocated node, or NULL in case of an error.
*/
struct kmip_node *kmip_new_sensitive(bool sensitive)
{
return kmip_node_new_boolean(KMIP_TAG_SENSITIVE, NULL, sensitive);
}
/**
* Gets the information from a Sensitive attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Sensitive Yes Boolean v1.4
*
* @param node the KMIP node
* @param sensitive the sensitive value
*
* @returns 0 on success, or a negative errno in case of an error
*/
int kmip_get_sensitive(const struct kmip_node *node, bool *sensitive)
{
if (node == NULL || sensitive == NULL)
return -EBADMSG;
if (kmip_node_get_tag(node) != KMIP_TAG_SENSITIVE)
return -EBADMSG;
*sensitive = kmip_node_get_boolean(node);
return 0;
}
/**
* Constructs a Always Sensitive attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Always Sensitive Yes Boolean v1.4
*
* @param sensitive the sensitive value
*
* @returns the allocated node, or NULL in case of an error.
*/
struct kmip_node *kmip_new_always_sensitive(bool sensitive)
{
return kmip_node_new_boolean(KMIP_TAG_ALWAYS_SENSITIVE, NULL,
sensitive);
}
/**
* Gets the information from a Always Sensitive attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Always Sensitive Yes Boolean v1.4
*
* @param node the KMIP node
* @param sensitive the sensitive value
*
* @returns 0 on success, or a negative errno in case of an error
*/
int kmip_get_always_sensitive(const struct kmip_node *node, bool *sensitive)
{
if (node == NULL || sensitive == NULL)
return -EBADMSG;
if (kmip_node_get_tag(node) != KMIP_TAG_ALWAYS_SENSITIVE)
return -EBADMSG;
*sensitive = kmip_node_get_boolean(node);
return 0;
}
/**
* Constructs a Extractable attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Extractable Yes Boolean v1.4
*
* @param extractable the extractable value
*
* @returns the allocated node, or NULL in case of an error.
*/
struct kmip_node *kmip_new_extractable(bool extractable)
{
return kmip_node_new_boolean(KMIP_TAG_EXTRACTABLE, NULL, extractable);
}
/**
* Gets the information from a Extractable attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Extractable Yes Boolean v1.4
*
* @param node the KMIP node
* @param extractable the extractable value
*
* @returns 0 on success, or a negative errno in case of an error
*/
int kmip_get_extractable(const struct kmip_node *node, bool *extractable)
{
if (node == NULL || extractable == NULL)
return -EBADMSG;
if (kmip_node_get_tag(node) != KMIP_TAG_EXTRACTABLE)
return -EBADMSG;
*extractable = kmip_node_get_boolean(node);
return 0;
}
/**
* Constructs a Never Extractable attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Never Extractable Yes Boolean v1.4
*
* @param extractable the extractable value
*
* @returns the allocated node, or NULL in case of an error.
*/
struct kmip_node *kmip_new_never_extractable(bool extractable)
{
return kmip_node_new_boolean(KMIP_TAG_NEVER_EXTRACTABLE, NULL,
extractable);
}
/**
* Gets the information from a Never Extractable attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Never Extractable Yes Boolean v1.4
*
* @param node the KMIP node
* @param extractable the extractable value
*
* @returns 0 on success, or a negative errno in case of an error
*/
int kmip_get_never_extractable(const struct kmip_node *node, bool *extractable)
{
if (node == NULL || extractable == NULL)
return -EBADMSG;
if (kmip_node_get_tag(node) != KMIP_TAG_NEVER_EXTRACTABLE)
return -EBADMSG;
*extractable = kmip_node_get_boolean(node);
return 0;
}
/**
* Constructs a Link attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Link Yes Structure v1.0
* Link Type Yes Enumeration v1.0
* Linked Object Identifier Yes Text String v1.0
* Enumeration v2.0
* Integer v2.0
*
* @param type the link type
* @param obj_id the linked object identifier
*
* @returns the allocated node, or NULL in case of an error.
*/
struct kmip_node *kmip_new_link(enum kmip_link_type type,
struct kmip_node *obj_id)
{
struct kmip_node *ret = NULL, *typ;
if (obj_id == NULL)
return NULL;
typ = kmip_node_new_enumeration(KMIP_TAG_LINK_TYPE, NULL,
type);
if (typ == NULL)
return NULL;
ret = kmip_node_new_structure_va(KMIP_TAG_LINK, NULL, 2,
typ, obj_id);
kmip_node_free(typ);
return ret;
}
/**
* Gets the information from a Link attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Link Yes Structure v1.0
* Link Type Yes Enumeration v1.0
* Linked Object Identifier Yes Text String v1.0
* Enumeration v2.0
* Integer v2.0
*
* @param node the KMIP node
* @param type the link type
* @param obj_id the linked object identifier
*
* @returns 0 on success, or a negative errno in case of an error
* The reference count of the returned nodes is increased. The caller must
* free the node via kmip_node_free() when no longer needed.
*/
int kmip_get_link(const struct kmip_node *node, enum kmip_link_type *type,
struct kmip_node **obj_id)
{
struct kmip_node *n;
if (type == NULL || obj_id == NULL)
return -EINVAL;
if (kmip_node_get_tag(node) != KMIP_TAG_LINK)
return -EBADMSG;
n = kmip_node_get_structure_element_by_tag(node, KMIP_TAG_LINK_TYPE, 0);
if (n == NULL)
return -EBADMSG;
*type = kmip_node_get_enumeration(n);
kmip_node_free(n);
*obj_id = kmip_node_get_structure_element_by_tag(node,
KMIP_TAG_LINKED_OBJECT_IDENTIFIER, 0);
if (*obj_id == NULL)
return -EBADMSG;
return 0;
}
/**
* Constructs a Linked Object Identifier attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Linked Object Identifier Yes Text String v1.0
* Enumeration v2.0
* Integer v2.0
*
* @param text_id the linked identifier as text string (or NULL)
* @param enum_id the linked identifier as enumeration (or 0)
* @param int_id the linked identifier as integer
*
* @returns the allocated node, or NULL in case of an error.
*/
struct kmip_node *kmip_new_linked_object_identifier(const char *text_id,
enum kmip_unique_identifier enum_id,
int32_t int_id)
{
if (text_id != NULL && enum_id != 0)
return NULL;
if (text_id != NULL)
return kmip_node_new_text_string(
KMIP_TAG_LINKED_OBJECT_IDENTIFIER, NULL, text_id);
if (enum_id != 0)
return kmip_node_new_enumeration(
KMIP_TAG_LINKED_OBJECT_IDENTIFIER, NULL, enum_id);
return kmip_node_new_integer(KMIP_TAG_LINKED_OBJECT_IDENTIFIER, NULL,
int_id);
}
/**
* Gets the information from a Linked Object Identifier attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Linked Object Identifier Yes Text String v1.0
* Enumeration v2.0
* Integer v2.0
*
* @param node the KMIP node
* @param text_id the linked identifier as text string (can be NULL)
* @param enum_id the linked identifier as enumeration (can be NULL)
* @param int_id the linked identifier as integer (can be NULL)
*
* @returns 0 on success, or a negative errno in case of an error
*/
int kmip_get_linked_object_identifier(const struct kmip_node *node,
const char **text_id,
enum kmip_unique_identifier *enum_id,
int32_t *int_id)
{
if (node == NULL)
return -EBADMSG;
if (kmip_node_get_tag(node) != KMIP_TAG_LINKED_OBJECT_IDENTIFIER)
return -EBADMSG;
if (text_id != NULL) {
if (kmip_node_get_type(node) == KMIP_TYPE_TEXT_STRING)
*text_id = kmip_node_get_text_string(node);
else
*text_id = NULL;
}
if (enum_id != NULL) {
if (kmip_node_get_type(node) == KMIP_TYPE_ENUMERATION)
*enum_id = kmip_node_get_enumeration(node);
else
*enum_id = 0;
}
if (int_id != NULL) {
if (kmip_node_get_type(node) == KMIP_TYPE_INTEGER)
*int_id = kmip_node_get_integer(node);
else
*int_id = 0;
}
return 0;
}
/**
* Constructs a Operation Policy Name attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Operation Policy Name Yes Text String v1.x only
*
* @param policy the policy name
*
* @returns the allocated node, or NULL in case of an error.
*/
struct kmip_node *kmip_new_operation_policy_name(const char *policy)
{
return kmip_node_new_text_string(KMIP_TAG_OPERATION_POLICY_NAME, NULL,
policy);
}
/**
* Gets the information from a Operation Policy Name attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Operation Policy Name Yes Text String v1.x only
*
* @param node the KMIP node
* @param policy the policy name
*
* @returns 0 on success, or a negative errno in case of an error
*/
int kmip_get_operation_policy_name(const struct kmip_node *node,
const char **policy)
{
if (node == NULL || policy == NULL)
return -EBADMSG;
if (kmip_node_get_tag(node) != KMIP_TAG_OPERATION_POLICY_NAME)
return -EBADMSG;
*policy = kmip_node_get_text_string(node);
return 0;
}
/**
* Constructs a Lease Time attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Lease Time Yes Interval v1.0
*
* @param lease_time the lease time
*
* @returns the allocated node, or NULL in case of an error.
*/
struct kmip_node *kmip_new_lease_time(uint32_t lease_time)
{
return kmip_node_new_interval(KMIP_TAG_LEASE_TIME, NULL, lease_time);
}
/**
* Gets the information from a Lease Time attribute node:
*
* Object Required Encoding KMIP version
* ---------------------------------------------------------------------
* Lease Time Yes Interval v1.0
*
* @param node the KMIP node
* @param lease_time the lease time
*
* @returns 0 on success, or a negative errno in case of an error
*/
int kmip_get_lease_time(const struct kmip_node *node, uint32_t *lease_time)
{
if (node == NULL || lease_time == NULL)
return -EBADMSG;
if (kmip_node_get_tag(node) != KMIP_TAG_LEASE_TIME)
return -EBADMSG;
*lease_time = kmip_node_get_interval(node);
return 0;
}