/*
 * Note: this file originally auto-generated by mib2c using
 *       version : 1.20 $ of : mfd-data-get.m2c,v $ 
 *
 * $Id$
 */
/*
 * standard Net-SNMP includes 
 */
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>

#include <openssl/dh.h>

/*
 * include our parent header 
 */
#define NEED_USMDH_FUNCTIONS
#include "usmDHUserKeyTable.h"
#include "snmp-usm-dh-objects-mib/usmDHParameters/usmDHParameters.h"

DH             *
usmDHGetUserDHptr(struct usmUser *user, int for_auth_key)
{
    DH             *dh, *dh_params;
    void          **theptr;

    if (user == NULL)
        return NULL;

    if (for_auth_key == 1)
        theptr = &user->usmDHUserAuthKeyChange;
    else
        theptr = &user->usmDHUserPrivKeyChange;

    if (!*theptr) {
        /*
         * copy the system parameters to the local ones 
         */
        dh = DH_new();
        if (!dh)
            return NULL;
        dh_params = get_dh_params();
        if (!dh_params)
            return NULL;
        dh->g = BN_dup(dh_params->g);
        dh->p = BN_dup(dh_params->p);
        if (!dh->g || !dh->p)
            return NULL;
        DH_generate_key(dh);
        *theptr = dh;
    } else {
        dh = (DH *) * theptr;
    }
    return dh;
}

int
usmDHGetUserKeyChange(struct usmUser *user, int for_auth_key,
                      u_char **keyobj, size_t *keyobj_len)
{
    DH             *dh;

    dh = usmDHGetUserDHptr(user, for_auth_key);

    if (!dh) {
        snmp_log(LOG_ERR, "ack...  shouldn't get here: %p %d\n",
                 user, for_auth_key);
        return MFD_ERROR;
    }

    *keyobj_len = BN_num_bytes(dh->pub_key);
    *keyobj = malloc(*keyobj_len);
    BN_bn2bin(dh->pub_key, *keyobj);

    return MFD_SUCCESS;
}

/** @ingroup data_access 
 * @defgroup data_get data_get: Routines to get data
 *
 * TODO:230:M: Implement usmDHUserKeyTable get routines.
 * TODO:240:M: Implement usmDHUserKeyTable mapping routines (if any).
 *
 * These routine are used to get the value for individual objects. The
 * row context is passed, along with a pointer to the memory where the
 * value should be copied.
 *
 * @{
 */
/**********************************************************************
 **********************************************************************
 ***
 *** Table usmDHUserKeyTable
 ***
 **********************************************************************
 **********************************************************************/
/*
 * SNMP-USM-DH-OBJECTS-MIB::usmDHUserKeyTable is subid 2 of usmDHPublicObjects.
 * Its status is Current.
 * OID: .1.3.6.1.3.101.1.1.2, length: 9
 */

/*
 * ---------------------------------------------------------------------
 * * TODO:200:r: Implement usmDHUserKeyTable data context functions.
 */
/*
 * usmDHUserKeyTable_allocate_data
 *
 * Purpose: create new usmDHUserKeyTable_data.
 */
usmDHUserKeyTable_data *
usmDHUserKeyTable_allocate_data(void)
{
    /*
     * TODO:201:r: |-> allocate memory for the usmDHUserKeyTable data context.
     */
    usmDHUserKeyTable_data *rtn =
        SNMP_MALLOC_TYPEDEF(usmDHUserKeyTable_data);

    DEBUGMSGTL(("verbose:usmDHUserKeyTable:usmDHUserKeyTable_allocate_data", "called\n"));

    if (NULL == rtn) {
        snmp_log(LOG_ERR, "unable to malloc memory for new "
                 "usmDHUserKeyTable_data.\n");
    }
    /*
     * not real user, not in a list. mark for testing
     */
    rtn->next = (struct usmUser *) -1;
    rtn->prev = (struct usmUser *) -1;

    return rtn;
}                               /* usmDHUserKeyTable_allocate_data */

