summaryrefslogtreecommitdiffstats
path: root/lasso/key.c
diff options
context:
space:
mode:
authorBenjamin Dauvergne <bdauvergne@entrouvert.com>2012-03-17 15:26:21 +0100
committerBenjamin Dauvergne <bdauvergne@entrouvert.com>2012-03-17 15:26:21 +0100
commitf42bef083667ce29e43dced8947e905febd158ef (patch)
tree420a8f236fd8c0f785fe298b13f3a2dde1b6e867 /lasso/key.c
parentf55c92725510f102a778878b45561aaba8ab887d (diff)
downloadlasso-f42bef083667ce29e43dced8947e905febd158ef.tar.gz
lasso-f42bef083667ce29e43dced8947e905febd158ef.tar.xz
lasso-f42bef083667ce29e43dced8947e905febd158ef.zip
[key] add methods to send message using SAML 2.0 redirect and post bindings
Diffstat (limited to 'lasso/key.c')
-rw-r--r--lasso/key.c153
1 files changed, 152 insertions, 1 deletions
diff --git a/lasso/key.c b/lasso/key.c
index b75352b5..2f6dcecc 100644
--- a/lasso/key.c
+++ b/lasso/key.c
@@ -24,6 +24,7 @@
#include "key.h"
#include "keyprivate.h"
#include "xml/private.h"
+#include "xmlsec/xmltree.h"
/*****************************************************************************/
/* private methods */
@@ -172,7 +173,7 @@ lasso_key_new_for_signature_from_file(char *filename_or_buffer,
* Return value:(transfer full): a newly allocated #LassoKey object
*/
LassoKey*
-lasso_key_new_for_signature_from_memory(void *buffer,
+lasso_key_new_for_signature_from_memory(const void *buffer,
size_t size,
char *password,
LassoSignatureMethod signature_method,
@@ -221,6 +222,149 @@ lasso_key_new_for_signature_from_base64_string(char *base64_string,
return key;
}
+static xmlNode *
+find_xmlnode_with_saml2_id(xmlNode *xmlnode, const char *id)
+{
+ xmlNode *found = NULL;
+ xmlNode *t;
+
+ if (! xmlnode)
+ return NULL;
+
+ if (xmlHasProp(xmlnode, BAD_CAST "ID")) {
+ xmlChar *value;
+
+ value = xmlGetProp(xmlnode, BAD_CAST "ID");
+ if (lasso_strisequal((char*)value, id)) {
+ found = xmlnode;
+ }
+ xmlFree(value);
+ }
+ if (found) {
+ return found;
+ }
+ t = xmlSecGetNextElementNode(xmlnode->children);
+ while (t) {
+ found = find_xmlnode_with_saml2_id(t, id);
+ if (found) {
+ return found;
+ }
+ t = xmlSecGetNextElementNode(t->next);
+ }
+ return NULL;
+}
+
+/**
+ * lasso_key_saml2_xml_verify:
+ * @key: a #LassoKey object
+ * @id: the value of the ID attribute of signed node
+ * @document: the document containing the signed node
+ *
+ * Verify the first signature node child of the node with the given id. It follows from the profile
+ * of XMLDsig used by the SAML 2.0 specification.
+ *
+ * Return value: 0 if the signature validate, an error code otherwise.
+ */
+lasso_error_t
+lasso_key_saml2_xml_verify(LassoKey *key, char *id, xmlNode *document)
+{
+ xmlNode *signed_node;
+ LassoSignatureContext signature_context;
+
+
+ signed_node = find_xmlnode_with_saml2_id(document, id);
+ if (! signed_node) {
+ return LASSO_DS_ERROR_INVALID_REFERENCE_FOR_SAML;
+ }
+ signature_context = lasso_key_get_signature_context(key);
+ return lasso_verify_signature(signed_node, signed_node->doc, "ID", NULL,
+ signature_context.signature_key, NO_OPTION, NULL);
+}
+
+/**
+ * lasso_key_saml2_xml_sign:
+ * @key: a #LassoKey object
+ * @id: the value of the ID attribute of signed node
+ * @document: the document containing the signed node
+ *
+ * Sign the first signature node child of the node with the given id. It no signature node is found
+ * a new one is added at the end of the children list of the signed node.
+ *
+ * The passed document node is modified in-place.
+ *
+ * Return value: The modified xmlNode object, or NULL if the signature failed.
+ */
+xmlNode*
+lasso_key_saml2_xml_sign(LassoKey *key, const char *id, xmlNode *document)
+{
+ xmlNode *signed_node;
+ LassoSignatureContext signature_context;
+
+ signed_node = find_xmlnode_with_saml2_id(document, id);
+ if (! signed_node) {
+ return NULL;
+ }
+ signature_context = lasso_key_get_signature_context(key);
+ lasso_xmlnode_add_saml2_signature_template(signed_node, signature_context, id);
+ if (lasso_sign_node(signed_node, signature_context,
+ "ID", id) == 0) {
+ return document;
+ } else {
+ return NULL;
+ }
+}
+
+/**
+ * lasso_key_query_verify:
+ * key: a #LassoKey object
+ * query: a raw HTTP query string
+ *
+ * Check if this query string contains a proper SAML2 signature for this key.
+ *
+ * Return value: 0 if a valid signature was found, an error code otherwise.
+ */
+lasso_error_t
+lasso_key_query_verify(LassoKey *key, const char *query)
+{
+ LassoSignatureContext signature_context;
+ lasso_bad_param(KEY, key);
+
+ signature_context = lasso_key_get_signature_context(key);
+ if (! lasso_validate_signature_context(signature_context))
+ return LASSO_ERROR_UNDEFINED;
+ return lasso_saml2_query_verify_signature(query, signature_context.signature_key);
+}
+
+/**
+ * lasso_key_query_verify:
+ * key: a #LassoKey object
+ * query: a raw HTTP query string
+ *
+ * Sign the given query string using the given key.
+ *
+ * Return value: the signed query string.
+ */
+char*
+lasso_key_query_sign(LassoKey *key, const char *query)
+{
+ LassoSignatureContext signature_context;
+
+ if (! LASSO_IS_KEY(key))
+ return NULL;
+ signature_context = lasso_key_get_signature_context(key);
+ if (! lasso_validate_signature_context(signature_context))
+ return NULL;
+ return lasso_query_sign((char*)query, signature_context);
+}
+
+/**
+ * lasso_key_get_signature_context:
+ * @key: a #LassoKey object
+ *
+ * Private method to extract the signature context embedded in a LassoKey object.
+ *
+ * Return value: a #LassoSignatureContext structure value.
+ */
LassoSignatureContext
lasso_key_get_signature_context(LassoKey *key) {
if (key->private_data && key->private_data->type == LASSO_KEY_TYPE_FOR_SIGNATURE) {
@@ -228,6 +372,13 @@ lasso_key_get_signature_context(LassoKey *key) {
}
return LASSO_SIGNATURE_CONTEXT_NONE;
}
+
+/**
+ * lasso_key_get_key_type:
+ * @key: a #LassoKey object
+ *
+ * Return the type of key, i.e. which operation it supports.
+ */
LassoKeyType
lasso_key_get_key_type(LassoKey *key) {
lasso_return_val_if_fail(LASSO_IS_KEY(key),