summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDamien Laniel <dlaniel@entrouvert.com>2006-11-15 18:56:34 +0000
committerDamien Laniel <dlaniel@entrouvert.com>2006-11-15 18:56:34 +0000
commit8a331ac747c43560857a8c918682b5650e4e1a1f (patch)
treef2526a68298c3b827eafd0a290e1a484d3c0eb06
parent0f11bb2491fd38e5b19484a6367e2d98452579a4 (diff)
Decryption of EncryptedID in Assertion
-rw-r--r--lasso/id-ff/server.c5
-rw-r--r--lasso/id-ff/serverprivate.h6
-rw-r--r--lasso/saml-2.0/login.c28
-rw-r--r--lasso/xml/xml.c97
-rw-r--r--lasso/xml/xml.h1
5 files changed, 126 insertions, 11 deletions
diff --git a/lasso/id-ff/server.c b/lasso/id-ff/server.c
index 3f5d00db..1b25c3c4 100644
--- a/lasso/id-ff/server.c
+++ b/lasso/id-ff/server.c
@@ -30,11 +30,6 @@
#include <lasso/id-ff/providerprivate.h>
#include <lasso/id-ff/serverprivate.h>
-struct _LassoServerPrivate
-{
- gboolean dispose_has_run;
- xmlSecKey *encryption_private_key;
-};
/*****************************************************************************/
/* public methods */
diff --git a/lasso/id-ff/serverprivate.h b/lasso/id-ff/serverprivate.h
index c18d0c8b..1e9aa8f9 100644
--- a/lasso/id-ff/serverprivate.h
+++ b/lasso/id-ff/serverprivate.h
@@ -29,6 +29,12 @@
extern "C" {
#endif /* __cplusplus */
+struct _LassoServerPrivate
+{
+ gboolean dispose_has_run;
+ xmlSecKey *encryption_private_key;
+};
+
gchar* lasso_server_get_first_providerID(LassoServer *server);
gchar* lasso_server_get_providerID_from_hash(LassoServer *server, gchar *b64_hash);
diff --git a/lasso/saml-2.0/login.c b/lasso/saml-2.0/login.c
index 5e619101..f6f212c7 100644
--- a/lasso/saml-2.0/login.c
+++ b/lasso/saml-2.0/login.c
@@ -31,6 +31,7 @@
#include <lasso/saml-2.0/federationprivate.h>
#include <lasso/id-ff/providerprivate.h>
+#include <lasso/id-ff/serverprivate.h>
#include <lasso/id-ff/login.h>
#include <lasso/id-ff/identityprivate.h>
#include <lasso/id-ff/sessionprivate.h>
@@ -892,6 +893,10 @@ lasso_saml20_login_process_response_status_and_assertion(LassoLogin *login)
if (LASSO_SAMLP2_RESPONSE(response)->Assertion) {
LassoProfile *profile = LASSO_PROFILE(login);
LassoSaml2Assertion *assertion = LASSO_SAMLP2_RESPONSE(response)->Assertion->data;
+ LassoNode *id_node = NULL;
+ xmlNode *encrypted_data = NULL;
+ xmlSecKey *encryption_private_key = NULL;
+
if (profile->remote_providerID == NULL)
return LASSO_PROFILE_ERROR_MISSING_REMOTE_PROVIDERID;
idp = g_hash_table_lookup(profile->server->providers, profile->remote_providerID);
@@ -905,8 +910,29 @@ lasso_saml20_login_process_response_status_and_assertion(LassoLogin *login)
return LASSO_PROFILE_ERROR_MISSING_SUBJECT;
}
- profile->nameIdentifier = g_object_ref(assertion->Subject->NameID);
+ if (assertion->Subject->NameID != NULL) {
+ id_node = g_object_ref(assertion->Subject->NameID);
+ if (id_node != NULL) {
+ profile->nameIdentifier = id_node;
+ return ret;
+ }
+ }
+ id_node = g_object_ref(assertion->Subject->EncryptedID);
+ if (id_node == NULL) {
+ return LASSO_PROFILE_ERROR_MISSING_NAME_IDENTIFIER;
+ }
+
+ encrypted_data = LASSO_SAML2_ENCRYPTED_ELEMENT(id_node)->EncryptedData;
+ encryption_private_key = profile->server->private_data->encryption_private_key;
+ if (encrypted_data != NULL && encryption_private_key != NULL) {
+ LASSO_PROFILE(login)->nameIdentifier =
+ lasso_node_decrypt(encrypted_data, encryption_private_key);
+ assertion->Subject->NameID =
+ LASSO_SAML2_NAME_ID(LASSO_PROFILE(login)->nameIdentifier);
+ assertion->Subject->EncryptedID = NULL;
+ }
+
if (LASSO_PROFILE(login)->nameIdentifier == NULL)
return LASSO_PROFILE_ERROR_MISSING_NAME_IDENTIFIER;
}
diff --git a/lasso/xml/xml.c b/lasso/xml/xml.c
index f906fd5a..52efef7a 100644
--- a/lasso/xml/xml.c
+++ b/lasso/xml/xml.c
@@ -396,6 +396,17 @@ lasso_node_export_to_soap(LassoNode *node)
return ret;
}
+/**
+ * lasso_node_encrypt:
+ * @lasso_node: a #LassoNode to encrypt
+ * @encryption_public_key : RSA public key the node will be encrypted with
+ *
+ * Generate a DES key and encrypt it with the RSA key.
+ * Then encrypt @lasso_node with the DES key.
+ *
+ * Return value: an xmlNode which is the @node in an encrypted fashion.
+ * It must be freed by the caller.
+ **/
xmlNode*
lasso_node_encrypt(LassoNode *lasso_node, xmlSecKey *encryption_public_key)
{
@@ -442,7 +453,7 @@ lasso_node_encrypt(LassoNode *lasso_node, xmlSecKey *encryption_public_key)
return NULL;
}
- /* add key to keys manager, from now on keys manager is responsible
+ /* add key to keys manager, from now on keys manager is responsible
* for destroying key
*/
if (xmlSecCryptoAppDefaultKeysMngrAdoptKey(key_manager, encryption_public_key) < 0) {
@@ -499,15 +510,13 @@ lasso_node_encrypt(LassoNode *lasso_node, xmlSecKey *encryption_public_key)
}
/* encrypt the data */
- if(xmlSecEncCtxXmlEncrypt(enc_ctx, encrypted_data_node, orig_node) < 0) {
+ if (xmlSecEncCtxXmlEncrypt(enc_ctx, encrypted_data_node, orig_node) < 0) {
message(G_LOG_LEVEL_WARNING, "Encryption failed");
return NULL;
}
/* cleanup */
- if(enc_ctx != NULL) {
- xmlSecEncCtxDestroy(enc_ctx);
- }
+ xmlSecEncCtxDestroy(enc_ctx);
/* if (encrypted_data_node != NULL) { */
/* xmlFreeNode(encrypted_data_node); */
@@ -522,6 +531,84 @@ lasso_node_encrypt(LassoNode *lasso_node, xmlSecKey *encryption_public_key)
/**
+ * lasso_node_decrypt:
+ * @xml_node: an EncryptedData #xmlNode to decrypt
+ * @encryption_private_key : RSA private key to decrypt the node
+ *
+ * Decrypt a DES EncryptedKey with the RSA key.
+ * Then decrypt @xml_node with the DES key.
+ *
+ * Return value: a LassoNode which is the decrypted @xml_node.
+ * It must be freed by the caller.
+ **/
+LassoNode*
+lasso_node_decrypt(xmlNode* xml_node, xmlSecKey *encryption_private_key)
+{
+ xmlDocPtr doc = NULL;
+ xmlSecEncCtxPtr encCtx = NULL;
+ xmlSecKeyPtr des_key = NULL;
+ xmlSecBufferPtr key_buffer;
+ LassoNode *decrypted_node;
+
+ /* Create a document to contain the node to decrypt */
+ doc = xmlNewDoc((xmlChar*)"1.0");
+ xmlDocSetRootElement(doc, xml_node);
+
+ xmlNode *t = xml_node;
+ while (t && strcmp((char*)t->name, "EncryptedKey") != 0 ) {
+ if (strcmp((char*)t->name, "EncryptedData") == 0 ||
+ strcmp((char*)t->name, "KeyInfo") == 0)
+ t = t->children;
+ t = t->next;
+ }
+ if (t == NULL)
+ return NULL;
+
+ /* create encryption context, with RSA key */
+ encCtx = xmlSecEncCtxCreate(NULL);
+ if (encCtx == NULL) {
+ message(G_LOG_LEVEL_WARNING, "Failed to create encryption context");
+ return NULL;
+ }
+ encCtx->encKey = encryption_private_key;
+ encCtx->mode = xmlEncCtxModeEncryptedKey;
+
+ /* decrypt the EncryptedKey */
+ key_buffer = xmlSecEncCtxDecryptToBuffer(encCtx, t);
+ if (key_buffer != NULL) {
+ des_key = xmlSecKeyReadBuffer(xmlSecKeyDataDesId, key_buffer);
+ }
+ if (des_key == NULL) {
+ message(G_LOG_LEVEL_WARNING, "Decryption failed");
+ return NULL;
+ }
+
+ /* create encryption context, with DES key */
+ xmlSecEncCtxDestroy(encCtx);
+ encCtx = xmlSecEncCtxCreate(NULL);
+ if (encCtx == NULL) {
+ message(G_LOG_LEVEL_WARNING, "Failed to create encryption context");
+ return NULL;
+ }
+ encCtx->encKey = des_key;
+ encCtx->mode = xmlEncCtxModeEncryptedData;
+
+ /* decrypt the EncryptedData */
+ if ((xmlSecEncCtxDecrypt(encCtx, xml_node) < 0) || (encCtx->result == NULL)) {
+ message(G_LOG_LEVEL_WARNING, "Decryption failed");
+ return NULL;
+ }
+
+ decrypted_node = lasso_node_new_from_xmlNode(doc->children);
+
+ /* cleanup */
+ xmlSecEncCtxDestroy(encCtx);
+ xmlFreeDoc(doc);
+
+ return decrypted_node;
+}
+
+/**
* lasso_node_init_from_query:
* @node: a #LassoNode (or derived class)
* @query: the query string
diff --git a/lasso/xml/xml.h b/lasso/xml/xml.h
index 330ac956..f52a1982 100644
--- a/lasso/xml/xml.h
+++ b/lasso/xml/xml.h
@@ -146,6 +146,7 @@ LASSO_EXPORT char* lasso_node_export_to_ecp_soap_response(LassoNode *node,
const char *assertionConsumerURL);
LASSO_EXPORT xmlNode* lasso_node_encrypt(LassoNode *lasso_node, xmlSecKey *encryption_public_key);
+LASSO_EXPORT LassoNode* lasso_node_decrypt(xmlNode* xml_node, xmlSecKey *encryption_private_key);
LASSO_EXPORT xmlNode* lasso_node_get_xmlNode(LassoNode *node, gboolean lasso_dump);