summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrederic Peters <fpeters@entrouvert.com>2004-12-10 16:13:34 +0000
committerFrederic Peters <fpeters@entrouvert.com>2004-12-10 16:13:34 +0000
commitd1b99b7bbbc74a0824054c0766c96bb15889654e (patch)
tree0f265f81e081f401e1ac1f52c62392d968704bfb
parentfad688adebffaab950dad2acf53617a7a4d5e401 (diff)
Added back xmlsec signature check (and disabled it in name identifier mapping
profile since it is buggy there). The signature check requires another call to xmlParseMemory; this makes them 3 per SOAP message (sign check + lasso_profile_get_request_type_from_soap_msg and lasso_node_init_from_message). I'll think further about this.
-rw-r--r--lasso/id-ff/lecp.c2
-rw-r--r--lasso/id-ff/login.c31
-rw-r--r--lasso/id-ff/name_identifier_mapping.c6
-rw-r--r--lasso/id-ff/provider.c141
-rw-r--r--lasso/xml/xml.c149
-rw-r--r--lasso/xml/xml.h3
6 files changed, 204 insertions, 128 deletions
diff --git a/lasso/id-ff/lecp.c b/lasso/id-ff/lecp.c
index ae6efadb..cf60e277 100644
--- a/lasso/id-ff/lecp.c
+++ b/lasso/id-ff/lecp.c
@@ -124,7 +124,7 @@ lasso_lecp_build_authn_response_msg(LassoLecp *lecp)
message(G_LOG_LEVEL_CRITICAL, "AssertionConsumerServiceURL not found");
return -1;
}
- profile->msg_body = lasso_node_export_to_base64(profile->response);
+ profile->msg_body = lasso_node_export_to_base64(profile->response, NULL, NULL);
if (profile->msg_body == NULL) {
message(G_LOG_LEVEL_CRITICAL, "AuthnResponse Base64 msg not found");
return -1;
diff --git a/lasso/id-ff/login.c b/lasso/id-ff/login.c
index 8397af10..f3055471 100644
--- a/lasso/id-ff/login.c
+++ b/lasso/id-ff/login.c
@@ -637,12 +637,12 @@ lasso_login_build_authn_request_msg(LassoLogin *login, const gchar *remote_provi
}
if (login->http_method == LASSO_HTTP_METHOD_POST) {
char *private_key = NULL, *certificate = NULL;
- if (! must_sign) {
+ if (must_sign) {
private_key = LASSO_PROFILE(login)->server->private_key;
certificate = LASSO_PROFILE(login)->server->certificate;
}
- /* XXX: lareq may need to be signed */
- lareq = lasso_node_export_to_base64(LASSO_PROFILE(login)->request);
+ lareq = lasso_node_export_to_base64(LASSO_PROFILE(login)->request,
+ private_key, certificate);
if (lareq == NULL) {
message(G_LOG_LEVEL_CRITICAL,
@@ -756,7 +756,8 @@ lasso_login_build_authn_response_msg(LassoLogin *login,
remote_provider = g_hash_table_lookup(profile->server->providers,
profile->remote_providerID);
/* build an lib:AuthnResponse base64 encoded */
- LASSO_PROFILE(login)->msg_body = lasso_node_export_to_base64(profile->response);
+ LASSO_PROFILE(login)->msg_body = lasso_node_export_to_base64(profile->response,
+ NULL, NULL);
LASSO_PROFILE(login)->msg_url = lasso_provider_get_metadata_one(
remote_provider, "AssertionConsumerServiceURL");
@@ -819,10 +820,6 @@ lasso_login_build_response_msg(LassoLogin *login, gchar *remote_providerID)
LASSO_PROFILE(login)->remote_providerID = g_strdup(remote_providerID);
remote_provider = g_hash_table_lookup(LASSO_PROFILE(login)->server->providers,
LASSO_PROFILE(login)->remote_providerID);
- /* FIXME verify the SOAP request signature */
- ret = lasso_node_verify_signature(LASSO_PROFILE(login)->request,
- remote_provider->public_key,
- remote_provider->ca_cert_chain);
/* changed status code into RequestDenied
if signature is invalid or not found
if an error occurs during verification */
@@ -892,10 +889,9 @@ lasso_login_init_authn_request(LassoLogin *login, lassoHttpMethod http_method)
request->ProviderID = g_strdup(LASSO_PROVIDER(LASSO_PROFILE(login)->server)->ProviderID);
if (http_method == LASSO_HTTP_METHOD_POST) {
- /* XXX: if post sign_type/sign_method
- LASSO_SIGNATURE_TYPE_WITHX509,
- LASSO_SIGNATURE_METHOD_RSA_SHA1);
- */
+ LASSO_SAMLP_REQUEST_ABSTRACT(request)->sign_method =
+ LASSO_SIGNATURE_METHOD_RSA_SHA1;
+ LASSO_SAMLP_REQUEST_ABSTRACT(request)->sign_type = LASSO_SIGNATURE_TYPE_WITHX509;
}
LASSO_PROFILE(login)->request = LASSO_NODE(request);
@@ -1192,6 +1188,7 @@ lasso_login_process_authn_response_msg(LassoLogin *login, gchar *authn_response_
{
gint ret1 = 0, ret2 = 0;
LassoMessageFormat format;
+ LassoProvider *remote_provider;
g_return_val_if_fail(LASSO_IS_LOGIN(login), LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
g_return_val_if_fail(authn_response_msg != NULL, LASSO_PARAM_ERROR_INVALID_VALUE);
@@ -1210,9 +1207,19 @@ lasso_login_process_authn_response_msg(LassoLogin *login, gchar *authn_response_
message(G_LOG_LEVEL_CRITICAL, "XXX");
}
+ remote_provider = g_hash_table_lookup(LASSO_PROFILE(login)->server->providers,
+ LASSO_PROFILE(login)->remote_providerID);
+
LASSO_PROFILE(login)->msg_relayState = g_strdup(LASSO_LIB_AUTHN_RESPONSE(
LASSO_PROFILE(login)->response)->RelayState);
+#if 0 /* XXX: disabled signature check; not sure it must be done here */
+ rc = lasso_provider_verify_signature(remote_provider,
+ authn_response_msg, "ResponseID", format);
+ if (rc)
+ return rc;
+#endif
+
ret2 = lasso_login_process_response_status_and_assertion(login);
return ret2 == 0 ? ret1 : ret2;
diff --git a/lasso/id-ff/name_identifier_mapping.c b/lasso/id-ff/name_identifier_mapping.c
index 58027cfb..91497e59 100644
--- a/lasso/id-ff/name_identifier_mapping.c
+++ b/lasso/id-ff/name_identifier_mapping.c
@@ -230,8 +230,11 @@ lasso_name_identifier_mapping_process_request_msg(LassoNameIdentifierMapping *ma
}
/* verify signature */
+#if 0 /* FIXME: signature is broken in name identifier mapping profile */
profile->signature_status = lasso_provider_verify_signature(
remote_provider, request_msg, "RequestID", format);
+#endif
+ profile->signature_status = 0;
profile->http_request_method = LASSO_HTTP_METHOD_SOAP;
@@ -272,7 +275,10 @@ lasso_name_identifier_mapping_process_response_msg(LassoNameIdentifierMapping *m
}
/* verify signature */
+#if 0 /* FIXME: signature is broken in name identifier mapping profile */
rc = lasso_provider_verify_signature(remote_provider, response_msg, "ResponseID", format);
+#endif
+ rc = 0;
statusCodeValue = LASSO_LIB_NAME_IDENTIFIER_MAPPING_RESPONSE(
profile->response)->Status->StatusCode->Value;
diff --git a/lasso/id-ff/provider.c b/lasso/id-ff/provider.c
index 01527778..f1276299 100644
--- a/lasso/id-ff/provider.c
+++ b/lasso/id-ff/provider.c
@@ -26,6 +26,7 @@
#include <libxml/xpath.h>
#include <libxml/xpathInternals.h>
+#include <xmlsec/base64.h>
#include <xmlsec/xmldsig.h>
#include <xmlsec/xmltree.h>
@@ -504,79 +505,113 @@ lasso_provider_new_from_dump(const gchar *dump)
int lasso_provider_verify_signature(LassoProvider *provider,
const char *message, const char *id_attr_name, LassoMessageFormat format)
{
+ /* this duplicates some code from lasso_node_init_from_message;
+ * reflection about code reuse is under way...
+ */
+ char *msg;
+ xmlDoc *doc;
+ xmlNode *xmlnode = NULL, *sign, *x509data;
+ xmlSecKeysMngr *keys_mngr = NULL;
+ xmlSecDSigCtx *dsigCtx;
+ lassoPemFileType public_key_file_type;
+ int rc;
+
+ msg = (char*)message;
+
if (format == LASSO_MESSAGE_FORMAT_ERROR)
return -2;
if (format == LASSO_MESSAGE_FORMAT_UNKNOWN)
return -2;
+ if (format == LASSO_MESSAGE_FORMAT_QUERY) {
+ return lasso_query_verify_signature(message, provider->public_key);
+ }
+
if (format == LASSO_MESSAGE_FORMAT_BASE64) {
- /* XXX: checking signature in base64 mode (probably going back
- * to XML mode)*/
- return 0;
+ msg = g_malloc(strlen(message));
+ rc = xmlSecBase64Decode(message, msg, strlen(message));
+ if (rc < 0) {
+ g_free(msg);
+ return -3;
+ }
}
- if (format == LASSO_MESSAGE_FORMAT_XML || format == LASSO_MESSAGE_FORMAT_SOAP) {
- xmlDoc *doc;
- xmlNode *xmlnode, *sign, *x509data;
- xmlSecKeysMngr *keys_mngr = NULL;
- xmlSecDSigCtx *dsigCtx;
- lassoPemFileType public_key_file_type;
+ doc = xmlParseMemory(msg, strlen(msg));
+ if (format == LASSO_MESSAGE_FORMAT_BASE64) {
+ g_free(msg);
+ msg = NULL;
+ }
- return 0; /* XXX: enable back signature check on xml messages */
+ if (format == LASSO_MESSAGE_FORMAT_SOAP) {
+ xmlXPathContext *xpathCtx = NULL;
+ xmlXPathObject *xpathObj;
- doc = xmlParseMemory(message, strlen(message));
- xmlnode = xmlDocGetRootElement(doc);
- sign = xmlSecFindNode(xmlnode, xmlSecNodeSignature, xmlSecDSigNs);
- if (sign == NULL) {
- xmlFreeDoc(doc);
- return LASSO_DS_ERROR_SIGNATURE_NOT_FOUND;
+ xpathCtx = xmlXPathNewContext(doc);
+ xmlXPathRegisterNs(xpathCtx, "s", LASSO_SOAP_ENV_HREF);
+ xpathObj = xmlXPathEvalExpression("//s:Body/*", xpathCtx);
+ if (xpathObj->nodesetval && xpathObj->nodesetval->nodeNr ) {
+ xmlnode = xpathObj->nodesetval->nodeTab[0];
}
+ xmlXPathFreeObject(xpathObj);
+ xmlXPathFreeContext(xpathCtx);
+ if (xmlnode == NULL)
+ return -4;
+ } else {
+ xmlnode = xmlDocGetRootElement(doc);
+ }
- x509data = xmlSecFindNode(xmlnode, xmlSecNodeX509Data, xmlSecDSigNs);
- if (x509data != NULL && provider->ca_cert_chain != NULL) {
- keys_mngr = lasso_load_certs_from_pem_certs_chain_file(
- provider->ca_cert_chain);
- if (keys_mngr == NULL)
- return LASSO_DS_ERROR_CA_CERT_CHAIN_LOAD_FAILED;
+ if (id_attr_name) {
+ char *id_value = xmlGetProp(xmlnode, id_attr_name);
+ xmlAttr *id_attr = xmlHasProp(xmlnode, id_attr_name);
+ if (id_value) {
+ xmlAddID(NULL, doc, id_value, id_attr);
+ xmlFree(id_value);
}
+ }
+
+ sign = xmlSecFindNode(xmlnode, xmlSecNodeSignature, xmlSecDSigNs);
+ if (sign == NULL) {
+ xmlFreeDoc(doc);
+ return LASSO_DS_ERROR_SIGNATURE_NOT_FOUND;
+ }
+
+ x509data = xmlSecFindNode(xmlnode, xmlSecNodeX509Data, xmlSecDSigNs);
+ if (x509data != NULL && provider->ca_cert_chain != NULL) {
+ keys_mngr = lasso_load_certs_from_pem_certs_chain_file(
+ provider->ca_cert_chain);
+ if (keys_mngr == NULL)
+ return LASSO_DS_ERROR_CA_CERT_CHAIN_LOAD_FAILED;
+ }
- dsigCtx = xmlSecDSigCtxCreate(keys_mngr);
- if (keys_mngr == NULL) {
- if (provider->public_key) {
- public_key_file_type = lasso_get_pem_file_type(
+ dsigCtx = xmlSecDSigCtxCreate(keys_mngr);
+ if (keys_mngr == NULL) {
+ if (provider->public_key) {
+ public_key_file_type = lasso_get_pem_file_type(
+ provider->public_key);
+ if (public_key_file_type == LASSO_PEM_FILE_TYPE_CERT) {
+ /* public_key_file is a certificate file
+ * => get public key in it */
+ dsigCtx->signKey = lasso_get_public_key_from_pem_cert_file(
provider->public_key);
- if (public_key_file_type == LASSO_PEM_FILE_TYPE_CERT) {
- /* public_key_file is a certificate file
- * => get public key in it */
- dsigCtx->signKey = lasso_get_public_key_from_pem_cert_file(
- provider->public_key);
- } else {
- /* load public key */
- dsigCtx->signKey = xmlSecCryptoAppKeyLoad(
- provider->public_key,
- xmlSecKeyDataFormatPem,
- NULL, NULL, NULL);
- }
- }
- if (dsigCtx->signKey == NULL) {
- return LASSO_DS_ERROR_PUBLIC_KEY_LOAD_FAILED;
+ } else {
+ /* load public key */
+ dsigCtx->signKey = xmlSecCryptoAppKeyLoad(
+ provider->public_key,
+ xmlSecKeyDataFormatPem,
+ NULL, NULL, NULL);
}
}
-
- if (xmlSecDSigCtxVerify(dsigCtx, sign) < 0) {
- return LASSO_DS_ERROR_SIGNATURE_VERIFICATION_FAILED;
+ if (dsigCtx->signKey == NULL) {
+ return LASSO_DS_ERROR_PUBLIC_KEY_LOAD_FAILED;
}
- if (dsigCtx->status != xmlSecDSigStatusSucceeded) {
- return LASSO_DS_ERROR_INVALID_SIGNATURE;
- }
-
- return 0;
}
- if (format == LASSO_MESSAGE_FORMAT_QUERY) {
- return lasso_query_verify_signature(message, provider->public_key);
+ if (xmlSecDSigCtxVerify(dsigCtx, sign) < 0) {
+ return LASSO_DS_ERROR_SIGNATURE_VERIFICATION_FAILED;
+ }
+ if (dsigCtx->status != xmlSecDSigStatusSucceeded) {
+ return LASSO_DS_ERROR_INVALID_SIGNATURE;
}
- return -1;
+ return 0;
}
-
diff --git a/lasso/xml/xml.c b/lasso/xml/xml.c
index af4cb6b1..a04c3ffa 100644
--- a/lasso/xml/xml.c
+++ b/lasso/xml/xml.c
@@ -111,22 +111,103 @@ lasso_node_destroy(LassoNode *node)
}
}
+static xmlNode*
+lasso_node_export_to_signed_xmlnode(LassoNode *node,
+ const char *private_key_file, const char *certificate_file)
+{
+ xmlDoc *doc;
+ xmlNode *message, *sign_tmpl;
+ xmlSecDSigCtx *dsig_ctx;
+ char *id_attr_name = NULL;
+
+ message = lasso_node_get_xmlNode(node);
+
+ sign_tmpl = xmlSecFindNode(message, xmlSecNodeSignature, xmlSecDSigNs);
+ if (sign_tmpl && private_key_file) {
+ doc = xmlNewDoc("1.0");
+ xmlDocSetRootElement(doc, message);
+ xmlSetTreeDoc(sign_tmpl, doc);
+ if (LASSO_NODE_GET_CLASS(node)->get_sign_attr_name)
+ id_attr_name = LASSO_NODE_GET_CLASS(node)->get_sign_attr_name();
+ if (id_attr_name) {
+ char *id_value = xmlGetProp(message, id_attr_name);
+ xmlAttr *id_attr = xmlHasProp(message, id_attr_name);
+ if (id_value) {
+ xmlAddID(NULL, doc, id_value, id_attr);
+ xmlFree(id_value);
+ }
+ }
+
+ dsig_ctx = xmlSecDSigCtxCreate(NULL);
+ dsig_ctx->signKey = xmlSecCryptoAppKeyLoad(private_key_file,
+ xmlSecKeyDataFormatPem,
+ NULL, NULL, NULL);
+ if (dsig_ctx->signKey == NULL) {
+ /* XXX: file existence should actually be tested on
+ * LassoServer creation */
+ message(G_LOG_LEVEL_CRITICAL,
+ lasso_strerror(LASSO_DS_ERROR_PRIVATE_KEY_LOAD_FAILED),
+ private_key_file);
+ xmlSecDSigCtxDestroy(dsig_ctx);
+ return NULL;
+ }
+ if (certificate_file != NULL && certificate_file[0] != 0) {
+ if (xmlSecCryptoAppKeyCertLoad(dsig_ctx->signKey, certificate_file,
+ xmlSecKeyDataFormatPem) < 0) {
+ message(G_LOG_LEVEL_CRITICAL,
+ lasso_strerror(LASSO_DS_ERROR_CERTIFICATE_LOAD_FAILED),
+ certificate_file);
+ xmlSecDSigCtxDestroy(dsig_ctx);
+ return NULL;
+ }
+ }
+ if (xmlSecDSigCtxSign(dsig_ctx, sign_tmpl) < 0) {
+ message(G_LOG_LEVEL_CRITICAL,
+ lasso_strerror(LASSO_DS_ERROR_SIGNATURE_FAILED),
+ message->name);
+ xmlSecDSigCtxDestroy(dsig_ctx);
+ return NULL;
+ }
+ xmlSecDSigCtxDestroy(dsig_ctx);
+ xmlUnlinkNode(message);
+ xmlFreeDoc(doc);
+ }
+
+ return message;
+}
+
+
/**
* lasso_node_export_to_base64:
* @node: a LassoNode
+ * @private_key_file: path to private key for signature
+ * @certificate_file: path to certificate for signature
*
* Base64 XML dump
*
* Return value: a Base64 encoded export of the LassoNode
**/
char*
-lasso_node_export_to_base64(LassoNode *node)
+lasso_node_export_to_base64(LassoNode *node,
+ const char *private_key_file, const char *certificate_file)
{
- char *buffer, *ret;
+ xmlNode *message;
+ xmlOutputBufferPtr buf;
+ xmlCharEncodingHandlerPtr handler = NULL;
+ char *buffer;
+ char *ret;
+
+ message = lasso_node_export_to_signed_xmlnode(node, private_key_file, certificate_file);
+
+ handler = xmlFindCharEncodingHandler("utf-8");
+ buf = xmlAllocOutputBuffer(handler);
+ xmlNodeDumpOutput(buf, NULL, message, 0, 0, "utf-8");
+ xmlOutputBufferFlush(buf);
+ buffer = buf->conv ? buf->conv->content : buf->buffer->content;
- buffer = lasso_node_dump(node, "utf-8", 0);
ret = xmlSecBase64Encode(buffer, strlen(buffer), 0);
- g_free(buffer);
+ xmlOutputBufferClose(buf);
+
return ret;
}
@@ -173,68 +254,14 @@ char*
lasso_node_export_to_soap(LassoNode *node,
const char *private_key_file, const char *certificate_file)
{
- xmlDoc *doc;
- xmlNode *envelope, *body, *message, *sign_tmpl;
+ xmlNode *envelope, *body, *message;
xmlOutputBuffer *buf;
xmlCharEncodingHandler *handler;
- xmlSecDSigCtx *dsig_ctx;
char *ret;
- char *id_attr_name = NULL;
g_return_val_if_fail (LASSO_IS_NODE(node), NULL);
- message = lasso_node_get_xmlNode(node);
-
- sign_tmpl = xmlSecFindNode(message, xmlSecNodeSignature, xmlSecDSigNs);
- if (sign_tmpl && private_key_file) {
- doc = xmlNewDoc("1.0");
- xmlDocSetRootElement(doc, message);
- xmlSetTreeDoc(sign_tmpl, doc);
- if (LASSO_NODE_GET_CLASS(node)->get_sign_attr_name)
- id_attr_name = LASSO_NODE_GET_CLASS(node)->get_sign_attr_name();
- if (id_attr_name) {
- char *id_value = xmlGetProp(message, id_attr_name);
- xmlAttr *id_attr = xmlHasProp(message, id_attr_name);
- if (id_value) {
- xmlAddID(NULL, doc, id_value, id_attr);
- xmlFree(id_value);
- }
- }
-
- dsig_ctx = xmlSecDSigCtxCreate(NULL);
- dsig_ctx->signKey = xmlSecCryptoAppKeyLoad(private_key_file,
- xmlSecKeyDataFormatPem,
- NULL, NULL, NULL);
- if (dsig_ctx->signKey == NULL) {
- /* XXX: file existence should actually be tested on
- * LassoServer creation */
- message(G_LOG_LEVEL_CRITICAL,
- lasso_strerror(LASSO_DS_ERROR_PRIVATE_KEY_LOAD_FAILED),
- private_key_file);
- xmlSecDSigCtxDestroy(dsig_ctx);
- return NULL;
- }
- if (certificate_file != NULL && certificate_file[0] != 0) {
- if (xmlSecCryptoAppKeyCertLoad(dsig_ctx->signKey, certificate_file,
- xmlSecKeyDataFormatPem) < 0) {
- message(G_LOG_LEVEL_CRITICAL,
- lasso_strerror(LASSO_DS_ERROR_CERTIFICATE_LOAD_FAILED),
- certificate_file);
- xmlSecDSigCtxDestroy(dsig_ctx);
- return NULL;
- }
- }
- if (xmlSecDSigCtxSign(dsig_ctx, sign_tmpl) < 0) {
- message(G_LOG_LEVEL_CRITICAL,
- lasso_strerror(LASSO_DS_ERROR_SIGNATURE_FAILED),
- message->name);
- xmlSecDSigCtxDestroy(dsig_ctx);
- return NULL;
- }
- xmlSecDSigCtxDestroy(dsig_ctx);
- xmlUnlinkNode(message);
- xmlFreeDoc(doc);
- }
+ message = lasso_node_export_to_signed_xmlnode(node, private_key_file, certificate_file);
envelope = xmlNewNode(NULL, "Envelope");
xmlSetNs(envelope, xmlNewNs(envelope, LASSO_SOAP_ENV_HREF, LASSO_SOAP_ENV_PREFIX));
@@ -244,7 +271,7 @@ lasso_node_export_to_soap(LassoNode *node,
handler = xmlFindCharEncodingHandler("utf-8");
buf = xmlAllocOutputBuffer(handler);
- xmlNodeDumpOutput(buf, NULL, envelope, 0, 1, "utf-8");
+ xmlNodeDumpOutput(buf, NULL, envelope, 0, 0, "utf-8");
xmlOutputBufferFlush(buf);
ret = g_strdup( buf->conv ? buf->conv->content : buf->buffer->content );
xmlOutputBufferClose(buf);
diff --git a/lasso/xml/xml.h b/lasso/xml/xml.h
index 1c2f36f7..7dedb894 100644
--- a/lasso/xml/xml.h
+++ b/lasso/xml/xml.h
@@ -99,7 +99,8 @@ LASSO_EXPORT LassoNode* lasso_node_new_from_xmlNode(xmlNode* node);
LASSO_EXPORT void lasso_node_destroy(LassoNode *node);
LASSO_EXPORT char* lasso_node_dump(LassoNode *node, const char *encoding, int format);
LASSO_EXPORT char* lasso_node_build_query(LassoNode *node);
-LASSO_EXPORT char* lasso_node_export_to_base64(LassoNode *node);
+LASSO_EXPORT char* lasso_node_export_to_base64(LassoNode *node,
+ const char *private_key_file, const char *certificate_file);
LASSO_EXPORT char* lasso_node_export_to_query(LassoNode *node,
lassoSignatureMethod sign_method, const char *private_key_file);