int
usmDHSetKey(struct usmUser *user, int for_auth_key,
            u_char *val, size_t val_len)
{
    DH             *dh;
    BIGNUM         *other_pub;
    u_char         *key;
    size_t          key_len;

    DEBUGMSGTL(("verbose:usmDHUserKeyTable:usmDHSetKey", "called\n"));
    /*
     * XXX: mem leaks on errors abound 
     */

    dh = usmDHGetUserDHptr(user, for_auth_key);
    if (!dh)
        return MFD_ERROR;

    other_pub = BN_bin2bn(val + val_len / 2, val_len / 2, NULL);
    if (!other_pub)
        return MFD_ERROR;

    /*
     * Set the new key for a user 
     */
    key_len = DH_size(dh);
    key = malloc(DH_size(dh));
    if (!key)
        return MFD_ERROR;

    if (DH_compute_key(key, other_pub, dh)) {
        u_char        **replkey;
        size_t          replkey_size;

        if (for_auth_key) {
            replkey_size = user->authKeyLen;
            replkey = &user->authKey;
        } else {
            replkey_size = user->privKeyLen;
            replkey = &user->privKey;
        }

        /*
         * is it large enough? 
         */
        if (key_len < replkey_size)
            return MFD_ERROR;

        /*
         * copy right most bits, per the object requirements 
         */
        SNMP_FREE(*replkey);
        memdup(replkey, key + key_len - replkey_size, replkey_size);

        return MFD_SUCCESS;
    }

    return MFD_ERROR;
}
int
usmDHGetUserKeyChange(struct usmUser *user, int for_auth_key,
                      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: %x %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;
}