/*
 * usmDHUserKeyTable_release_data
 *
 * Purpose: release usmDHUserKeyTable data.
 */
void
usmDHUserKeyTable_release_data(usmDHUserKeyTable_data * data)
{
    struct usmUser *user = data;

    DEBUGMSGTL(("verbose:usmDHUserKeyTable:usmDHUserKeyTable_release_data",
                "called\n"));

    netsnmp_assert(user->next == (struct usmUser *) -1);
    netsnmp_assert(user->prev == (struct usmUser *) -1);

    /*
     * TODO:202:r: |-> release memory for the usmDHUserKeyTable data context.
     */
    if (user) {
        SNMP_FREE(user->authKey);
        SNMP_FREE(user->privKey);
    }

    free(data);
}                               /* usmDHUserKeyTable_release_data */



/**
 * set mib index(es)
 *
 * @param tbl_idx mib index structure
 * @param usmUserEngineID_val_ptr
 * @param usmUserEngineID_val_ptr_len
 * @param usmUserName_val_ptr
 * @param usmUserName_val_ptr_len
 *
 * @retval MFD_SUCCESS     : success.
 * @retval MFD_ERROR       : other error.
 *
 * @remark
 *  This convenience function is useful for setting all the MIB index
 *  components with a single function call. It is assume that the C values
 *  have already been mapped from their native/rawformat to the MIB format.
 */
int
usmDHUserKeyTable_indexes_set_tbl_idx(usmDHUserKeyTable_mib_index *
                                      tbl_idx,
                                      u_char *usmUserEngineID_val_ptr,
                                      size_t usmUserEngineID_val_ptr_len,
                                      char *usmUserName_val_ptr,
                                      size_t usmUserName_val_ptr_len)
{
    DEBUGMSGTL(("verbose:usmDHUserKeyTable:usmDHUserKeyTable_indexes_set_tbl_idx", "called\n"));

    /*
     * usmUserEngineID(1)/SnmpEngineID/ASN_OCTET_STR/char(char)//L/a/w/e/R/d/h 
     */
    tbl_idx->usmUserEngineID_len = sizeof(tbl_idx->usmUserEngineID) / sizeof(tbl_idx->usmUserEngineID[0]);      /* max length */
    /** WARNING: this code might not work for struct usmUser */
    /*
     * make sure there is enough space for usmUserEngineID data
     */
    if ((NULL == tbl_idx->usmUserEngineID) ||
        (tbl_idx->usmUserEngineID_len < (usmUserEngineID_val_ptr_len))) {
        snmp_log(LOG_ERR, "not enough space for value\n");
        return MFD_ERROR;
    }
    tbl_idx->usmUserEngineID_len = usmUserEngineID_val_ptr_len;
    memcpy(tbl_idx->usmUserEngineID, usmUserEngineID_val_ptr,
           usmUserEngineID_val_ptr_len *
           sizeof(usmUserEngineID_val_ptr[0]));

    /*
     * usmUserName(2)/SnmpAdminString/ASN_OCTET_STR/char(char)//L/a/w/e/R/d/H 
     */
    tbl_idx->usmUserName_len = sizeof(tbl_idx->usmUserName) / sizeof(tbl_idx->usmUserName[0]);  /* max length */

    /** WARNING: this code might not work for struct usmUser */
    /*
     * make sure there is enough space for usmUserName data
     */
    if ((NULL == tbl_idx->usmUserName) ||
        (tbl_idx->usmUserName_len < (usmUserName_val_ptr_len))) {
        snmp_log(LOG_ERR, "not enough space for value\n");
        return MFD_ERROR;
    }
    tbl_idx->usmUserName_len = usmUserName_val_ptr_len;
    memcpy(tbl_idx->usmUserName, usmUserName_val_ptr,
           usmUserName_val_ptr_len * sizeof(usmUserName_val_ptr[0]));


    return MFD_SUCCESS;
}                               /* usmDHUserKeyTable_indexes_set_tbl_idx */

