VirtualBox

source: vbox/trunk/src/libs/libxslt-1.1.22/libexslt/crypto.c@ 26688

Last change on this file since 26688 was 7299, checked in by vboxsync, 17 years ago

Added vboxconfig.h for linux builds.

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette