1#define IN_LIBEXSLT 2#include "libexslt/libexslt.h" 3 4#if defined(WIN32) && !defined (__CYGWIN__) && (!__MINGW32__) 5#include <win32config.h> 6#else 7#include "config.h" 8#endif 9 10#include <libxml/tree.h> 11#include <libxml/xpath.h> 12#include <libxml/xpathInternals.h> 13#include <libxml/parser.h> 14#include <libxml/encoding.h> 15#include <libxml/uri.h> 16 17#include <libxslt/xsltconfig.h> 18#include <libxslt/xsltutils.h> 19#include <libxslt/xsltInternals.h> 20#include <libxslt/extensions.h> 21 22#include "exslt.h" 23 24#ifdef EXSLT_CRYPTO_ENABLED 25 26#define HASH_DIGEST_LENGTH 32 27#define MD5_DIGEST_LENGTH 16 28#define SHA1_DIGEST_LENGTH 20 29 30/* gcrypt rc4 can do 256 bit keys, but cryptoapi limit 31 seems to be 128 for the default provider */ 32#define RC4_KEY_LENGTH 128 33 34/* The following routines have been declared static - this should be 35 reviewed to consider whether we want to expose them to the API 36 exsltCryptoBin2Hex 37 exsltCryptoHex2Bin 38 exsltCryptoGcryptInit 39 exsltCryptoGcryptHash 40 exsltCryptoGcryptRc4Encrypt 41 exsltCryptoGcryptRC4Decrypt 42*/ 43 44/** 45 * exsltCryptoBin2Hex: 46 * @bin: binary blob to convert 47 * @binlen: length of binary blob 48 * @hex: buffer to store hex version of blob 49 * @hexlen: length of buffer to store hex version of blob 50 * 51 * Helper function which encodes a binary blob as hex. 52 */ 53static void 54exsltCryptoBin2Hex (const unsigned char *bin, int binlen, 55 unsigned char *hex, int hexlen) { 56 static const char bin2hex[] = { '0', '1', '2', '3', 57 '4', '5', '6', '7', 58 '8', '9', 'a', 'b', 59 'c', 'd', 'e', 'f' 60 }; 61 62 unsigned char lo, hi; 63 int i, pos; 64 for (i = 0, pos = 0; (i < binlen && pos < hexlen); i++) { 65 lo = bin[i] & 0xf; 66 hi = bin[i] >> 4; 67 hex[pos++] = bin2hex[hi]; 68 hex[pos++] = bin2hex[lo]; 69 } 70 71 hex[pos] = '\0'; 72} 73 74/** 75 * exsltCryptoHex2Bin: 76 * @hex: hex version of blob to convert 77 * @hexlen: length of hex buffer 78 * @bin: destination binary buffer 79 * @binlen: length of binary buffer 80 * 81 * Helper function which decodes a hex blob to binary 82 */ 83static int 84exsltCryptoHex2Bin (const unsigned char *hex, int hexlen, 85 unsigned char *bin, int binlen) { 86 int i = 0, j = 0; 87 unsigned char lo, hi, result, tmp; 88 89 while (i < hexlen && j < binlen) { 90 hi = lo = 0; 91 92 tmp = hex[i++]; 93 if (tmp >= '0' && tmp <= '9') 94 hi = tmp - '0'; 95 else if (tmp >= 'a' && tmp <= 'f') 96 hi = 10 + (tmp - 'a'); 97 98 tmp = hex[i++]; 99 if (tmp >= '0' && tmp <= '9') 100 lo = tmp - '0'; 101 else if (tmp >= 'a' && tmp <= 'f') 102 lo = 10 + (tmp - 'a'); 103 104 result = hi << 4; 105 result += lo; 106 bin[j++] = result; 107 } 108 109 return j; 110} 111 112#if defined(WIN32) 113 114#define HAVE_CRYPTO 115#define PLATFORM_HASH exsltCryptoCryptoApiHash 116#define PLATFORM_RC4_ENCRYPT exsltCryptoCryptoApiRc4Encrypt 117#define PLATFORM_RC4_DECRYPT exsltCryptoCryptoApiRc4Decrypt 118#define PLATFORM_MD4 CALG_MD4 119#define PLATFORM_MD5 CALG_MD5 120#define PLATFORM_SHA1 CALG_SHA1 121 122#include <windows.h> 123#include <wincrypt.h> 124#pragma comment(lib, "advapi32.lib") 125 126static void 127exsltCryptoCryptoApiReportError (xmlXPathParserContextPtr ctxt, 128 int line) { 129 LPVOID lpMsgBuf; 130 DWORD dw = GetLastError (); 131 132 FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | 133 FORMAT_MESSAGE_FROM_SYSTEM, NULL, dw, 134 MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), 135 (LPTSTR) & lpMsgBuf, 0, NULL); 136 137 xsltTransformError (xsltXPathGetTransformContext (ctxt), NULL, NULL, 138 "exslt:crypto error (line %d). %s", line, 139 lpMsgBuf); 140 LocalFree (lpMsgBuf); 141} 142 143HCRYPTHASH 144exsltCryptoCryptoApiCreateHash (xmlXPathParserContextPtr ctxt, 145 HCRYPTPROV hCryptProv, ALG_ID algorithm, 146 const char *msg, unsigned int msglen, 147 char *dest, unsigned int destlen) 148{ 149 HCRYPTHASH hHash = 0; 150 DWORD dwHashLen = destlen; 151 152 if (!CryptCreateHash (hCryptProv, algorithm, 0, 0, &hHash)) { 153 exsltCryptoCryptoApiReportError (ctxt, __LINE__); 154 return 0; 155 } 156 157 if (!CryptHashData (hHash, (const BYTE *) msg, msglen, 0)) { 158 exsltCryptoCryptoApiReportError (ctxt, __LINE__); 159 goto fail; 160 } 161 162 if (!CryptGetHashParam (hHash, HP_HASHVAL, dest, &dwHashLen, 0)) { 163 exsltCryptoCryptoApiReportError (ctxt, __LINE__); 164 goto fail; 165 } 166 167 fail: 168 return hHash; 169} 170 171/** 172 * exsltCryptoCryptoApiHash: 173 * @ctxt: an XPath parser context 174 * @algorithm: hashing algorithm to use 175 * @msg: text to be hashed 176 * @msglen: length of text to be hashed 177 * @dest: buffer to place hash result 178 * 179 * Helper function which hashes a message using MD4, MD5, or SHA1. 180 * Uses Win32 CryptoAPI. 181 */ 182static void 183exsltCryptoCryptoApiHash (xmlXPathParserContextPtr ctxt, 184 ALG_ID algorithm, const char *msg, 185 unsigned long msglen, 186 char dest[HASH_DIGEST_LENGTH]) { 187 HCRYPTPROV hCryptProv; 188 HCRYPTHASH hHash; 189 190 if (!CryptAcquireContext (&hCryptProv, NULL, NULL, PROV_RSA_FULL, 191 CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) { 192 exsltCryptoCryptoApiReportError (ctxt, __LINE__); 193 return; 194 } 195 196 hHash = exsltCryptoCryptoApiCreateHash (ctxt, hCryptProv, 197 algorithm, msg, msglen, 198 dest, HASH_DIGEST_LENGTH); 199 if (0 != hHash) { 200 CryptDestroyHash (hHash); 201 } 202 203 CryptReleaseContext (hCryptProv, 0); 204} 205 206void 207exsltCryptoCryptoApiRc4Encrypt (xmlXPathParserContextPtr ctxt, 208 const unsigned char *key, 209 const unsigned char *msg, int msglen, 210 unsigned char *dest, int destlen) { 211 HCRYPTPROV hCryptProv; 212 HCRYPTKEY hKey; 213 HCRYPTHASH hHash; 214 DWORD dwDataLen; 215 unsigned char hash[HASH_DIGEST_LENGTH]; 216 217 if (msglen > destlen) { 218 xsltTransformError (xsltXPathGetTransformContext (ctxt), NULL, 219 NULL, 220 "exslt:crypto : internal error exsltCryptoCryptoApiRc4Encrypt dest buffer too small.\n"); 221 return; 222 } 223 224 if (!CryptAcquireContext (&hCryptProv, NULL, NULL, PROV_RSA_FULL, 225 CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) { 226 exsltCryptoCryptoApiReportError (ctxt, __LINE__); 227 return; 228 } 229 230 hHash = exsltCryptoCryptoApiCreateHash (ctxt, hCryptProv, 231 CALG_SHA1, key, 232 RC4_KEY_LENGTH, hash, 233 HASH_DIGEST_LENGTH); 234 235 if (!CryptDeriveKey 236 (hCryptProv, CALG_RC4, hHash, 0x00800000, &hKey)) { 237 exsltCryptoCryptoApiReportError (ctxt, __LINE__); 238 goto fail; 239 } 240/* Now encrypt data. */ 241 dwDataLen = msglen; 242 memcpy (dest, msg, msglen); 243 if (!CryptEncrypt (hKey, 0, TRUE, 0, dest, &dwDataLen, msglen)) { 244 exsltCryptoCryptoApiReportError (ctxt, __LINE__); 245 goto fail; 246 } 247 248 fail: 249 if (0 != hHash) { 250 CryptDestroyHash (hHash); 251 } 252 253 CryptDestroyKey (hKey); 254 CryptReleaseContext (hCryptProv, 0); 255} 256 257void 258exsltCryptoCryptoApiRc4Decrypt (xmlXPathParserContextPtr ctxt, 259 const unsigned char *key, 260 const unsigned char *msg, int msglen, 261 unsigned char *dest, int destlen) { 262 HCRYPTPROV hCryptProv; 263 HCRYPTKEY hKey; 264 HCRYPTHASH hHash; 265 DWORD dwDataLen; 266 unsigned char hash[HASH_DIGEST_LENGTH]; 267 268 if (msglen > destlen) { 269 xsltTransformError (xsltXPathGetTransformContext (ctxt), NULL, 270 NULL, 271 "exslt:crypto : internal error exsltCryptoCryptoApiRc4Encrypt dest buffer too small.\n"); 272 return; 273 } 274 275 if (!CryptAcquireContext (&hCryptProv, NULL, NULL, PROV_RSA_FULL, 276 CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) { 277 exsltCryptoCryptoApiReportError (ctxt, __LINE__); 278 return; 279 } 280 281 hHash = exsltCryptoCryptoApiCreateHash (ctxt, hCryptProv, 282 CALG_SHA1, key, 283 RC4_KEY_LENGTH, hash, 284 HASH_DIGEST_LENGTH); 285 286 if (!CryptDeriveKey 287 (hCryptProv, CALG_RC4, hHash, 0x00800000, &hKey)) { 288 exsltCryptoCryptoApiReportError (ctxt, __LINE__); 289 goto fail; 290 } 291/* Now encrypt data. */ 292 dwDataLen = msglen; 293 memcpy (dest, msg, msglen); 294 if (!CryptDecrypt (hKey, 0, TRUE, 0, dest, &dwDataLen)) { 295 exsltCryptoCryptoApiReportError (ctxt, __LINE__); 296 goto fail; 297 } 298 299 fail: 300 if (0 != hHash) { 301 CryptDestroyHash (hHash); 302 } 303 304 CryptDestroyKey (hKey); 305 CryptReleaseContext (hCryptProv, 0); 306} 307 308#endif /* defined(WIN32) */ 309 310#if defined(HAVE_GCRYPT) 311 312#define HAVE_CRYPTO 313#define PLATFORM_HASH exsltCryptoGcryptHash 314#define PLATFORM_RC4_ENCRYPT exsltCryptoGcryptRc4Encrypt 315#define PLATFORM_RC4_DECRYPT exsltCryptoGcryptRc4Decrypt 316#define PLATFORM_MD4 GCRY_MD_MD4 317#define PLATFORM_MD5 GCRY_MD_MD5 318#define PLATFORM_SHA1 GCRY_MD_SHA1 319 320#ifdef HAVE_SYS_SELECT_H 321#include <sys/select.h> /* needed by gcrypt.h 4 Jul 04 */ 322#endif 323#include <gcrypt.h> 324 325static void 326exsltCryptoGcryptInit (void) { 327 static int gcrypt_init; 328 xmlLockLibrary (); 329 330 if (!gcrypt_init) { 331/* The function `gcry_check_version' must be called before any other 332 function in the library, because it initializes the thread support 333 subsystem in Libgcrypt. To achieve this in all generality, it is 334 necessary to synchronize the call to this function with all other calls 335 to functions in the library, using the synchronization mechanisms 336 available in your thread library. (from gcrypt.info) 337*/ 338 gcry_check_version (GCRYPT_VERSION); 339 gcrypt_init = 1; 340 } 341 342 xmlUnlockLibrary (); 343} 344 345/** 346 * exsltCryptoGcryptHash: 347 * @ctxt: an XPath parser context 348 * @algorithm: hashing algorithm to use 349 * @msg: text to be hashed 350 * @msglen: length of text to be hashed 351 * @dest: buffer to place hash result 352 * 353 * Helper function which hashes a message using MD4, MD5, or SHA1. 354 * using gcrypt 355 */ 356static void 357exsltCryptoGcryptHash (xmlXPathParserContextPtr ctxt ATTRIBUTE_UNUSED, 358/* changed the enum to int */ 359 int algorithm, const char *msg, 360 unsigned long msglen, 361 char dest[HASH_DIGEST_LENGTH]) { 362 exsltCryptoGcryptInit (); 363 gcry_md_hash_buffer (algorithm, dest, msg, msglen); 364} 365 366static void 367exsltCryptoGcryptRc4Encrypt (xmlXPathParserContextPtr ctxt, 368 const unsigned char *key, 369 const unsigned char *msg, int msglen, 370 unsigned char *dest, int destlen) { 371 gcry_cipher_hd_t cipher; 372 gcry_error_t rc = 0; 373 374 exsltCryptoGcryptInit (); 375 376 rc = gcry_cipher_open (&cipher, GCRY_CIPHER_ARCFOUR, 377 GCRY_CIPHER_MODE_STREAM, 0); 378 if (rc) { 379 xsltTransformError (xsltXPathGetTransformContext (ctxt), NULL, 380 NULL, 381 "exslt:crypto internal error %s (gcry_cipher_open)\n", 382 gcry_strerror (rc)); 383 } 384 385 rc = gcry_cipher_setkey (cipher, key, RC4_KEY_LENGTH); 386 if (rc) { 387 xsltTransformError (xsltXPathGetTransformContext (ctxt), NULL, 388 NULL, 389 "exslt:crypto internal error %s (gcry_cipher_setkey)\n", 390 gcry_strerror (rc)); 391 } 392 393 rc = gcry_cipher_encrypt (cipher, (unsigned char *) dest, destlen, 394 (const unsigned char *) msg, msglen); 395 if (rc) { 396 xsltTransformError (xsltXPathGetTransformContext (ctxt), NULL, 397 NULL, 398 "exslt:crypto internal error %s (gcry_cipher_encrypt)\n", 399 gcry_strerror (rc)); 400 } 401 402 gcry_cipher_close (cipher); 403} 404 405static void 406exsltCryptoGcryptRc4Decrypt (xmlXPathParserContextPtr ctxt, 407 const unsigned char *key, 408 const unsigned char *msg, int msglen, 409 unsigned char *dest, int destlen) { 410 gcry_cipher_hd_t cipher; 411 gcry_error_t rc = 0; 412 413 exsltCryptoGcryptInit (); 414 415 rc = gcry_cipher_open (&cipher, GCRY_CIPHER_ARCFOUR, 416 GCRY_CIPHER_MODE_STREAM, 0); 417 if (rc) { 418 xsltTransformError (xsltXPathGetTransformContext (ctxt), NULL, 419 NULL, 420 "exslt:crypto internal error %s (gcry_cipher_open)\n", 421 gcry_strerror (rc)); 422 } 423 424 rc = gcry_cipher_setkey (cipher, key, RC4_KEY_LENGTH); 425 if (rc) { 426 xsltTransformError (xsltXPathGetTransformContext (ctxt), NULL, 427 NULL, 428 "exslt:crypto internal error %s (gcry_cipher_setkey)\n", 429 gcry_strerror (rc)); 430 } 431 432 rc = gcry_cipher_decrypt (cipher, (unsigned char *) dest, destlen, 433 (const unsigned char *) msg, msglen); 434 if (rc) { 435 xsltTransformError (xsltXPathGetTransformContext (ctxt), NULL, 436 NULL, 437 "exslt:crypto internal error %s (gcry_cipher_decrypt)\n", 438 gcry_strerror (rc)); 439 } 440 441 gcry_cipher_close (cipher); 442} 443 444#endif /* defined(HAVE_GCRYPT) */ 445 446#if defined(HAVE_CRYPTO) 447 448/** 449 * exsltCryptoPopString: 450 * @ctxt: an XPath parser context 451 * @nargs: the number of arguments 452 * 453 * Helper function which checks for and returns first string argument and its length 454 */ 455static int 456exsltCryptoPopString (xmlXPathParserContextPtr ctxt, int nargs, 457 xmlChar ** str) { 458 459 int str_len = 0; 460 461 if ((nargs < 1) || (nargs > 2)) { 462 xmlXPathSetArityError (ctxt); 463 return 0; 464 } 465 466 *str = xmlXPathPopString (ctxt); 467 str_len = xmlUTF8Strlen (*str); 468 469 if (str_len == 0) { 470 xmlXPathReturnEmptyString (ctxt); 471 xmlFree (*str); 472 return 0; 473 } 474 475 return str_len; 476} 477 478/** 479 * exsltCryptoMd4Function: 480 * @ctxt: an XPath parser context 481 * @nargs: the number of arguments 482 * 483 * computes the md4 hash of a string and returns as hex 484 */ 485static void 486exsltCryptoMd4Function (xmlXPathParserContextPtr ctxt, int nargs) { 487 488 int str_len = 0; 489 xmlChar *str = NULL, *ret = NULL; 490 unsigned char hash[HASH_DIGEST_LENGTH]; 491 unsigned char hex[MD5_DIGEST_LENGTH * 2 + 1]; 492 493 str_len = exsltCryptoPopString (ctxt, nargs, &str); 494 if (str_len == 0) { 495 xmlXPathReturnEmptyString (ctxt); 496 xmlFree (str); 497 return; 498 } 499 500 PLATFORM_HASH (ctxt, PLATFORM_MD4, (const char *) str, str_len, 501 (char *) hash); 502 exsltCryptoBin2Hex (hash, sizeof (hash) - 1, hex, sizeof (hex) - 1); 503 504 ret = xmlStrdup ((xmlChar *) hex); 505 xmlXPathReturnString (ctxt, ret); 506 507 if (str != NULL) 508 xmlFree (str); 509} 510 511/** 512 * exsltCryptoMd5Function: 513 * @ctxt: an XPath parser context 514 * @nargs: the number of arguments 515 * 516 * computes the md5 hash of a string and returns as hex 517 */ 518static void 519exsltCryptoMd5Function (xmlXPathParserContextPtr ctxt, int nargs) { 520 521 int str_len = 0; 522 xmlChar *str = NULL, *ret = NULL; 523 unsigned char hash[HASH_DIGEST_LENGTH]; 524 unsigned char hex[MD5_DIGEST_LENGTH * 2 + 1]; 525 526 str_len = exsltCryptoPopString (ctxt, nargs, &str); 527 if (str_len == 0) { 528 xmlXPathReturnEmptyString (ctxt); 529 xmlFree (str); 530 return; 531 } 532 533 PLATFORM_HASH (ctxt, PLATFORM_MD5, (const char *) str, str_len, 534 (char *) hash); 535 exsltCryptoBin2Hex (hash, sizeof (hash) - 1, hex, sizeof (hex) - 1); 536 537 ret = xmlStrdup ((xmlChar *) hex); 538 xmlXPathReturnString (ctxt, ret); 539 540 if (str != NULL) 541 xmlFree (str); 542} 543 544/** 545 * exsltCryptoSha1Function: 546 * @ctxt: an XPath parser context 547 * @nargs: the number of arguments 548 * 549 * computes the sha1 hash of a string and returns as hex 550 */ 551static void 552exsltCryptoSha1Function (xmlXPathParserContextPtr ctxt, int nargs) { 553 554 int str_len = 0; 555 xmlChar *str = NULL, *ret = NULL; 556 unsigned char hash[HASH_DIGEST_LENGTH]; 557 unsigned char hex[SHA1_DIGEST_LENGTH * 2 + 1]; 558 559 str_len = exsltCryptoPopString (ctxt, nargs, &str); 560 if (str_len == 0) { 561 xmlXPathReturnEmptyString (ctxt); 562 xmlFree (str); 563 return; 564 } 565 566 PLATFORM_HASH (ctxt, PLATFORM_SHA1, (const char *) str, str_len, 567 (char *) hash); 568 exsltCryptoBin2Hex (hash, sizeof (hash) - 1, hex, sizeof (hex) - 1); 569 570 ret = xmlStrdup ((xmlChar *) hex); 571 xmlXPathReturnString (ctxt, ret); 572 573 if (str != NULL) 574 xmlFree (str); 575} 576 577/** 578 * exsltCryptoRc4EncryptFunction: 579 * @ctxt: an XPath parser context 580 * @nargs: the number of arguments 581 * 582 * computes the sha1 hash of a string and returns as hex 583 */ 584static void 585exsltCryptoRc4EncryptFunction (xmlXPathParserContextPtr ctxt, int nargs) { 586 587 int key_len = 0, key_size = 0; 588 int str_len = 0, bin_len = 0, hex_len = 0; 589 xmlChar *key = NULL, *str = NULL, *padkey = NULL; 590 xmlChar *bin = NULL, *hex = NULL; 591 592 if ((nargs < 1) || (nargs > 3)) { 593 xmlXPathSetArityError (ctxt); 594 return; 595 } 596 597 str = xmlXPathPopString (ctxt); 598 str_len = xmlUTF8Strlen (str); 599 600 if (str_len == 0) { 601 xmlXPathReturnEmptyString (ctxt); 602 xmlFree (str); 603 return; 604 } 605 606 key = xmlXPathPopString (ctxt); 607 key_len = xmlUTF8Strlen (str); 608 609 if (key_len == 0) { 610 xmlXPathReturnEmptyString (ctxt); 611 xmlFree (key); 612 xmlFree (str); 613 return; 614 } 615 616 padkey = xmlMallocAtomic (RC4_KEY_LENGTH); 617 key_size = xmlUTF8Strsize (key, key_len); 618 memcpy (padkey, key, key_size); 619 memset (padkey + key_size, '\0', sizeof (padkey)); 620 621/* encrypt it */ 622 bin_len = str_len; 623 bin = xmlStrdup (str); 624 if (bin == NULL) { 625 xmlXPathReturnEmptyString (ctxt); 626 goto done; 627 } 628 PLATFORM_RC4_ENCRYPT (ctxt, padkey, str, str_len, bin, bin_len); 629 630/* encode it */ 631 hex_len = str_len * 2 + 1; 632 hex = xmlMallocAtomic (hex_len); 633 if (hex == NULL) { 634 xmlXPathReturnEmptyString (ctxt); 635 goto done; 636 } 637 638 exsltCryptoBin2Hex (bin, str_len, hex, hex_len); 639 xmlXPathReturnString (ctxt, hex); 640 641done: 642 if (key != NULL) 643 xmlFree (key); 644 if (str != NULL) 645 xmlFree (str); 646 if (padkey != NULL) 647 xmlFree (padkey); 648 if (bin != NULL) 649 xmlFree (bin); 650} 651 652/** 653 * exsltCryptoRc4DecryptFunction: 654 * @ctxt: an XPath parser context 655 * @nargs: the number of arguments 656 * 657 * computes the sha1 hash of a string and returns as hex 658 */ 659static void 660exsltCryptoRc4DecryptFunction (xmlXPathParserContextPtr ctxt, int nargs) { 661 662 int key_len = 0, key_size = 0; 663 int str_len = 0, bin_len = 0, ret_len = 0; 664 xmlChar *key = NULL, *str = NULL, *padkey = NULL, *bin = 665 NULL, *ret = NULL; 666 667 if ((nargs < 1) || (nargs > 3)) { 668 xmlXPathSetArityError (ctxt); 669 return; 670 } 671 672 str = xmlXPathPopString (ctxt); 673 str_len = xmlUTF8Strlen (str); 674 675 if (str_len == 0) { 676 xmlXPathReturnEmptyString (ctxt); 677 xmlFree (str); 678 return; 679 } 680 681 key = xmlXPathPopString (ctxt); 682 key_len = xmlUTF8Strlen (str); 683 684 if (key_len == 0) { 685 xmlXPathReturnEmptyString (ctxt); 686 xmlFree (key); 687 xmlFree (str); 688 return; 689 } 690 691 padkey = xmlMallocAtomic (RC4_KEY_LENGTH); 692 key_size = xmlUTF8Strsize (key, key_len); 693 memcpy (padkey, key, key_size); 694 memset (padkey + key_size, '\0', sizeof (padkey)); 695 696/* decode hex to binary */ 697 bin_len = str_len; 698 bin = xmlMallocAtomic (bin_len); 699 ret_len = exsltCryptoHex2Bin (str, str_len, bin, bin_len); 700 701/* decrypt the binary blob */ 702 ret = xmlMallocAtomic (ret_len); 703 PLATFORM_RC4_DECRYPT (ctxt, padkey, bin, ret_len, ret, ret_len); 704 705 xmlXPathReturnString (ctxt, ret); 706 707 if (key != NULL) 708 xmlFree (key); 709 if (str != NULL) 710 xmlFree (str); 711 if (padkey != NULL) 712 xmlFree (padkey); 713 if (bin != NULL) 714 xmlFree (bin); 715} 716 717/** 718 * exsltCryptoRegister: 719 * 720 * Registers the EXSLT - Crypto module 721 */ 722 723void 724exsltCryptoRegister (void) { 725 xsltRegisterExtModuleFunction ((const xmlChar *) "md4", 726 EXSLT_CRYPTO_NAMESPACE, 727 exsltCryptoMd4Function); 728 xsltRegisterExtModuleFunction ((const xmlChar *) "md5", 729 EXSLT_CRYPTO_NAMESPACE, 730 exsltCryptoMd5Function); 731 xsltRegisterExtModuleFunction ((const xmlChar *) "sha1", 732 EXSLT_CRYPTO_NAMESPACE, 733 exsltCryptoSha1Function); 734 xsltRegisterExtModuleFunction ((const xmlChar *) "rc4_encrypt", 735 EXSLT_CRYPTO_NAMESPACE, 736 exsltCryptoRc4EncryptFunction); 737 xsltRegisterExtModuleFunction ((const xmlChar *) "rc4_decrypt", 738 EXSLT_CRYPTO_NAMESPACE, 739 exsltCryptoRc4DecryptFunction); 740} 741 742#else 743void 744exsltCryptoRegister (void) { 745} 746 747#endif /* defined(HAVE_CRYPTO) */ 748 749#endif /* EXSLT_CRYPTO_ENABLED */ 750