blob: b2b4c0b5d1f4496204acc3840e1777f0e964250e [file] [log] [blame]
/*
* 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("");
}