/* * 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 #include #include #include #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 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 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 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 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 * No 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 * No 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--' * are transformed into a KMIP v2.x vendor attribute with vendor id * and 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 * No 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 * No 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 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 * No 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(ffl); 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; }