Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: third_party/libxslt/libexslt/crypto.c

Issue 2865973002: Check in the libxslt roll script. (Closed)
Patch Set: Consistent quotes. Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/libxslt/libexslt/common.c ('k') | third_party/libxslt/libexslt/date.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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 */
53 static void
54 exsltCryptoBin2Hex (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 */
83 static int
84 exsltCryptoHex2Bin (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
126 static void
127 exsltCryptoCryptoApiReportError (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
143 static HCRYPTHASH
144 exsltCryptoCryptoApiCreateHash (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 */
182 static void
183 exsltCryptoCryptoApiHash (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
206 static void
207 exsltCryptoCryptoApiRc4Encrypt (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 exsltCryptoCryptoApiR c4Encrypt 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
257 static void
258 exsltCryptoCryptoApiRc4Decrypt (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 exsltCryptoCryptoApiR c4Encrypt 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_TYPES_H
321 # include <sys/types.h>
322 #endif
323 #ifdef HAVE_STDINT_H
324 # include <stdint.h>
325 #endif
326
327 #ifdef HAVE_SYS_SELECT_H
328 #include <sys/select.h> /* needed by gcrypt.h 4 Jul 04 */
329 #endif
330 #include <gcrypt.h>
331
332 static void
333 exsltCryptoGcryptInit (void) {
334 static int gcrypt_init;
335 xmlLockLibrary ();
336
337 if (!gcrypt_init) {
338 /* The function `gcry_check_version' must be called before any other
339 function in the library, because it initializes the thread support
340 subsystem in Libgcrypt. To achieve this in all generality, it is
341 necessary to synchronize the call to this function with all other calls
342 to functions in the library, using the synchronization mechanisms
343 available in your thread library. (from gcrypt.info)
344 */
345 gcry_check_version (GCRYPT_VERSION);
346 gcrypt_init = 1;
347 }
348
349 xmlUnlockLibrary ();
350 }
351
352 /**
353 * exsltCryptoGcryptHash:
354 * @ctxt: an XPath parser context
355 * @algorithm: hashing algorithm to use
356 * @msg: text to be hashed
357 * @msglen: length of text to be hashed
358 * @dest: buffer to place hash result
359 *
360 * Helper function which hashes a message using MD4, MD5, or SHA1.
361 * using gcrypt
362 */
363 static void
364 exsltCryptoGcryptHash (xmlXPathParserContextPtr ctxt ATTRIBUTE_UNUSED,
365 /* changed the enum to int */
366 int algorithm, const char *msg,
367 unsigned long msglen,
368 char dest[HASH_DIGEST_LENGTH]) {
369 exsltCryptoGcryptInit ();
370 gcry_md_hash_buffer (algorithm, dest, msg, msglen);
371 }
372
373 static void
374 exsltCryptoGcryptRc4Encrypt (xmlXPathParserContextPtr ctxt,
375 const unsigned char *key,
376 const unsigned char *msg, int msglen,
377 unsigned char *dest, int destlen) {
378 gcry_cipher_hd_t cipher;
379 gcry_error_t rc = 0;
380
381 exsltCryptoGcryptInit ();
382
383 rc = gcry_cipher_open (&cipher, GCRY_CIPHER_ARCFOUR,
384 GCRY_CIPHER_MODE_STREAM, 0);
385 if (rc) {
386 xsltTransformError (xsltXPathGetTransformContext (ctxt), NULL,
387 NULL,
388 "exslt:crypto internal error %s (gcry_cipher_open)\n ",
389 gcry_strerror (rc));
390 }
391
392 rc = gcry_cipher_setkey (cipher, key, RC4_KEY_LENGTH);
393 if (rc) {
394 xsltTransformError (xsltXPathGetTransformContext (ctxt), NULL,
395 NULL,
396 "exslt:crypto internal error %s (gcry_cipher_setkey) \n",
397 gcry_strerror (rc));
398 }
399
400 rc = gcry_cipher_encrypt (cipher, (unsigned char *) dest, destlen,
401 (const unsigned char *) msg, msglen);
402 if (rc) {
403 xsltTransformError (xsltXPathGetTransformContext (ctxt), NULL,
404 NULL,
405 "exslt:crypto internal error %s (gcry_cipher_encrypt )\n",
406 gcry_strerror (rc));
407 }
408
409 gcry_cipher_close (cipher);
410 }
411
412 static void
413 exsltCryptoGcryptRc4Decrypt (xmlXPathParserContextPtr ctxt,
414 const unsigned char *key,
415 const unsigned char *msg, int msglen,
416 unsigned char *dest, int destlen) {
417 gcry_cipher_hd_t cipher;
418 gcry_error_t rc = 0;
419
420 exsltCryptoGcryptInit ();
421
422 rc = gcry_cipher_open (&cipher, GCRY_CIPHER_ARCFOUR,
423 GCRY_CIPHER_MODE_STREAM, 0);
424 if (rc) {
425 xsltTransformError (xsltXPathGetTransformContext (ctxt), NULL,
426 NULL,
427 "exslt:crypto internal error %s (gcry_cipher_open)\n ",
428 gcry_strerror (rc));
429 }
430
431 rc = gcry_cipher_setkey (cipher, key, RC4_KEY_LENGTH);
432 if (rc) {
433 xsltTransformError (xsltXPathGetTransformContext (ctxt), NULL,
434 NULL,
435 "exslt:crypto internal error %s (gcry_cipher_setkey) \n",
436 gcry_strerror (rc));
437 }
438
439 rc = gcry_cipher_decrypt (cipher, (unsigned char *) dest, destlen,
440 (const unsigned char *) msg, msglen);
441 if (rc) {
442 xsltTransformError (xsltXPathGetTransformContext (ctxt), NULL,
443 NULL,
444 "exslt:crypto internal error %s (gcry_cipher_decrypt )\n",
445 gcry_strerror (rc));
446 }
447
448 gcry_cipher_close (cipher);
449 }
450
451 #endif /* defined(HAVE_GCRYPT) */
452
453 #if defined(HAVE_CRYPTO)
454
455 /**
456 * exsltCryptoPopString:
457 * @ctxt: an XPath parser context
458 * @nargs: the number of arguments
459 *
460 * Helper function which checks for and returns first string argument and its
461 * length in bytes.
462 */
463 static int
464 exsltCryptoPopString (xmlXPathParserContextPtr ctxt, int nargs,
465 xmlChar ** str) {
466
467 int str_len = 0;
468
469 if ((nargs < 1) || (nargs > 2)) {
470 xmlXPathSetArityError (ctxt);
471 return 0;
472 }
473
474 *str = xmlXPathPopString (ctxt);
475 str_len = xmlStrlen (*str);
476
477 if (str_len == 0) {
478 xmlXPathReturnEmptyString (ctxt);
479 xmlFree (*str);
480 return 0;
481 }
482
483 return str_len;
484 }
485
486 /**
487 * exsltCryptoMd4Function:
488 * @ctxt: an XPath parser context
489 * @nargs: the number of arguments
490 *
491 * computes the md4 hash of a string and returns as hex
492 */
493 static void
494 exsltCryptoMd4Function (xmlXPathParserContextPtr ctxt, int nargs) {
495
496 int str_len = 0;
497 xmlChar *str = NULL, *ret = NULL;
498 unsigned char hash[HASH_DIGEST_LENGTH];
499 unsigned char hex[MD5_DIGEST_LENGTH * 2 + 1];
500
501 str_len = exsltCryptoPopString (ctxt, nargs, &str);
502 if (str_len == 0)
503 return;
504
505 PLATFORM_HASH (ctxt, PLATFORM_MD4, (const char *) str, str_len,
506 (char *) hash);
507 exsltCryptoBin2Hex (hash, sizeof (hash) - 1, hex, sizeof (hex) - 1);
508
509 ret = xmlStrdup ((xmlChar *) hex);
510 xmlXPathReturnString (ctxt, ret);
511
512 if (str != NULL)
513 xmlFree (str);
514 }
515
516 /**
517 * exsltCryptoMd5Function:
518 * @ctxt: an XPath parser context
519 * @nargs: the number of arguments
520 *
521 * computes the md5 hash of a string and returns as hex
522 */
523 static void
524 exsltCryptoMd5Function (xmlXPathParserContextPtr ctxt, int nargs) {
525
526 int str_len = 0;
527 xmlChar *str = NULL, *ret = NULL;
528 unsigned char hash[HASH_DIGEST_LENGTH];
529 unsigned char hex[MD5_DIGEST_LENGTH * 2 + 1];
530
531 str_len = exsltCryptoPopString (ctxt, nargs, &str);
532 if (str_len == 0)
533 return;
534
535 PLATFORM_HASH (ctxt, PLATFORM_MD5, (const char *) str, str_len,
536 (char *) hash);
537 exsltCryptoBin2Hex (hash, sizeof (hash) - 1, hex, sizeof (hex) - 1);
538
539 ret = xmlStrdup ((xmlChar *) hex);
540 xmlXPathReturnString (ctxt, ret);
541
542 if (str != NULL)
543 xmlFree (str);
544 }
545
546 /**
547 * exsltCryptoSha1Function:
548 * @ctxt: an XPath parser context
549 * @nargs: the number of arguments
550 *
551 * computes the sha1 hash of a string and returns as hex
552 */
553 static void
554 exsltCryptoSha1Function (xmlXPathParserContextPtr ctxt, int nargs) {
555
556 int str_len = 0;
557 xmlChar *str = NULL, *ret = NULL;
558 unsigned char hash[HASH_DIGEST_LENGTH];
559 unsigned char hex[SHA1_DIGEST_LENGTH * 2 + 1];
560
561 str_len = exsltCryptoPopString (ctxt, nargs, &str);
562 if (str_len == 0)
563 return;
564
565 PLATFORM_HASH (ctxt, PLATFORM_SHA1, (const char *) str, str_len,
566 (char *) hash);
567 exsltCryptoBin2Hex (hash, sizeof (hash) - 1, hex, sizeof (hex) - 1);
568
569 ret = xmlStrdup ((xmlChar *) hex);
570 xmlXPathReturnString (ctxt, ret);
571
572 if (str != NULL)
573 xmlFree (str);
574 }
575
576 /**
577 * exsltCryptoRc4EncryptFunction:
578 * @ctxt: an XPath parser context
579 * @nargs: the number of arguments
580 *
581 * computes the sha1 hash of a string and returns as hex
582 */
583 static void
584 exsltCryptoRc4EncryptFunction (xmlXPathParserContextPtr ctxt, int nargs) {
585
586 int key_len = 0;
587 int str_len = 0, bin_len = 0, hex_len = 0;
588 xmlChar *key = NULL, *str = NULL, *padkey = NULL;
589 xmlChar *bin = NULL, *hex = NULL;
590 xsltTransformContextPtr tctxt = NULL;
591
592 if (nargs != 2) {
593 xmlXPathSetArityError (ctxt);
594 return;
595 }
596 tctxt = xsltXPathGetTransformContext(ctxt);
597
598 str = xmlXPathPopString (ctxt);
599 str_len = xmlStrlen (str);
600
601 if (str_len == 0) {
602 xmlXPathReturnEmptyString (ctxt);
603 xmlFree (str);
604 return;
605 }
606
607 key = xmlXPathPopString (ctxt);
608 key_len = xmlStrlen (key);
609
610 if (key_len == 0) {
611 xmlXPathReturnEmptyString (ctxt);
612 xmlFree (key);
613 xmlFree (str);
614 return;
615 }
616
617 padkey = xmlMallocAtomic (RC4_KEY_LENGTH + 1);
618 if (padkey == NULL) {
619 xsltTransformError(tctxt, NULL, tctxt->inst,
620 "exsltCryptoRc4EncryptFunction: Failed to allocate padkey\n");
621 tctxt->state = XSLT_STATE_STOPPED;
622 xmlXPathReturnEmptyString (ctxt);
623 goto done;
624 }
625 memset(padkey, 0, RC4_KEY_LENGTH + 1);
626
627 if ((key_len > RC4_KEY_LENGTH) || (key_len < 0)) {
628 xsltTransformError(tctxt, NULL, tctxt->inst,
629 "exsltCryptoRc4EncryptFunction: key size too long or key broken\n");
630 tctxt->state = XSLT_STATE_STOPPED;
631 xmlXPathReturnEmptyString (ctxt);
632 goto done;
633 }
634 memcpy (padkey, key, key_len);
635
636 /* encrypt it */
637 bin_len = str_len;
638 bin = xmlStrdup (str);
639 if (bin == NULL) {
640 xsltTransformError(tctxt, NULL, tctxt->inst,
641 "exsltCryptoRc4EncryptFunction: Failed to allocate string\n");
642 tctxt->state = XSLT_STATE_STOPPED;
643 xmlXPathReturnEmptyString (ctxt);
644 goto done;
645 }
646 PLATFORM_RC4_ENCRYPT (ctxt, padkey, str, str_len, bin, bin_len);
647
648 /* encode it */
649 hex_len = str_len * 2 + 1;
650 hex = xmlMallocAtomic (hex_len);
651 if (hex == NULL) {
652 xsltTransformError(tctxt, NULL, tctxt->inst,
653 "exsltCryptoRc4EncryptFunction: Failed to allocate result\n");
654 tctxt->state = XSLT_STATE_STOPPED;
655 xmlXPathReturnEmptyString (ctxt);
656 goto done;
657 }
658
659 exsltCryptoBin2Hex (bin, str_len, hex, hex_len);
660 xmlXPathReturnString (ctxt, hex);
661
662 done:
663 if (key != NULL)
664 xmlFree (key);
665 if (str != NULL)
666 xmlFree (str);
667 if (padkey != NULL)
668 xmlFree (padkey);
669 if (bin != NULL)
670 xmlFree (bin);
671 }
672
673 /**
674 * exsltCryptoRc4DecryptFunction:
675 * @ctxt: an XPath parser context
676 * @nargs: the number of arguments
677 *
678 * computes the sha1 hash of a string and returns as hex
679 */
680 static void
681 exsltCryptoRc4DecryptFunction (xmlXPathParserContextPtr ctxt, int nargs) {
682
683 int key_len = 0;
684 int str_len = 0, bin_len = 0, ret_len = 0;
685 xmlChar *key = NULL, *str = NULL, *padkey = NULL, *bin =
686 NULL, *ret = NULL;
687 xsltTransformContextPtr tctxt = NULL;
688
689 if (nargs != 2) {
690 xmlXPathSetArityError (ctxt);
691 return;
692 }
693 tctxt = xsltXPathGetTransformContext(ctxt);
694
695 str = xmlXPathPopString (ctxt);
696 str_len = xmlStrlen (str);
697
698 if (str_len == 0) {
699 xmlXPathReturnEmptyString (ctxt);
700 xmlFree (str);
701 return;
702 }
703
704 key = xmlXPathPopString (ctxt);
705 key_len = xmlStrlen (key);
706
707 if (key_len == 0) {
708 xmlXPathReturnEmptyString (ctxt);
709 xmlFree (key);
710 xmlFree (str);
711 return;
712 }
713
714 padkey = xmlMallocAtomic (RC4_KEY_LENGTH + 1);
715 if (padkey == NULL) {
716 xsltTransformError(tctxt, NULL, tctxt->inst,
717 "exsltCryptoRc4EncryptFunction: Failed to allocate padkey\n");
718 tctxt->state = XSLT_STATE_STOPPED;
719 xmlXPathReturnEmptyString (ctxt);
720 goto done;
721 }
722 memset(padkey, 0, RC4_KEY_LENGTH + 1);
723 if ((key_len > RC4_KEY_LENGTH) || (key_len < 0)) {
724 xsltTransformError(tctxt, NULL, tctxt->inst,
725 "exsltCryptoRc4EncryptFunction: key size too long or key broken\n");
726 tctxt->state = XSLT_STATE_STOPPED;
727 xmlXPathReturnEmptyString (ctxt);
728 goto done;
729 }
730 memcpy (padkey, key, key_len);
731
732 /* decode hex to binary */
733 bin_len = str_len;
734 bin = xmlMallocAtomic (bin_len);
735 if (bin == NULL) {
736 xsltTransformError(tctxt, NULL, tctxt->inst,
737 "exsltCryptoRc4EncryptFunction: Failed to allocate string\n");
738 tctxt->state = XSLT_STATE_STOPPED;
739 xmlXPathReturnEmptyString (ctxt);
740 goto done;
741 }
742 ret_len = exsltCryptoHex2Bin (str, str_len, bin, bin_len);
743
744 /* decrypt the binary blob */
745 ret = xmlMallocAtomic (ret_len + 1);
746 if (ret == NULL) {
747 xsltTransformError(tctxt, NULL, tctxt->inst,
748 "exsltCryptoRc4EncryptFunction: Failed to allocate result\n");
749 tctxt->state = XSLT_STATE_STOPPED;
750 xmlXPathReturnEmptyString (ctxt);
751 goto done;
752 }
753 PLATFORM_RC4_DECRYPT (ctxt, padkey, bin, ret_len, ret, ret_len);
754 ret[ret_len] = 0;
755
756 xmlXPathReturnString (ctxt, ret);
757
758 done:
759 if (key != NULL)
760 xmlFree (key);
761 if (str != NULL)
762 xmlFree (str);
763 if (padkey != NULL)
764 xmlFree (padkey);
765 if (bin != NULL)
766 xmlFree (bin);
767 }
768
769 /**
770 * exsltCryptoRegister:
771 *
772 * Registers the EXSLT - Crypto module
773 */
774
775 void
776 exsltCryptoRegister (void) {
777 xsltRegisterExtModuleFunction ((const xmlChar *) "md4",
778 EXSLT_CRYPTO_NAMESPACE,
779 exsltCryptoMd4Function);
780 xsltRegisterExtModuleFunction ((const xmlChar *) "md5",
781 EXSLT_CRYPTO_NAMESPACE,
782 exsltCryptoMd5Function);
783 xsltRegisterExtModuleFunction ((const xmlChar *) "sha1",
784 EXSLT_CRYPTO_NAMESPACE,
785 exsltCryptoSha1Function);
786 xsltRegisterExtModuleFunction ((const xmlChar *) "rc4_encrypt",
787 EXSLT_CRYPTO_NAMESPACE,
788 exsltCryptoRc4EncryptFunction);
789 xsltRegisterExtModuleFunction ((const xmlChar *) "rc4_decrypt",
790 EXSLT_CRYPTO_NAMESPACE,
791 exsltCryptoRc4DecryptFunction);
792 }
793
794 #else
795 /**
796 * exsltCryptoRegister:
797 *
798 * Registers the EXSLT - Crypto module
799 */
800 void
801 exsltCryptoRegister (void) {
802 }
803
804 #endif /* defined(HAVE_CRYPTO) */
805
806 #endif /* EXSLT_CRYPTO_ENABLED */
OLDNEW
« no previous file with comments | « third_party/libxslt/libexslt/common.c ('k') | third_party/libxslt/libexslt/date.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698