/**
 * @internal
 * set row context indexes
 *
 * @param reqreq_ctx the row context that needs updated indexes
 *
 * @retval MFD_SUCCESS     : success.
 * @retval MFD_ERROR       : other error.
 *
 * @remark
 *  This function sets the mib indexs, then updates the oid indexs
 *  from the mib index.
 */
int
usmDHUserKeyTable_indexes_set(usmDHUserKeyTable_rowreq_ctx * rowreq_ctx,
                              u_char *usmUserEngineID_val_ptr,
                              size_t usmUserEngineID_val_ptr_len,
                              char *usmUserName_val_ptr,
                              size_t usmUserName_val_ptr_len)
{
    DEBUGMSGTL(("verbose:usmDHUserKeyTable:usmDHUserKeyTable_indexes_set",
                "called\n"));

    if (MFD_SUCCESS !=
        usmDHUserKeyTable_indexes_set_tbl_idx(&rowreq_ctx->tbl_idx,
                                              usmUserEngineID_val_ptr,
                                              usmUserEngineID_val_ptr_len,
                                              usmUserName_val_ptr,
                                              usmUserName_val_ptr_len))
        return MFD_ERROR;

    /*
     * convert mib index to oid index
     */
    rowreq_ctx->oid_idx.len = sizeof(rowreq_ctx->oid_tmp) / sizeof(oid);
    if (0 != usmDHUserKeyTable_index_to_oid(&rowreq_ctx->oid_idx,
                                            &rowreq_ctx->tbl_idx)) {
        return MFD_ERROR;
    }

    return MFD_SUCCESS;
}                               /* usmDHUserKeyTable_indexes_set */


/*---------------------------------------------------------------------
 * SNMP-USM-DH-OBJECTS-MIB::usmDHUserKeyEntry.usmDHUserAuthKeyChange
 * usmDHUserAuthKeyChange is subid 1 of usmDHUserKeyEntry.
 * Its status is Current, and its access level is Create.
 * OID: .1.3.6.1.3.101.1.1.2.1.1
 * Description:
The object used to change any given user's Authentication Key
    using a Diffie-Hellman key exchange.

    The right-most n bits of the shared secret 'sk', where 'n' is the
    number of bits required for the protocol defined by
    usmUserAuthProtocol, are installed as the operational
    authentication key for this row after a successful SET.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   1
 *
 *
 * Its syntax is DHKeyChange (based on perltype OCTETSTR)
 * The net-snmp type is ASN_OCTET_STR. The C type decl is char (char)
 * This data type requires a length.
 */
/**
 * Extract the current value of the usmDHUserAuthKeyChange data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param usmDHUserAuthKeyChange_val_ptr_ptr
 *        Pointer to storage for a char variable
 * @param usmDHUserAuthKeyChange_val_ptr_len_ptr
 *        Pointer to a size_t. On entry, it will contain the size (in bytes)
 *        pointed to by usmDHUserAuthKeyChange.
 *        On exit, this value should contain the data size (in bytes).
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
*
 * @note If you need more than (*usmDHUserAuthKeyChange_val_ptr_len_ptr) bytes of memory,
 *       allocate it using malloc() and update usmDHUserAuthKeyChange_val_ptr_ptr.
 *       <b>DO NOT</b> free the previous pointer.
 *       The MFD helper will release the memory you allocate.
 *
 * @remark If you call this function yourself, you are responsible
 *         for checking if the pointer changed, and freeing any
 *         previously allocated memory. (Not necessary if you pass
 *         in a pointer to static memory, obviously.)
 */
