[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).
This commit is contained in:
Benjamin Dauvergne 2011-03-29 18:12:44 +02:00
parent f840037c6a
commit f289edb534
2 changed files with 74 additions and 0 deletions

View File

@ -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;
}

View File

@ -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 */