summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrederic Peters <fpeters@entrouvert.com>2005-04-25 10:43:48 +0000
committerFrederic Peters <fpeters@entrouvert.com>2005-04-25 10:43:48 +0000
commit397e980c6c345fa4d74f605041fbf74ab12bd1a9 (patch)
tree359fecdf188b733d12480e305bfdfbc9e2d6048e
parentddbcde8dddeecc039ceddf554447b2c3f6b944fa (diff)
loads public key into xmlSecKey on LassoProvider instanciation; this merges
signature verification in XML messages and in query strings.
-rw-r--r--lasso/id-ff/provider.c65
-rw-r--r--lasso/id-ff/providerprivate.h2
-rw-r--r--lasso/id-ff/server.c1
-rw-r--r--lasso/xml/private.h2
-rw-r--r--lasso/xml/tools.c75
5 files changed, 82 insertions, 63 deletions
diff --git a/lasso/id-ff/provider.c b/lasso/id-ff/provider.c
index 4fb2b908..eb1c66a8 100644
--- a/lasso/id-ff/provider.c
+++ b/lasso/id-ff/provider.c
@@ -40,6 +40,7 @@ struct _LassoProviderPrivate
char *default_assertion_consumer;
GHashTable *IDPDescriptor;
xmlNode *organization;
+ xmlSecKey *public_key;
};
static char *protocol_uris[] = {
@@ -59,8 +60,6 @@ static char *protocol_md_nodename[] = {
static char *protocol_roles[] = { NULL, "sp", "idp"};
char *protocol_methods[] = {"", "", "", "", "", "-http", "-soap"};
-
-
/*****************************************************************************/
/* public methods */
/*****************************************************************************/
@@ -462,8 +461,15 @@ dispose(GObject *object)
provider->private_data->organization = NULL;
}
- if (provider->private_data->default_assertion_consumer)
+ if (provider->private_data->default_assertion_consumer) {
g_free(provider->private_data->default_assertion_consumer);
+ provider->private_data->default_assertion_consumer = NULL;
+ }
+
+ if (provider->private_data->public_key) {
+ xmlSecKeyDestroy(provider->private_data->public_key);
+ provider->private_data->public_key = NULL;
+ }
G_OBJECT_CLASS(parent_class)->dispose(G_OBJECT(provider));
}
@@ -500,6 +506,7 @@ instance_init(LassoProvider *provider)
provider->private_data->dispose_has_run = FALSE;
provider->private_data->default_assertion_consumer = NULL;
provider->private_data->organization = NULL;
+ provider->private_data->public_key = NULL;
/* no value_destroy_func since it shouldn't destroy the GList on insert */
provider->private_data->IDPDescriptor = g_hash_table_new_full(
@@ -673,9 +680,39 @@ lasso_provider_new(LassoProviderRole role, const char *metadata,
provider->public_key = g_strdup(public_key);
provider->ca_cert_chain = g_strdup(ca_cert_chain);
+ lasso_provider_load_public_key(provider);
+
return provider;
}
+void
+lasso_provider_load_public_key(LassoProvider *provider)
+{
+ LassoPemFileType file_type;
+ xmlSecKey *pub_key = NULL;
+
+ if (provider->public_key == NULL)
+ return;
+
+ file_type = lasso_get_pem_file_type(provider->public_key);
+ switch (file_type) {
+ case LASSO_PEM_FILE_TYPE_UNKNOWN:
+ break; /* with a warning ? */
+ case LASSO_PEM_FILE_TYPE_CERT:
+ pub_key = lasso_get_public_key_from_pem_cert_file(
+ provider->public_key);
+ break;
+ case LASSO_PEM_FILE_TYPE_PUB_KEY:
+ pub_key = xmlSecCryptoAppKeyLoad(provider->public_key,
+ xmlSecKeyDataFormatPem, NULL, NULL, NULL);
+ break;
+ case LASSO_PEM_FILE_TYPE_PRIVATE_KEY:
+ break; /* with a warning ? */
+ }
+ provider->private_data->public_key = pub_key;
+}
+
+
/**
* lasso_provider_new_from_dump:
* @dump: XML provider dump
@@ -694,6 +731,8 @@ lasso_provider_new_from_dump(const gchar *dump)
doc = xmlParseMemory(dump, strlen(dump));
init_from_xml(LASSO_NODE(provider), xmlDocGetRootElement(doc));
+ lasso_provider_load_public_key(provider);
+
return provider;
}
@@ -708,7 +747,6 @@ int lasso_provider_verify_signature(LassoProvider *provider,
xmlNode *xmlnode = NULL, *sign, *x509data;
xmlSecKeysMngr *keys_mngr = NULL;
xmlSecDSigCtx *dsigCtx;
- LassoPemFileType public_key_file_type;
int rc;
msg = (char*)message;
@@ -722,7 +760,7 @@ int lasso_provider_verify_signature(LassoProvider *provider,
return -2;
if (format == LASSO_MESSAGE_FORMAT_QUERY) {
- return lasso_query_verify_signature(message, provider->public_key);
+ return lasso_query_verify_signature(message, provider->private_data->public_key);
}
if (format == LASSO_MESSAGE_FORMAT_BASE64) {
@@ -792,22 +830,9 @@ int lasso_provider_verify_signature(LassoProvider *provider,
dsigCtx = xmlSecDSigCtxCreate(keys_mngr);
if (keys_mngr == NULL) {
- if (provider->public_key) {
- public_key_file_type = lasso_get_pem_file_type(provider->public_key);
- if (public_key_file_type == LASSO_PEM_FILE_TYPE_CERT) {
- /* public_key_file is a certificate file
- * => get public key in it */
- dsigCtx->signKey = lasso_get_public_key_from_pem_cert_file(
- provider->public_key);
- } else {
- /* load public key */
- dsigCtx->signKey = xmlSecCryptoAppKeyLoad(
- provider->public_key,
- xmlSecKeyDataFormatPem,
- NULL, NULL, NULL);
- }
- }
+ dsigCtx->signKey = provider->private_data->public_key;
if (dsigCtx->signKey == NULL) {
+ /* XXX: should this be detected on lasso_provider_new ? */
xmlSecDSigCtxDestroy(dsigCtx);
xmlFreeDoc(doc);
return LASSO_DS_ERROR_PUBLIC_KEY_LOAD_FAILED;
diff --git a/lasso/id-ff/providerprivate.h b/lasso/id-ff/providerprivate.h
index c026c889..b7714244 100644
--- a/lasso/id-ff/providerprivate.h
+++ b/lasso/id-ff/providerprivate.h
@@ -39,6 +39,8 @@ gboolean lasso_provider_load_metadata(LassoProvider *provider, const gchar *meta
int lasso_provider_verify_signature(LassoProvider *provider,
const char *message, const char *id_attr_name, LassoMessageFormat format);
LibertyConformanceLevel lasso_provider_compatibility_level(LassoProvider *provider);
+void lasso_provider_load_public_key(LassoProvider *provider);
+
#ifdef __cplusplus
}
diff --git a/lasso/id-ff/server.c b/lasso/id-ff/server.c
index 89adbd6e..4f2bc366 100644
--- a/lasso/id-ff/server.c
+++ b/lasso/id-ff/server.c
@@ -206,6 +206,7 @@ init_from_xml(LassoNode *node, xmlNode *xmlnode)
}
p = g_object_new(LASSO_TYPE_PROVIDER, NULL);
LASSO_NODE_GET_CLASS(p)->init_from_xml(LASSO_NODE(p), t2);
+ lasso_provider_load_public_key(p);
g_hash_table_insert(server->providers, g_strdup(p->ProviderID), p);
t2 = t2->next;
}
diff --git a/lasso/xml/private.h b/lasso/xml/private.h
index 78e8f2dd..9283dd03 100644
--- a/lasso/xml/private.h
+++ b/lasso/xml/private.h
@@ -103,7 +103,7 @@ xmlSecKeysMngr* lasso_load_certs_from_pem_certs_chain_file (const char *file);
xmlChar* lasso_query_sign(xmlChar *query,
LassoSignatureMethod sign_method, const char *private_key_file);
-int lasso_query_verify_signature(const char *query, const char *sender_public_key_file);
+int lasso_query_verify_signature(const char *query, const xmlSecKey *public_key);
char* lasso_sha1(const char *str);
diff --git a/lasso/xml/tools.c b/lasso/xml/tools.c
index 0b785a22..61aeebc2 100644
--- a/lasso/xml/tools.c
+++ b/lasso/xml/tools.c
@@ -403,7 +403,7 @@ done:
/**
* lasso_query_verify_signature:
* @query: a query (an url-encoded message)
- * @sender_public_key_file: the query sender public key
+ * @sender_public_key: the query sender public key
*
* Verifies the query signature.
*
@@ -412,9 +412,8 @@ done:
* a negative value if an error occurs during verification
**/
int
-lasso_query_verify_signature(const char *query, const char *sender_public_key_file)
+lasso_query_verify_signature(const char *query, const xmlSecKey *sender_public_key)
{
- BIO *bio = NULL;
RSA *rsa = NULL;
DSA *dsa = NULL;
gchar **str_split = NULL;
@@ -425,50 +424,49 @@ lasso_query_verify_signature(const char *query, const char *sender_public_key_fi
int key_size, status = 0, ret = 0;
g_return_val_if_fail(query != NULL, LASSO_PARAM_ERROR_INVALID_VALUE);
- g_return_val_if_fail(sender_public_key_file != NULL, LASSO_PARAM_ERROR_INVALID_VALUE);
+ g_return_val_if_fail(sender_public_key != NULL, LASSO_PARAM_ERROR_INVALID_VALUE);
+ g_return_val_if_fail(sender_public_key->value != NULL, LASSO_PARAM_ERROR_INVALID_VALUE);
/* split query, the signature MUST be the last param of the query */
/* FIXME: actually there could be more params in the URL; but they
* wouldn't be covered by the signature */
str_split = g_strsplit(query, "&Signature=", 0);
if (str_split[1] == NULL) {
- ret = LASSO_DS_ERROR_SIGNATURE_NOT_FOUND;
- goto done;
+ g_strfreev(str_split);
+ return LASSO_DS_ERROR_SIGNATURE_NOT_FOUND;
}
- /* create bio to read public key */
- bio = BIO_new_file(sender_public_key_file, "rb");
- if (bio == NULL) {
- ret = critical_error(LASSO_DS_ERROR_PUBLIC_KEY_LOAD_FAILED);
- goto done;
- }
+ if (sender_public_key->value->id == xmlSecOpenSSLKeyDataRsaId) {
+ rsa = xmlSecOpenSSLKeyDataRsaGetRsa(sender_public_key->value);
+ } else if (sender_public_key->value->id == xmlSecOpenSSLKeyDataDsaId) {
+ dsa = xmlSecOpenSSLKeyDataDsaGetDsa(sender_public_key->value);
+ } else {
+ /* no key; it will fail later */
+ }
/* get signature method (algorithm) and read public key */
e_rsa_alg = xmlURIEscapeStr(xmlSecHrefRsaSha1, NULL);
- e_dsa_alg = xmlURIEscapeStr(xmlSecHrefDsaSha1, NULL);
if (g_strrstr(str_split[0], e_rsa_alg) != NULL) {
sign_method = LASSO_SIGNATURE_METHOD_RSA_SHA1;
- rsa = PEM_read_bio_RSA_PUBKEY(bio, NULL, NULL, NULL);
- /* rsa = PEM_read_bio_RSAPublicKey(bio, NULL, NULL, NULL); */
if (rsa == NULL) {
- ret = LASSO_DS_ERROR_PUBLIC_KEY_LOAD_FAILED;
+ ret = critical_error(LASSO_DS_ERROR_PUBLIC_KEY_LOAD_FAILED);
goto done;
}
key_size = RSA_size(rsa);
- }
- else if (g_strrstr(str_split[0], e_dsa_alg) != NULL) {
- sign_method = LASSO_SIGNATURE_METHOD_DSA_SHA1;
- dsa = PEM_read_bio_DSA_PUBKEY(bio, NULL, NULL, NULL);
- if (dsa == NULL) {
- ret = LASSO_DS_ERROR_PUBLIC_KEY_LOAD_FAILED;
+ } else {
+ e_dsa_alg = xmlURIEscapeStr(xmlSecHrefDsaSha1, NULL);
+
+ if (g_strrstr(str_split[0], e_dsa_alg) != NULL) {
+ sign_method = LASSO_SIGNATURE_METHOD_DSA_SHA1;
+ if (dsa == NULL) {
+ ret = critical_error(LASSO_DS_ERROR_PUBLIC_KEY_LOAD_FAILED);
+ goto done;
+ }
+ key_size = DSA_size(dsa);
+ } else {
+ ret = critical_error(LASSO_DS_ERROR_INVALID_SIGALG);
goto done;
}
- key_size = DSA_size(dsa);
- }
- else {
- message(G_LOG_LEVEL_CRITICAL, lasso_strerror(LASSO_DS_ERROR_INVALID_SIGALG));
- ret = LASSO_DS_ERROR_INVALID_SIGALG;
- goto done;
}
/* get signature (unescape + base64 decode) */
@@ -476,23 +474,19 @@ lasso_query_verify_signature(const char *query, const char *sender_public_key_fi
b64_signature = xmlURIUnescapeString(str_split[1], 0, NULL);
xmlSecBase64Decode(b64_signature, signature, key_size+1);
- /* calculate signature digest */
+ /* compute signature digest */
digest = lasso_sha1(str_split[0]);
if (digest == NULL) {
- message(G_LOG_LEVEL_CRITICAL,
- lasso_strerror(LASSO_DS_ERROR_DIGEST_COMPUTE_FAILED));
- ret = LASSO_DS_ERROR_DIGEST_COMPUTE_FAILED;
+ ret = critical_error(LASSO_DS_ERROR_DIGEST_COMPUTE_FAILED);
goto done;
}
- if (sign_method == LASSO_SIGNATURE_METHOD_RSA_SHA1) {
- status = RSA_verify(NID_sha1, digest, 20, signature, RSA_size(rsa), rsa);
- /* printf("OpenSSL %s\n", ERR_error_string(ERR_get_error(), NULL)); */
- /* printf("OpenSSL %s\n", ERR_error_string(ERR_peek_last_error(), NULL)); */
- }
- else if (sign_method == LASSO_SIGNATURE_METHOD_DSA_SHA1) {
- status = DSA_verify(NID_sha1, digest, 20, signature, DSA_size(dsa), dsa);
+ if (rsa) {
+ status = RSA_verify(NID_sha1, digest, 20, signature, key_size, rsa);
+ } else if (dsa) {
+ status = DSA_verify(NID_sha1, digest, 20, signature, key_size, dsa);
}
+
if (status == 0) {
ret = LASSO_DS_ERROR_INVALID_SIGNATURE;
}
@@ -504,9 +498,6 @@ done:
xmlFree(e_rsa_alg);
xmlFree(e_dsa_alg);
g_strfreev(str_split);
- BIO_free(bio);
- RSA_free(rsa);
- DSA_free(dsa);
return ret;
}