summaryrefslogtreecommitdiffstats
path: root/lasso
diff options
context:
space:
mode:
authorBenjamin Dauvergne <bdauvergne@entrouvert.com>2011-05-17 11:04:05 +0200
committerBenjamin Dauvergne <bdauvergne@entrouvert.com>2011-05-19 17:54:16 +0200
commite67f2bb6587770d024f740d92356c827a40120bb (patch)
tree366f9562f4d31b4121128217e9c80382d0a3aaf7 /lasso
parente14652e7a41332f954b72dd2fbc6f9962970e8c3 (diff)
downloadlasso-e67f2bb6587770d024f740d92356c827a40120bb.tar.gz
lasso-e67f2bb6587770d024f740d92356c827a40120bb.tar.xz
lasso-e67f2bb6587770d024f740d92356c827a40120bb.zip
[core] first try at multiple signing keys support
The idea was to replace every use of an xmlSecKey* by a loop over a GList* of xmlSecKey*. - In the structure LassoProviderPrivate changed xmlSecKey*public_key -> GList* signing_public_keys xmlNode*signing_key_descriptor -> GList* signing_key_descriptors. - Renamed lasso_provider_try_loading_public_key to lasso_provider_try_loading_public_keys and chaned its signature accordingly - Renamed lasso_provider_get_public_key to lasso_provider_get_public_keys and changed the signature accordingly. - Changed lasso_provider_get_encryption_public_key to return the first signing key from the list as a temporary work around. Multiple encryption keys will be supported later. - Changed lasso_provider_load_public_key to load keys from the passed file on the LassoProvider constructor, from every key descriptors found for signing and eventually from the key descriptor marked for encryption. - Every failure to load from a file or an XML KeyInfo descriptor are noew reported as warning. - Query signature checking was completely moved to lasso_provider_verify_query_signature and lasso_provider_verify_signature now calls it. - lasso_provider_verify_signature is now using lasso_verify_signature from the xml/tools.o module. - lasso_provider_verify_single_signature was modified to support multiple signing keys.
Diffstat (limited to 'lasso')
-rw-r--r--lasso/id-ff/provider.c253
-rw-r--r--lasso/id-ff/providerprivate.h6
2 files changed, 143 insertions, 116 deletions
diff --git a/lasso/id-ff/provider.c b/lasso/id-ff/provider.c
index 163d73bc..28c9e1d2 100644
--- a/lasso/id-ff/provider.c
+++ b/lasso/id-ff/provider.c
@@ -97,15 +97,15 @@ void _lasso_provider_add_metadata_value_for_role(LassoProvider *provider,
typedef int LassoProviderRoleIndex;
static int
-lasso_provider_try_loading_public_key(LassoProvider *provider, xmlSecKeyPtr *public_key, gboolean mandatory) {
- if (provider->public_key || provider->private_data->signing_key_descriptor) {
- *public_key = lasso_provider_get_public_key(provider);
- if (*public_key == NULL)
+lasso_provider_try_loading_public_keys(LassoProvider *provider, GList **public_keys, gboolean mandatory) {
+ if (provider->public_key || provider->private_data->signing_key_descriptors) {
+ *public_keys = lasso_provider_get_public_keys(provider);
+ if (*public_keys == NULL)
return LASSO_DS_ERROR_PUBLIC_KEY_LOAD_FAILED;
} else {
- *public_key = NULL;
+ *public_keys = NULL;
}
- if (*public_key == NULL && mandatory)
+ if (*public_keys == NULL && mandatory)
return LASSO_PROVIDER_ERROR_MISSING_PUBLIC_KEY;
return 0;
}
@@ -521,18 +521,18 @@ static struct XmlSnippet schema_snippets[] = {
static LassoNodeClass *parent_class = NULL;
/**
- * lasso_provider_get_public_key:
+ * lasso_provider_get_public_keys:
* @provider: a #LassoProvider object
*
- * Return the public key associated with this provider.
+ * Return the public keys associated with this provider.
*
* Return value: an #xmlSecKey object.
*/
-xmlSecKey*
-lasso_provider_get_public_key(const LassoProvider *provider)
+GList*
+lasso_provider_get_public_keys(const LassoProvider *provider)
{
g_return_val_if_fail(LASSO_IS_PROVIDER(provider), NULL);
- return provider->private_data->public_key;
+ return provider->private_data->signing_public_keys;
}
/**
@@ -548,11 +548,16 @@ xmlSecKey*
lasso_provider_get_encryption_public_key(const LassoProvider *provider)
{
g_return_val_if_fail(LASSO_IS_PROVIDER(provider), NULL);
+ GList *public_keys;
if (provider->private_data->encryption_public_key) {
return provider->private_data->encryption_public_key;
}
- return lasso_provider_get_public_key(provider);
+ public_keys = lasso_provider_get_public_keys(provider);
+ if (! public_keys) {
+ return NULL;
+ }
+ return (xmlSecKey*)public_keys->data;
}
static void
@@ -647,7 +652,8 @@ _lasso_provider_load_key_descriptor(LassoProvider *provider, xmlNode *key_descri
private_data = provider->private_data;
use = xmlGetProp(key_descriptor, (xmlChar*)"use");
if (use == NULL || lasso_strisequal((char *)use,"signing")) {
- lasso_assign_xml_node(private_data->signing_key_descriptor, key_descriptor);
+ lasso_list_add_xml_node(private_data->signing_key_descriptors,
+ key_descriptor);
}
if (use == NULL || strcmp((char*)use, "encryption") == 0) {
lasso_assign_xml_node(private_data->encryption_key_descriptor, key_descriptor);
@@ -835,14 +841,12 @@ dispose(GObject *object)
provider->private_data->default_assertion_consumer = NULL;
}
- if (provider->private_data->public_key) {
- xmlSecKeyDestroy(provider->private_data->public_key);
- provider->private_data->public_key = NULL;
+ if (provider->private_data->signing_public_keys) {
+ lasso_release_list_of_sec_key(provider->private_data->signing_public_keys);
}
- if (provider->private_data->signing_key_descriptor) {
- xmlFreeNode(provider->private_data->signing_key_descriptor);
- provider->private_data->signing_key_descriptor = NULL;
+ if (provider->private_data->signing_key_descriptors) {
+ lasso_release_list_of_xml_node(provider->private_data->signing_key_descriptors);
}
if (provider->private_data->encryption_key_descriptor) {
@@ -898,8 +902,8 @@ instance_init(LassoProvider *provider)
provider->private_data->affiliation_id = NULL;
provider->private_data->affiliation_owner_id = NULL;
provider->private_data->organization = NULL;
- provider->private_data->public_key = NULL;
- provider->private_data->signing_key_descriptor = NULL;
+ provider->private_data->signing_public_keys = NULL;
+ provider->private_data->signing_key_descriptors = NULL;
provider->private_data->encryption_key_descriptor = NULL;
provider->private_data->encryption_public_key_str = NULL;
provider->private_data->encryption_public_key = NULL;
@@ -1230,44 +1234,72 @@ gboolean
lasso_provider_load_public_key(LassoProvider *provider, LassoPublicKeyType public_key_type)
{
gchar *public_key = NULL;
+ GList *keys_descriptors = NULL;
xmlNode *key_descriptor = NULL;
- xmlSecKey *pub_key = NULL;
+ GList *keys = NULL;
g_return_val_if_fail(LASSO_IS_PROVIDER(provider), FALSE);
if (public_key_type == LASSO_PUBLIC_KEY_SIGNING) {
public_key = provider->public_key;
- key_descriptor = provider->private_data->signing_key_descriptor;
+ keys_descriptors = provider->private_data->signing_key_descriptors;
} else {
key_descriptor = provider->private_data->encryption_key_descriptor;
}
- if (public_key == NULL && key_descriptor == NULL) {
+ if (public_key == NULL && keys_descriptors == NULL && key_descriptor == NULL) {
return TRUE;
}
- if (public_key == NULL) {
- pub_key = lasso_xmlsec_load_key_info(key_descriptor);
- if (! pub_key) {
+ if (public_key != NULL) {
+ xmlSecKey *key = lasso_xmlsec_load_private_key(public_key, NULL);
+ if (key) {
+ lasso_list_add_new_sec_key(keys, key);
+ } else {
+ message(G_LOG_LEVEL_WARNING, "Could not read public key from file %s", public_key);
+ }
+ }
+ if (key_descriptor) {
+ xmlSecKey *key = lasso_xmlsec_load_key_info(key_descriptor);
+ if (key) {
+ lasso_list_add_new_sec_key(keys, key);
+ } else {
message(G_LOG_LEVEL_WARNING, "Could not read KeyInfo from %s KeyDescriptor", public_key_type == LASSO_PUBLIC_KEY_SIGNING ? "signing" : "encryption");
}
- } else {
- pub_key = lasso_xmlsec_load_private_key(public_key, NULL);
}
- if (pub_key) {
+ if (keys_descriptors) {
+ lasso_foreach_full_begin(xmlNode*, key_descriptor, it, keys_descriptors);
+ {
+ xmlSecKey *key = lasso_xmlsec_load_key_info(key_descriptor);
+ if (key) {
+ lasso_list_add_new_sec_key(keys, key);
+ } else {
+ message(G_LOG_LEVEL_WARNING, "Could not read KeyInfo from %s "
+ "KeyDescriptor",
+ public_key_type == LASSO_PUBLIC_KEY_SIGNING ? "signing" :
+ "encryption");
+ }
+ }
+ lasso_foreach_full_end();
+ }
+
+ if (keys) {
switch (public_key_type) {
case LASSO_PUBLIC_KEY_SIGNING:
- lasso_assign_new_sec_key(provider->private_data->public_key, pub_key);
+ lasso_transfer_full(provider->private_data->signing_public_keys, keys,
+ list_of_sec_key);
break;
case LASSO_PUBLIC_KEY_ENCRYPTION:
- lasso_assign_new_sec_key(provider->private_data->encryption_public_key, pub_key);
+ lasso_assign_new_sec_key(provider->private_data->encryption_public_key,
+ (xmlSecKey*)keys->data);
break;
default:
- xmlSecKeyDestroy(pub_key);
+ lasso_release_list_of_sec_key(keys);
}
+ return TRUE;
+ } else {
+ return FALSE;
}
-
- return (pub_key != NULL);
}
@@ -1297,9 +1329,10 @@ lasso_provider_verify_saml_signature(LassoProvider *provider,
{
const char *id_attribute_name = NULL;
const xmlChar *node_ns = NULL;
- xmlSecKey *public_key = NULL;
+ GList *public_keys = NULL;
xmlSecKeysMngr *keys_manager = NULL;
int rc = 0;
+ int signature_rc = 0;
lasso_bad_param(PROVIDER, provider);
lasso_null_param(signed_node);
@@ -1320,9 +1353,17 @@ lasso_provider_verify_saml_signature(LassoProvider *provider,
goto_cleanup_if_fail_with_rc(id_attribute_name, LASSO_PARAM_ERROR_INVALID_VALUE);
/* Get provider credentials */
lasso_check_good_rc(lasso_provider_try_loading_ca_cert_chain(provider, &keys_manager));
- lasso_check_good_rc(lasso_provider_try_loading_public_key(provider, &public_key, keys_manager == NULL));
- rc = lasso_verify_signature(signed_node, doc, id_attribute_name, keys_manager, public_key,
- NO_OPTION, NULL);
+ lasso_check_good_rc(lasso_provider_try_loading_public_keys(provider, &public_keys, keys_manager == NULL));
+ lasso_foreach_full_begin(xmlSecKey*, public_key, it, public_keys);
+ {
+ signature_rc = lasso_verify_signature(signed_node, doc, id_attribute_name, keys_manager, public_key,
+ NO_OPTION, NULL);
+ if (signature_rc == 0) {
+ break;
+ }
+ }
+ lasso_foreach_full_end();
+ rc = signature_rc;
cleanup:
lasso_release_key_manager(keys_manager);
return rc;
@@ -1336,45 +1377,35 @@ lasso_provider_verify_signature(LassoProvider *provider,
* reflection about code reuse is under way...
*/
xmlDoc *doc = NULL;
- xmlNode *xmlnode = NULL, *sign = NULL, *x509data = NULL;
+ xmlNode *xmlnode = NULL;
xmlSecKeysMngr *keys_mngr = NULL;
- xmlSecDSigCtx *dsigCtx = NULL;
int rc = 0;
+ int signature_rc = 0;
xmlXPathContext *xpathCtx = NULL;
xmlXPathObject *xpathObj = NULL;
- xmlSecKey *public_key = NULL;
+ GList *public_keys = NULL;
g_return_val_if_fail(LASSO_IS_PROVIDER(provider), LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
if (lasso_flag_verify_signature == FALSE)
return 0;
-
if (message == NULL)
return LASSO_PROFILE_ERROR_INVALID_MSG;
if (format == LASSO_MESSAGE_FORMAT_ERROR)
return LASSO_PROFILE_ERROR_INVALID_MSG;
+
if (format == LASSO_MESSAGE_FORMAT_UNKNOWN)
return LASSO_PROFILE_ERROR_INVALID_MSG;
if (format == LASSO_MESSAGE_FORMAT_QUERY) {
- lasso_check_good_rc(lasso_provider_try_loading_public_key(provider, &public_key, TRUE));
-
- switch (lasso_provider_get_protocol_conformance(provider)) {
- case LASSO_PROTOCOL_LIBERTY_1_0:
- case LASSO_PROTOCOL_LIBERTY_1_1:
- case LASSO_PROTOCOL_LIBERTY_1_2:
- return lasso_query_verify_signature(message, public_key);
- case LASSO_PROTOCOL_SAML_2_0:
- return lasso_saml2_query_verify_signature(message, public_key);
- default:
- return LASSO_PROFILE_ERROR_CANNOT_VERIFY_SIGNATURE;
- }
+ return lasso_provider_verify_query_signature(provider, message);
}
lasso_check_good_rc(lasso_provider_try_loading_ca_cert_chain(provider, &keys_mngr));
/* public key is mandatory if no keys manager is present */
- lasso_check_good_rc(lasso_provider_try_loading_public_key(provider, &public_key, keys_mngr == NULL));
+ lasso_check_good_rc(lasso_provider_try_loading_public_keys(provider, &public_keys,
+ keys_mngr == NULL));
if (format == LASSO_MESSAGE_FORMAT_BASE64) {
int len;
@@ -1402,64 +1433,20 @@ lasso_provider_verify_signature(LassoProvider *provider,
}
- sign = NULL;
- for (sign = xmlnode->children; sign; sign = sign->next) {
- if (strcmp((char*)sign->name, "Signature") == 0)
+ lasso_foreach_full_begin(xmlSecKeyPtr, public_key, it, public_keys);
+ {
+ signature_rc = lasso_verify_signature(xmlnode, doc, id_attr_name,
+ keys_mngr, public_key, NO_OPTION, NULL);
+ if (signature_rc == 0) {
break;
- }
-
- /* If no signature was found, look for one in assertion */
- if (sign == NULL) {
- for (sign = xmlnode->children; sign; sign = sign->next) {
- if (strcmp((char*)sign->name, "Assertion") == 0)
- break;
- }
- if (sign != NULL) {
- xmlnode = sign;
- for (sign = xmlnode->children; sign; sign = sign->next) {
- if (strcmp((char*)sign->name, "Signature") == 0)
- break;
- }
}
}
-
- goto_cleanup_if_fail_with_rc (sign != NULL, LASSO_DS_ERROR_SIGNATURE_NOT_FOUND);
-
- if (id_attr_name) {
- xmlChar *id_value = xmlGetProp(xmlnode, (xmlChar*)id_attr_name);
- xmlAttr *id_attr = xmlHasProp(xmlnode, (xmlChar*)id_attr_name);
- if (id_value != NULL) {
- xmlAddID(NULL, doc, id_value, id_attr);
- xmlFree(id_value);
- }
- }
-
- x509data = xmlSecFindNode(xmlnode, xmlSecNodeX509Data, xmlSecDSigNs);
- if (x509data == NULL) { /* no need for a keys mngr if there is no X509 data */
- lasso_release_key_manager(keys_mngr);
- }
-
- dsigCtx = xmlSecDSigCtxCreate(keys_mngr);
- if (public_key) {
- dsigCtx->signKey = xmlSecKeyDuplicate(public_key);
- }
-
- goto_cleanup_if_fail_with_rc (xmlSecDSigCtxVerify(dsigCtx, sign) >= 0,
- LASSO_DS_ERROR_SIGNATURE_VERIFICATION_FAILED);
-
- if (dsigCtx->status != xmlSecDSigStatusSucceeded) {
- rc = LASSO_DS_ERROR_INVALID_SIGNATURE;
- goto cleanup;
- }
+ lasso_foreach_full_end();
+ rc = signature_rc;
cleanup:
lasso_release_key_manager(keys_mngr);
- lasso_release_signature_context(dsigCtx);
- if (xpathCtx)
- xmlXPathFreeContext(xpathCtx);
- if (xpathObj)
- xmlXPathFreeObject(xpathObj);
- lasso_release_doc(doc);
+ lasso_release_xpath_job(xpathObj, xpathCtx, doc);
return rc;
}
@@ -1543,7 +1530,40 @@ lasso_provider_get_encryption_sym_key_type(const LassoProvider *provider)
int
lasso_provider_verify_query_signature(LassoProvider *provider, const char *message)
{
- return lasso_provider_verify_signature(provider, message, "", LASSO_MESSAGE_FORMAT_QUERY);
+ int (*check)(const char *, const xmlSecKey *) = NULL;
+ int rc = 0;
+ int signature_rc = 0;
+ GList *public_keys = NULL;
+
+ lasso_bad_param(PROVIDER, provider);
+ lasso_null_param(message);
+
+ lasso_check_good_rc(lasso_provider_try_loading_public_keys(provider, &public_keys, TRUE));
+
+ switch (lasso_provider_get_protocol_conformance(provider)) {
+ case LASSO_PROTOCOL_LIBERTY_1_0:
+ case LASSO_PROTOCOL_LIBERTY_1_1:
+ case LASSO_PROTOCOL_LIBERTY_1_2:
+ check = lasso_query_verify_signature;
+ break;
+ case LASSO_PROTOCOL_SAML_2_0:
+ check = lasso_saml2_query_verify_signature;
+ break;
+ default:
+ return LASSO_PROFILE_ERROR_CANNOT_VERIFY_SIGNATURE;
+ }
+ /* Check with all known signing keys... */
+ lasso_foreach_full_begin(xmlSecKeyPtr, public_key, it, public_keys);
+ {
+ signature_rc = check(message, public_key);
+ if (signature_rc == 0) {
+ break;
+ }
+ }
+ lasso_foreach_full_end();
+ rc = signature_rc;
+cleanup:
+ return rc;
}
/**
@@ -1606,7 +1626,7 @@ int
lasso_provider_verify_single_node_signature (LassoProvider *provider, LassoNode *node, const char *id_attr_name)
{
xmlNode *xmlnode = NULL;
- xmlSecKey *public_key = NULL;
+ GList *public_keys = NULL;
xmlSecKeysMngr *keys_mngr = NULL;
int rc = 0;
@@ -1615,10 +1635,17 @@ lasso_provider_verify_single_node_signature (LassoProvider *provider, LassoNode
return LASSO_DS_ERROR_SIGNATURE_VERIFICATION_FAILED;
}
lasso_check_good_rc(lasso_provider_try_loading_ca_cert_chain(provider, &keys_mngr));
- lasso_check_good_rc(lasso_provider_try_loading_public_key(provider, &public_key,
+ lasso_check_good_rc(lasso_provider_try_loading_public_keys(provider, &public_keys,
keys_mngr == NULL));
- rc = lasso_verify_signature(xmlnode, NULL, id_attr_name, keys_mngr, public_key,
- NO_SINGLE_REFERENCE, NULL);
+
+ lasso_foreach_full_begin(xmlSecKey*, public_key, it, public_keys);
+ {
+ rc = lasso_verify_signature(xmlnode, NULL, id_attr_name, keys_mngr, public_key,
+ NO_SINGLE_REFERENCE, NULL);
+ if (rc == 0)
+ break;
+ }
+ lasso_foreach_full_end();
cleanup:
return rc;
}
diff --git a/lasso/id-ff/providerprivate.h b/lasso/id-ff/providerprivate.h
index 2c8d7139..bd9c46cc 100644
--- a/lasso/id-ff/providerprivate.h
+++ b/lasso/id-ff/providerprivate.h
@@ -68,8 +68,8 @@ struct _LassoProviderPrivate
char *affiliation_owner_id;
char *affiliation_id;
- xmlSecKey *public_key;
- xmlNode *signing_key_descriptor;
+ GList *signing_public_keys;
+ GList *signing_key_descriptors;
xmlNode *encryption_key_descriptor;
char *encryption_public_key_str;
xmlSecKey *encryption_public_key;
@@ -86,7 +86,7 @@ int lasso_provider_verify_signature(LassoProvider *provider,
const char *message, const char *id_attr_name, LassoMessageFormat format);
gboolean lasso_provider_load_public_key(LassoProvider *provider,
LassoPublicKeyType public_key_type);
-xmlSecKey* lasso_provider_get_public_key(const LassoProvider *provider);
+GList* lasso_provider_get_public_keys(const LassoProvider *provider);
xmlSecKey* lasso_provider_get_encryption_public_key(const LassoProvider *provider);
LassoEncryptionSymKeyType lasso_provider_get_encryption_sym_key_type(const LassoProvider* provider);
int lasso_provider_verify_saml_signature(LassoProvider *provider, xmlNode *signed_node, xmlDoc *doc);