diff options
| author | Frederic Peters <fpeters@entrouvert.com> | 2005-04-25 10:43:48 +0000 |
|---|---|---|
| committer | Frederic Peters <fpeters@entrouvert.com> | 2005-04-25 10:43:48 +0000 |
| commit | 397e980c6c345fa4d74f605041fbf74ab12bd1a9 (patch) | |
| tree | 359fecdf188b733d12480e305bfdfbc9e2d6048e | |
| parent | ddbcde8dddeecc039ceddf554447b2c3f6b944fa (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.c | 65 | ||||
| -rw-r--r-- | lasso/id-ff/providerprivate.h | 2 | ||||
| -rw-r--r-- | lasso/id-ff/server.c | 1 | ||||
| -rw-r--r-- | lasso/xml/private.h | 2 | ||||
| -rw-r--r-- | lasso/xml/tools.c | 75 |
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; } |
