summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Dauvergne <bdauvergne@entrouvert.com>2011-03-29 18:12:44 +0200
committerBenjamin Dauvergne <bdauvergne@entrouvert.com>2011-03-29 18:43:48 +0200
commitf289edb53447b5435d04f3bb8d3884f280c8eee6 (patch)
tree0b82f380cebb1f3fb8da71283d7360647f2f6c91
parentf840037c6a89587958c570ed44f87bc1b35e8ce3 (diff)
downloadlasso-f289edb53447b5435d04f3bb8d3884f280c8eee6.tar.gz
lasso-f289edb53447b5435d04f3bb8d3884f280c8eee6.tar.xz
lasso-f289edb53447b5435d04f3bb8d3884f280c8eee6.zip
[core] add a lasso_server_load_federation method
This method allows to load providers in bulk from what is called a federation file, i.e a SAML metadata file containing declarations for more than one provider. Those file are usually signed to bind some trust to its content, so lasso_server_load_federation can take an optional file path to a certificate chain file used to check the signature on the given XML content. Only same document signature is accepted (i.e. there must be only one XML signature reference and it should be to the empty string meaning the « current » document).
-rw-r--r--lasso/id-ff/server.c71
-rw-r--r--lasso/id-ff/server.h3
2 files changed, 74 insertions, 0 deletions
diff --git a/lasso/id-ff/server.c b/lasso/id-ff/server.c
index 22f253fe..b3955b2c 100644
--- a/lasso/id-ff/server.c
+++ b/lasso/id-ff/server.c
@@ -748,3 +748,74 @@ lasso_server_get_encryption_private_key(LassoServer *server)
return server->private_data->encryption_private_key;
}
+
+/**
+ * lasso_server_load_federation:
+ * @server: a #LassoServer object
+ * @role: a #LassoProviderRole value
+ * @federation_file: a C string formatted as SAML 2.0 metadata XML content,
+ * @trusted_roots:(allow-none): a PEM encoded files containing the certificates to check signatures
+ * on the metadata files (optional)
+ *
+ * Load all the SAML 2.0 entities from @federation_file which contain a declaration for @role. If
+ * @trusted_roots is non-NULL, use it to check a signature on the metadata file.
+ *
+* Return value: 0 on success, an error code otherwise, amon:
+ * <itemizedlist>
+ * <listitem><para>
+ * LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ if server is not a #LassoServer object or @role is not a
+ * valid role value,
+ * </listitem></para>
+ * LASSO_DS_ERROR_CA_CERT_CHAIN_LOAD_FAILED if the @trusted_root file cannot be loaded,
+ * <listitem><para>
+ * </listitem></para>
+ * </itemizedlist>
+ */
+lasso_error_t
+lasso_server_load_federation(LassoServer *server, LassoProviderRole role, const gchar *federation_metadata, const gchar
+ *trusted_roots)
+{
+ xmlDoc *doc = NULL;
+ xmlNode *root = NULL;
+ xmlSecKeysMngr *keys_mngr = NULL;
+ lasso_error_t rc = 0;
+ GList *uri_references = NULL;
+
+ lasso_bad_param(SERVER, server);
+ g_return_val_if_fail(role == LASSO_PROVIDER_ROLE_SP || role == LASSO_PROVIDER_ROLE_IDP,
+ LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
+
+ if (trusted_roots) {
+ keys_mngr = lasso_load_certs_from_pem_certs_chain_file(trusted_roots);
+ lasso_return_val_if_fail(keys_mngr != NULL,
+ LASSO_DS_ERROR_CA_CERT_CHAIN_LOAD_FAILED);
+ }
+ doc = lasso_xml_parse_memory(federation_metadata, strlen(federation_metadata));
+ goto_cleanup_if_fail_with_rc(doc, LASSO_SERVER_ERROR_INVALID_XML);
+ root = xmlDocGetRootElement(doc);
+ if (trusted_roots) {
+ /* check metadata file signature */
+ lasso_check_good_rc(lasso_verify_signature(root, doc, NULL, keys_mngr, NULL,
+ EMPTY_URI, &uri_references));
+ if (! uri_references || uri_references->next != NULL || !
+ lasso_strisequal(uri_references->data, "")) {
+ warning("lasso_server_load_federation: metadata signature check failed, it"
+ " does not sign the complete file");
+ goto_cleanup_with_rc(LASSO_DS_ERROR_INVALID_SIGNATURE);
+ }
+ }
+ /* TODO: branch to the SAML2 version of this function */
+ if (lasso_strisequal((char*)root->ns->href, LASSO_SAML2_METADATA_HREF)) {
+ lasso_check_good_rc(lasso_saml20_server_load_federation(server, role, root));
+ } else {
+ /* TODO: iterate SPDescriptor and IDPDescriptor, choose which one to parse by looking at the role enum.
+ * */
+ goto_cleanup_with_rc(LASSO_ERROR_UNIMPLEMENTED);
+ }
+
+cleanup:
+ lasso_release_list_of_strings(uri_references);
+ lasso_release_key_manager(keys_mngr);
+ lasso_release_doc(doc);
+ return rc;
+}
diff --git a/lasso/id-ff/server.h b/lasso/id-ff/server.h
index 666e9d91..c5d35af2 100644
--- a/lasso/id-ff/server.h
+++ b/lasso/id-ff/server.h
@@ -103,6 +103,9 @@ LASSO_EXPORT lasso_error_t lasso_server_load_affiliation(LassoServer *server, co
LASSO_EXPORT lasso_error_t lasso_server_set_encryption_private_key_with_password(LassoServer *server,
const gchar *filename_or_buffer, const gchar *password);
+LASSO_EXPORT lasso_error_t lasso_server_load_federation(LassoServer *server, LassoProviderRole role,
+ const gchar *federation_file, const gchar *trusted_roots);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */