From 9836f4a40be07086328b912dc6d6674b82f9f1f5 Mon Sep 17 00:00:00 2001 From: Benjamin Dauvergne Date: Fri, 2 Dec 2011 18:32:21 +0100 Subject: [PATCH] [core] add a new class LassoKey LassoKey currenly store a LassoSignatureContext inside a reference-counted and bindable object. It will be used to export API around key management to bindings. --- bindings/overrides.xml | 1 + lasso/Makefile.am | 6 +- lasso/key.c | 236 +++++++++++++++++++++++++++++++++++++++++ lasso/key.h | 80 ++++++++++++++ lasso/keyprivate.h | 40 +++++++ tests/basic_tests.c | 30 ++++++ 6 files changed, 390 insertions(+), 3 deletions(-) create mode 100644 lasso/key.c create mode 100644 lasso/key.h create mode 100644 lasso/keyprivate.h diff --git a/bindings/overrides.xml b/bindings/overrides.xml index fadccefe..e30c97a1 100644 --- a/bindings/overrides.xml +++ b/bindings/overrides.xml @@ -197,6 +197,7 @@ + diff --git a/lasso/Makefile.am b/lasso/Makefile.am index 6f27f0c4..93b90d37 100644 --- a/lasso/Makefile.am +++ b/lasso/Makefile.am @@ -19,11 +19,11 @@ lasso.rc.lo: $(top_srcdir)/win32/lasso.rc lib_LTLIBRARIES = liblasso.la liblassoinclude_HEADERS = export.h lasso.h lasso_config.h errors.h \ - registry.h ctypes.h -nodist_liblassoinclude_HEADERS = debug.h utils.h registry-private.h logging.h backward_comp.h + registry.h ctypes.h key.h +nodist_liblassoinclude_HEADERS = debug.h utils.h registry-private.h logging.h backward_comp.h keyprivate.h BUILT_SOURCES = types.c errors.c symbols.sym -liblasso_la_SOURCES = lasso.c errors.c registry.c utils.c logging.c +liblasso_la_SOURCES = lasso.c errors.c registry.c utils.c logging.c key.c if WSF_ENABLED SYMBOLS_ARGS = -wsf diff --git a/lasso/key.c b/lasso/key.c new file mode 100644 index 00000000..e62efe1d --- /dev/null +++ b/lasso/key.c @@ -0,0 +1,236 @@ +/* + * Lasso - A free implementation of the Liberty Alliance specifications. + * + * Copyright (C) 2004-2011 Entr'ouvert + * http://lasso.entrouvert.org + * + * Authors: See AUTHORS file in top-level directory. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "./key.h" +#include "./keyprivate.h" +#include "./xml/private.h" + +/*****************************************************************************/ +/* private methods */ +/*****************************************************************************/ + +struct _LassoKeyPrivate { + enum _LassoKeyType type; + union { + LassoSignatureContext signature; + } context; +}; + +#define LASSO_KEY_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((o), LASSO_TYPE_KEY, LassoKeyPrivate)) + +static struct XmlSnippet schema_snippets[] = { + {NULL, 0, 0, NULL, NULL, NULL} +}; + +static LassoNodeClass *parent_class = NULL; + + +/*****************************************************************************/ +/* instance and class init functions */ +/*****************************************************************************/ + +static void +instance_init(LassoKey *key) +{ + key->private_data = LASSO_KEY_GET_PRIVATE(key); +} + +static void +dispose(GObject *g_object) +{ + LassoKey *key = (LassoKey*)g_object; + + if (key->private_data) { + switch (key->private_data->type) { + case LASSO_KEY_TYPE_FOR_SIGNATURE: + lasso_assign_new_signature_context( + key->private_data->context.signature, + LASSO_SIGNATURE_CONTEXT_NONE); + break; + } + } + + G_OBJECT_CLASS(parent_class)->dispose(G_OBJECT(key)); +} + +static void +class_init(LassoKeyClass *klass) +{ + LassoNodeClass *nclass = LASSO_NODE_CLASS(klass); + + parent_class = g_type_class_peek_parent(klass); + nclass->node_data = g_new0(LassoNodeClassData, 1); + lasso_node_class_set_nodename(nclass, "Key"); + lasso_node_class_set_ns(nclass, LASSO_LASSO_HREF, LASSO_LASSO_PREFIX); + lasso_node_class_add_snippets(nclass, schema_snippets); + g_type_class_add_private(klass, sizeof(LassoKeyPrivate)); + G_OBJECT_CLASS(klass)->dispose = dispose; +} + +GType +lasso_key_get_type() +{ + static GType this_type = 0; + + if (!this_type) { + static const GTypeInfo this_info = { + sizeof (LassoKeyClass), + NULL, + NULL, + (GClassInitFunc) class_init, + NULL, + NULL, + sizeof(LassoKey), + 0, + (GInstanceInitFunc) instance_init, + NULL + }; + + this_type = g_type_register_static(LASSO_TYPE_NODE, + "LassoKey", &this_info, 0); + } + return this_type; +} + +static LassoKey* +lasso_key_new() +{ + return g_object_new(LASSO_TYPE_KEY, NULL); +} + +static LassoKey* +lasso_key_new_for_signature_from_context(LassoSignatureContext context) { + LassoKey *key = lasso_key_new(); + + key->private_data->type = LASSO_KEY_TYPE_FOR_SIGNATURE; + lasso_assign_new_signature_context( + key->private_data->context.signature, context); + if (! lasso_validate_signature_context(key->private_data->context.signature)) { + lasso_release_gobject(key); + } + return key; +} + +/** + * lasso_key_new_for_signature_from_file; + * @filename_or_buffer: a file path of a string containing the key PEM or Base64 encoded + * @password: an eventual password to decoded the private key contained in @buffer + * @signature_method: the signature method to associate to this key + * @certificate: a certificate as a file path or PEM encoded in a NULL-terminated string, to + * associate with the key, it will be used to fill the KeyInfo node in an eventual signature. + * + * Create a new #LassoKey object, you can use it to sign XML message or to specify the key of a + * provider. + * + * Return value:(transfer full): a newly allocated #LassoKey object + */ +LassoKey* +lasso_key_new_for_signature_from_file(char *filename_or_buffer, + char *password, + LassoSignatureMethod signature_method, + char *certificate) { + return lasso_key_new_for_signature_from_context( + lasso_make_signature_context_from_path_or_string(filename_or_buffer, + password, + signature_method, + certificate)); +} + +/** + * lasso_key_new_for_signature_from_memory; + * @buffer: a byte buffer of size @size + * @size: the size of @buffer + * @password: an eventual password to decoded the private key contained in @buffer + * @signature_method: the signature method to associate to this key + * @certificate: a certificate as a file path or PEM encoded in a NULL-terminated string, to + * associate with the key, it will be used to fill the KeyInfo node in an eventual signature. + * + * Create a new #LassoKey object, you can use it to sign XML message or to specify the key of a + * provider. + * + * Return value:(transfer full): a newly allocated #LassoKey object + */ +LassoKey* +lasso_key_new_for_signature_from_memory(void *buffer, + size_t size, + char *password, + LassoSignatureMethod signature_method, + char *certificate) +{ + return lasso_key_new_for_signature_from_context( + lasso_make_signature_context_from_buffer(buffer, + size, + password, + signature_method, + certificate)); +} + +/** + * lasso_key_new_for_signature_from_base64_string; + * @base64_string: a NULL-terminated string containing a base64 encode representation of the key + * @password: an eventual password to decoded the private key contained in @buffer + * @signature_method: the signature method to associate to this key + * @certificate: a certificate as a file path or PEM encoded in a NULL-terminated string, to + * associate with the key, it will be used to fill the KeyInfo node in an eventual signature. + * + * Create a new #LassoKey object, you can use it to sign XML message or to specify the key of a + * provider. + * + * Return value:(transfer full): a newly allocated #LassoKey object + */ +LassoKey* +lasso_key_new_for_signature_from_base64_string(char *base64_string, + char *password, + LassoSignatureMethod signature_method, + char *certificate) +{ + LassoKey *key = NULL; + char *buffer = NULL; + int length = 0; + + if (lasso_base64_decode(base64_string, &buffer, &length)) { + key = lasso_key_new_for_signature_from_context( + lasso_make_signature_context_from_buffer(buffer, + length, + password, + signature_method, + certificate)); + lasso_release_string(buffer); + } + return key; +} + +LassoSignatureContext +lasso_key_get_signature_context(LassoKey *key) { + if (key->private_data && key->private_data->type == LASSO_KEY_TYPE_FOR_SIGNATURE) { + return key->private_data->context.signature; + } + return LASSO_SIGNATURE_CONTEXT_NONE; +} +LassoKeyType +lasso_key_get_key_type(LassoKey *key) { + lasso_return_val_if_fail(LASSO_IS_KEY(key), + LASSO_KEY_TYPE_FOR_SIGNATURE); + return key->private_data->type; +} diff --git a/lasso/key.h b/lasso/key.h new file mode 100644 index 00000000..ae9c4c27 --- /dev/null +++ b/lasso/key.h @@ -0,0 +1,80 @@ +/* + * Lasso - A free implementation of the Liberty Alliance specifications. + * + * Copyright (C) 2004-2011 Entr'ouvert + * http://lasso.entrouvert.org + * + * Authors: See AUTHORS file in top-level directory. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __LASSO_KEY_H__ +#define __LASSO_KEY_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "./xml/xml.h" + +#define LASSO_TYPE_KEY (lasso_key_get_type()) +#define LASSO_KEY(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), LASSO_TYPE_KEY, \ + LassoKey)) +#define LASSO_KEY_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), LASSO_TYPE_KEY, \ + LassoKeyClass)) +#define LASSO_IS_KEY(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), LASSO_TYPE_KEY)) +#define LASSO_IS_KEY_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), LASSO_TYPE_KEY)) +#define LASSO_KEY_GET_CLASS(o) \ + (G_TYPE_INSTANCE_GET_CLASS ((o), LASSO_TYPE_KEY, \ + LassoKeyClass)) + +typedef struct _LassoKey LassoKey; +typedef struct _LassoKeyClass LassoKeyClass; +typedef struct _LassoKeyPrivate LassoKeyPrivate; + +typedef enum _LassoKeyType { + LASSO_KEY_TYPE_FOR_SIGNATURE, +} LassoKeyType; + +struct _LassoKey { + LassoNode parent; + LassoKeyPrivate *private_data; +}; + +struct _LassoKeyClass { + LassoNodeClass parent; +}; + +LASSO_EXPORT GType lasso_key_get_type(); + +LASSO_EXPORT LassoKey* lasso_key_new_for_signature_from_memory(void *buffer, size_t size, + char *password, LassoSignatureMethod signature_method, char *certificate); + +LASSO_EXPORT LassoKey* lasso_key_new_for_signature_from_base64_string(char *base64_string, + char *password, LassoSignatureMethod signature_method, char *certificate); + +LASSO_EXPORT LassoKey* lasso_key_new_for_signature_from_file(char *filename_or_buffer, + char *password, LassoSignatureMethod signature_method, char *certificate); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __LASSO_KEY_H__ */ diff --git a/lasso/keyprivate.h b/lasso/keyprivate.h new file mode 100644 index 00000000..9d72f2b0 --- /dev/null +++ b/lasso/keyprivate.h @@ -0,0 +1,40 @@ +/* + * Lasso - A free implementation of the Liberty Alliance specifications. + * + * Copyright (C) 2004-2011 Entr'ouvert + * http://lasso.entrouvert.org + * + * Authors: See AUTHORS file in top-level directory. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __LASSO_KEY_PRIVATE_H__ +#define __LASSO_KEY_PRIVATE_H__ + +#include "./xml/private.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +LassoSignatureContext lasso_key_get_signature_context(LassoKey *key); +LassoKeyType lasso_key_get_key_type(LassoKey *key); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __LASSO_KEY_PRIVATE_H__ */ diff --git a/tests/basic_tests.c b/tests/basic_tests.c index 69991d4b..f2d3e51c 100644 --- a/tests/basic_tests.c +++ b/tests/basic_tests.c @@ -1985,6 +1985,33 @@ START_TEST(test13_test_lasso_server_load_metadata) } END_TEST +#include "../lasso/key.h" + +/* test load federation */ +START_TEST(test14_lasso_key) +{ + LassoKey *key; + char *buffer; + gsize length; + char *base64_encoded; + + check_true(g_file_get_contents(TESTSDATADIR "sp1-la/private-key-raw.pem", &buffer, &length, NULL)); + check_not_null(key = lasso_key_new_for_signature_from_memory(buffer, + length, NULL, LASSO_SIGNATURE_METHOD_RSA_SHA1, + NULL)); + lasso_release_gobject(key); + check_not_null(key = lasso_key_new_for_signature_from_file(TESTSDATADIR + "sp1-la/private-key-raw.pem", NULL, LASSO_SIGNATURE_METHOD_RSA_SHA1, + NULL)); + lasso_release_gobject(key); + base64_encoded = g_base64_encode(BAD_CAST buffer, length); + check_not_null(key = lasso_key_new_for_signature_from_base64_string(base64_encoded, NULL, + LASSO_SIGNATURE_METHOD_RSA_SHA1, NULL)); + lasso_release_string(base64_encoded); + lasso_release_string(buffer); +} +END_TEST + Suite* basic_suite() { @@ -2000,6 +2027,7 @@ basic_suite() TCase *tc_response_new_from_xmlNode = tcase_create("Test parsing a message from Ping Federate"); TCase *tc_custom_namespace = tcase_create("Test custom namespace handling"); TCase *tc_load_metadata = tcase_create("Test loading a federation metadata file"); + TCase *tc_key = tcase_create("Test loading and manipulating LassoKey objects"); suite_add_tcase(s, tc_server_load_dump_empty_string); suite_add_tcase(s, tc_server_load_dump_random_string); @@ -2012,6 +2040,7 @@ basic_suite() suite_add_tcase(s, tc_response_new_from_xmlNode); suite_add_tcase(s, tc_custom_namespace); suite_add_tcase(s, tc_load_metadata); + suite_add_tcase(s, tc_key); tcase_add_test(tc_server_load_dump_empty_string, test01_server_load_dump_empty_string); tcase_add_test(tc_server_load_dump_random_string, test02_server_load_dump_random_string); @@ -2026,6 +2055,7 @@ basic_suite() tcase_add_test(tc_response_new_from_xmlNode, test11_get_default_name_id_format); tcase_add_test(tc_custom_namespace, test12_custom_namespace); tcase_add_test(tc_load_metadata, test13_test_lasso_server_load_metadata); + tcase_add_test(tc_key, test14_lasso_key); tcase_set_timeout(tc_load_metadata, 10); return s; }