16cd6a6acSopenharmony_ci#include <stdlib.h>
26cd6a6acSopenharmony_ci#include <string.h>
36cd6a6acSopenharmony_ci#include <netinet/in.h>
46cd6a6acSopenharmony_ci#include <arpa/inet.h>
56cd6a6acSopenharmony_ci#include <errno.h>
66cd6a6acSopenharmony_ci#include <sepol/ibpkey_record.h>
76cd6a6acSopenharmony_ci
86cd6a6acSopenharmony_ci#include "ibpkey_internal.h"
96cd6a6acSopenharmony_ci#include "context_internal.h"
106cd6a6acSopenharmony_ci#include "debug.h"
116cd6a6acSopenharmony_ci
126cd6a6acSopenharmony_cistruct sepol_ibpkey {
136cd6a6acSopenharmony_ci	/* Subnet prefix */
146cd6a6acSopenharmony_ci	uint64_t subnet_prefix;
156cd6a6acSopenharmony_ci
166cd6a6acSopenharmony_ci	/* Low - High range. Same for single ibpkeys. */
176cd6a6acSopenharmony_ci	int low, high;
186cd6a6acSopenharmony_ci
196cd6a6acSopenharmony_ci	/* Context */
206cd6a6acSopenharmony_ci	sepol_context_t *con;
216cd6a6acSopenharmony_ci};
226cd6a6acSopenharmony_ci
236cd6a6acSopenharmony_cistruct sepol_ibpkey_key {
246cd6a6acSopenharmony_ci	/* Subnet prefix */
256cd6a6acSopenharmony_ci	uint64_t subnet_prefix;
266cd6a6acSopenharmony_ci
276cd6a6acSopenharmony_ci	/* Low - High range. Same for single ibpkeys. */
286cd6a6acSopenharmony_ci	int low, high;
296cd6a6acSopenharmony_ci};
306cd6a6acSopenharmony_ci
316cd6a6acSopenharmony_ci/* Converts a string represtation (subnet_prefix_str)
326cd6a6acSopenharmony_ci * to a numeric representation (subnet_prefix_bytes)
336cd6a6acSopenharmony_ci */
346cd6a6acSopenharmony_cistatic int ibpkey_parse_subnet_prefix(sepol_handle_t *handle,
356cd6a6acSopenharmony_ci				      const char *subnet_prefix_str,
366cd6a6acSopenharmony_ci				      uint64_t *subnet_prefix)
376cd6a6acSopenharmony_ci{
386cd6a6acSopenharmony_ci	struct in6_addr in_addr;
396cd6a6acSopenharmony_ci
406cd6a6acSopenharmony_ci	if (inet_pton(AF_INET6, subnet_prefix_str, &in_addr) <= 0) {
416cd6a6acSopenharmony_ci		ERR(handle, "could not parse IPv6 address for ibpkey subnet prefix %s: %m",
426cd6a6acSopenharmony_ci		    subnet_prefix_str);
436cd6a6acSopenharmony_ci		return STATUS_ERR;
446cd6a6acSopenharmony_ci	}
456cd6a6acSopenharmony_ci
466cd6a6acSopenharmony_ci	memcpy(subnet_prefix, in_addr.s6_addr, sizeof(*subnet_prefix));
476cd6a6acSopenharmony_ci
486cd6a6acSopenharmony_ci	return STATUS_SUCCESS;
496cd6a6acSopenharmony_ci}
506cd6a6acSopenharmony_ci
516cd6a6acSopenharmony_ci/* Converts a numeric representation (subnet_prefix_bytes)
526cd6a6acSopenharmony_ci * to a string representation (subnet_prefix_str)
536cd6a6acSopenharmony_ci */
546cd6a6acSopenharmony_ci
556cd6a6acSopenharmony_cistatic int ibpkey_expand_subnet_prefix(sepol_handle_t *handle,
566cd6a6acSopenharmony_ci				       uint64_t subnet_prefix,
576cd6a6acSopenharmony_ci				       char *subnet_prefix_str)
586cd6a6acSopenharmony_ci{
596cd6a6acSopenharmony_ci	struct in6_addr addr;
606cd6a6acSopenharmony_ci
616cd6a6acSopenharmony_ci	memset(&addr, 0, sizeof(struct in6_addr));
626cd6a6acSopenharmony_ci	memcpy(&addr.s6_addr[0], &subnet_prefix, sizeof(subnet_prefix));
636cd6a6acSopenharmony_ci
646cd6a6acSopenharmony_ci	if (inet_ntop(AF_INET6, &addr, subnet_prefix_str,
656cd6a6acSopenharmony_ci		      INET6_ADDRSTRLEN) == NULL) {
666cd6a6acSopenharmony_ci		ERR(handle,
676cd6a6acSopenharmony_ci		    "could not expand IPv6 address to string: %m");
686cd6a6acSopenharmony_ci		return STATUS_ERR;
696cd6a6acSopenharmony_ci	}
706cd6a6acSopenharmony_ci
716cd6a6acSopenharmony_ci	return STATUS_SUCCESS;
726cd6a6acSopenharmony_ci}
736cd6a6acSopenharmony_ci
746cd6a6acSopenharmony_ci/* Allocates a sufficiently large string (subnet_prefix)
756cd6a6acSopenharmony_ci * for an IPV6 address for the subnet prefix
766cd6a6acSopenharmony_ci */
776cd6a6acSopenharmony_cistatic int ibpkey_alloc_subnet_prefix_string(sepol_handle_t *handle,
786cd6a6acSopenharmony_ci					     char **subnet_prefix)
796cd6a6acSopenharmony_ci{
806cd6a6acSopenharmony_ci	char *tmp_subnet_prefix = NULL;
816cd6a6acSopenharmony_ci
826cd6a6acSopenharmony_ci	tmp_subnet_prefix = malloc(INET6_ADDRSTRLEN);
836cd6a6acSopenharmony_ci
846cd6a6acSopenharmony_ci	if (!tmp_subnet_prefix)
856cd6a6acSopenharmony_ci		goto omem;
866cd6a6acSopenharmony_ci
876cd6a6acSopenharmony_ci	*subnet_prefix = tmp_subnet_prefix;
886cd6a6acSopenharmony_ci	return STATUS_SUCCESS;
896cd6a6acSopenharmony_ci
906cd6a6acSopenharmony_ciomem:
916cd6a6acSopenharmony_ci	ERR(handle, "out of memory");
926cd6a6acSopenharmony_ci
936cd6a6acSopenharmony_ci	ERR(handle, "could not allocate string buffer for subnet_prefix");
946cd6a6acSopenharmony_ci	return STATUS_ERR;
956cd6a6acSopenharmony_ci}
966cd6a6acSopenharmony_ci
976cd6a6acSopenharmony_ci/* Key */
986cd6a6acSopenharmony_ciint sepol_ibpkey_key_create(sepol_handle_t *handle,
996cd6a6acSopenharmony_ci			    const char *subnet_prefix,
1006cd6a6acSopenharmony_ci			    int low, int high,
1016cd6a6acSopenharmony_ci			    sepol_ibpkey_key_t **key_ptr)
1026cd6a6acSopenharmony_ci{
1036cd6a6acSopenharmony_ci	sepol_ibpkey_key_t *tmp_key =
1046cd6a6acSopenharmony_ci	    (sepol_ibpkey_key_t *)malloc(sizeof(sepol_ibpkey_key_t));
1056cd6a6acSopenharmony_ci
1066cd6a6acSopenharmony_ci	if (!tmp_key) {
1076cd6a6acSopenharmony_ci		ERR(handle, "out of memory, could not create ibpkey key");
1086cd6a6acSopenharmony_ci		goto omem;
1096cd6a6acSopenharmony_ci	}
1106cd6a6acSopenharmony_ci
1116cd6a6acSopenharmony_ci	if (ibpkey_parse_subnet_prefix(handle, subnet_prefix, &tmp_key->subnet_prefix) < 0)
1126cd6a6acSopenharmony_ci		goto err;
1136cd6a6acSopenharmony_ci
1146cd6a6acSopenharmony_ci	tmp_key->low = low;
1156cd6a6acSopenharmony_ci	tmp_key->high = high;
1166cd6a6acSopenharmony_ci
1176cd6a6acSopenharmony_ci	*key_ptr = tmp_key;
1186cd6a6acSopenharmony_ci	return STATUS_SUCCESS;
1196cd6a6acSopenharmony_ci
1206cd6a6acSopenharmony_ciomem:
1216cd6a6acSopenharmony_ci	ERR(handle, "out of memory");
1226cd6a6acSopenharmony_ci
1236cd6a6acSopenharmony_cierr:
1246cd6a6acSopenharmony_ci	sepol_ibpkey_key_free(tmp_key);
1256cd6a6acSopenharmony_ci	ERR(handle, "could not create ibpkey key for subnet prefix%s, range %u, %u",
1266cd6a6acSopenharmony_ci	    subnet_prefix, low, high);
1276cd6a6acSopenharmony_ci	return STATUS_ERR;
1286cd6a6acSopenharmony_ci}
1296cd6a6acSopenharmony_ci
1306cd6a6acSopenharmony_ci
1316cd6a6acSopenharmony_civoid sepol_ibpkey_key_unpack(const sepol_ibpkey_key_t *key,
1326cd6a6acSopenharmony_ci			     uint64_t *subnet_prefix, int *low, int *high)
1336cd6a6acSopenharmony_ci{
1346cd6a6acSopenharmony_ci	*subnet_prefix = key->subnet_prefix;
1356cd6a6acSopenharmony_ci	*low = key->low;
1366cd6a6acSopenharmony_ci	*high = key->high;
1376cd6a6acSopenharmony_ci}
1386cd6a6acSopenharmony_ci
1396cd6a6acSopenharmony_ci
1406cd6a6acSopenharmony_ciint sepol_ibpkey_key_extract(sepol_handle_t *handle,
1416cd6a6acSopenharmony_ci			     const sepol_ibpkey_t *ibpkey,
1426cd6a6acSopenharmony_ci			     sepol_ibpkey_key_t **key_ptr)
1436cd6a6acSopenharmony_ci{
1446cd6a6acSopenharmony_ci	char subnet_prefix_str[INET6_ADDRSTRLEN];
1456cd6a6acSopenharmony_ci
1466cd6a6acSopenharmony_ci	ibpkey_expand_subnet_prefix(handle, ibpkey->subnet_prefix, subnet_prefix_str);
1476cd6a6acSopenharmony_ci
1486cd6a6acSopenharmony_ci	if (sepol_ibpkey_key_create
1496cd6a6acSopenharmony_ci	    (handle, subnet_prefix_str, ibpkey->low, ibpkey->high, key_ptr) < 0) {
1506cd6a6acSopenharmony_ci		ERR(handle, "could not extract key from ibpkey %s %d:%d",
1516cd6a6acSopenharmony_ci		    subnet_prefix_str,
1526cd6a6acSopenharmony_ci		    ibpkey->low, ibpkey->high);
1536cd6a6acSopenharmony_ci
1546cd6a6acSopenharmony_ci		return STATUS_ERR;
1556cd6a6acSopenharmony_ci	}
1566cd6a6acSopenharmony_ci
1576cd6a6acSopenharmony_ci	return STATUS_SUCCESS;
1586cd6a6acSopenharmony_ci}
1596cd6a6acSopenharmony_ci
1606cd6a6acSopenharmony_civoid sepol_ibpkey_key_free(sepol_ibpkey_key_t *key)
1616cd6a6acSopenharmony_ci{
1626cd6a6acSopenharmony_ci	if (!key)
1636cd6a6acSopenharmony_ci		return;
1646cd6a6acSopenharmony_ci	free(key);
1656cd6a6acSopenharmony_ci}
1666cd6a6acSopenharmony_ci
1676cd6a6acSopenharmony_ciint sepol_ibpkey_compare(const sepol_ibpkey_t *ibpkey, const sepol_ibpkey_key_t *key)
1686cd6a6acSopenharmony_ci{
1696cd6a6acSopenharmony_ci	if (ibpkey->subnet_prefix < key->subnet_prefix)
1706cd6a6acSopenharmony_ci		return -1;
1716cd6a6acSopenharmony_ci	if (key->subnet_prefix < ibpkey->subnet_prefix)
1726cd6a6acSopenharmony_ci		return 1;
1736cd6a6acSopenharmony_ci
1746cd6a6acSopenharmony_ci	if (ibpkey->low < key->low)
1756cd6a6acSopenharmony_ci		return -1;
1766cd6a6acSopenharmony_ci	if (key->low < ibpkey->low)
1776cd6a6acSopenharmony_ci		return 1;
1786cd6a6acSopenharmony_ci
1796cd6a6acSopenharmony_ci	if (ibpkey->high < key->high)
1806cd6a6acSopenharmony_ci		return -1;
1816cd6a6acSopenharmony_ci	if (key->high < ibpkey->high)
1826cd6a6acSopenharmony_ci		return 1;
1836cd6a6acSopenharmony_ci
1846cd6a6acSopenharmony_ci	return 0;
1856cd6a6acSopenharmony_ci}
1866cd6a6acSopenharmony_ci
1876cd6a6acSopenharmony_ciint sepol_ibpkey_compare2(const sepol_ibpkey_t *ibpkey, const sepol_ibpkey_t *ibpkey2)
1886cd6a6acSopenharmony_ci{
1896cd6a6acSopenharmony_ci	if (ibpkey->subnet_prefix < ibpkey2->subnet_prefix)
1906cd6a6acSopenharmony_ci		return -1;
1916cd6a6acSopenharmony_ci	if (ibpkey2->subnet_prefix < ibpkey->subnet_prefix)
1926cd6a6acSopenharmony_ci		return 1;
1936cd6a6acSopenharmony_ci
1946cd6a6acSopenharmony_ci	if (ibpkey->low < ibpkey2->low)
1956cd6a6acSopenharmony_ci		return -1;
1966cd6a6acSopenharmony_ci	if (ibpkey2->low < ibpkey->low)
1976cd6a6acSopenharmony_ci		return 1;
1986cd6a6acSopenharmony_ci
1996cd6a6acSopenharmony_ci	if (ibpkey->high < ibpkey2->high)
2006cd6a6acSopenharmony_ci		return -1;
2016cd6a6acSopenharmony_ci	if (ibpkey2->high < ibpkey->high)
2026cd6a6acSopenharmony_ci		return 1;
2036cd6a6acSopenharmony_ci
2046cd6a6acSopenharmony_ci	return 0;
2056cd6a6acSopenharmony_ci}
2066cd6a6acSopenharmony_ci
2076cd6a6acSopenharmony_ci/* Pkey */
2086cd6a6acSopenharmony_ciint sepol_ibpkey_get_low(const sepol_ibpkey_t *ibpkey)
2096cd6a6acSopenharmony_ci{
2106cd6a6acSopenharmony_ci	return ibpkey->low;
2116cd6a6acSopenharmony_ci}
2126cd6a6acSopenharmony_ci
2136cd6a6acSopenharmony_ci
2146cd6a6acSopenharmony_ciint sepol_ibpkey_get_high(const sepol_ibpkey_t *ibpkey)
2156cd6a6acSopenharmony_ci{
2166cd6a6acSopenharmony_ci	return ibpkey->high;
2176cd6a6acSopenharmony_ci}
2186cd6a6acSopenharmony_ci
2196cd6a6acSopenharmony_ci
2206cd6a6acSopenharmony_civoid sepol_ibpkey_set_pkey(sepol_ibpkey_t *ibpkey, int pkey_num)
2216cd6a6acSopenharmony_ci{
2226cd6a6acSopenharmony_ci	ibpkey->low = pkey_num;
2236cd6a6acSopenharmony_ci	ibpkey->high = pkey_num;
2246cd6a6acSopenharmony_ci}
2256cd6a6acSopenharmony_ci
2266cd6a6acSopenharmony_civoid sepol_ibpkey_set_range(sepol_ibpkey_t *ibpkey, int low, int high)
2276cd6a6acSopenharmony_ci{
2286cd6a6acSopenharmony_ci	ibpkey->low = low;
2296cd6a6acSopenharmony_ci	ibpkey->high = high;
2306cd6a6acSopenharmony_ci}
2316cd6a6acSopenharmony_ci
2326cd6a6acSopenharmony_ci
2336cd6a6acSopenharmony_ciint sepol_ibpkey_get_subnet_prefix(sepol_handle_t *handle,
2346cd6a6acSopenharmony_ci				   const sepol_ibpkey_t *ibpkey,
2356cd6a6acSopenharmony_ci				   char **subnet_prefix)
2366cd6a6acSopenharmony_ci{
2376cd6a6acSopenharmony_ci	char *tmp_subnet_prefix = NULL;
2386cd6a6acSopenharmony_ci
2396cd6a6acSopenharmony_ci	if (ibpkey_alloc_subnet_prefix_string(handle, &tmp_subnet_prefix) < 0)
2406cd6a6acSopenharmony_ci		goto err;
2416cd6a6acSopenharmony_ci
2426cd6a6acSopenharmony_ci	if (ibpkey_expand_subnet_prefix(handle, ibpkey->subnet_prefix, tmp_subnet_prefix) < 0)
2436cd6a6acSopenharmony_ci		goto err;
2446cd6a6acSopenharmony_ci
2456cd6a6acSopenharmony_ci	*subnet_prefix = tmp_subnet_prefix;
2466cd6a6acSopenharmony_ci	return STATUS_SUCCESS;
2476cd6a6acSopenharmony_ci
2486cd6a6acSopenharmony_cierr:
2496cd6a6acSopenharmony_ci	free(tmp_subnet_prefix);
2506cd6a6acSopenharmony_ci	ERR(handle, "could not get ibpkey subnet_prefix");
2516cd6a6acSopenharmony_ci	return STATUS_ERR;
2526cd6a6acSopenharmony_ci}
2536cd6a6acSopenharmony_ci
2546cd6a6acSopenharmony_ci
2556cd6a6acSopenharmony_ci/* Subnet prefix */
2566cd6a6acSopenharmony_ciuint64_t sepol_ibpkey_get_subnet_prefix_bytes(const sepol_ibpkey_t *ibpkey)
2576cd6a6acSopenharmony_ci{
2586cd6a6acSopenharmony_ci	return ibpkey->subnet_prefix;
2596cd6a6acSopenharmony_ci}
2606cd6a6acSopenharmony_ci
2616cd6a6acSopenharmony_ci
2626cd6a6acSopenharmony_ciint sepol_ibpkey_set_subnet_prefix(sepol_handle_t *handle,
2636cd6a6acSopenharmony_ci				   sepol_ibpkey_t *ibpkey,
2646cd6a6acSopenharmony_ci				   const char *subnet_prefix_str)
2656cd6a6acSopenharmony_ci{
2666cd6a6acSopenharmony_ci	uint64_t tmp = 0;
2676cd6a6acSopenharmony_ci
2686cd6a6acSopenharmony_ci	if (ibpkey_parse_subnet_prefix(handle, subnet_prefix_str, &tmp) < 0)
2696cd6a6acSopenharmony_ci		goto err;
2706cd6a6acSopenharmony_ci
2716cd6a6acSopenharmony_ci	ibpkey->subnet_prefix = tmp;
2726cd6a6acSopenharmony_ci	return STATUS_SUCCESS;
2736cd6a6acSopenharmony_ci
2746cd6a6acSopenharmony_cierr:
2756cd6a6acSopenharmony_ci	ERR(handle, "could not set ibpkey subnet prefix to %s", subnet_prefix_str);
2766cd6a6acSopenharmony_ci	return STATUS_ERR;
2776cd6a6acSopenharmony_ci}
2786cd6a6acSopenharmony_ci
2796cd6a6acSopenharmony_ci
2806cd6a6acSopenharmony_civoid sepol_ibpkey_set_subnet_prefix_bytes(sepol_ibpkey_t *ibpkey,
2816cd6a6acSopenharmony_ci					  uint64_t subnet_prefix)
2826cd6a6acSopenharmony_ci{
2836cd6a6acSopenharmony_ci	ibpkey->subnet_prefix = subnet_prefix;
2846cd6a6acSopenharmony_ci}
2856cd6a6acSopenharmony_ci
2866cd6a6acSopenharmony_ci
2876cd6a6acSopenharmony_ci/* Create */
2886cd6a6acSopenharmony_ciint sepol_ibpkey_create(sepol_handle_t *handle, sepol_ibpkey_t **ibpkey)
2896cd6a6acSopenharmony_ci{
2906cd6a6acSopenharmony_ci	sepol_ibpkey_t *tmp_ibpkey = (sepol_ibpkey_t *)malloc(sizeof(sepol_ibpkey_t));
2916cd6a6acSopenharmony_ci
2926cd6a6acSopenharmony_ci	if (!tmp_ibpkey) {
2936cd6a6acSopenharmony_ci		ERR(handle, "out of memory, could not create ibpkey record");
2946cd6a6acSopenharmony_ci		return STATUS_ERR;
2956cd6a6acSopenharmony_ci	}
2966cd6a6acSopenharmony_ci
2976cd6a6acSopenharmony_ci	tmp_ibpkey->subnet_prefix = 0;
2986cd6a6acSopenharmony_ci	tmp_ibpkey->low = 0;
2996cd6a6acSopenharmony_ci	tmp_ibpkey->high = 0;
3006cd6a6acSopenharmony_ci	tmp_ibpkey->con = NULL;
3016cd6a6acSopenharmony_ci	*ibpkey = tmp_ibpkey;
3026cd6a6acSopenharmony_ci
3036cd6a6acSopenharmony_ci	return STATUS_SUCCESS;
3046cd6a6acSopenharmony_ci}
3056cd6a6acSopenharmony_ci
3066cd6a6acSopenharmony_ci
3076cd6a6acSopenharmony_ci/* Deep copy clone */
3086cd6a6acSopenharmony_ciint sepol_ibpkey_clone(sepol_handle_t *handle,
3096cd6a6acSopenharmony_ci		       const sepol_ibpkey_t *ibpkey, sepol_ibpkey_t **ibpkey_ptr)
3106cd6a6acSopenharmony_ci{
3116cd6a6acSopenharmony_ci	sepol_ibpkey_t *new_ibpkey = NULL;
3126cd6a6acSopenharmony_ci
3136cd6a6acSopenharmony_ci	if (sepol_ibpkey_create(handle, &new_ibpkey) < 0)
3146cd6a6acSopenharmony_ci		goto err;
3156cd6a6acSopenharmony_ci
3166cd6a6acSopenharmony_ci	new_ibpkey->subnet_prefix = ibpkey->subnet_prefix;
3176cd6a6acSopenharmony_ci	new_ibpkey->low = ibpkey->low;
3186cd6a6acSopenharmony_ci	new_ibpkey->high = ibpkey->high;
3196cd6a6acSopenharmony_ci
3206cd6a6acSopenharmony_ci	if (ibpkey->con &&
3216cd6a6acSopenharmony_ci	    (sepol_context_clone(handle, ibpkey->con, &new_ibpkey->con) < 0))
3226cd6a6acSopenharmony_ci		goto err;
3236cd6a6acSopenharmony_ci
3246cd6a6acSopenharmony_ci	*ibpkey_ptr = new_ibpkey;
3256cd6a6acSopenharmony_ci	return STATUS_SUCCESS;
3266cd6a6acSopenharmony_ci
3276cd6a6acSopenharmony_cierr:
3286cd6a6acSopenharmony_ci	ERR(handle, "could not clone ibpkey record");
3296cd6a6acSopenharmony_ci	sepol_ibpkey_free(new_ibpkey);
3306cd6a6acSopenharmony_ci	return STATUS_ERR;
3316cd6a6acSopenharmony_ci}
3326cd6a6acSopenharmony_ci
3336cd6a6acSopenharmony_ci/* Destroy */
3346cd6a6acSopenharmony_civoid sepol_ibpkey_free(sepol_ibpkey_t *ibpkey)
3356cd6a6acSopenharmony_ci{
3366cd6a6acSopenharmony_ci	if (!ibpkey)
3376cd6a6acSopenharmony_ci		return;
3386cd6a6acSopenharmony_ci
3396cd6a6acSopenharmony_ci	sepol_context_free(ibpkey->con);
3406cd6a6acSopenharmony_ci	free(ibpkey);
3416cd6a6acSopenharmony_ci}
3426cd6a6acSopenharmony_ci
3436cd6a6acSopenharmony_ci
3446cd6a6acSopenharmony_ci/* Context */
3456cd6a6acSopenharmony_cisepol_context_t *sepol_ibpkey_get_con(const sepol_ibpkey_t *ibpkey)
3466cd6a6acSopenharmony_ci{
3476cd6a6acSopenharmony_ci	return ibpkey->con;
3486cd6a6acSopenharmony_ci}
3496cd6a6acSopenharmony_ci
3506cd6a6acSopenharmony_ci
3516cd6a6acSopenharmony_ciint sepol_ibpkey_set_con(sepol_handle_t *handle,
3526cd6a6acSopenharmony_ci			 sepol_ibpkey_t *ibpkey, sepol_context_t *con)
3536cd6a6acSopenharmony_ci{
3546cd6a6acSopenharmony_ci	sepol_context_t *newcon;
3556cd6a6acSopenharmony_ci
3566cd6a6acSopenharmony_ci	if (sepol_context_clone(handle, con, &newcon) < 0) {
3576cd6a6acSopenharmony_ci		ERR(handle, "out of memory, could not set ibpkey context");
3586cd6a6acSopenharmony_ci		return STATUS_ERR;
3596cd6a6acSopenharmony_ci	}
3606cd6a6acSopenharmony_ci
3616cd6a6acSopenharmony_ci	sepol_context_free(ibpkey->con);
3626cd6a6acSopenharmony_ci	ibpkey->con = newcon;
3636cd6a6acSopenharmony_ci	return STATUS_SUCCESS;
3646cd6a6acSopenharmony_ci}
3656cd6a6acSopenharmony_ci
366