00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifdef HAVE_CONFIG_H
00025 #include <config.h>
00026 #endif
00027
00028 #ifdef HAVE_SYS_TYPES_H
00029 #include <sys/types.h>
00030 #endif
00031
00032 #ifdef HAVE_SYS_UIO_H
00033 #include <sys/uio.h>
00034 #endif
00035
00036 #ifdef HAVE_STDIO_H
00037 #include <stdio.h>
00038 #endif
00039
00040 #ifdef HAVE_STRING_H
00041 #include <string.h>
00042 #endif
00043
00044 #ifdef HAVE_STDLIB_H
00045 #include <stdlib.h>
00046 #endif
00047
00048 #ifdef HAVE_ERRNO_H
00049 #include <errno.h>
00050 #endif
00051
00052 #ifdef HAVE_FCNTL_H
00053 #include <fcntl.h>
00054 #endif
00055
00056 #ifdef HAVE_CTYPE_H
00057 #include <ctype.h>
00058 #endif
00059
00060 #ifdef HAVE_UNISTD_H
00061 #include <unistd.h>
00062 #endif
00063
00064 #ifdef HAVE_PTHREAD_H
00065 #include <pthread.h>
00066 #endif
00067
00068 #include <libxml/tree.h>
00069 #include <libxml/uri.h>
00070 #include <libxml/parser.h>
00071 #include <libxml/xmlmemory.h>
00072 #include <libxml/xmlstring.h>
00073 #include <libxml/xpath.h>
00074 #include <libxml/xpathInternals.h>
00075
00076 #ifndef XMLSEC_NO_XSLT
00077 #include <libxslt/xslt.h>
00078 #endif
00079
00080 #include <xmlsec/xmlsec.h>
00081 #include <xmlsec/xmltree.h>
00082 #include <xmlsec/xmlenc.h>
00083 #include <xmlsec/xmldsig.h>
00084 #include <xmlsec/templates.h>
00085 #include <xmlsec/crypto.h>
00086 #include <xmlsec/errors.h>
00087
00088 #include <nanohttp/nanohttp-logging.h>
00089 #include <nanohttp/nanohttp-error.h>
00090 #include <nanohttp/nanohttp-common.h>
00091 #include <nanohttp/nanohttp-stream.h>
00092 #include <nanohttp/nanohttp-request.h>
00093 #include <nanohttp/nanohttp-response.h>
00094 #include <nanohttp/nanohttp-client.h>
00095 #include <nanohttp/nanohttp-server.h>
00096
00097 #include "soap-env.h"
00098 #include "soap-ctx.h"
00099 #include "soap-service.h"
00100 #include "soap-router.h"
00101 #include "soap-server.h"
00102 #include "soap-transport.h"
00103 #include "soap-addressing.h"
00104 #include "soap-xmlsec.h"
00105
00106 static int _soap_xmlsec_enabled = 0;
00107 static pthread_mutex_t _soap_xmlsec_lock;
00108
00109 static char *_soap_xmlsec_keyfile = NULL;
00110 static char *_soap_xmlsec_password = NULL;
00111 static char *_soap_xmlsec_certfile = NULL;
00112
00113 static xmlSecKeysMngrPtr _soap_xmlsec_key_manager = NULL;
00114 static xmlSecKeyPtr _soap_xmlsec_key = NULL;
00115
00116 static void _soap_xmlsec_error_callback(const char *file, int line, const char *func, const char *errorObject, const char *errorSubject, int reason, const char *msg)
00117 {
00118 log_error5("xmlsec error func=\"%s\" obj=\"%s\" sub=\"%s\" %s", func, errorObject, errorSubject, msg);
00119
00120 return;
00121 }
00122
00135 static xmlSecKeyPtr
00136 _soap_xmlsec_files_keys_store_find_key(xmlSecKeyStorePtr store, const xmlChar * name, xmlSecKeyInfoCtxPtr keyInfoCtx)
00137 {
00138 xmlSecKeyPtr key;
00139 xmlURI *uri;
00140 char *file;
00141
00142 log_verbose2("trying to find key \"%s\"\n", name);
00143
00144
00145
00146
00147
00148
00149 if (name == NULL)
00150 {
00151 printf("key name is NULL\n");
00152 return NULL;
00153 }
00154
00155 if (keyInfoCtx->keyReq.keyId == xmlSecKeyDataIdUnknown)
00156 {
00157 printf("keyReq.keyID == xmlSecKeyDataIdUnkown\n");
00158 return NULL;
00159 }
00160
00161 if (!(uri = xmlParseURI(name)))
00162 {
00163 printf("xmlParseURI failed\n");
00164 return NULL;
00165 }
00166
00167
00168
00169
00170
00171
00172 {
00173 char *tmp;
00174 char buf[4096];
00175 FILE *fp;
00176
00177 if (!(tmp = getenv("CSOAP_TEMP")))
00178 {
00179 tmp = "/tmp";
00180 }
00181 sprintf(buf, "%s/csoap-XXXXXX-key.pem", tmp);
00182
00183 if (mkstemps(buf, 8) < 0)
00184 {
00185 printf("mkstemps failed (%s)", strerror(errno));
00186 return NULL;
00187 }
00188
00189 file = strdup(buf);
00190
00191 if (!(fp = fopen(buf, "w")))
00192 {
00193 printf("fopen failed (%s)\n", strerror(errno));
00194 return NULL;
00195 }
00196
00197 if (!strcmp("https", uri->scheme) || !strcmp("http", uri->scheme))
00198 {
00199 size_t len;
00200 httpc_conn_t *conn;
00201 hresponse_t *res;
00202 herror_t status;
00203
00204 conn = httpc_new();
00205
00206 if ((status = (httpc_get(conn, &res, name))) != H_OK)
00207 {
00208 log_error2("httpc_get failed (%s)", herror_message(status));
00209 herror_release(status);
00210 return NULL;
00211 }
00212
00213 while (http_input_stream_is_ready(res->in))
00214 {
00215 len = http_input_stream_read(res->in, buf, 4096);
00216 fwrite(buf, len, 1, fp);
00217 }
00218 hresponse_free(res);
00219
00220 httpc_free(conn);
00221 }
00222 fclose(fp);
00223 }
00224
00225 if ((keyInfoCtx->keyReq.keyId == xmlSecKeyDataDsaId) || (keyInfoCtx->keyReq.keyId == xmlSecKeyDataRsaId)) {
00226
00227
00228
00229
00230 key = xmlSecCryptoAppKeyLoad(file, xmlSecKeyDataFormatPem, NULL, NULL, NULL);
00231 if (key == NULL) {
00232 fprintf(stderr, "Error: failed to load public pem key from \"%s\"\n", name);
00233 return (NULL);
00234 }
00235 }
00236 else {
00237
00238
00239
00240
00241 key = xmlSecKeyReadBinaryFile(keyInfoCtx->keyReq.keyId, file);
00242 if (key == NULL) {
00243 fprintf(stderr, "Error: failed to load key from binary file \"%s\"\n", name);
00244 return (NULL);
00245 }
00246 }
00247
00248
00249 if (xmlSecKeySetName(key, name) < 0) {
00250 fprintf(stderr, "Error: failed to set key name for key from \"%s\"\n", name);
00251 xmlSecKeyDestroy(key);
00252 return (NULL);
00253 }
00254
00255 if (unlink(file) < 0)
00256 {
00257 log_error2("unlink file failed (%s)", strerror(errno));
00258 }
00259 free(file);
00260
00261 return (key);
00262 }
00263
00264 static xmlSecKeyStoreKlass _soap_xmlsec_files_keys_store_klass =
00265 {
00266 sizeof(xmlSecKeyStoreKlass),
00267 sizeof(xmlSecKeyStore),
00268 BAD_CAST "uri-based-keys-store",
00269 NULL,
00270 NULL,
00271 _soap_xmlsec_files_keys_store_find_key,
00272
00273 NULL,
00274 NULL,
00275 };
00276
00277 static inline xmlSecKeyStoreId
00278 _soap_xmlsec_files_keys_store_get_klass(void)
00279 {
00280 return (&_soap_xmlsec_files_keys_store_klass);
00281 }
00282
00283 static herror_t
00284 _soap_xmlsec_create_key_manager(void)
00285 {
00286 xmlSecKeyStorePtr keysStore;
00287
00288
00289 keysStore = xmlSecKeyStoreCreate(_soap_xmlsec_files_keys_store_get_klass());
00290 if (keysStore == NULL)
00291 {
00292 log_error1("failed to create keys store");
00293 return herror_new("_soap_xmlxec_create_key_manager", XMLSEC_ERROR_KEYSTORE, "failed to create keys store");
00294 }
00295
00296
00297 if ((_soap_xmlsec_key_manager = xmlSecKeysMngrCreate()) == NULL)
00298 {
00299 log_error1("failed to create keys manager");
00300 xmlSecKeyStoreDestroy(keysStore);
00301 return herror_new("_soap_xmlsec_key_manager", XMLSEC_ERROR_KEYMANAGER, "failed to create keys manager");
00302 }
00303
00304
00305
00306
00307
00308 if (xmlSecKeysMngrAdoptKeysStore(_soap_xmlsec_key_manager, keysStore) < 0)
00309 {
00310 log_error1("failed to add keys store to keys manager");
00311 xmlSecKeyStoreDestroy(keysStore);
00312 xmlSecKeysMngrDestroy(_soap_xmlsec_key_manager);
00313 _soap_xmlsec_key_manager = NULL;
00314 return herror_new("_soap_xmlsec_create_key_manager", XMLSEC_ERROR_KEYMANAGER, "failed to add keys store to keys manager");
00315 }
00316
00317
00318 if (xmlSecCryptoKeysMngrInit(_soap_xmlsec_key_manager) < 0)
00319 {
00320 log_error1("failed to initialize crypto data in keys manager");
00321 xmlSecKeysMngrDestroy(_soap_xmlsec_key_manager);
00322 _soap_xmlsec_key_manager = NULL;
00323 return herror_new("_soap_xmlsec_create_key_manager", XMLSEC_ERROR_KEYMANAGER, "failed to initialize crypto data in keys manager");
00324 }
00325
00326
00327 _soap_xmlsec_key_manager->getKey = xmlSecKeysMngrGetKey;
00328
00329 return H_OK;
00330 }
00331
00332 static herror_t
00333 _soap_xmlsec_load_key(void)
00334 {
00335 int err;
00336 xmlChar keyName[256];
00337
00338 if ((_soap_xmlsec_key = xmlSecCryptoAppKeyLoad(_soap_xmlsec_keyfile, xmlSecKeyDataFormatPem, _soap_xmlsec_password, NULL, NULL)) == NULL)
00339 {
00340 log_error2("xmlSecCryptoAppKeyLoad(\"%s\") failed", _soap_xmlsec_keyfile);
00341 return herror_new("_soap_xmlsec_load_key", XMLSEC_ERROR_KEY, "xmlSecCryptoAppKeyLoad(\"%s\") failed", _soap_xmlsec_keyfile);
00342 }
00343
00344 if (_soap_xmlsec_certfile)
00345 {
00346 if (xmlSecCryptoAppKeyCertLoad(_soap_xmlsec_key, _soap_xmlsec_certfile, xmlSecKeyDataFormatPem) < 0)
00347 {
00348 log_error2("xmlSecCryptoAppKeyCertLoad(\"%s\") failed", _soap_xmlsec_certfile);
00349 xmlSecKeyDestroy(_soap_xmlsec_key);
00350 return herror_new("_soap_xmlsec_load_key", XMLSEC_ERROR_CERTIFICATE, "xmlSecCryptoAppKeyCertLoad(\"%s\") failed", _soap_xmlsec_certfile);
00351 }
00352 }
00353
00354 xmlStrPrintf(keyName, 256, "%s/key.pem", soap_server_get_name());
00355 log_error2("keyName is \"%s\"", keyName);
00356 if ((err = xmlSecKeySetName(_soap_xmlsec_key, keyName)) < 0)
00357 {
00358 xmlSecKeyDestroy(_soap_xmlsec_key);
00359 log_error3("xmlSecKeySetName(\"%s\") failed (%i)", keyName, err);
00360 return herror_new("_soap_xmlsec_load_key", XMLSEC_ERROR_KEY, "xmlSecKeySetName(\"%s\") failed (%i)", keyName, err);
00361 }
00362
00363
00364
00365
00366 return H_OK;
00367 }
00368
00369 static void
00370 _soap_xmlsec_key_service(httpd_conn_t *conn, struct hrequest_t *req)
00371 {
00372 char buf[4096];
00373 size_t len;
00374 int fd;
00375
00376 httpd_set_header(conn, HEADER_CONTENT_TYPE, "text/plain");
00377 if (!(fd = open(_soap_xmlsec_keyfile, O_RDONLY)))
00378 {
00379 httpd_send_header(conn, 404, HTTP_STATUS_404_REASON_PHRASE);
00380 http_output_stream_write_string(conn->out, "Public key not found!\n");
00381 }
00382 else
00383 {
00384 httpd_send_header(conn, 200, HTTP_STATUS_200_REASON_PHRASE);
00385
00386 while ((len = read(fd, buf, 4096)) > 0)
00387 http_output_stream_write(conn->out, buf, len);
00388 }
00389
00390 return;
00391 }
00392
00393 static herror_t
00394 _soap_xmlsec_publish_key(void)
00395 {
00396 herror_t status;
00397
00398 if ((status = httpd_register("/key.pem", _soap_xmlsec_key_service)) != H_OK)
00399 {
00400 log_error2("Cannot register key service (%s)", herror_message(status));
00401 return status;
00402 }
00403
00404 return H_OK;
00405 }
00406
00407 static inline void
00408 _soap_xmlsec_parse_arguments(int argc, char **argv)
00409 {
00410 int i;
00411
00412 for (i=1; i<=argc; i++)
00413 {
00414 if (!strcmp(argv[i-1], CSOAP_ENABLE_XMLSEC))
00415 {
00416 _soap_xmlsec_enabled = 1;
00417 }
00418 else if (!strcmp(argv[i-1], CSOAP_XMLSEC_KEYFILE))
00419 {
00420 _soap_xmlsec_keyfile = strdup(argv[i]);
00421 }
00422 else if (!strcmp(argv[i-1], CSOAP_XMLSEC_PASSWORD))
00423 {
00424 _soap_xmlsec_password = strdup(argv[i]);
00425 }
00426 else if (!strcmp(argv[i-1], CSOAP_XMLSEC_CERTFILE))
00427 {
00428 _soap_xmlsec_certfile = strdup(argv[i]);
00429 }
00430 }
00431 return;
00432 }
00433
00434 herror_t
00435 _soap_xmlsec_init(void)
00436 {
00437 static int initialized = 0;
00438 int err;
00439 herror_t status;
00440
00441 if (initialized)
00442 return H_OK;
00443
00444 log_info1("initializing xmlsec1");
00445
00446 xmlSecErrorsDefaultCallbackEnableOutput(1);
00447 xmlSecErrorsSetCallback(_soap_xmlsec_error_callback);
00448
00449 if (xmlSecInit() < 0)
00450 {
00451 log_error1("xmlSecInit failed");
00452 return herror_new("soap_xmlsec_init", XMLSEC_ERROR_INIT, "xmlSecInit failed");
00453 }
00454
00455 if (xmlSecCheckVersion() != 1)
00456 {
00457 log_error1("xmlSecCheckVersion failed, wrong xmlsec version");
00458 return herror_new("soap_xmlsec_init", XMLSEC_ERROR_VERSION, "Wrong xmlsec version");
00459 }
00460
00461 #ifdef XMLSEC_CRYPTO_DYNAMIC_LOADING
00462 log_verbose2("loading \"%s\" dynamic", XMLSEC_CRYPTO);
00463 if (xmlSecCryptoDLLoadLibrary(BAD_CAST XMLSEC_CRYPTO) < 0)
00464 {
00465 log_error1("xmlSecCryptoDLLoadLibrary failed");
00466 return herror_new("soap_xmlsec_init", XMLSEC_ERROR_DLLOAD, "xmlSecCryptoDLLoadLibrary failed");
00467 }
00468 #endif
00469
00470 if (xmlSecCryptoAppInit(NULL) < 0)
00471 {
00472 log_error1("xmlSecCryptoAppInit failed");
00473 return herror_new("soap_xmlsec_init", XMLSEC_ERROR_INIT, "xmlSecCryptoAppInit failed");
00474 }
00475
00476 if (xmlSecCryptoInit() < 0)
00477 {
00478 log_error1("xmlSecCryptoInit failed");
00479 return herror_new("soap_xmlsec_init", XMLSEC_ERROR_INIT, "xmlSecCryptoInit failed");
00480 }
00481
00482 if ((status = _soap_xmlsec_create_key_manager()) != H_OK)
00483 {
00484 log_error2("_soap_xmlsec_create_key_manager failed (%s)", herror_message(status));
00485 return status;
00486 }
00487
00488 if ((err = pthread_mutex_init(&_soap_xmlsec_lock, NULL)) < 0)
00489 {
00490 log_error2("pthread_mutex_init failed (%s)", strerror(err));
00491 return herror_new("soap_xmlsec_init", XMLSEC_ERROR_INIT, "pthread_mutex_init failed (%s)", strerror(err));
00492 }
00493
00494 if ((status = _soap_xmlsec_load_key()) != H_OK)
00495 {
00496 log_error2("_soap_xmlsec_load_key failed (%s)", herror_message(status));
00497 return status;
00498 }
00499
00500 initialized = 1;
00501
00502 return H_OK;
00503 }
00504
00505 herror_t
00506 soap_xmlsec_client_init_args(int argc, char **argv)
00507 {
00508 _soap_xmlsec_parse_arguments(argc, argv);
00509
00510 if (!_soap_xmlsec_enabled)
00511 return H_OK;
00512
00513 return _soap_xmlsec_init();
00514 }
00515
00516 herror_t
00517 soap_xmlsec_server_init_args(int argc, char **argv)
00518 {
00519 herror_t status;
00520
00521 _soap_xmlsec_parse_arguments(argc, argv);
00522
00523 if (!_soap_xmlsec_enabled)
00524 return H_OK;
00525
00526 if ((status = _soap_xmlsec_init()) != H_OK)
00527 {
00528 log_error2("_soap_xmlsec_init failed (%s)", herror_message(status));
00529 return status;
00530 }
00531
00532 if ((status = _soap_xmlsec_publish_key()) != H_OK)
00533 {
00534 log_error2("_soap_xmlsec_publish_key failed (%s)", herror_message(status));
00535 return status;
00536 }
00537
00538 return H_OK;
00539 }
00540
00541 herror_t soap_xmlsec_sign(struct SoapCtx *context)
00542 {
00543 xmlNodePtr signature;
00544 xmlNsPtr ns;
00545 xmlNodePtr signNode;
00546 xmlNodePtr refNode;
00547 xmlNodePtr keyInfoNode;
00548 xmlSecDSigCtxPtr dsigCtx;
00549 herror_t ret;
00550 struct SoapEnv *envelope;
00551
00552 if (!_soap_xmlsec_enabled)
00553 return H_OK;
00554
00555 envelope = context->env;
00556
00557 ret = H_OK;
00558
00559 pthread_mutex_lock(&_soap_xmlsec_lock);
00560
00561 if (!(signNode = xmlSecTmplSignatureCreate(envelope->root->doc, xmlSecTransformExclC14NId, xmlSecTransformRsaSha1Id, NULL)))
00562 {
00563 log_error1("xmlSecTmplSignatureCreate failed");
00564 ret = herror_new("soap_xmlsec_sign", XMLSEC_ERROR_SIGN_INIT, "xmlSecTmplSignatureCreate failed");
00565 goto out;
00566 }
00567
00568 signature = xmlNewNode(NULL, "Signature");
00569 ns = xmlNewNs(signature, SOAP_SECURITY_NAMESPACE, SOAP_SECURITY_PREFIX);
00570 xmlSetNs(signature, ns);
00571
00572 xmlSetNsProp(signature, envelope->root->ns, BAD_CAST "actor", soap_transport_get_name());
00573 xmlSetNsProp(signature, envelope->root->ns, BAD_CAST "mustUnderstand", BAD_CAST "1");
00574
00575 xmlAddChild(envelope->header, signature);
00576
00577 xmlAddChild(signature, signNode);
00578
00579 if (!(refNode = xmlSecTmplSignatureAddReference(signNode, xmlSecTransformSha1Id, "#Body", NULL, NULL)))
00580 {
00581 log_error1("xmlSecTmplSignatureAddReference failed");
00582 ret = herror_new("soap_xmlsec_sign", XMLSEC_ERROR_SIGN_INIT, "xmlSecTmplSignatureAddReference failed");
00583 goto out;
00584 }
00585
00586 if (!(keyInfoNode = xmlSecTmplSignatureEnsureKeyInfo(signNode, NULL)))
00587 {
00588 log_error1("xmlSecTmplSignatureEnsureKeyInfo failed");
00589 ret = herror_new("soap_xmlsec_sign", XMLSEC_ERROR_SIGN_INIT, "xmlSecTmplSignatureEnsureKeyInfo failed");
00590 goto out;
00591 }
00592
00593 if (xmlSecTmplKeyInfoAddKeyName(keyInfoNode, soap_server_get_name()) == NULL)
00594 {
00595 log_error1("xmlSecTmplKeyInfoAddKeyName failed");
00596 ret = herror_new("soap_xmlsec_sign", XMLSEC_ERROR_SIGN_INIT, "xmlSecTmplKeyInfoAddKeyName failed");
00597 goto out;
00598 }
00599
00600 if (!(dsigCtx = xmlSecDSigCtxCreate(_soap_xmlsec_key_manager)))
00601 {
00602 log_error1("xmlSecDSigCtxCreate failed");
00603 ret = herror_new("soap_xmlsec_sign", XMLSEC_ERROR_SIGN_INIT, "xmlSecDSigCtxCreate failed");
00604 goto out;
00605 }
00606
00607 dsigCtx->signKey = _soap_xmlsec_key;
00608
00609 if (xmlSecDSigCtxSign(dsigCtx, signNode) < 0)
00610 {
00611 log_error1("xmlSecDSigCtxSign failed");
00612 ret = herror_new("soap_xmlsec_sign", XMLSEC_ERROR_SIGN, "xmlSecDSigCtxSign failed");
00613 goto out;
00614 }
00615
00616 out:
00617
00618 pthread_mutex_unlock(&_soap_xmlsec_lock);
00619
00620 return H_OK;
00621 }
00622
00623 herror_t soap_xmlsec_encrypt(struct SoapCtx *context)
00624 {
00625 struct SoapEnv *envelope;
00626 herror_t ret;
00627 xmlNodePtr encDataNode = NULL;
00628 xmlNodePtr keyInfoNode = NULL;
00629 xmlNodePtr encKeyNode = NULL;
00630 xmlNodePtr keyInfoNode2 = NULL;
00631 xmlSecEncCtxPtr encCtx = NULL;
00632 xmlURI *to;
00633 xmlChar buf[256];
00634 xmlDocPtr doc;
00635
00636 if (!_soap_xmlsec_enabled)
00637 return H_OK;
00638
00639 ret = H_OK;
00640
00641 pthread_mutex_lock(&_soap_xmlsec_lock);
00642
00643 envelope = context->env;
00644
00645 doc = context->env->root->doc;
00646
00647
00648
00649
00650
00651 encDataNode = xmlSecTmplEncDataCreate(doc, xmlSecTransformDes3CbcId, NULL, xmlSecTypeEncElement, NULL, NULL);
00652 if (encDataNode == NULL)
00653 {
00654 log_error1("xmlSecTmplEnvDataCreate failed");
00655 ret = herror_new("soap_xmlsec_encrypt", XMLSEC_ERROR_ENCRYPT_INIT, "xmlSecTmplEnvDataCreate failed");
00656 goto out;
00657 }
00658
00659 if (xmlSecTmplEncDataEnsureCipherValue(encDataNode) == NULL)
00660 {
00661 log_error1("failed to add CipherValue node");
00662 ret = herror_new("soap_xmlsec_encrypt", XMLSEC_ERROR_ENCRYPT_INIT, "failed to add CipherValue node");
00663 goto out;
00664 }
00665
00666 keyInfoNode = xmlSecTmplEncDataEnsureKeyInfo(encDataNode, NULL);
00667 if (keyInfoNode == NULL)
00668 {
00669 log_error1("failed to add KeyInfo node");
00670 ret = herror_new("soap_xmlsec_encrypt", XMLSEC_ERROR_ENCRYPT_INIT, "failed to add KeyInfo node");
00671 goto out;
00672 }
00673
00674 encKeyNode = xmlSecTmplKeyInfoAddEncryptedKey(keyInfoNode, xmlSecTransformRsaOaepId, NULL, NULL, NULL);
00675 if (encKeyNode == NULL)
00676 {
00677 log_error1("failed to add KeyInfo");
00678 ret = herror_new("soap_xmlsec_encrypt", XMLSEC_ERROR_ENCRYPT_INIT, "failed to add KeyInfo");
00679 goto out;
00680 }
00681
00682 if (xmlSecTmplEncDataEnsureCipherValue(encKeyNode) == NULL)
00683 {
00684 log_error1("failed to add CipherValue node");
00685 ret = herror_new("soap_xmlsec_encrypt", XMLSEC_ERROR_ENCRYPT_INIT, "failed to add CipherValue node");
00686 goto out;
00687 }
00688
00689 keyInfoNode2 = xmlSecTmplEncDataEnsureKeyInfo(encKeyNode, NULL);
00690 if (keyInfoNode2 == NULL)
00691 {
00692 log_error1("failed to add key info (2)\n");
00693 ret = herror_new("soap_xmlsec_encrypt", XMLSEC_ERROR_ENCRYPT_INIT, "failed to add key info (2)");
00694 goto out;
00695 }
00696
00697 if (!(to = soap_addressing_get_to_address(envelope)))
00698 {
00699 log_error1("cannot get to address");
00700 ret = herror_new("soap_xmlsec_encrypt", XMLSEC_ERROR_ENCRYPT, "cannot get to address");
00701 goto out;
00702 }
00703 xmlStrPrintf(buf, 256, "http://%s:%i/key.pem", to->server, to->port);
00704 log_error2("adding key \"%s\"", buf);
00705 xmlFreeURI(to);
00706
00707 if (xmlSecTmplKeyInfoAddKeyName(keyInfoNode2, buf) == NULL)
00708 {
00709 log_error2("failed to add key name \"%s\"", buf);
00710 ret = herror_new("soap_xmlsec_encrypt", XMLSEC_ERROR_ENCRYPT_INIT, "failed to add key name \"%s\"", buf);
00711 goto out;
00712 }
00713
00714 encCtx = xmlSecEncCtxCreate(_soap_xmlsec_key_manager);
00715 if (encCtx == NULL)
00716 {
00717 log_error1("failed to create encryption context");
00718 ret = herror_new("soap_xmlsec_encrypt", XMLSEC_ERROR_ENCRYPT_INIT, "failed to create encryption context");
00719 goto out;
00720 }
00721
00722 encCtx->encKey = xmlSecKeyGenerate(xmlSecKeyDataDesId, 192, xmlSecKeyDataTypeSession);
00723 if (encCtx->encKey == NULL)
00724 {
00725 log_error1("failed to generate session key");
00726 ret = herror_new("soap_xmlsec_encrypt", XMLSEC_ERROR_ENCRYPT_INIT, "failed to generate session key");
00727 goto out;
00728 }
00729
00730
00731
00732
00733
00734 if (xmlSecEncCtxXmlEncrypt(encCtx, encDataNode, soap_env_get_method(envelope)) < 0)
00735 {
00736 log_error1("encryption failed");
00737 ret = herror_new("soap_xmlsec_encrypt", XMLSEC_ERROR_ENCRYPT, "encryption failed");
00738 goto out;
00739 }
00740
00741
00742
00743
00744
00745
00746
00747 out:
00748
00749 if (encCtx != NULL)
00750 xmlSecEncCtxDestroy(encCtx);
00751
00752 pthread_mutex_unlock(&_soap_xmlsec_lock);
00753
00754 return ret;
00755 }
00756
00757 herror_t soap_xmlsec_decrypt(struct SoapCtx *context)
00758 {
00759 struct SoapEnv *envelope;
00760 herror_t ret;
00761 xmlNodePtr method;
00762 xmlDocPtr doc = NULL;
00763 xmlNodePtr node = NULL;
00764 xmlSecEncCtxPtr encCtx = NULL;
00765
00766 if (!_soap_xmlsec_enabled)
00767 return H_OK;
00768
00769 ret = H_OK;
00770
00771 envelope = context->env;
00772
00773 if (!(method = soap_env_get_method(envelope)))
00774 {
00775 log_error1("cannot find messages method");
00776 return herror_new("soap_xmlsec_decrypt", 0, "cannot find message method");
00777 }
00778
00779 if (xmlStrcmp(method->name, BAD_CAST "EncryptedData"))
00780 {
00781 log_error2("message doesn't contain encrypted data (%s)", method->name);
00782 return H_OK;
00783 }
00784
00785 if (xmlStrcmp(method->ns->href, "http://www.w3.org/2001/04/xmlenc#"))
00786 {
00787 log_error2("message encryption isn't understood (%s)", method->ns->href);
00788 return herror_new("soap_xmlsec_decrypt", 0, "message encryption isn't understood (%s)", method->ns->href);
00789 }
00790
00791 doc = envelope->root->doc;
00792
00793
00794 node = xmlSecFindNode(envelope->root, xmlSecNodeEncryptedData, xmlSecEncNs);
00795 if (node == NULL)
00796 {
00797 log_error1("start node not found");
00798 ret = herror_new("soap_xmlsec_decrypt", 0, "start node not found");
00799 goto done;
00800 }
00801
00802
00803 encCtx = xmlSecEncCtxCreate(_soap_xmlsec_key_manager);
00804 if (encCtx == NULL)
00805 {
00806 log_error1("failed to create encryption context");
00807 ret = herror_new("soap_xmlsec_decrypt", 0, "failed to create encryption context");
00808 goto done;
00809 }
00810
00811
00812 if ((xmlSecEncCtxDecrypt(encCtx, node) < 0) || (encCtx->result == NULL))
00813 {
00814 log_error1("decryption failed");
00815 ret = herror_new("soap_xmlsec_decrypt", 0, "decryption failed");
00816 goto done;
00817 }
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836 done:
00837
00838 if (encCtx != NULL)
00839 {
00840 xmlSecEncCtxDestroy(encCtx);
00841 }
00842
00843 return ret;
00844 }
00845
00846 herror_t soap_xmlsec_verify(struct SoapCtx *context)
00847 {
00848 struct SoapEnv *envelope;
00849 xmlNodePtr walker;
00850
00851 if (!_soap_xmlsec_enabled)
00852 return H_OK;
00853
00854 envelope = context->env;
00855
00856 if (!envelope->header)
00857 {
00858 log_error1("message doesn't contain a SOAP header");
00859 return herror_new("soap_xmlsec_verify", 0, "message doesn't contain a SOAP header");
00860 }
00861
00862 for (walker=envelope->header->children; walker; walker=walker->next)
00863 {
00864 if (walker->type == XML_ELEMENT_NODE)
00865 {
00866 if (!xmlStrcmp(walker->name, "Signature"))
00867 {
00868 if (!xmlStrcmp(walker->ns->href, SOAP_SECURITY_NAMESPACE))
00869 {
00870 xmlNodePtr node;
00871 xmlSecDSigCtxPtr dsigCtx;
00872
00873 node = xmlSecFindNode(envelope->root, xmlSecNodeSignature, xmlSecDSigNs);
00874 if (node == NULL)
00875 {
00876 log_error1("cannot find message signature");
00877 return herror_new("soap_xmlsec_verify", 0, "message signature wasn't found");
00878 }
00879
00880 dsigCtx = xmlSecDSigCtxCreate(_soap_xmlsec_key_manager);
00881 if (dsigCtx == NULL)
00882 {
00883 log_error1("cannot create signature context");
00884 return herror_new("soap_xmlsec_verify", 0, "cannot create signatur context");
00885 }
00886
00887 if (xmlSecDSigCtxVerify(dsigCtx, node) < 0)
00888 {
00889 log_error1("xmlsecDSigCtxVerify failed");
00890 return herror_new("soap_xmlsec_verify", 0, "verification failed");
00891 }
00892
00893 if (dsigCtx->status == xmlSecDSigStatusSucceeded)
00894 {
00895 return H_OK;
00896 }
00897 else
00898 {
00899 log_error1("signature invalid");
00900 return herror_new("soap_xmlsec_verify", 0, "signature invalid");
00901 }
00902 }
00903 else
00904 {
00905 log_error2("message signature isn't understood (%s)", walker->ns->href);
00906 return herror_new("soap_xmlsec_verify", 0, "message signature isn't understood (%s)", walker->ns->href);
00907 }
00908 }
00909 }
00910 }
00911 return H_OK;
00912 }
00913
00914 void soap_xmlsec_destroy(void)
00915 {
00916 if (!_soap_xmlsec_enabled)
00917 return;
00918
00919 xmlSecKeysMngrDestroy(_soap_xmlsec_key_manager);
00920
00921 xmlSecCryptoShutdown();
00922
00923 xmlSecCryptoAppShutdown();
00924
00925 xmlSecShutdown();
00926
00927 #ifndef XMLSEC_NO_XSLT
00928 xsltCleanupGlobals();
00929 #endif
00930
00931 return;
00932 }