int
usmDHUserAuthKeyChange_get(usmDHUserKeyTable_rowreq_ctx * rowreq_ctx,
                           u_char **usmDHUserAuthKeyChange_val_ptr_ptr,
                           size_t *usmDHUserAuthKeyChange_val_ptr_len_ptr)
{
   /** we should have a non-NULL pointer and enough storage */
    netsnmp_assert((NULL != usmDHUserAuthKeyChange_val_ptr_ptr)
                   && (NULL != *usmDHUserAuthKeyChange_val_ptr_ptr));
    netsnmp_assert(NULL != usmDHUserAuthKeyChange_val_ptr_len_ptr);


    DEBUGMSGTL(("verbose:usmDHUserKeyTable:usmDHUserAuthKeyChange_get",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the usmDHUserAuthKeyChange data.
     * copy (* usmDHUserAuthKeyChange_val_ptr_ptr ) data and (* usmDHUserAuthKeyChange_val_ptr_len_ptr ) from rowreq_ctx->data
     */
    if (!rowreq_ctx || !usmDHUserAuthKeyChange_val_ptr_len_ptr ||
        !usmDHUserAuthKeyChange_val_ptr_ptr ||
        !*usmDHUserAuthKeyChange_val_ptr_ptr) {
        return MFD_ERROR;
    }

    return usmDHGetUserKeyChange(rowreq_ctx->data, 1,
                                 usmDHUserAuthKeyChange_val_ptr_ptr,
                                 usmDHUserAuthKeyChange_val_ptr_len_ptr);
}                               /* usmDHUserAuthKeyChange_get */

/*---------------------------------------------------------------------
 * SNMP-USM-DH-OBJECTS-MIB::usmDHUserKeyEntry.usmDHUserOwnAuthKeyChange
 * usmDHUserOwnAuthKeyChange is subid 2 of usmDHUserKeyEntry.
 * Its status is Current, and its access level is Create.
 * OID: .1.3.6.1.3.101.1.1.2.1.2
 * Description:
The object used to change the agents own Authentication Key
    using a Diffie-Hellman key exchange.

    The right-most n bits of the shared secret 'sk', where 'n' is the
    number of bits required for the protocol defined by
    usmUserAuthProtocol, are installed as the operational
    authentication key for this row after a successful SET.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   1
 *
 *
 * Its syntax is DHKeyChange (based on perltype OCTETSTR)
 * The net-snmp type is ASN_OCTET_STR. The C type decl is char (char)
 * This data type requires a length.
 */
/**
 * Extract the current value of the usmDHUserOwnAuthKeyChange data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param usmDHUserOwnAuthKeyChange_val_ptr_ptr
 *        Pointer to storage for a char variable
 * @param usmDHUserOwnAuthKeyChange_val_ptr_len_ptr
 *        Pointer to a size_t. On entry, it will contain the size (in bytes)
 *        pointed to by usmDHUserOwnAuthKeyChange.
 *        On exit, this value should contain the data size (in bytes).
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
*
 * @note If you need more than (*usmDHUserOwnAuthKeyChange_val_ptr_len_ptr) bytes of memory,
 *       allocate it using malloc() and update usmDHUserOwnAuthKeyChange_val_ptr_ptr.
 *       <b>DO NOT</b> free the previous pointer.
 *       The MFD helper will release the memory you allocate.
 *
 * @remark If you call this function yourself, you are responsible
 *         for checking if the pointer changed, and freeing any
 *         previously allocated memory. (Not necessary if you pass
 *         in a pointer to static memory, obviously.)
 */
int
usmDHUserOwnAuthKeyChange_get(usmDHUserKeyTable_rowreq_ctx * rowreq_ctx,
                              u_char **usmDHUserOwnAuthKeyChange_val_ptr_ptr,
                              size_t
                              *usmDHUserOwnAuthKeyChange_val_ptr_len_ptr)
{
   /** we should have a non-NULL pointer and enough storage */
    netsnmp_assert((NULL != usmDHUserOwnAuthKeyChange_val_ptr_ptr)
                   && (NULL != *usmDHUserOwnAuthKeyChange_val_ptr_ptr));
    netsnmp_assert(NULL != usmDHUserOwnAuthKeyChange_val_ptr_len_ptr);


    DEBUGMSGTL(("verbose:usmDHUserKeyTable:usmDHUserOwnAuthKeyChange_get",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the usmDHUserOwnAuthKeyChange data.
     * copy (* usmDHUserOwnAuthKeyChange_val_ptr_ptr ) data and (* usmDHUserOwnAuthKeyChange_val_ptr_len_ptr ) from rowreq_ctx->data
     */
    if (!rowreq_ctx || !usmDHUserOwnAuthKeyChange_val_ptr_len_ptr ||
        !usmDHUserOwnAuthKeyChange_val_ptr_ptr ||
        !*usmDHUserOwnAuthKeyChange_val_ptr_ptr) {
        return MFD_ERROR;
    }

    return usmDHGetUserKeyChange(rowreq_ctx->data, 1,
                                 usmDHUserOwnAuthKeyChange_val_ptr_ptr,
                                 usmDHUserOwnAuthKeyChange_val_ptr_len_ptr);
}                               /* usmDHUserOwnAuthKeyChange_get */

/*---------------------------------------------------------------------
 * SNMP-USM-DH-OBJECTS-MIB::usmDHUserKeyEntry.usmDHUserPrivKeyChange
 * usmDHUserPrivKeyChange is subid 3 of usmDHUserKeyEntry.
 * Its status is Current, and its access level is Create.
 * OID: .1.3.6.1.3.101.1.1.2.1.3
 * Description:
The object used to change any given user's Privacy Key using
    a Diffie-Hellman key exchange.

    The right-most n bits of the shared secret 'sk', where 'n' is the
    number of bits required for the protocol defined by
    usmUserPrivProtocol, are installed as the operational privacy key
    for this row after a successful SET.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   1
 *
 *
 * Its syntax is DHKeyChange (based on perltype OCTETSTR)
 * The net-snmp type is ASN_OCTET_STR. The C type decl is char (char)
 * This data type requires a length.
 */
/**
 * Extract the current value of the usmDHUserPrivKeyChange data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param usmDHUserPrivKeyChange_val_ptr_ptr
 *        Pointer to storage for a char variable
 * @param usmDHUserPrivKeyChange_val_ptr_len_ptr
 *        Pointer to a size_t. On entry, it will contain the size (in bytes)
 *        pointed to by usmDHUserPrivKeyChange.
 *        On exit, this value should contain the data size (in bytes).
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
*
 * @note If you need more than (*usmDHUserPrivKeyChange_val_ptr_len_ptr) bytes of memory,
 *       allocate it using malloc() and update usmDHUserPrivKeyChange_val_ptr_ptr.
 *       <b>DO NOT</b> free the previous pointer.
 *       The MFD helper will release the memory you allocate.
 *
 * @remark If you call this function yourself, you are responsible
 *         for checking if the pointer changed, and freeing any
 *         previously allocated memory. (Not necessary if you pass
 *         in a pointer to static memory, obviously.)
 */
int
usmDHUserPrivKeyChange_get(usmDHUserKeyTable_rowreq_ctx * rowreq_ctx,
                           u_char **usmDHUserPrivKeyChange_val_ptr_ptr,
                           size_t *usmDHUserPrivKeyChange_val_ptr_len_ptr)
{
   /** we should have a non-NULL pointer and enough storage */
    netsnmp_assert((NULL != usmDHUserPrivKeyChange_val_ptr_ptr)
                   && (NULL != *usmDHUserPrivKeyChange_val_ptr_ptr));
    netsnmp_assert(NULL != usmDHUserPrivKeyChange_val_ptr_len_ptr);


    DEBUGMSGTL(("verbose:usmDHUserKeyTable:usmDHUserPrivKeyChange_get",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the usmDHUserPrivKeyChange data.
     * copy (* usmDHUserPrivKeyChange_val_ptr_ptr ) data and (* usmDHUserPrivKeyChange_val_ptr_len_ptr ) from rowreq_ctx->data
     */
    if (!rowreq_ctx || !usmDHUserPrivKeyChange_val_ptr_len_ptr ||
        !usmDHUserPrivKeyChange_val_ptr_ptr ||
        !*usmDHUserPrivKeyChange_val_ptr_ptr) {
        return MFD_ERROR;
    }

    return usmDHGetUserKeyChange(rowreq_ctx->data, 0,
                                 usmDHUserPrivKeyChange_val_ptr_ptr,
                                 usmDHUserPrivKeyChange_val_ptr_len_ptr);
}                               /* usmDHUserPrivKeyChange_get */

/*---------------------------------------------------------------------
 * SNMP-USM-DH-OBJECTS-MIB::usmDHUserKeyEntry.usmDHUserOwnPrivKeyChange
 * usmDHUserOwnPrivKeyChange is subid 4 of usmDHUserKeyEntry.
 * Its status is Current, and its access level is Create.
 * OID: .1.3.6.1.3.101.1.1.2.1.4
 * Description:
The object used to change the agent's own Privacy Key using a
    Diffie-Hellman key exchange.

    The right-most n bits of the shared secret 'sk', where 'n' is the
    number of bits required for the protocol defined by
    usmUserPrivProtocol, are installed as the operational privacy key
    for this row after a successful SET.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   1
 *
 *
 * Its syntax is DHKeyChange (based on perltype OCTETSTR)
 * The net-snmp type is ASN_OCTET_STR. The C type decl is char (char)
 * This data type requires a length.
 */
/**
 * Extract the current value of the usmDHUserOwnPrivKeyChange data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param usmDHUserOwnPrivKeyChange_val_ptr_ptr
 *        Pointer to storage for a char variable
 * @param usmDHUserOwnPrivKeyChange_val_ptr_len_ptr
 *        Pointer to a size_t. On entry, it will contain the size (in bytes)
 *        pointed to by usmDHUserOwnPrivKeyChange.
 *        On exit, this value should contain the data size (in bytes).
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
*
 * @note If you need more than (*usmDHUserOwnPrivKeyChange_val_ptr_len_ptr) bytes of memory,
 *       allocate it using malloc() and update usmDHUserOwnPrivKeyChange_val_ptr_ptr.
 *       <b>DO NOT</b> free the previous pointer.
 *       The MFD helper will release the memory you allocate.
 *
 * @remark If you call this function yourself, you are responsible
 *         for checking if the pointer changed, and freeing any
 *         previously allocated memory. (Not necessary if you pass
 *         in a pointer to static memory, obviously.)
 */
int
usmDHUserOwnPrivKeyChange_get(usmDHUserKeyTable_rowreq_ctx * rowreq_ctx,
                              u_char **usmDHUserOwnPrivKeyChange_val_ptr_ptr,
                              size_t
                              *usmDHUserOwnPrivKeyChange_val_ptr_len_ptr)
{
   /** we should have a non-NULL pointer and enough storage */
    netsnmp_assert((NULL != usmDHUserOwnPrivKeyChange_val_ptr_ptr)
                   && (NULL != *usmDHUserOwnPrivKeyChange_val_ptr_ptr));
    netsnmp_assert(NULL != usmDHUserOwnPrivKeyChange_val_ptr_len_ptr);


    DEBUGMSGTL(("verbose:usmDHUserKeyTable:usmDHUserOwnPrivKeyChange_get",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the usmDHUserOwnPrivKeyChange data.
     * copy (* usmDHUserOwnPrivKeyChange_val_ptr_ptr ) data and (* usmDHUserOwnPrivKeyChange_val_ptr_len_ptr ) from rowreq_ctx->data
     */
    if (!rowreq_ctx || !usmDHUserOwnPrivKeyChange_val_ptr_len_ptr ||
        !usmDHUserOwnPrivKeyChange_val_ptr_ptr ||
        !*usmDHUserOwnPrivKeyChange_val_ptr_ptr) {
        return MFD_ERROR;
    }
  
    return usmDHGetUserKeyChange(rowreq_ctx->data, 0,
                                 usmDHUserOwnPrivKeyChange_val_ptr_ptr,
                                 usmDHUserOwnPrivKeyChange_val_ptr_len_ptr);
}                               /* usmDHUserOwnPrivKeyChange_get */



/** @} */
