diff options
| author | Damien Laniel <dlaniel@entrouvert.com> | 2006-11-15 18:56:34 +0000 |
|---|---|---|
| committer | Damien Laniel <dlaniel@entrouvert.com> | 2006-11-15 18:56:34 +0000 |
| commit | 8a331ac747c43560857a8c918682b5650e4e1a1f (patch) | |
| tree | f2526a68298c3b827eafd0a290e1a484d3c0eb06 | |
| parent | 0f11bb2491fd38e5b19484a6367e2d98452579a4 (diff) | |
Decryption of EncryptedID in Assertion
| -rw-r--r-- | lasso/id-ff/server.c | 5 | ||||
| -rw-r--r-- | lasso/id-ff/serverprivate.h | 6 | ||||
| -rw-r--r-- | lasso/saml-2.0/login.c | 28 | ||||
| -rw-r--r-- | lasso/xml/xml.c | 97 | ||||
| -rw-r--r-- | lasso/xml/xml.h | 1 |
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); |
