/*
 *  Crypto plugin API.
 *
 *  This file initially created by Google, Inc.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2 as
 *  published by the Free Software Foundation.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */


#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <string.h>
#include <unistd.h>

#include <connman/assert.h>

#include "connman.h"

#define _DBG_CRYPTO(fmt, arg...)        DBG(DBG_CRYPTO, fmt, ## arg)

static GSList *crypto_list = NULL;

static gint compare_priority(gconstpointer a, gconstpointer b)
{
        const struct connman_crypto *crypto1 = a;
        const struct connman_crypto *crypto2 = b;

        return crypto2->priority - crypto1->priority;
}

/**
 * connman_crypto_register:
 * @crypto: crypto module
 *
 * Register a new crypto module
 *
 * Returns: %0 on success
 */
int connman_crypto_register(struct connman_crypto *crypto)
{
        _DBG_CRYPTO("crypto %p name %s", crypto, crypto->name);

        crypto->prefix = g_strdup_printf("%s:", crypto->name);
        crypto->prefix_size = strlen(crypto->prefix);

        crypto_list = g_slist_insert_sorted(crypto_list, crypto,
            compare_priority);

        return 0;
}

/**
 * connman_crypto_unregister:
 * @crypto: crypto module
 *
 * Remove a previously registered crypto module
 */
void connman_crypto_unregister(struct connman_crypto *crypto)
{
        _DBG_CRYPTO("crypto %p name %s", crypto, crypto->name);

        g_free(crypto->prefix);
        crypto_list = g_slist_remove(crypto_list, crypto);
}

char *__connman_crypto_decrypt_keyvalue(const char *key, const char *value)
{
        GSList *list;

        CONNMAN_ASSERT(value != NULL);

        for (list = crypto_list; list; list = list->next) {
                struct connman_crypto *crypto = list->data;

                if (strncmp(crypto->prefix, value, crypto->prefix_size) == 0) {
                        /*
                         * The prefix matches, so this plugin *must* be the
                         * one that knows how to decrypt.
                         */
                        return crypto->decrypt_keyvalue(key,
                            &value[crypto->prefix_size]);
                }
        }

        /*
         * No plugins match the prefix of the encrypted value, return a copy of
         * the plaintext.
         */
        return g_strdup(value);
}

char *__connman_crypto_encrypt_keyvalue(const char *key, const char *value)
{
        GSList *list;
        char *rv = NULL;

        if (value == NULL)
                return NULL;

        for (list = crypto_list; list; list = list->next) {
                struct connman_crypto *crypto = list->data;
                char *ciphertext = crypto->encrypt_keyvalue(key, value);

                if (ciphertext != NULL) {
                        rv = g_strdup_printf("%s%s", crypto->prefix,
                            ciphertext);
                        g_free(ciphertext);
                        break;
                }
        }

        if (rv == NULL) {
                /*
                 * Nobody wanted to encrypt the value, return a copy of the
                 * plaintext.
                 */
                rv = g_strdup(value);
        }

        return rv;
}

int __connman_crypto_init(void)
{
        _DBG_CRYPTO("");

        return 0;
}

void __connman_crypto_cleanup(void)
{
        _DBG_CRYPTO("");
}
