[core] introduce the LassoSignatureContext context, to pass around signature parameters
This structure is used to pass around the signature algorithm and the signature key.
This commit is contained in:
parent
71721b370c
commit
cd017964d0
|
@ -30,7 +30,7 @@ extern "C" {
|
||||||
|
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
#include "profile.h"
|
#include "./profile.h"
|
||||||
|
|
||||||
struct _LassoProfilePrivate
|
struct _LassoProfilePrivate
|
||||||
{
|
{
|
||||||
|
|
|
@ -896,6 +896,7 @@ instance_init(LassoProvider *provider)
|
||||||
provider->private_data->encryption_public_keys = NULL;
|
provider->private_data->encryption_public_keys = NULL;
|
||||||
provider->private_data->encryption_mode = LASSO_ENCRYPTION_MODE_NONE;
|
provider->private_data->encryption_mode = LASSO_ENCRYPTION_MODE_NONE;
|
||||||
provider->private_data->encryption_sym_key_type = LASSO_ENCRYPTION_SYM_KEY_TYPE_AES_128;
|
provider->private_data->encryption_sym_key_type = LASSO_ENCRYPTION_SYM_KEY_TYPE_AES_128;
|
||||||
|
provider->private_data->signature_context = LASSO_SIGNATURE_CONTEXT_NONE;
|
||||||
|
|
||||||
/* no value_destroy_func since it shouldn't destroy the GList on insert */
|
/* no value_destroy_func since it shouldn't destroy the GList on insert */
|
||||||
provider->private_data->Descriptors = g_hash_table_new_full(
|
provider->private_data->Descriptors = g_hash_table_new_full(
|
||||||
|
@ -1239,7 +1240,8 @@ lasso_provider_load_public_key(LassoProvider *provider, LassoPublicKeyType publi
|
||||||
}
|
}
|
||||||
|
|
||||||
if (public_key != NULL) {
|
if (public_key != NULL) {
|
||||||
xmlSecKey *key = lasso_xmlsec_load_private_key(public_key, NULL);
|
xmlSecKey *key = lasso_xmlsec_load_private_key(public_key, NULL,
|
||||||
|
LASSO_SIGNATURE_METHOD_RSA_SHA1, NULL);
|
||||||
if (key) {
|
if (key) {
|
||||||
lasso_list_add_new_sec_key(keys, key);
|
lasso_list_add_new_sec_key(keys, key);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -25,10 +25,14 @@
|
||||||
#ifndef __LASSO_PROVIDER_PRIVATE_H__
|
#ifndef __LASSO_PROVIDER_PRIVATE_H__
|
||||||
#define __LASSO_PROVIDER_PRIVATE_H__
|
#define __LASSO_PROVIDER_PRIVATE_H__
|
||||||
|
|
||||||
|
#include <./serverprivate.h>
|
||||||
|
#include "../xml/private.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* LassoPublicKeyType:
|
* LassoPublicKeyType:
|
||||||
* @LASSO_PUBLIC_KEY_SIGNING: Signing public key
|
* @LASSO_PUBLIC_KEY_SIGNING: Signing public key
|
||||||
|
@ -78,6 +82,7 @@ struct _LassoProviderPrivate
|
||||||
char *valid_until;
|
char *valid_until;
|
||||||
char *cache_duration;
|
char *cache_duration;
|
||||||
GList *endpoints; /* of EndpointType_s */
|
GList *endpoints; /* of EndpointType_s */
|
||||||
|
LassoSignatureContext signature_context;
|
||||||
};
|
};
|
||||||
|
|
||||||
gboolean lasso_provider_load_metadata(LassoProvider *provider, const gchar *metadata);
|
gboolean lasso_provider_load_metadata(LassoProvider *provider, const gchar *metadata);
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
|
|
||||||
#include "../xml/private.h"
|
#include "../xml/private.h"
|
||||||
#include <xmlsec/base64.h>
|
#include <xmlsec/base64.h>
|
||||||
|
#include <xmlsec/xmltree.h>
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
|
@ -46,6 +47,9 @@
|
||||||
#include "../id-wsf-2.0/serverprivate.h"
|
#include "../id-wsf-2.0/serverprivate.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define RSA_SHA1 "RSA_SHA1"
|
||||||
|
#define DSA_SHA1 "DSA_SHA1"
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* public methods */
|
/* public methods */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -79,9 +83,7 @@ lasso_server_add_provider_helper(LassoServer *server, LassoProviderRole role,
|
||||||
return LASSO_SERVER_ERROR_ADD_PROVIDER_PROTOCOL_MISMATCH;
|
return LASSO_SERVER_ERROR_ADD_PROVIDER_PROTOCOL_MISMATCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_hash_table_insert(server->providers, g_strdup(provider->ProviderID), provider);
|
return lasso_server_add_provider2(server, provider);
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -200,7 +202,8 @@ lasso_server_set_encryption_private_key_with_password(LassoServer *server,
|
||||||
const gchar *filename_or_buffer, const gchar *password)
|
const gchar *filename_or_buffer, const gchar *password)
|
||||||
{
|
{
|
||||||
if (filename_or_buffer) {
|
if (filename_or_buffer) {
|
||||||
xmlSecKey *key = lasso_xmlsec_load_private_key(filename_or_buffer, password);
|
xmlSecKey *key = lasso_xmlsec_load_private_key(filename_or_buffer, password,
|
||||||
|
server->signature_method, NULL);
|
||||||
if (! key || ! (xmlSecKeyGetType(key) & xmlSecKeyDataTypePrivate)) {
|
if (! key || ! (xmlSecKeyGetType(key) & xmlSecKeyDataTypePrivate)) {
|
||||||
return LASSO_SERVER_ERROR_SET_ENCRYPTION_PRIVATE_KEY_FAILED;
|
return LASSO_SERVER_ERROR_SET_ENCRYPTION_PRIVATE_KEY_FAILED;
|
||||||
}
|
}
|
||||||
|
@ -271,10 +274,12 @@ get_xmlNode(LassoNode *node, gboolean lasso_dump)
|
||||||
{
|
{
|
||||||
LassoServer *server = LASSO_SERVER(node);
|
LassoServer *server = LASSO_SERVER(node);
|
||||||
char *signature_methods[] = { NULL, "RSA_SHA1", "DSA_SHA1"};
|
char *signature_methods[] = { NULL, "RSA_SHA1", "DSA_SHA1"};
|
||||||
xmlNode *xmlnode;
|
xmlNode *xmlnode = NULL, *ret_xmlnode = NULL;
|
||||||
|
|
||||||
xmlnode = parent_class->get_xmlNode(node, lasso_dump);
|
xmlnode = parent_class->get_xmlNode(node, lasso_dump);
|
||||||
xmlSetProp(xmlnode, (xmlChar*)"ServerDumpVersion", (xmlChar*)"2");
|
xmlSetProp(xmlnode, (xmlChar*)"ServerDumpVersion", (xmlChar*)"2");
|
||||||
|
if (server->signature_method >= G_N_ELEMENTS(signature_methods))
|
||||||
|
goto cleanup;
|
||||||
xmlSetProp(xmlnode, (xmlChar*)"SignatureMethod",
|
xmlSetProp(xmlnode, (xmlChar*)"SignatureMethod",
|
||||||
(xmlChar*)signature_methods[server->signature_method]);
|
(xmlChar*)signature_methods[server->signature_method]);
|
||||||
|
|
||||||
|
@ -292,8 +297,11 @@ get_xmlNode(LassoNode *node, gboolean lasso_dump)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
xmlCleanNs(xmlnode);
|
xmlCleanNs(xmlnode);
|
||||||
|
lasso_transfer_xml_node(ret_xmlnode, xmlnode);
|
||||||
|
|
||||||
return xmlnode;
|
cleanup:
|
||||||
|
lasso_release_xml_node(xmlnode);
|
||||||
|
return ret_xmlnode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -315,41 +323,39 @@ init_from_xml(LassoNode *node, xmlNode *xmlnode)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
s = xmlGetProp(xmlnode, (xmlChar*)"SignatureMethod");
|
s = xmlGetProp(xmlnode, (xmlChar*)"SignatureMethod");
|
||||||
if (s && strcmp((char*)s, "RSA_SHA1") == 0)
|
if (lasso_strisequal((char*) s, RSA_SHA1))
|
||||||
server->signature_method = LASSO_SIGNATURE_METHOD_RSA_SHA1;
|
server->signature_method = LASSO_SIGNATURE_METHOD_RSA_SHA1;
|
||||||
if (s && strcmp((char*)s, "DSA_SHA1") == 0)
|
else if (lasso_strisequal((char*) s, DSA_SHA1))
|
||||||
server->signature_method = LASSO_SIGNATURE_METHOD_DSA_SHA1;
|
server->signature_method = LASSO_SIGNATURE_METHOD_DSA_SHA1;
|
||||||
if (s)
|
else {
|
||||||
xmlFree(s);
|
warning("Unable to rebuild a LassoServer object from XML, bad SignatureMethod: %s",
|
||||||
|
s);
|
||||||
|
goto_cleanup_with_rc(LASSO_XML_ERROR_OBJECT_CONSTRUCTION_FAILED);
|
||||||
|
}
|
||||||
|
|
||||||
t = xmlnode->children;
|
t = xmlSecGetNextElementNode(xmlnode->children);
|
||||||
while (t) {
|
while (t) {
|
||||||
xmlNode *t2 = t->children;
|
|
||||||
|
|
||||||
if (t->type != XML_ELEMENT_NODE) {
|
|
||||||
t = t->next;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Providers */
|
/* Providers */
|
||||||
if (strcmp((char*)t->name, "Providers") == 0) {
|
if (strcmp((char*)t->name, "Providers") == 0) {
|
||||||
|
xmlNode *t2 = xmlSecGetNextElementNode(t->children);
|
||||||
|
|
||||||
while (t2) {
|
while (t2) {
|
||||||
LassoProvider *p;
|
LassoProvider *p;
|
||||||
if (t2->type != XML_ELEMENT_NODE) {
|
|
||||||
t2 = t2->next;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
p = g_object_new(LASSO_TYPE_PROVIDER, NULL);
|
p = g_object_new(LASSO_TYPE_PROVIDER, NULL);
|
||||||
LASSO_NODE_GET_CLASS(p)->init_from_xml(LASSO_NODE(p), t2);
|
lasso_check_good_rc(lasso_node_init_from_xml((LassoNode*)p,
|
||||||
|
t2))
|
||||||
if (lasso_provider_load_public_key(p, LASSO_PUBLIC_KEY_SIGNING)) {
|
if (lasso_provider_load_public_key(p, LASSO_PUBLIC_KEY_SIGNING)) {
|
||||||
g_hash_table_insert(server->providers,
|
g_hash_table_insert(server->providers,
|
||||||
g_strdup(p->ProviderID), p);
|
g_strdup(p->ProviderID), p);
|
||||||
} else {
|
} else {
|
||||||
message(G_LOG_LEVEL_CRITICAL,
|
critical("Failed to load signing public key for %s.",
|
||||||
"Failed to load signing public key for %s.",
|
|
||||||
p->ProviderID);
|
p->ProviderID);
|
||||||
|
lasso_release_gobject(p);
|
||||||
|
goto_cleanup_with_rc(
|
||||||
|
LASSO_XML_ERROR_OBJECT_CONSTRUCTION_FAILED);
|
||||||
}
|
}
|
||||||
t2 = t2->next;
|
t2 = xmlSecGetNextElementNode(t2->next);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -358,9 +364,12 @@ init_from_xml(LassoNode *node, xmlNode *xmlnode)
|
||||||
lasso_server_init_id_wsf20_svcmds(server, t);
|
lasso_server_init_id_wsf20_svcmds(server, t);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
t = t->next;
|
t = xmlSecGetNextElementNode(t->next);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
lasso_release_xml_string(s);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -746,7 +755,154 @@ lasso_server_get_private_key(LassoServer *server)
|
||||||
if (! server->private_key)
|
if (! server->private_key)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return lasso_xmlsec_load_private_key(server->private_key, server->private_key_password);
|
return lasso_xmlsec_load_private_key(server->private_key, server->private_key_password,
|
||||||
|
server->signature_method, server->certificate);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* lasso_server_get_signature_context_for_provider:
|
||||||
|
* @server: a #LassoServer object
|
||||||
|
* @provider: a #LassoProvider object
|
||||||
|
*
|
||||||
|
* Find the key and signature method to sign messages adressed to @provider. If @provider has an
|
||||||
|
* override over the private key of the @server object, use this override.
|
||||||
|
*
|
||||||
|
* The returned context content is now owned by the caller, if it must survives the @server or
|
||||||
|
* @provider object life, the key should be copied.
|
||||||
|
*
|
||||||
|
* Return value: 0 if successful, an error code otherwise.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
lasso_error_t
|
||||||
|
lasso_server_get_signature_context_for_provider(LassoServer *server,
|
||||||
|
LassoProvider *provider, LassoSignatureContext *signature_context)
|
||||||
|
{
|
||||||
|
lasso_error_t rc = 0;
|
||||||
|
LassoSignatureContext *private_context = NULL;
|
||||||
|
|
||||||
|
lasso_bad_param(SERVER, server);
|
||||||
|
lasso_null_param(signature_context);
|
||||||
|
|
||||||
|
if (provider) {
|
||||||
|
lasso_bad_param(PROVIDER, provider);
|
||||||
|
private_context = &provider->private_data->signature_context;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (private_context && lasso_validate_signature_method(private_context->signature_method)) {
|
||||||
|
lasso_assign_signature_context(*signature_context, *private_context);
|
||||||
|
} else {
|
||||||
|
rc = lasso_server_get_signature_context(server, signature_context);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* lasso_server_get_signature_context:
|
||||||
|
* @server: a #LassoServer object
|
||||||
|
* @context: a pointer to an allocated and initialized #LassoSignatureContext structure
|
||||||
|
*
|
||||||
|
* Try to create a signature context for this server. Beware that you should better use
|
||||||
|
* lasso_server_get_signature_context_for_provider() or
|
||||||
|
* lasso_server_get_signature_context_for_provider_by_name() in mot of the case when you know the
|
||||||
|
* target for your signature, because the provider could have special signature needs, like using a
|
||||||
|
* shared secret signature.
|
||||||
|
*
|
||||||
|
* Return value: 0 if successful, an error code otherwise.
|
||||||
|
*/
|
||||||
|
lasso_error_t
|
||||||
|
lasso_server_get_signature_context(LassoServer *server, LassoSignatureContext *context)
|
||||||
|
{
|
||||||
|
lasso_bad_param(SERVER, server);
|
||||||
|
lasso_null_param(context);
|
||||||
|
|
||||||
|
lasso_assign_new_signature_context(*context,
|
||||||
|
lasso_make_signature_context_from_path_or_string(
|
||||||
|
server->private_key, server->private_key_password,
|
||||||
|
server->signature_method, server->certificate));
|
||||||
|
if (! lasso_validate_signature_context(*context)) {
|
||||||
|
return LASSO_DS_ERROR_PRIVATE_KEY_LOAD_FAILED;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* lasso_server_get_signature_context_for_provider_by_name:
|
||||||
|
* @server: a #LassoServer object
|
||||||
|
* @provider_id: the identifier of a known provider
|
||||||
|
*
|
||||||
|
* Find the key and signature method to sign messages adressed to @provider. If @provider has an
|
||||||
|
* override over the private key of the @server object, use this override.
|
||||||
|
*
|
||||||
|
* The returned context content is now owned by the caller, if it must survives the @server or
|
||||||
|
* provider object life, the key should be copied.
|
||||||
|
*
|
||||||
|
* Return value: 0 if successful, an error code otherwise.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
lasso_error_t
|
||||||
|
lasso_server_get_signature_context_for_provider_by_name(LassoServer *server,
|
||||||
|
const char *provider_id, LassoSignatureContext *signature_context)
|
||||||
|
{
|
||||||
|
LassoProvider *provider;
|
||||||
|
lasso_bad_param(SERVER, server);
|
||||||
|
|
||||||
|
provider = lasso_server_get_provider(server, provider_id);
|
||||||
|
return lasso_server_get_signature_context_for_provider(server,
|
||||||
|
provider, signature_context);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* lasso_server_set_signature_for_provider_by_name:
|
||||||
|
* @server: a #LassoServer object
|
||||||
|
* @provider_id: the identifier of a known provider
|
||||||
|
* @node: a #LassoNode object
|
||||||
|
*
|
||||||
|
* Return value: 0 if successful, an error code otherwise.
|
||||||
|
*/
|
||||||
|
lasso_error_t
|
||||||
|
lasso_server_set_signature_for_provider_by_name(LassoServer *server, const char *provider_id, LassoNode *node)
|
||||||
|
{
|
||||||
|
LassoSignatureContext context = LASSO_SIGNATURE_CONTEXT_NONE;
|
||||||
|
lasso_error_t rc = 0;
|
||||||
|
|
||||||
|
lasso_check_good_rc(lasso_server_get_signature_context_for_provider_by_name(server,
|
||||||
|
provider_id, &context));
|
||||||
|
lasso_node_set_signature(node, context);
|
||||||
|
cleanup:
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* lasso_server_export_to_query_for_provider_by_name:
|
||||||
|
* @server: a #LassoServer object
|
||||||
|
* @provider_id: the identifier of a known provider
|
||||||
|
* @node: a #LassoNode object
|
||||||
|
*
|
||||||
|
* Return value: 0 if successful, an error code otherwise.
|
||||||
|
*/
|
||||||
|
lasso_error_t
|
||||||
|
lasso_server_export_to_query_for_provider_by_name(LassoServer *server, const char *provider_id, LassoNode *node, char **out)
|
||||||
|
{
|
||||||
|
LassoSignatureContext context = LASSO_SIGNATURE_CONTEXT_NONE;
|
||||||
|
lasso_error_t rc = 0;
|
||||||
|
char *query = NULL;
|
||||||
|
|
||||||
|
lasso_check_good_rc(lasso_server_get_signature_context_for_provider_by_name(server,
|
||||||
|
provider_id, &context));
|
||||||
|
query = lasso_node_build_query(node);
|
||||||
|
goto_cleanup_if_fail_with_rc(query, LASSO_PROFILE_ERROR_BUILDING_QUERY_FAILED);
|
||||||
|
if (lasso_validate_signature_method(context.signature_method)) {
|
||||||
|
lasso_assign_new_string(query, lasso_query_sign(query, context));
|
||||||
|
}
|
||||||
|
goto_cleanup_if_fail_with_rc(query,
|
||||||
|
LASSO_PROFILE_ERROR_BUILDING_QUERY_FAILED);
|
||||||
|
lasso_assign_new_string(*out, query);
|
||||||
|
context = LASSO_SIGNATURE_CONTEXT_NONE;
|
||||||
|
cleanup:
|
||||||
|
lasso_assign_new_signature_context(context, LASSO_SIGNATURE_CONTEXT_NONE);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -25,10 +25,14 @@
|
||||||
#ifndef __LASSO_SERVER_PRIVATE_H__
|
#ifndef __LASSO_SERVER_PRIVATE_H__
|
||||||
#define __LASSO_SERVER_PRIVATE_H__
|
#define __LASSO_SERVER_PRIVATE_H__
|
||||||
|
|
||||||
|
#include "./server.h"
|
||||||
|
#include "../xml/private.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
|
||||||
struct _LassoServerPrivate
|
struct _LassoServerPrivate
|
||||||
{
|
{
|
||||||
gboolean dispose_has_run;
|
gboolean dispose_has_run;
|
||||||
|
@ -42,6 +46,21 @@ gchar* lasso_server_get_providerID_from_hash(LassoServer *server, gchar *b64_has
|
||||||
xmlSecKey* lasso_server_get_private_key(LassoServer *server);
|
xmlSecKey* lasso_server_get_private_key(LassoServer *server);
|
||||||
GList* lasso_server_get_encryption_private_keys(LassoServer *server);
|
GList* lasso_server_get_encryption_private_keys(LassoServer *server);
|
||||||
|
|
||||||
|
lasso_error_t lasso_server_get_signature_context_for_provider(LassoServer *server,
|
||||||
|
LassoProvider *provider, LassoSignatureContext *signature_context);
|
||||||
|
|
||||||
|
lasso_error_t lasso_server_get_signature_context_for_provider_by_name(LassoServer *server,
|
||||||
|
const char *provider_id, LassoSignatureContext *signature_context);
|
||||||
|
|
||||||
|
lasso_error_t lasso_server_set_signature_for_provider_by_name(LassoServer *server,
|
||||||
|
const char *provider_id, LassoNode *node);
|
||||||
|
|
||||||
|
lasso_error_t lasso_server_export_to_query_for_provider_by_name(LassoServer *server,
|
||||||
|
const char *provider_id, LassoNode *node, char **query);
|
||||||
|
|
||||||
|
lasso_error_t lasso_server_get_signature_context(LassoServer *server, LassoSignatureContext
|
||||||
|
*context);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
|
@ -52,7 +52,7 @@
|
||||||
|
|
||||||
static char* lasso_saml20_profile_build_artifact(LassoProvider *provider);
|
static char* lasso_saml20_profile_build_artifact(LassoProvider *provider);
|
||||||
static int lasso_saml20_profile_export_to_query(LassoProfile *profile, LassoNode *msg, char **query,
|
static int lasso_saml20_profile_export_to_query(LassoProfile *profile, LassoNode *msg, char **query,
|
||||||
LassoSignatureMethod method, const char *private_key, const char *private_key_password);
|
LassoSignatureContext context);
|
||||||
static gint lasso_profile_saml20_build_artifact_get_request_msg(LassoProfile *profile,
|
static gint lasso_profile_saml20_build_artifact_get_request_msg(LassoProfile *profile,
|
||||||
const char *service);
|
const char *service);
|
||||||
static gint lasso_profile_saml20_build_artifact_post_request_msg(LassoProfile *profile,
|
static gint lasso_profile_saml20_build_artifact_post_request_msg(LassoProfile *profile,
|
||||||
|
@ -61,8 +61,6 @@ static gint lasso_profile_saml20_build_artifact_get_response_msg(LassoProfile *p
|
||||||
const char *service);
|
const char *service);
|
||||||
static gint lasso_profile_saml20_build_artifact_post_response_msg(LassoProfile *profile,
|
static gint lasso_profile_saml20_build_artifact_post_response_msg(LassoProfile *profile,
|
||||||
const char *service);
|
const char *service);
|
||||||
static gboolean has_signature(LassoNode *node, LassoSignatureMethod *signature_method,
|
|
||||||
char **private_key_file, char **private_key_password);
|
|
||||||
static char* lasso_saml20_profile_generate_artifact(LassoProfile *profile, int part);
|
static char* lasso_saml20_profile_generate_artifact(LassoProfile *profile, int part);
|
||||||
|
|
||||||
#define check_msg_body \
|
#define check_msg_body \
|
||||||
|
@ -1097,8 +1095,7 @@ cleanup:
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
lasso_saml20_profile_export_to_query(LassoProfile *profile, LassoNode *msg, char **query,
|
lasso_saml20_profile_export_to_query(LassoProfile *profile, LassoNode *msg, char **query,
|
||||||
LassoSignatureMethod signature_method, const char *private_key_file,
|
LassoSignatureContext context) {
|
||||||
const char *private_key_password) {
|
|
||||||
char *unsigned_query = NULL;
|
char *unsigned_query = NULL;
|
||||||
char *result = NULL;
|
char *result = NULL;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
@ -1115,9 +1112,8 @@ lasso_saml20_profile_export_to_query(LassoProfile *profile, LassoNode *msg, char
|
||||||
"see #3.4.3 of saml-bindings-2.0-os");
|
"see #3.4.3 of saml-bindings-2.0-os");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (signature_method && private_key_file && lasso_flag_add_signature) {
|
if (lasso_validate_signature_method(context.signature_method)) {
|
||||||
result = lasso_query_sign(unsigned_query, signature_method, private_key_file,
|
result = lasso_query_sign(unsigned_query, context);
|
||||||
private_key_password);
|
|
||||||
goto_cleanup_if_fail_with_rc(result != NULL,
|
goto_cleanup_if_fail_with_rc(result != NULL,
|
||||||
LASSO_PROFILE_ERROR_BUILDING_QUERY_FAILED);
|
LASSO_PROFILE_ERROR_BUILDING_QUERY_FAILED);
|
||||||
lasso_transfer_string(*query, result);
|
lasso_transfer_string(*query, result);
|
||||||
|
@ -1130,48 +1126,6 @@ cleanup:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
|
||||||
has_signature(LassoNode *node, LassoSignatureMethod *method, char **private_key_file,
|
|
||||||
char **private_key_password) {
|
|
||||||
LassoNodeClass *klass;
|
|
||||||
LassoSignatureType sign_type;
|
|
||||||
LassoSignatureMethod sign_method;
|
|
||||||
char *key = NULL;
|
|
||||||
char *password = NULL;
|
|
||||||
|
|
||||||
if (node == NULL)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
/* new signature parameters storage */
|
|
||||||
lasso_node_get_signature(node, &sign_type, &sign_method, &key, &password, NULL);
|
|
||||||
if (sign_type) {
|
|
||||||
*method = sign_method;
|
|
||||||
lasso_assign_string(*private_key_file, key);
|
|
||||||
lasso_assign_string(*private_key_password, password);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
klass = LASSO_NODE_GET_CLASS(node);
|
|
||||||
/* follow the class parenting chain */
|
|
||||||
while (klass && LASSO_IS_NODE_CLASS(klass)) {
|
|
||||||
if (klass && klass->node_data && klass->node_data->sign_type_offset != 0) {
|
|
||||||
if (G_STRUCT_MEMBER(LassoSignatureType, node,
|
|
||||||
klass->node_data->sign_type_offset)
|
|
||||||
!= LASSO_SIGNATURE_TYPE_NONE) {
|
|
||||||
*method = G_STRUCT_MEMBER(LassoSignatureMethod, node,
|
|
||||||
klass->node_data->sign_method_offset);
|
|
||||||
lasso_assign_string(*private_key_file, G_STRUCT_MEMBER(char*, node,
|
|
||||||
klass->node_data->private_key_file_offset));
|
|
||||||
/** FIXME: retrieve the stored key password */
|
|
||||||
*private_key_password = NULL;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
klass = g_type_class_peek_parent(klass);
|
|
||||||
}
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* lasso_saml20_profile_build_http_redirect:
|
* lasso_saml20_profile_build_http_redirect:
|
||||||
* @profile: a #LassoProfile object
|
* @profile: a #LassoProfile object
|
||||||
|
@ -1191,26 +1145,23 @@ lasso_saml20_profile_build_http_redirect(LassoProfile *profile,
|
||||||
{
|
{
|
||||||
char *query = NULL;
|
char *query = NULL;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
LassoSignatureMethod signature_method = 0;
|
LassoSignatureContext context = LASSO_SIGNATURE_CONTEXT_NONE;
|
||||||
char *private_key_file = NULL;
|
|
||||||
char *private_key_password = NULL;
|
|
||||||
|
|
||||||
goto_cleanup_if_fail_with_rc (url != NULL, LASSO_PROFILE_ERROR_UNKNOWN_PROFILE_URL);
|
goto_cleanup_if_fail_with_rc (url != NULL, LASSO_PROFILE_ERROR_UNKNOWN_PROFILE_URL);
|
||||||
/* if message is signed, remove XML signature, add query signature */
|
/* if message is signed, remove XML signature, add query signature */
|
||||||
if (has_signature(msg, &signature_method, (char **)&private_key_file,
|
context = lasso_node_get_signature(msg);
|
||||||
(char **)&private_key_password)) {
|
/* We must duplicate the key since lasso_node_remove_signature will free it. */
|
||||||
|
context.signature_key = xmlSecKeyDuplicate(context.signature_key);
|
||||||
|
if (lasso_validate_signature_method(context.signature_method)) {
|
||||||
lasso_node_remove_signature(msg);
|
lasso_node_remove_signature(msg);
|
||||||
}
|
}
|
||||||
lasso_check_good_rc(lasso_saml20_profile_export_to_query(profile, msg, &query,
|
lasso_check_good_rc(lasso_saml20_profile_export_to_query(profile, msg, &query, context));
|
||||||
signature_method, private_key_file, private_key_password));
|
|
||||||
|
|
||||||
lasso_assign_new_string(profile->msg_url, lasso_concat_url_query(url, query));
|
lasso_assign_new_string(profile->msg_url, lasso_concat_url_query(url, query));
|
||||||
lasso_release(profile->msg_body);
|
lasso_release(profile->msg_body);
|
||||||
lasso_release(query);
|
lasso_release(query);
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
lasso_release_string(private_key_file);
|
|
||||||
lasso_release_string(private_key_password);
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1549,6 +1500,8 @@ gint
|
||||||
lasso_profile_saml20_setup_message_signature(LassoProfile *profile, LassoNode *request_or_response)
|
lasso_profile_saml20_setup_message_signature(LassoProfile *profile, LassoNode *request_or_response)
|
||||||
{
|
{
|
||||||
lasso_bad_param(PROFILE, profile);
|
lasso_bad_param(PROFILE, profile);
|
||||||
|
LassoSignatureContext context = LASSO_SIGNATURE_CONTEXT_NONE;
|
||||||
|
lasso_error_t rc = 0;
|
||||||
|
|
||||||
switch (lasso_profile_get_signature_hint(profile)) {
|
switch (lasso_profile_get_signature_hint(profile)) {
|
||||||
case LASSO_PROFILE_SIGNATURE_HINT_MAYBE:
|
case LASSO_PROFILE_SIGNATURE_HINT_MAYBE:
|
||||||
|
@ -1567,49 +1520,11 @@ lasso_profile_saml20_setup_message_signature(LassoProfile *profile, LassoNode *r
|
||||||
if (! LASSO_IS_SERVER(profile->server)) {
|
if (! LASSO_IS_SERVER(profile->server)) {
|
||||||
return LASSO_PROFILE_ERROR_MISSING_SERVER;
|
return LASSO_PROFILE_ERROR_MISSING_SERVER;
|
||||||
}
|
}
|
||||||
if (! profile->server->private_key) {
|
lasso_check_good_rc(lasso_server_get_signature_context_for_provider_by_name(profile->server,
|
||||||
return LASSO_DS_ERROR_PRIVATE_KEY_LOAD_FAILED;
|
profile->remote_providerID, &context));
|
||||||
}
|
lasso_check_good_rc(lasso_node_set_signature(request_or_response, context));
|
||||||
if (LASSO_IS_SAMLP2_REQUEST_ABSTRACT(request_or_response)) {
|
cleanup:
|
||||||
LassoSamlp2RequestAbstract *request;
|
return rc;
|
||||||
|
|
||||||
request = (LassoSamlp2RequestAbstract*)request_or_response;
|
|
||||||
if (profile->server->certificate) {
|
|
||||||
request->sign_type = LASSO_SIGNATURE_TYPE_WITHX509;
|
|
||||||
} else {
|
|
||||||
request->sign_type = LASSO_SIGNATURE_TYPE_SIMPLE;
|
|
||||||
}
|
|
||||||
request->sign_method = profile->server->signature_method;
|
|
||||||
lasso_assign_string(request->private_key_file,
|
|
||||||
profile->server->private_key);
|
|
||||||
lasso_assign_string(request->certificate_file,
|
|
||||||
profile->server->certificate);
|
|
||||||
lasso_node_set_signature(request_or_response, request->sign_type,
|
|
||||||
request->sign_method, profile->server->private_key,
|
|
||||||
profile->server->private_key_password,
|
|
||||||
profile->server->certificate);
|
|
||||||
} else if (LASSO_IS_SAMLP2_STATUS_RESPONSE(request_or_response)) {
|
|
||||||
LassoSamlp2StatusResponse *response;
|
|
||||||
|
|
||||||
response = (LassoSamlp2StatusResponse*)request_or_response;
|
|
||||||
if (profile->server->certificate) {
|
|
||||||
response->sign_type = LASSO_SIGNATURE_TYPE_WITHX509;
|
|
||||||
} else {
|
|
||||||
response->sign_type = LASSO_SIGNATURE_TYPE_SIMPLE;
|
|
||||||
}
|
|
||||||
response->sign_method = profile->server->signature_method;
|
|
||||||
lasso_assign_string(response->private_key_file,
|
|
||||||
profile->server->private_key);
|
|
||||||
lasso_assign_string(response->certificate_file,
|
|
||||||
profile->server->certificate);
|
|
||||||
lasso_node_set_signature(request_or_response, response->sign_type,
|
|
||||||
response->sign_method, profile->server->private_key,
|
|
||||||
profile->server->private_key_password,
|
|
||||||
profile->server->certificate);
|
|
||||||
} else {
|
|
||||||
return LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -678,27 +678,19 @@ int
|
||||||
lasso_server_saml2_assertion_setup_signature(LassoServer *server,
|
lasso_server_saml2_assertion_setup_signature(LassoServer *server,
|
||||||
LassoSaml2Assertion *saml2_assertion)
|
LassoSaml2Assertion *saml2_assertion)
|
||||||
{
|
{
|
||||||
|
LassoSignatureContext context = LASSO_SIGNATURE_CONTEXT_NONE;
|
||||||
|
lasso_error_t rc = 0;
|
||||||
|
|
||||||
lasso_bad_param(SERVER, server);
|
lasso_bad_param(SERVER, server);
|
||||||
lasso_bad_param(SAML2_ASSERTION, saml2_assertion);
|
lasso_bad_param(SAML2_ASSERTION, saml2_assertion);
|
||||||
|
|
||||||
if (server->certificate) {
|
|
||||||
saml2_assertion->sign_type = LASSO_SIGNATURE_TYPE_WITHX509;
|
|
||||||
} else {
|
|
||||||
saml2_assertion->sign_type = LASSO_SIGNATURE_TYPE_SIMPLE;
|
|
||||||
}
|
|
||||||
saml2_assertion->sign_method = server->signature_method;
|
|
||||||
lasso_assign_string(saml2_assertion->private_key_file,
|
|
||||||
server->private_key);
|
|
||||||
lasso_assign_string(saml2_assertion->certificate_file,
|
|
||||||
server->certificate);
|
|
||||||
lasso_node_set_signature((LassoNode*)saml2_assertion, saml2_assertion->sign_type,
|
|
||||||
saml2_assertion->sign_method, server->private_key,
|
|
||||||
server->private_key_password, server->certificate);
|
|
||||||
if (! saml2_assertion->ID) {
|
if (! saml2_assertion->ID) {
|
||||||
lasso_assign_new_string(saml2_assertion->ID, lasso_build_unique_id(32));
|
lasso_assign_new_string(saml2_assertion->ID, lasso_build_unique_id(32));
|
||||||
}
|
}
|
||||||
|
lasso_check_good_rc(lasso_server_get_signature_context(server, &context));
|
||||||
return 0;
|
lasso_check_good_rc(lasso_node_set_signature((LassoNode*)saml2_assertion, context));
|
||||||
|
cleanup:
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -34,6 +34,7 @@ extern "C" {
|
||||||
#include <xmlsec/crypto.h>
|
#include <xmlsec/crypto.h>
|
||||||
#include <xmlsec/xmlenc.h>
|
#include <xmlsec/xmlenc.h>
|
||||||
#include "saml-2.0/saml2_encrypted_element.h"
|
#include "saml-2.0/saml2_encrypted_element.h"
|
||||||
|
#include "../utils.h"
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
SNIPPET_NODE,
|
SNIPPET_NODE,
|
||||||
|
@ -186,8 +187,7 @@ xmlSecKeyPtr lasso_get_public_key_from_pem_file(const char *file);
|
||||||
xmlSecKeyPtr lasso_get_public_key_from_pem_cert_file(const char *file);
|
xmlSecKeyPtr lasso_get_public_key_from_pem_cert_file(const char *file);
|
||||||
xmlSecKeysMngr* lasso_load_certs_from_pem_certs_chain_file (const char *file);
|
xmlSecKeysMngr* lasso_load_certs_from_pem_certs_chain_file (const char *file);
|
||||||
|
|
||||||
char* lasso_query_sign(char *query, LassoSignatureMethod sign_method,
|
char* lasso_query_sign(char *query, LassoSignatureContext signature_context);
|
||||||
const char *private_key_file, const char *private_key_file_password);
|
|
||||||
|
|
||||||
int lasso_query_verify_signature(const char *query, const xmlSecKey *public_key);
|
int lasso_query_verify_signature(const char *query, const xmlSecKey *public_key);
|
||||||
|
|
||||||
|
@ -197,9 +197,7 @@ char* lasso_sha1(const char *str);
|
||||||
|
|
||||||
char** urlencoded_to_strings(const char *str);
|
char** urlencoded_to_strings(const char *str);
|
||||||
|
|
||||||
int lasso_sign_node(xmlNode *xmlnode, const char *id_attr_name, const char *id_value,
|
int lasso_sign_node(xmlNode *xmlnode, LassoSignatureContext context, const char *id_attr_name, const char *id_value);
|
||||||
const char *private_key_file, const char *private_key_password,
|
|
||||||
const char *certificate_file);
|
|
||||||
|
|
||||||
int lasso_verify_signature(xmlNode *signed_node, xmlDoc *doc, const char *id_attr_name,
|
int lasso_verify_signature(xmlNode *signed_node, xmlDoc *doc, const char *id_attr_name,
|
||||||
xmlSecKeysMngr *keys_manager, xmlSecKey *public_key,
|
xmlSecKeysMngr *keys_manager, xmlSecKey *public_key,
|
||||||
|
@ -243,8 +241,9 @@ gboolean lasso_eval_xpath_expression(xmlXPathContextPtr xpath_ctx, const char *e
|
||||||
|
|
||||||
char * lasso_get_relaystate_from_query(const char *query);
|
char * lasso_get_relaystate_from_query(const char *query);
|
||||||
char * lasso_url_add_parameters(char *url, gboolean free, ...);
|
char * lasso_url_add_parameters(char *url, gboolean free, ...);
|
||||||
xmlSecKey* lasso_xmlsec_load_private_key_from_buffer(const char *buffer, size_t length, const char *password);
|
xmlSecKey* lasso_xmlsec_load_private_key_from_buffer(const char *buffer, size_t length, const char *password, LassoSignatureMethod signature_method, const char *certificate);
|
||||||
xmlSecKey* lasso_xmlsec_load_private_key(const char *filename_or_buffer, const char *password);
|
xmlSecKey* lasso_xmlsec_load_private_key(const char *filename_or_buffer, const char *password,
|
||||||
|
LassoSignatureMethod signature_method, const char *certificate);
|
||||||
xmlDocPtr lasso_xml_parse_file(const char *filepath);
|
xmlDocPtr lasso_xml_parse_file(const char *filepath);
|
||||||
xmlDocPtr lasso_xml_parse_memory_with_error(const char *buffer, int size, xmlError *error);
|
xmlDocPtr lasso_xml_parse_memory_with_error(const char *buffer, int size, xmlError *error);
|
||||||
xmlSecKeyPtr lasso_xmlsec_load_key_info(xmlNode *key_descriptor);
|
xmlSecKeyPtr lasso_xmlsec_load_key_info(xmlNode *key_descriptor);
|
||||||
|
@ -254,16 +253,9 @@ void lasso_set_string_from_prop(char **str, xmlNode *node, xmlChar *name, xmlCha
|
||||||
|
|
||||||
void lasso_node_add_custom_namespace(LassoNode *node, const char *prefix, const char *href);
|
void lasso_node_add_custom_namespace(LassoNode *node, const char *prefix, const char *href);
|
||||||
|
|
||||||
void lasso_apply_signature(LassoNode *node, gboolean lasso_dump,
|
int lasso_node_set_signature(LassoNode *node, LassoSignatureContext context);
|
||||||
xmlNode **xmlnode, char *id_attribute, char *id_value, LassoSignatureType sign_type,
|
|
||||||
char *private_key_file, char *certificate_file);
|
|
||||||
|
|
||||||
int lasso_node_set_signature(LassoNode *node, LassoSignatureType type, LassoSignatureMethod method,
|
LassoSignatureContext lasso_node_get_signature(LassoNode *node);
|
||||||
const char *private_key, const char *private_key_password, const char *certificate);
|
|
||||||
|
|
||||||
void lasso_node_get_signature(LassoNode *node, LassoSignatureType *type, LassoSignatureMethod *method,
|
|
||||||
char **private_key, char **private_key_password,
|
|
||||||
char **certificate);
|
|
||||||
|
|
||||||
void lasso_node_set_encryption(LassoNode *node, xmlSecKey *encryption_public_key,
|
void lasso_node_set_encryption(LassoNode *node, xmlSecKey *encryption_public_key,
|
||||||
LassoEncryptionSymKeyType encryption_sym_key_type);
|
LassoEncryptionSymKeyType encryption_sym_key_type);
|
||||||
|
@ -272,6 +264,14 @@ void lasso_node_get_encryption(LassoNode *node, xmlSecKey **encryption_public_ke
|
||||||
LassoEncryptionSymKeyType *encryption_sym_key_type);
|
LassoEncryptionSymKeyType *encryption_sym_key_type);
|
||||||
gboolean lasso_base64_decode(const char *from, char **buffer, int *buffer_len);
|
gboolean lasso_base64_decode(const char *from, char **buffer, int *buffer_len);
|
||||||
|
|
||||||
|
LassoSignatureContext lasso_make_signature_context_from_buffer(const char *buffer, size_t length,
|
||||||
|
const char *password, LassoSignatureMethod signature_method,
|
||||||
|
const char *certificate);
|
||||||
|
|
||||||
|
LassoSignatureContext lasso_make_signature_context_from_path_or_string(char *filename_or_buffer,
|
||||||
|
const char *password, LassoSignatureMethod signature_method,
|
||||||
|
const char *certificate);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
|
@ -40,6 +40,8 @@
|
||||||
#include <openssl/pem.h>
|
#include <openssl/pem.h>
|
||||||
#include <openssl/sha.h>
|
#include <openssl/sha.h>
|
||||||
#include <openssl/engine.h>
|
#include <openssl/engine.h>
|
||||||
|
#include <openssl/hmac.h>
|
||||||
|
#include <openssl/evp.h>
|
||||||
|
|
||||||
#include <xmlsec/base64.h>
|
#include <xmlsec/base64.h>
|
||||||
#include <xmlsec/crypto.h>
|
#include <xmlsec/crypto.h>
|
||||||
|
@ -454,16 +456,6 @@ cleanup:
|
||||||
return keys_mngr;
|
return keys_mngr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
_lasso_openssl_pwd_callback(char *buf, int size, G_GNUC_UNUSED int rwflag, void *u)
|
|
||||||
{
|
|
||||||
if (u) {
|
|
||||||
strncpy(buf, u, size);
|
|
||||||
return strlen(u);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* lasso_query_sign:
|
* lasso_query_sign:
|
||||||
* @query: a query (an url-encoded node)
|
* @query: a query (an url-encoded node)
|
||||||
|
@ -476,83 +468,87 @@ _lasso_openssl_pwd_callback(char *buf, int size, G_GNUC_UNUSED int rwflag, void
|
||||||
* Return value: a newly allocated query signed or NULL if an error occurs.
|
* Return value: a newly allocated query signed or NULL if an error occurs.
|
||||||
**/
|
**/
|
||||||
char*
|
char*
|
||||||
lasso_query_sign(char *query, LassoSignatureMethod sign_method, const char *private_key_file,
|
lasso_query_sign(char *query, LassoSignatureContext context)
|
||||||
const char *private_key_file_password)
|
|
||||||
{
|
{
|
||||||
BIO *bio = NULL;
|
|
||||||
char *digest = NULL; /* 160 bit buffer */
|
char *digest = NULL; /* 160 bit buffer */
|
||||||
RSA *rsa = NULL;
|
RSA *rsa = NULL;
|
||||||
DSA *dsa = NULL;
|
DSA *dsa = NULL;
|
||||||
unsigned char *sigret = NULL;
|
unsigned char *sigret = NULL;
|
||||||
unsigned int siglen;
|
unsigned int siglen;
|
||||||
char *b64_sigret = NULL, *e_b64_sigret = NULL;
|
xmlChar *b64_sigret = NULL, *e_b64_sigret = NULL;
|
||||||
char *new_query = NULL, *s_new_query = NULL;
|
char *new_query = NULL, *s_new_query = NULL;
|
||||||
int status = 0;
|
int status = 0;
|
||||||
char *t;
|
const xmlChar *algo_href = NULL;
|
||||||
|
xmlSecKey *key;
|
||||||
|
xmlSecKeyData *key_data;
|
||||||
|
int sigret_size;
|
||||||
|
LassoSignatureMethod sign_method;
|
||||||
|
|
||||||
g_return_val_if_fail(query != NULL, NULL);
|
g_return_val_if_fail(query != NULL, NULL);
|
||||||
g_return_val_if_fail(sign_method == LASSO_SIGNATURE_METHOD_RSA_SHA1 ||
|
g_return_val_if_fail(lasso_validate_signature_method(context.signature_method), NULL);
|
||||||
sign_method == LASSO_SIGNATURE_METHOD_DSA_SHA1, NULL);
|
|
||||||
g_return_val_if_fail(private_key_file != NULL, NULL);
|
key = context.signature_key;
|
||||||
|
sign_method = context.signature_method;
|
||||||
|
key_data = xmlSecKeyGetValue(key);
|
||||||
|
|
||||||
if (access(private_key_file, R_OK) == 0) {
|
|
||||||
bio = BIO_new_file(private_key_file, "rb");
|
|
||||||
} else {
|
|
||||||
// Safe deconst cast, the BIO is read-only
|
|
||||||
bio = BIO_new_mem_buf((char*)private_key_file, -1);
|
|
||||||
}
|
|
||||||
if (bio == NULL) {
|
|
||||||
message(G_LOG_LEVEL_CRITICAL, "Failed to open %s private key file",
|
|
||||||
private_key_file);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* add SigAlg */
|
/* add SigAlg */
|
||||||
switch (sign_method) {
|
switch (sign_method) {
|
||||||
case LASSO_SIGNATURE_METHOD_RSA_SHA1:
|
case LASSO_SIGNATURE_METHOD_RSA_SHA1:
|
||||||
t = (char*)xmlURIEscapeStr(xmlSecHrefRsaSha1, NULL);
|
algo_href = xmlSecHrefRsaSha1;
|
||||||
new_query = g_strdup_printf("%s&SigAlg=%s", query, t);
|
|
||||||
xmlFree(t);
|
|
||||||
break;
|
break;
|
||||||
case LASSO_SIGNATURE_METHOD_DSA_SHA1:
|
case LASSO_SIGNATURE_METHOD_DSA_SHA1:
|
||||||
t = (char*)xmlURIEscapeStr(xmlSecHrefDsaSha1, NULL);
|
algo_href = xmlSecHrefDsaSha1;
|
||||||
new_query = g_strdup_printf("%s&SigAlg=%s", query, t);
|
|
||||||
xmlFree(t);
|
|
||||||
break;
|
break;
|
||||||
case LASSO_SIGNATURE_METHOD_NONE:
|
case LASSO_SIGNATURE_METHOD_NONE:
|
||||||
case LASSO_SIGNATURE_METHOD_LAST:
|
case LASSO_SIGNATURE_METHOD_LAST:
|
||||||
g_assert_not_reached();
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const char *t = (char*)xmlURIEscapeStr(algo_href, NULL);
|
||||||
|
new_query = g_strdup_printf("%s&SigAlg=%s", query, t);
|
||||||
|
xmlFree(BAD_CAST t);
|
||||||
|
}
|
||||||
|
|
||||||
/* build buffer digest */
|
/* build buffer digest */
|
||||||
digest = lasso_sha1(new_query);
|
digest = lasso_sha1(new_query);
|
||||||
if (digest == NULL) {
|
if (digest == NULL) {
|
||||||
message(G_LOG_LEVEL_CRITICAL, "Failed to build the buffer digest");
|
message(G_LOG_LEVEL_CRITICAL, "Failed to build the buffer digest");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
/* extract the OpenSSL key */
|
||||||
|
switch (sign_method) {
|
||||||
|
case LASSO_SIGNATURE_METHOD_RSA_SHA1:
|
||||||
|
rsa = xmlSecOpenSSLKeyDataRsaGetRsa(key_data);
|
||||||
|
g_assert(rsa);
|
||||||
|
/* alloc memory for sigret */
|
||||||
|
sigret_size = RSA_size(rsa);
|
||||||
|
break;
|
||||||
|
case LASSO_SIGNATURE_METHOD_DSA_SHA1:
|
||||||
|
dsa = xmlSecOpenSSLKeyDataDsaGetDsa(key_data);
|
||||||
|
g_assert(dsa);
|
||||||
|
/* alloc memory for sigret */
|
||||||
|
sigret_size = DSA_size(dsa);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_assert_not_reached();
|
||||||
|
}
|
||||||
|
sigret = (unsigned char *)g_malloc (sigret_size);
|
||||||
|
|
||||||
/* calculate signature value */
|
switch (sign_method) {
|
||||||
if (sign_method == LASSO_SIGNATURE_METHOD_RSA_SHA1) {
|
case LASSO_SIGNATURE_METHOD_RSA_SHA1:
|
||||||
/* load private key */
|
/* sign digest message */
|
||||||
rsa = PEM_read_bio_RSAPrivateKey(bio, NULL, _lasso_openssl_pwd_callback,
|
status = RSA_sign(NID_sha1, (unsigned char*)digest, 20, sigret,
|
||||||
(void*)private_key_file_password);
|
&siglen, rsa);
|
||||||
if (rsa == NULL) {
|
break;
|
||||||
goto done;
|
case LASSO_SIGNATURE_METHOD_DSA_SHA1:
|
||||||
}
|
status = DSA_sign(NID_sha1, (unsigned char*)digest, 20, sigret,
|
||||||
/* alloc memory for sigret */
|
&siglen, dsa);
|
||||||
sigret = (unsigned char *)g_malloc (RSA_size(rsa));
|
break;
|
||||||
/* sign digest message */
|
case LASSO_SIGNATURE_METHOD_LAST:
|
||||||
status = RSA_sign(NID_sha1, (unsigned char*)digest, 20, sigret, &siglen, rsa);
|
case LASSO_SIGNATURE_METHOD_NONE:
|
||||||
RSA_free(rsa);
|
g_assert_not_reached();
|
||||||
} else if (sign_method == LASSO_SIGNATURE_METHOD_DSA_SHA1) {
|
|
||||||
dsa = PEM_read_bio_DSAPrivateKey(bio, NULL, _lasso_openssl_pwd_callback,
|
|
||||||
(void*)private_key_file_password);
|
|
||||||
if (dsa == NULL) {
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
sigret = (unsigned char *)g_malloc (DSA_size(dsa));
|
|
||||||
status = DSA_sign(NID_sha1, (unsigned char*)digest, 20, sigret, &siglen, dsa);
|
|
||||||
DSA_free(dsa);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status == 0) {
|
if (status == 0) {
|
||||||
|
@ -560,17 +556,16 @@ lasso_query_sign(char *query, LassoSignatureMethod sign_method, const char *priv
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Base64 encode the signature value */
|
/* Base64 encode the signature value */
|
||||||
b64_sigret = (char*)xmlSecBase64Encode(sigret, siglen, 0);
|
b64_sigret = xmlSecBase64Encode(sigret, siglen, 0);
|
||||||
/* escape b64_sigret */
|
/* escape b64_sigret */
|
||||||
e_b64_sigret = (char*)xmlURIEscapeStr((xmlChar*)b64_sigret, NULL);
|
e_b64_sigret = xmlURIEscapeStr((xmlChar*)b64_sigret, NULL);
|
||||||
|
|
||||||
/* add signature */
|
/* add signature */
|
||||||
switch (sign_method) {
|
switch (sign_method) {
|
||||||
case LASSO_SIGNATURE_METHOD_RSA_SHA1:
|
case LASSO_SIGNATURE_METHOD_RSA_SHA1:
|
||||||
s_new_query = g_strdup_printf("%s&Signature=%s", new_query, e_b64_sigret);
|
|
||||||
break;
|
|
||||||
case LASSO_SIGNATURE_METHOD_DSA_SHA1:
|
case LASSO_SIGNATURE_METHOD_DSA_SHA1:
|
||||||
s_new_query = g_strdup_printf("%s&Signature=%s", new_query, e_b64_sigret);
|
s_new_query = g_strdup_printf("%s&Signature=%s", new_query, (char*)
|
||||||
|
e_b64_sigret);
|
||||||
break;
|
break;
|
||||||
case LASSO_SIGNATURE_METHOD_NONE:
|
case LASSO_SIGNATURE_METHOD_NONE:
|
||||||
case LASSO_SIGNATURE_METHOD_LAST:
|
case LASSO_SIGNATURE_METHOD_LAST:
|
||||||
|
@ -579,11 +574,10 @@ lasso_query_sign(char *query, LassoSignatureMethod sign_method, const char *priv
|
||||||
|
|
||||||
done:
|
done:
|
||||||
lasso_release(new_query);
|
lasso_release(new_query);
|
||||||
xmlFree(digest);
|
lasso_release_string(digest);
|
||||||
BIO_free(bio);
|
|
||||||
lasso_release(sigret);
|
lasso_release(sigret);
|
||||||
xmlFree(b64_sigret);
|
lasso_release_xml_string(b64_sigret);
|
||||||
xmlFree(e_b64_sigret);
|
lasso_release_xml_string(e_b64_sigret);
|
||||||
|
|
||||||
return s_new_query;
|
return s_new_query;
|
||||||
}
|
}
|
||||||
|
@ -722,7 +716,7 @@ lasso_query_verify_signature(const char *query, const xmlSecKey *sender_public_k
|
||||||
done:
|
done:
|
||||||
xmlFree(b64_signature);
|
xmlFree(b64_signature);
|
||||||
xmlFree(signature);
|
xmlFree(signature);
|
||||||
xmlFree(digest);
|
lasso_release_string(digest);
|
||||||
xmlFree(usig_alg);
|
xmlFree(usig_alg);
|
||||||
g_strfreev(str_split);
|
g_strfreev(str_split);
|
||||||
|
|
||||||
|
@ -884,7 +878,7 @@ lasso_saml2_query_verify_signature(const char *query, const xmlSecKey *sender_pu
|
||||||
done:
|
done:
|
||||||
xmlFree(b64_signature);
|
xmlFree(b64_signature);
|
||||||
xmlFree(signature);
|
xmlFree(signature);
|
||||||
xmlFree(digest);
|
lasso_release_string(digest);
|
||||||
xmlFree(usig_alg);
|
xmlFree(usig_alg);
|
||||||
lasso_release(components);
|
lasso_release(components);
|
||||||
lasso_release(query_copy);
|
lasso_release(query_copy);
|
||||||
|
@ -970,22 +964,21 @@ void _lasso_xmlsec_password_callback() {
|
||||||
* Return value: 0 if successful, an error code otherwise.
|
* Return value: 0 if successful, an error code otherwise.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
lasso_sign_node(xmlNode *xmlnode, const char *id_attr_name, const char *id_value,
|
lasso_sign_node(xmlNode *xmlnode, LassoSignatureContext context, const char *id_attr_name,
|
||||||
const char *private_key_file, const char *private_key_password,
|
const char *id_value)
|
||||||
const char *certificate_file)
|
|
||||||
{
|
{
|
||||||
xmlDoc *doc;
|
xmlDoc *doc = NULL;
|
||||||
xmlNode *sign_tmpl, *old_parent;
|
xmlNode *sign_tmpl = NULL, *old_parent = NULL;
|
||||||
xmlSecDSigCtx *dsig_ctx;
|
xmlSecDSigCtx *dsig_ctx = NULL;
|
||||||
xmlAttr *id_attr = NULL;
|
xmlAttr *id_attr = NULL;
|
||||||
void *password_callback = NULL;
|
lasso_error_t rc = 0;
|
||||||
|
|
||||||
if (private_key_file == NULL || xmlnode == NULL)
|
g_return_val_if_fail(context.signature_method, LASSO_DS_ERROR_INVALID_SIGALG);
|
||||||
return LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ;
|
g_return_val_if_fail(context.signature_key, LASSO_DS_ERROR_PRIVATE_KEY_LOAD_FAILED);
|
||||||
|
|
||||||
sign_tmpl = xmlSecFindNode(xmlnode, xmlSecNodeSignature, xmlSecDSigNs);
|
sign_tmpl = xmlSecFindNode(xmlnode, xmlSecNodeSignature, xmlSecDSigNs);
|
||||||
if (sign_tmpl == NULL)
|
goto_cleanup_if_fail_with_rc(sign_tmpl != NULL,
|
||||||
return LASSO_DS_ERROR_SIGNATURE_TEMPLATE_NOT_FOUND;
|
LASSO_DS_ERROR_SIGNATURE_TEMPLATE_NOT_FOUND);
|
||||||
|
|
||||||
doc = xmlNewDoc((xmlChar*)"1.0");
|
doc = xmlNewDoc((xmlChar*)"1.0");
|
||||||
old_parent = xmlnode->parent;
|
old_parent = xmlnode->parent;
|
||||||
|
@ -998,52 +991,21 @@ lasso_sign_node(xmlNode *xmlnode, const char *id_attr_name, const char *id_value
|
||||||
}
|
}
|
||||||
|
|
||||||
dsig_ctx = xmlSecDSigCtxCreate(NULL);
|
dsig_ctx = xmlSecDSigCtxCreate(NULL);
|
||||||
if (! private_key_password) {
|
lasso_assign_sec_key(dsig_ctx->signKey, context.signature_key);
|
||||||
password_callback = _lasso_openssl_pwd_callback;
|
|
||||||
}
|
|
||||||
if (access(private_key_file, R_OK) == 0) {
|
|
||||||
dsig_ctx->signKey = xmlSecCryptoAppKeyLoad(private_key_file,
|
|
||||||
xmlSecKeyDataFormatPem, private_key_password,
|
|
||||||
password_callback, NULL /* password_callback_ctx */);
|
|
||||||
} else {
|
|
||||||
int len = private_key_file ? strlen(private_key_file) : 0;
|
|
||||||
dsig_ctx->signKey = xmlSecCryptoAppKeyLoadMemory((xmlSecByte*)private_key_file, len,
|
|
||||||
xmlSecKeyDataFormatPem, private_key_password,
|
|
||||||
password_callback, NULL /* password_callback_ctx */);
|
|
||||||
}
|
|
||||||
if (dsig_ctx->signKey == NULL) {
|
|
||||||
xmlSecDSigCtxDestroy(dsig_ctx);
|
|
||||||
return critical_error(LASSO_DS_ERROR_PRIVATE_KEY_LOAD_FAILED);
|
|
||||||
}
|
|
||||||
if (certificate_file != NULL && certificate_file[0] != 0) {
|
|
||||||
int rc = -1;
|
|
||||||
|
|
||||||
if (access(certificate_file, R_OK) == 0) {
|
|
||||||
rc = xmlSecCryptoAppKeyCertLoad(dsig_ctx->signKey, certificate_file,
|
|
||||||
xmlSecKeyDataFormatPem);
|
|
||||||
} else {
|
|
||||||
int len = certificate_file ? strlen(certificate_file) : 0;
|
|
||||||
|
|
||||||
rc = xmlSecCryptoAppKeyCertLoadMemory(dsig_ctx->signKey, (xmlSecByte*)certificate_file,
|
|
||||||
len, xmlSecKeyDataFormatPem);
|
|
||||||
}
|
|
||||||
if (rc < 0) {
|
|
||||||
xmlSecDSigCtxDestroy(dsig_ctx);
|
|
||||||
return critical_error(LASSO_DS_ERROR_CERTIFICATE_LOAD_FAILED);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (xmlSecDSigCtxSign(dsig_ctx, sign_tmpl) < 0) {
|
if (xmlSecDSigCtxSign(dsig_ctx, sign_tmpl) < 0) {
|
||||||
xmlSecDSigCtxDestroy(dsig_ctx);
|
goto_cleanup_with_rc(LASSO_DS_ERROR_SIGNATURE_FAILED);
|
||||||
return critical_error(LASSO_DS_ERROR_SIGNATURE_FAILED);
|
|
||||||
}
|
}
|
||||||
xmlSecDSigCtxDestroy(dsig_ctx);
|
|
||||||
xmlRemoveID(doc, id_attr);
|
|
||||||
xmlUnlinkNode(xmlnode);
|
|
||||||
lasso_release_doc(doc);
|
|
||||||
xmlnode->parent = old_parent;
|
|
||||||
xmlSetTreeDoc(xmlnode, NULL);
|
|
||||||
|
|
||||||
return 0;
|
cleanup:
|
||||||
|
if (doc) {
|
||||||
|
xmlRemoveID(doc, id_attr);
|
||||||
|
xmlUnlinkNode(xmlnode);
|
||||||
|
lasso_release_doc(doc);
|
||||||
|
xmlnode->parent = old_parent;
|
||||||
|
xmlSetTreeDoc(xmlnode, NULL);
|
||||||
|
}
|
||||||
|
lasso_release_signature_context(dsig_ctx);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
gchar*
|
gchar*
|
||||||
|
@ -1975,7 +1937,8 @@ cleanup:
|
||||||
}
|
}
|
||||||
|
|
||||||
xmlSecKey*
|
xmlSecKey*
|
||||||
_lasso_xmlsec_load_key_from_buffer(const char *buffer, size_t length, const char *password)
|
_lasso_xmlsec_load_key_from_buffer(const char *buffer, size_t length, const char *password,
|
||||||
|
LassoSignatureMethod signature_method, const char *certificate)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
xmlSecKeyDataFormat key_formats[] = {
|
xmlSecKeyDataFormat key_formats[] = {
|
||||||
|
@ -1988,15 +1951,53 @@ _lasso_xmlsec_load_key_from_buffer(const char *buffer, size_t length, const char
|
||||||
xmlSecKeyDataFormatPkcs8Pem,
|
xmlSecKeyDataFormatPkcs8Pem,
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
xmlSecKeyDataFormat cert_formats[] = {
|
||||||
|
xmlSecKeyDataFormatCertPem,
|
||||||
|
xmlSecKeyDataFormatCertDer,
|
||||||
|
0
|
||||||
|
};
|
||||||
xmlSecKey *private_key = NULL;
|
xmlSecKey *private_key = NULL;
|
||||||
|
|
||||||
xmlSecErrorsDefaultCallbackEnableOutput(FALSE);
|
xmlSecErrorsDefaultCallbackEnableOutput(FALSE);
|
||||||
for (i = 0; key_formats[i] && private_key == NULL; i++) {
|
switch (signature_method) {
|
||||||
private_key = xmlSecCryptoAppKeyLoadMemory((xmlSecByte*)buffer, length,
|
case LASSO_SIGNATURE_METHOD_RSA_SHA1:
|
||||||
key_formats[i], password, NULL, NULL);
|
case LASSO_SIGNATURE_METHOD_DSA_SHA1:
|
||||||
|
for (i = 0; key_formats[i] && private_key == NULL; i++) {
|
||||||
|
private_key = xmlSecCryptoAppKeyLoadMemory((xmlSecByte*)buffer, length,
|
||||||
|
key_formats[i], password, NULL, NULL);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case LASSO_SIGNATURE_METHOD_LAST:
|
||||||
|
case LASSO_SIGNATURE_METHOD_NONE:
|
||||||
|
g_assert_not_reached();
|
||||||
|
}
|
||||||
|
goto_cleanup_if_fail(private_key != NULL);
|
||||||
|
if (certificate) {
|
||||||
|
if (signature_method == LASSO_SIGNATURE_METHOD_RSA_SHA1 || signature_method == LASSO_SIGNATURE_METHOD_DSA_SHA1) {
|
||||||
|
int done = 0;
|
||||||
|
|
||||||
|
for (i=0; cert_formats[i]; i++) {
|
||||||
|
if (xmlSecCryptoAppKeyCertLoad(private_key, certificate, cert_formats[i])
|
||||||
|
== 0) {
|
||||||
|
done = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (xmlSecCryptoAppKeyCertLoadMemory(private_key, BAD_CAST certificate,
|
||||||
|
strlen(certificate), cert_formats[i]) == 0) {
|
||||||
|
done = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (done == 0) {
|
||||||
|
warning("Unable to load certificate: %s", certificate);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
warning("Attaching a certificate for signature only "
|
||||||
|
"works with DSA and RSA algorithms.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
xmlSecErrorsDefaultCallbackEnableOutput(TRUE);
|
xmlSecErrorsDefaultCallbackEnableOutput(TRUE);
|
||||||
|
cleanup:
|
||||||
return private_key;
|
return private_key;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
@ -2040,28 +2041,29 @@ lasso_base64_decode(const char *from, char **buffer, int *buffer_len)
|
||||||
* @password: eventually a password
|
* @password: eventually a password
|
||||||
*/
|
*/
|
||||||
xmlSecKey*
|
xmlSecKey*
|
||||||
lasso_xmlsec_load_private_key_from_buffer(const char *buffer, size_t length, const char *password) {
|
lasso_xmlsec_load_private_key_from_buffer(const char *buffer, size_t length, const char *password,
|
||||||
|
LassoSignatureMethod signature_method, const char *certificate) {
|
||||||
xmlSecKey *private_key = NULL;
|
xmlSecKey *private_key = NULL;
|
||||||
|
|
||||||
private_key = _lasso_xmlsec_load_key_from_buffer(buffer, length, password);
|
private_key = _lasso_xmlsec_load_key_from_buffer(buffer, length, password, signature_method, certificate);
|
||||||
|
|
||||||
/* special lasso metadata hack */
|
/* special lasso metadata hack */
|
||||||
if (! private_key) {
|
if (! private_key) {
|
||||||
xmlChar *out;
|
char *out = NULL;
|
||||||
int len;
|
int len;
|
||||||
out = xmlMalloc(length*4);
|
|
||||||
xmlSecErrorsDefaultCallbackEnableOutput(FALSE);
|
if (lasso_base64_decode(buffer, &out, &len)) {
|
||||||
len = xmlSecBase64Decode(BAD_CAST buffer, out, length*4);
|
private_key = _lasso_xmlsec_load_key_from_buffer((char*)out, len, password,
|
||||||
xmlSecErrorsDefaultCallbackEnableOutput(TRUE);
|
signature_method, certificate);
|
||||||
private_key = _lasso_xmlsec_load_key_from_buffer((char*)out, len, password);
|
}
|
||||||
xmlFree(out);
|
lasso_release_string(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
return private_key;
|
return private_key;
|
||||||
}
|
}
|
||||||
|
|
||||||
xmlSecKey*
|
xmlSecKey*
|
||||||
lasso_xmlsec_load_private_key(const char *filename_or_buffer, const char *password) {
|
lasso_xmlsec_load_private_key(const char *filename_or_buffer, const char *password, LassoSignatureMethod signature_method, const char *certificate) {
|
||||||
char *buffer = NULL;
|
char *buffer = NULL;
|
||||||
size_t length;
|
size_t length;
|
||||||
xmlSecKey *ret;
|
xmlSecKey *ret;
|
||||||
|
@ -2070,9 +2072,11 @@ lasso_xmlsec_load_private_key(const char *filename_or_buffer, const char *passwo
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (g_file_get_contents(filename_or_buffer, &buffer, &length, NULL)) {
|
if (g_file_get_contents(filename_or_buffer, &buffer, &length, NULL)) {
|
||||||
ret = lasso_xmlsec_load_private_key_from_buffer(buffer, length, password);
|
ret = lasso_xmlsec_load_private_key_from_buffer(buffer, length, password, signature_method, certificate);
|
||||||
} else {
|
} else {
|
||||||
ret = lasso_xmlsec_load_private_key_from_buffer(filename_or_buffer, strlen(filename_or_buffer), password);
|
ret = lasso_xmlsec_load_private_key_from_buffer(filename_or_buffer,
|
||||||
|
strlen(filename_or_buffer), password, signature_method,
|
||||||
|
certificate);
|
||||||
}
|
}
|
||||||
lasso_release_string(buffer);
|
lasso_release_string(buffer);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -2189,7 +2193,8 @@ next:
|
||||||
|
|
||||||
content = xmlNodeGetContent(key_value);
|
content = xmlNodeGetContent(key_value);
|
||||||
if (content) {
|
if (content) {
|
||||||
result = lasso_xmlsec_load_private_key_from_buffer((char*)content, strlen((char*)content), NULL);
|
result = lasso_xmlsec_load_private_key_from_buffer((char*)content,
|
||||||
|
strlen((char*)content), NULL, LASSO_SIGNATURE_METHOD_RSA_SHA1, NULL);
|
||||||
xmlFree(content);
|
xmlFree(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2314,46 +2319,61 @@ lasso_log_remove_handler(guint handler_id)
|
||||||
g_log_remove_handler(LASSO_LOG_DOMAIN, handler_id);
|
g_log_remove_handler(LASSO_LOG_DOMAIN, handler_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
/**
|
||||||
lasso_apply_signature(LassoNode *node, gboolean lasso_dump,
|
* lasso_make_signature_context_from_buffer:
|
||||||
xmlNode **xmlnode, char *id_attribute, char *id_value, LassoSignatureType old_sign_type, char *old_private_key_file, char *old_certificate_file)
|
* @buffer: a byte buffer of size @length
|
||||||
{
|
* @length: the size of @buffer as bytes
|
||||||
int rc = 0;
|
* @password: an eventual password to decoded the private key contained in @buffer
|
||||||
LassoSignatureType sign_type = LASSO_SIGNATURE_TYPE_NONE;
|
* @signature_method: the signature method to associate to this key
|
||||||
LassoSignatureMethod sign_method = LASSO_SIGNATURE_METHOD_RSA_SHA1;
|
* @certificate: a certificate as a file path or PEM encoded in a NULL-terminated string, to
|
||||||
char *private_key_file = NULL;
|
* associate with the key, it will be used to fill the KeyInfo node in an eventual signature.
|
||||||
char *private_key_password = NULL;
|
*
|
||||||
char *certificate_file = NULL;
|
* Load a signature key and return an initialized #LassoSignatureContext structure. If the structure
|
||||||
|
* contains a new #xmlSecKey it must be freed by the caller. If your must store it. use
|
||||||
|
* lasso_assign_new_signature_context and not lasso_assign_signature_context which is gonna
|
||||||
|
* duplicate the key and so make a leak.
|
||||||
|
*
|
||||||
|
* Return value: an initialized LassoSignatureContext containing a freshly created @xmlSecKey object
|
||||||
|
* successful, LASSO_SIGNATURE_CONTEXT_NONE otherwise. The caller must free the #xmlSecKey.
|
||||||
|
*/
|
||||||
|
LassoSignatureContext
|
||||||
|
lasso_make_signature_context_from_buffer(const char *buffer, size_t length, const char *password,
|
||||||
|
LassoSignatureMethod signature_method, const char *certificate) {
|
||||||
|
LassoSignatureContext context = LASSO_SIGNATURE_CONTEXT_NONE;
|
||||||
|
|
||||||
lasso_node_get_signature(node, &sign_type, &sign_method, &private_key_file, &private_key_password,
|
context.signature_key = lasso_xmlsec_load_private_key_from_buffer(buffer, length, password,
|
||||||
&certificate_file);
|
signature_method, certificate);
|
||||||
|
if (context.signature_key) {
|
||||||
if (!sign_type) {
|
context.signature_method = signature_method;
|
||||||
sign_type = old_sign_type;
|
|
||||||
private_key_password = NULL;
|
|
||||||
private_key_file = old_private_key_file;
|
|
||||||
certificate_file = old_certificate_file;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lasso_dump == FALSE && sign_type) {
|
|
||||||
char *node_name;
|
|
||||||
char *prefix;
|
|
||||||
|
|
||||||
node_name = LASSO_NODE_GET_CLASS(node)->node_data->node_name;
|
|
||||||
prefix = (char*)LASSO_NODE_GET_CLASS(node)->node_data->ns->prefix;
|
|
||||||
|
|
||||||
if (private_key_file == NULL) {
|
|
||||||
message(G_LOG_LEVEL_WARNING,
|
|
||||||
"No Private Key set for signing %s:%s", prefix, node_name);
|
|
||||||
} else {
|
|
||||||
rc = lasso_sign_node(*xmlnode, id_attribute, id_value, private_key_file,
|
|
||||||
private_key_password, certificate_file);
|
|
||||||
if (rc != 0) {
|
|
||||||
message(G_LOG_LEVEL_WARNING, "Signing of %s:%s: %s", prefix, node_name, lasso_strerror(rc));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (rc != 0) {
|
|
||||||
lasso_release_xml_node(*xmlnode);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* lasso_make_signature_context_from_path_or_string:
|
||||||
|
* @filename_or_buffer: a file path of a string containing the key PEM or Base64 encoded
|
||||||
|
* @password: an eventual password to decoded the private key contained in @buffer
|
||||||
|
* @signature_method: the signature method to associate to this key
|
||||||
|
* @certificate: a certificate as a file path or PEM encoded in a NULL-terminated string, to
|
||||||
|
* associate with the key, it will be used to fill the KeyInfo node in an eventual signature.
|
||||||
|
*
|
||||||
|
* Load a signature key and return an initialized #LassoSignatureContext structure. If the structure
|
||||||
|
* contains a new #xmlSecKey it must be freed by the caller. If your must store it. use
|
||||||
|
* lasso_assign_new_signature_context and not lasso_assign_signature_context which is gonna
|
||||||
|
* duplicate the key and so make a leak.
|
||||||
|
*
|
||||||
|
* Return value: an initialized LassoSignatureContext containing a freshly created @xmlSecKey object
|
||||||
|
* successful, LASSO_SIGNATURE_CONTEXT_NONE otherwise.
|
||||||
|
*/
|
||||||
|
LassoSignatureContext
|
||||||
|
lasso_make_signature_context_from_path_or_string(char *filename_or_buffer, const char *password,
|
||||||
|
LassoSignatureMethod signature_method, const char *certificate) {
|
||||||
|
LassoSignatureContext context = LASSO_SIGNATURE_CONTEXT_NONE;
|
||||||
|
|
||||||
|
context.signature_key = lasso_xmlsec_load_private_key(filename_or_buffer, password,
|
||||||
|
signature_method, certificate);
|
||||||
|
if (context.signature_key) {
|
||||||
|
context.signature_method = signature_method;
|
||||||
|
}
|
||||||
|
return context;
|
||||||
}
|
}
|
||||||
|
|
317
lasso/xml/xml.c
317
lasso/xml/xml.c
|
@ -402,22 +402,28 @@ lasso_node_export_to_query_with_password(LassoNode *node,
|
||||||
const char *private_key_file_password)
|
const char *private_key_file_password)
|
||||||
{
|
{
|
||||||
char *unsigned_query, *query = NULL;
|
char *unsigned_query, *query = NULL;
|
||||||
|
LassoSignatureContext context = LASSO_SIGNATURE_CONTEXT_NONE;
|
||||||
|
|
||||||
g_return_val_if_fail(LASSO_IS_NODE(node), NULL);
|
g_return_val_if_fail(LASSO_IS_NODE(node), NULL);
|
||||||
|
|
||||||
unsigned_query = lasso_node_build_query(node);
|
context.signature_method = sign_method;
|
||||||
if (unsigned_query == NULL) {
|
context.signature_key = lasso_xmlsec_load_private_key(private_key_file,
|
||||||
|
private_key_file_password, sign_method, NULL);
|
||||||
|
|
||||||
|
if (! context.signature_key) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (private_key_file) {
|
|
||||||
query = lasso_query_sign(unsigned_query, sign_method, private_key_file,
|
|
||||||
private_key_file_password);
|
|
||||||
} else {
|
|
||||||
lasso_transfer_string(query, unsigned_query);
|
|
||||||
}
|
|
||||||
lasso_release(unsigned_query);
|
|
||||||
|
|
||||||
return query;
|
unsigned_query = lasso_node_build_query(node);
|
||||||
|
if (unsigned_query){
|
||||||
|
query = lasso_query_sign(unsigned_query, context);
|
||||||
|
if (query) {
|
||||||
|
lasso_release(unsigned_query);
|
||||||
|
unsigned_query = query;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lasso_release_sec_key(context.signature_key);
|
||||||
|
return unsigned_query;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -724,6 +730,52 @@ lasso_node_build_query(LassoNode *node)
|
||||||
return class->build_query(node);
|
return class->build_query(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static LassoNodeClassData*
|
||||||
|
lasso_legacy_get_signature_node_data(LassoNode *node, LassoNodeClass **out_klass)
|
||||||
|
{
|
||||||
|
LassoNodeClass *klass = NULL;
|
||||||
|
LassoNodeClassData *node_data = NULL;
|
||||||
|
|
||||||
|
klass = LASSO_NODE_GET_CLASS(node);
|
||||||
|
/* find a klass defining a signature */
|
||||||
|
while (klass && LASSO_IS_NODE_CLASS(klass)) {
|
||||||
|
if (klass->node_data && klass->node_data->sign_type_offset) {
|
||||||
|
if (out_klass) {
|
||||||
|
*out_klass = klass;
|
||||||
|
}
|
||||||
|
node_data = klass->node_data;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
klass = g_type_class_peek_parent(klass);
|
||||||
|
}
|
||||||
|
|
||||||
|
return node_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
lasso_legacy_extract_and_copy_signature_parameters(LassoNode *node, LassoNodeClassData *node_data)
|
||||||
|
{
|
||||||
|
LassoSignatureMethod signature_method = LASSO_SIGNATURE_METHOD_NONE;
|
||||||
|
char *private_key_file = NULL;
|
||||||
|
char *certificate_file = NULL;
|
||||||
|
|
||||||
|
if (! node_data) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
signature_method = G_STRUCT_MEMBER(LassoSignatureMethod, node,
|
||||||
|
node_data->sign_method_offset);
|
||||||
|
private_key_file = G_STRUCT_MEMBER(char *, node, node_data->private_key_file_offset);
|
||||||
|
certificate_file = G_STRUCT_MEMBER(char *, node, node_data->certificate_file_offset);
|
||||||
|
if (! lasso_validate_signature_method(signature_method)) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (lasso_node_set_signature(node,
|
||||||
|
lasso_make_signature_context_from_path_or_string(private_key_file, NULL,
|
||||||
|
signature_method, certificate_file)) != 0) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* lasso_node_get_xmlNode:
|
* lasso_node_get_xmlNode:
|
||||||
|
@ -737,35 +789,31 @@ lasso_node_build_query(LassoNode *node)
|
||||||
xmlNode*
|
xmlNode*
|
||||||
lasso_node_get_xmlNode(LassoNode *node, gboolean lasso_dump)
|
lasso_node_get_xmlNode(LassoNode *node, gboolean lasso_dump)
|
||||||
{
|
{
|
||||||
LassoNodeClass *class;
|
xmlNode *xmlnode = NULL;
|
||||||
xmlNode *xmlnode;
|
LassoSignatureContext context = LASSO_SIGNATURE_CONTEXT_NONE;
|
||||||
LassoNodeClassData *node_data = NULL;
|
LassoNodeClassData *node_data;
|
||||||
|
|
||||||
g_return_val_if_fail (LASSO_IS_NODE(node), NULL);
|
g_return_val_if_fail (LASSO_IS_NODE(node), NULL);
|
||||||
class = LASSO_NODE_GET_CLASS(node);
|
xmlnode = LASSO_NODE_GET_CLASS(node)->get_xmlNode(node, lasso_dump);
|
||||||
xmlnode = class->get_xmlNode(node, lasso_dump);
|
node_data = lasso_legacy_get_signature_node_data(node, NULL);
|
||||||
|
context = lasso_node_get_signature(node);
|
||||||
/* find a class defining a signature */
|
/* support for legacy way to put a signature on a node */
|
||||||
while (class && LASSO_IS_NODE_CLASS(class)) {
|
if (! lasso_validate_signature_context(context)) {
|
||||||
if (class->node_data && class->node_data->sign_type_offset) {
|
if (lasso_legacy_extract_and_copy_signature_parameters(node, node_data))
|
||||||
node_data = class->node_data;
|
context = lasso_node_get_signature(node);
|
||||||
break;
|
|
||||||
}
|
|
||||||
class = g_type_class_peek_parent(class);
|
|
||||||
}
|
}
|
||||||
|
if (! lasso_dump && node_data && xmlnode && lasso_validate_signature_context(context)) {
|
||||||
|
int rc;
|
||||||
|
char *id_attribute = G_STRUCT_MEMBER(char*, node,
|
||||||
|
node_data->id_attribute_offset);
|
||||||
|
|
||||||
/* add signature */
|
rc = lasso_sign_node(xmlnode, context, node_data->id_attribute_name,
|
||||||
if (xmlnode && node_data && node_data->sign_type_offset) {
|
id_attribute);
|
||||||
LassoSignatureType sign_type = G_STRUCT_MEMBER(LassoSignatureType, node,
|
if (rc != 0) {
|
||||||
node_data->sign_type_offset);
|
warning("Signing of %s:%s failed: %s", xmlnode->ns->prefix,
|
||||||
char *id_attribute = G_STRUCT_MEMBER(char*, node, node_data->id_attribute_offset);
|
xmlnode->name, lasso_strerror(rc));
|
||||||
char *private_key_file = G_STRUCT_MEMBER(char*, node,
|
lasso_release_xml_node(xmlnode);
|
||||||
node_data->private_key_file_offset);
|
}
|
||||||
char *certificate_file = G_STRUCT_MEMBER(char*, node,
|
|
||||||
node_data->certificate_file_offset);
|
|
||||||
|
|
||||||
lasso_apply_signature(node, lasso_dump, &xmlnode, node_data->id_attribute_name,
|
|
||||||
id_attribute, sign_type, private_key_file, certificate_file);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return xmlnode;
|
return xmlnode;
|
||||||
|
@ -873,11 +921,7 @@ struct _CustomElement {
|
||||||
char *href;
|
char *href;
|
||||||
char *nodename;
|
char *nodename;
|
||||||
GHashTable *namespaces;
|
GHashTable *namespaces;
|
||||||
LassoSignatureType signature_type;
|
LassoSignatureContext signature_context;
|
||||||
LassoSignatureMethod signature_method;
|
|
||||||
char *private_key;
|
|
||||||
char *private_key_password;
|
|
||||||
char *certificate;
|
|
||||||
xmlSecKey *encryption_public_key;
|
xmlSecKey *encryption_public_key;
|
||||||
LassoEncryptionSymKeyType encryption_sym_key_type;
|
LassoEncryptionSymKeyType encryption_sym_key_type;
|
||||||
};
|
};
|
||||||
|
@ -898,10 +942,8 @@ _lasso_node_free_custom_element(struct _CustomElement *custom_element)
|
||||||
lasso_release_string(custom_element->href);
|
lasso_release_string(custom_element->href);
|
||||||
lasso_release_string(custom_element->nodename);
|
lasso_release_string(custom_element->nodename);
|
||||||
lasso_release_ghashtable(custom_element->namespaces);
|
lasso_release_ghashtable(custom_element->namespaces);
|
||||||
lasso_release_string(custom_element->private_key);
|
|
||||||
lasso_release_string(custom_element->private_key_password);
|
|
||||||
lasso_release_string(custom_element->certificate);
|
|
||||||
lasso_release_sec_key(custom_element->encryption_public_key);
|
lasso_release_sec_key(custom_element->encryption_public_key);
|
||||||
|
lasso_release_sec_key(custom_element->signature_context.signature_key);
|
||||||
}
|
}
|
||||||
lasso_release(custom_element);
|
lasso_release(custom_element);
|
||||||
}
|
}
|
||||||
|
@ -965,19 +1007,14 @@ lasso_node_set_custom_namespace(LassoNode *node, const char *prefix, const char
|
||||||
/**
|
/**
|
||||||
* lasso_node_set_signature:
|
* lasso_node_set_signature:
|
||||||
* @node: a #LassoNode object
|
* @node: a #LassoNode object
|
||||||
* @signature_type: a #LassoSignatureType enum
|
* @signature_context: a #LassoSignatureContext structure
|
||||||
* @signature_method: a #LassoSignatureMethod enum
|
|
||||||
* @private_key: a private key as file path or a PEM string
|
|
||||||
* @private_key_password: the password for the private key
|
|
||||||
* @certificate: an eventual certificate to bind with the signature
|
|
||||||
*
|
*
|
||||||
* Setup a signature on @node.
|
* Setup a signature on @node.
|
||||||
*
|
*
|
||||||
* Return value: 0 if successful, an error code otherwise.
|
* Return value: 0 if successful, an error code otherwise.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
lasso_node_set_signature(LassoNode *node, LassoSignatureType type, LassoSignatureMethod method,
|
lasso_node_set_signature(LassoNode *node, LassoSignatureContext context)
|
||||||
const char *private_key, const char *private_key_password, const char *certificate)
|
|
||||||
{
|
{
|
||||||
struct _CustomElement *custom_element;
|
struct _CustomElement *custom_element;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
@ -985,11 +1022,13 @@ lasso_node_set_signature(LassoNode *node, LassoSignatureType type, LassoSignatur
|
||||||
lasso_bad_param(NODE, node);
|
lasso_bad_param(NODE, node);
|
||||||
custom_element = _lasso_node_get_custom_element_or_create(node);
|
custom_element = _lasso_node_get_custom_element_or_create(node);
|
||||||
g_return_val_if_fail (custom_element != NULL, LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
|
g_return_val_if_fail (custom_element != NULL, LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
|
||||||
custom_element->signature_type = type;
|
|
||||||
custom_element->signature_method = method;
|
if (custom_element->signature_context.signature_key) {
|
||||||
lasso_assign_string(custom_element->private_key, private_key);
|
lasso_release_sec_key(custom_element->signature_context.signature_key);
|
||||||
lasso_assign_string(custom_element->private_key_password, private_key_password);
|
}
|
||||||
lasso_assign_string(custom_element->certificate, certificate);
|
custom_element->signature_context.signature_method = context.signature_method;
|
||||||
|
lasso_assign_new_sec_key(custom_element->signature_context.signature_key,
|
||||||
|
context.signature_key);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1004,37 +1043,17 @@ lasso_node_set_signature(LassoNode *node, LassoSignatureType type, LassoSignatur
|
||||||
*
|
*
|
||||||
* Return signature parameters stored with this node.
|
* Return signature parameters stored with this node.
|
||||||
*/
|
*/
|
||||||
void
|
LassoSignatureContext
|
||||||
lasso_node_get_signature(LassoNode *node, LassoSignatureType *type, LassoSignatureMethod *method,
|
lasso_node_get_signature(LassoNode *node)
|
||||||
char **private_key, char **private_key_password, char **certificate)
|
|
||||||
{
|
{
|
||||||
struct _CustomElement *custom_element;
|
struct _CustomElement *custom_element;
|
||||||
|
|
||||||
g_return_if_fail (LASSO_IS_NODE(node));
|
g_return_val_if_fail (LASSO_IS_NODE(node), LASSO_SIGNATURE_CONTEXT_NONE);
|
||||||
custom_element = _lasso_node_get_custom_element(node);
|
custom_element = _lasso_node_get_custom_element(node);
|
||||||
if (! custom_element) {
|
if (! custom_element) {
|
||||||
if (type)
|
return LASSO_SIGNATURE_CONTEXT_NONE;
|
||||||
*type = 0;
|
|
||||||
if (method)
|
|
||||||
*method = 0;
|
|
||||||
if (private_key)
|
|
||||||
lasso_assign_string(*private_key, NULL);
|
|
||||||
if (private_key_password)
|
|
||||||
lasso_assign_string(*private_key_password, NULL);
|
|
||||||
if (certificate)
|
|
||||||
lasso_assign_string(*certificate, NULL);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
if (type)
|
return custom_element->signature_context;
|
||||||
*type = custom_element->signature_type;
|
|
||||||
if (method)
|
|
||||||
*method = custom_element->signature_method;
|
|
||||||
if (private_key)
|
|
||||||
*private_key = custom_element->private_key;
|
|
||||||
if (private_key_password)
|
|
||||||
*private_key_password = custom_element->private_key_password;
|
|
||||||
if (certificate)
|
|
||||||
*certificate = custom_element->certificate;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1542,11 +1561,12 @@ lasso_node_impl_init_from_xml(LassoNode *node, xmlNode *xmlnode)
|
||||||
|
|
||||||
/* Collect signature parameters */
|
/* Collect signature parameters */
|
||||||
{
|
{
|
||||||
LassoSignatureMethod method;
|
LassoSignatureMethod method = 0;
|
||||||
LassoSignatureType type;
|
LassoSignatureType type = 0;
|
||||||
xmlChar *private_key = NULL;
|
xmlChar *private_key = NULL;
|
||||||
xmlChar *private_key_password = NULL;
|
xmlChar *private_key_password = NULL;
|
||||||
xmlChar *certificate = NULL;
|
xmlChar *certificate = NULL;
|
||||||
|
LassoSignatureContext signature_context = LASSO_SIGNATURE_CONTEXT_NONE;
|
||||||
|
|
||||||
while (snippet_signature) {
|
while (snippet_signature) {
|
||||||
int what;
|
int what;
|
||||||
|
@ -1561,7 +1581,7 @@ lasso_node_impl_init_from_xml(LassoNode *node, xmlNode *xmlnode)
|
||||||
LASSO_SIGNATURE_TYPE_LAST))
|
LASSO_SIGNATURE_TYPE_LAST))
|
||||||
break;
|
break;
|
||||||
type = what;
|
type = what;
|
||||||
private_key = xmlGetNsProp(xmlnode, LASSO_PRIVATE_KEY_PASSWORD_ATTRIBUTE,
|
private_key_password = xmlGetNsProp(xmlnode, LASSO_PRIVATE_KEY_PASSWORD_ATTRIBUTE,
|
||||||
BAD_CAST LASSO_LIB_HREF);
|
BAD_CAST LASSO_LIB_HREF);
|
||||||
if (! private_key)
|
if (! private_key)
|
||||||
break;
|
break;
|
||||||
|
@ -1569,8 +1589,11 @@ lasso_node_impl_init_from_xml(LassoNode *node, xmlNode *xmlnode)
|
||||||
LASSO_LIB_HREF);
|
LASSO_LIB_HREF);
|
||||||
certificate = xmlGetNsProp(xmlnode, LASSO_CERTIFICATE_ATTRIBUTE, BAD_CAST
|
certificate = xmlGetNsProp(xmlnode, LASSO_CERTIFICATE_ATTRIBUTE, BAD_CAST
|
||||||
LASSO_LIB_HREF);
|
LASSO_LIB_HREF);
|
||||||
lasso_node_set_signature(node, type,
|
|
||||||
method, (char*) private_key, (char*) private_key_password, (char*) certificate);
|
signature_context.signature_method = method;
|
||||||
|
signature_context.signature_key = lasso_xmlsec_load_private_key((char*) private_key,
|
||||||
|
(char*) private_key_password, method, (char*) certificate);
|
||||||
|
lasso_node_set_signature(node, signature_context);
|
||||||
}
|
}
|
||||||
lasso_release_xml_string(private_key);
|
lasso_release_xml_string(private_key);
|
||||||
lasso_release_xml_string(private_key_password);
|
lasso_release_xml_string(private_key_password);
|
||||||
|
@ -1652,8 +1675,7 @@ lasso_node_remove_signature(LassoNode *node) {
|
||||||
}
|
}
|
||||||
klass = g_type_class_peek_parent(klass);
|
klass = g_type_class_peek_parent(klass);
|
||||||
}
|
}
|
||||||
lasso_node_set_signature(node, LASSO_SIGNATURE_TYPE_NONE, LASSO_SIGNATURE_METHOD_RSA_SHA1,
|
lasso_node_set_signature(node, LASSO_SIGNATURE_CONTEXT_NONE);
|
||||||
NULL, NULL, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -1797,37 +1819,6 @@ lasso_node_impl_get_xmlNode(LassoNode *node, gboolean lasso_dump)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* store signature parameters */
|
|
||||||
if (lasso_dump)
|
|
||||||
{
|
|
||||||
LassoSignatureType type;
|
|
||||||
LassoSignatureMethod method;
|
|
||||||
const char *private_key = NULL;
|
|
||||||
const char *private_key_password = NULL;
|
|
||||||
const char *certificate = NULL;
|
|
||||||
xmlNsPtr ns = NULL;
|
|
||||||
char buffer[64] = { 0 };
|
|
||||||
|
|
||||||
lasso_node_get_signature(node, &type, &method, (char **)&private_key,
|
|
||||||
(char **)&private_key_password,
|
|
||||||
(char **)&certificate);
|
|
||||||
if (private_key) {
|
|
||||||
ns = get_or_define_ns(xmlnode, BAD_CAST LASSO_LASSO_HREF);
|
|
||||||
sprintf(buffer, "%u", type);
|
|
||||||
xmlSetNsProp(xmlnode, ns, LASSO_SIGNATURE_TYPE_ATTRIBUTE, BAD_CAST buffer);
|
|
||||||
sprintf(buffer, "%u", method);
|
|
||||||
xmlSetNsProp(xmlnode, ns, LASSO_SIGNATURE_METHOD_ATTRIBUTE, BAD_CAST buffer);
|
|
||||||
xmlSetNsProp(xmlnode, ns, LASSO_PRIVATE_KEY_ATTRIBUTE, BAD_CAST private_key);
|
|
||||||
if (private_key_password) {
|
|
||||||
xmlSetNsProp(xmlnode, ns, LASSO_PRIVATE_KEY_PASSWORD_ATTRIBUTE, BAD_CAST private_key_password);
|
|
||||||
}
|
|
||||||
if (certificate) {
|
|
||||||
xmlSetNsProp(xmlnode, ns, LASSO_CERTIFICATE_ATTRIBUTE, BAD_CAST certificate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return xmlnode;
|
return xmlnode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2732,50 +2723,50 @@ lasso_node_build_xmlNode_from_snippets(LassoNode *node, LassoNodeClass *class, x
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static void
|
||||||
void lasso_node_add_signature_template(LassoNode *node, xmlNode *xmlnode,
|
lasso_node_add_signature_template(LassoNode *node, xmlNode *xmlnode,
|
||||||
struct XmlSnippet *snippet_signature)
|
struct XmlSnippet *snippet_signature)
|
||||||
{
|
{
|
||||||
LassoNodeClass *klass = LASSO_NODE_GET_CLASS(node);
|
LassoNodeClass *klass = NULL;
|
||||||
GType g_type = G_TYPE_FROM_CLASS(klass);
|
LassoNodeClassData *node_data = NULL;
|
||||||
LassoSignatureType sign_type;
|
LassoSignatureContext context;
|
||||||
LassoSignatureMethod sign_method;
|
xmlSecTransformId transform_id;
|
||||||
xmlNode *signature = NULL, *reference, *key_info, *t;
|
xmlNode *signature = NULL, *reference, *key_info;
|
||||||
char *uri;
|
char *uri;
|
||||||
char *id;
|
char *id;
|
||||||
|
|
||||||
while (klass && LASSO_IS_NODE_CLASS(klass) && klass->node_data) {
|
|
||||||
if (klass->node_data->sign_type_offset)
|
node_data = lasso_legacy_get_signature_node_data(node, &klass);
|
||||||
|
if (! node_data)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (node_data->sign_type_offset == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
context = lasso_node_get_signature(node);
|
||||||
|
if (! lasso_validate_signature_context(context))
|
||||||
|
if (lasso_legacy_extract_and_copy_signature_parameters(node, node_data))
|
||||||
|
context = lasso_node_get_signature(node);
|
||||||
|
|
||||||
|
if (! lasso_validate_signature_context(context))
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (context.signature_method) {
|
||||||
|
case LASSO_SIGNATURE_METHOD_RSA_SHA1:
|
||||||
|
transform_id = xmlSecTransformRsaSha1Id;
|
||||||
break;
|
break;
|
||||||
klass = g_type_class_peek_parent(klass);
|
case LASSO_SIGNATURE_METHOD_DSA_SHA1:
|
||||||
|
transform_id = xmlSecTransformDsaSha1Id;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
signature = xmlSecTmplSignatureCreate(NULL,
|
||||||
if (klass->node_data->sign_type_offset == 0)
|
xmlSecTransformExclC14NId,
|
||||||
return;
|
transform_id, NULL);
|
||||||
|
|
||||||
sign_type = G_STRUCT_MEMBER(
|
|
||||||
LassoSignatureType, node,
|
|
||||||
klass->node_data->sign_type_offset);
|
|
||||||
sign_method = G_STRUCT_MEMBER(
|
|
||||||
LassoSignatureMethod, node,
|
|
||||||
klass->node_data->sign_method_offset);
|
|
||||||
|
|
||||||
if (sign_type == LASSO_SIGNATURE_TYPE_NONE)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (sign_method == LASSO_SIGNATURE_METHOD_RSA_SHA1) {
|
|
||||||
signature = xmlSecTmplSignatureCreate(NULL,
|
|
||||||
xmlSecTransformExclC14NId,
|
|
||||||
xmlSecTransformRsaSha1Id, NULL);
|
|
||||||
} else {
|
|
||||||
signature = xmlSecTmplSignatureCreate(NULL,
|
|
||||||
xmlSecTransformExclC14NId,
|
|
||||||
xmlSecTransformDsaSha1Id, NULL);
|
|
||||||
}
|
|
||||||
/* XXX: get out if signature == NULL ? */
|
|
||||||
xmlAddChild(xmlnode, signature);
|
xmlAddChild(xmlnode, signature);
|
||||||
|
|
||||||
id = SNIPPET_STRUCT_MEMBER(char *, node, g_type, snippet_signature);
|
id = SNIPPET_STRUCT_MEMBER(char *, node, G_TYPE_FROM_CLASS(klass), snippet_signature);
|
||||||
uri = g_strdup_printf("#%s", id);
|
uri = g_strdup_printf("#%s", id);
|
||||||
reference = xmlSecTmplSignatureAddReference(signature,
|
reference = xmlSecTmplSignatureAddReference(signature,
|
||||||
xmlSecTransformSha1Id, NULL, (xmlChar*)uri, NULL);
|
xmlSecTransformSha1Id, NULL, (xmlChar*)uri, NULL);
|
||||||
|
@ -2785,11 +2776,21 @@ void lasso_node_add_signature_template(LassoNode *node, xmlNode *xmlnode,
|
||||||
xmlSecTmplReferenceAddTransform(reference, xmlSecTransformEnvelopedId);
|
xmlSecTmplReferenceAddTransform(reference, xmlSecTransformEnvelopedId);
|
||||||
/* add exclusive C14N transform */
|
/* add exclusive C14N transform */
|
||||||
xmlSecTmplReferenceAddTransform(reference, xmlSecTransformExclC14NId);
|
xmlSecTmplReferenceAddTransform(reference, xmlSecTransformExclC14NId);
|
||||||
|
/* if the key is the public part of a symetric key, add its certificate or the key itself */
|
||||||
if (sign_type == LASSO_SIGNATURE_TYPE_WITHX509) {
|
switch (context.signature_method) {
|
||||||
/* add <dsig:KeyInfo/> */
|
case LASSO_SIGNATURE_METHOD_RSA_SHA1:
|
||||||
key_info = xmlSecTmplSignatureEnsureKeyInfo(signature, NULL);
|
case LASSO_SIGNATURE_METHOD_DSA_SHA1:
|
||||||
t = xmlSecTmplKeyInfoAddX509Data(key_info);
|
/* symetric cryptography methods */
|
||||||
|
key_info = xmlSecTmplSignatureEnsureKeyInfo(signature, NULL);
|
||||||
|
if (xmlSecKeyGetData(context.signature_key, xmlSecOpenSSLKeyDataX509Id)) {
|
||||||
|
/* add <dsig:KeyInfo/> */
|
||||||
|
xmlSecTmplKeyInfoAddX509Data(key_info);
|
||||||
|
} else {
|
||||||
|
xmlSecTmplKeyInfoAddKeyValue(key_info);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -278,7 +278,8 @@ START_TEST(test06_lib_statuscode)
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
extern xmlSecKey* lasso_xmlsec_load_private_key_from_buffer(const char *buffer, size_t length, const char *password);
|
extern xmlSecKey* lasso_xmlsec_load_private_key_from_buffer(const char *buffer, size_t length, const
|
||||||
|
char *password, LassoSignatureMethod method, const char *certificate);
|
||||||
|
|
||||||
extern int lasso_saml2_query_verify_signature(const char *query, const xmlSecKey *sender_public_key);
|
extern int lasso_saml2_query_verify_signature(const char *query, const xmlSecKey *sender_public_key);
|
||||||
|
|
||||||
|
@ -315,7 +316,8 @@ NC1/bzp8cGOcJ88BD5+Ny6qgPVCrMLE5twQumJ12V3SvjGNtzFBvg2c/9S5OmVqR\n\
|
||||||
LlTxKnCrWAXftSm1rNtewTsF\n\
|
LlTxKnCrWAXftSm1rNtewTsF\n\
|
||||||
-----END CERTIFICATE-----";
|
-----END CERTIFICATE-----";
|
||||||
|
|
||||||
xmlSecKeyPtr key = lasso_xmlsec_load_private_key_from_buffer(pkey, sizeof(pkey)-1, NULL);
|
xmlSecKeyPtr key = lasso_xmlsec_load_private_key_from_buffer(pkey, sizeof(pkey)-1, NULL,
|
||||||
|
LASSO_SIGNATURE_METHOD_RSA_SHA1, NULL);
|
||||||
|
|
||||||
fail_unless(key != NULL, "Cannot load public key");
|
fail_unless(key != NULL, "Cannot load public key");
|
||||||
fail_unless(lasso_saml2_query_verify_signature(query1, key) == 0, "Signature was not validated");
|
fail_unless(lasso_saml2_query_verify_signature(query1, key) == 0, "Signature was not validated");
|
||||||
|
|
Loading…
Reference in New Issue