diff options
author | Daniel Veillard <veillard@src.gnome.org> | 2004-06-30 16:43:53 +0000 |
---|---|---|
committer | Daniel Veillard <veillard@src.gnome.org> | 2004-06-30 16:43:53 +0000 |
commit | 1bc6a1a495c2acec0fa2c46783a4dc0adefc1860 (patch) | |
tree | 803d776b536c44194efbb353452da2652334ad2d | |
parent | 19739dbd5fd3449b0cdae8984f3dd8b787d18ad2 (diff) | |
download | libxslt-1bc6a1a495c2acec0fa2c46783a4dc0adefc1860.tar.gz libxslt-1bc6a1a495c2acec0fa2c46783a4dc0adefc1860.tar.bz2 libxslt-1bc6a1a495c2acec0fa2c46783a4dc0adefc1860.zip |
applied patch from Joel Reed to get EXSLT crypto extensions based on
* win32/Makefile.msvc win32/Makefile.mingw libexslt/Makefile.am
libexslt/exslt.c libexslt/exslt.h config.h.in configure.in
libexslt/crypto.c: applied patch from Joel Reed to get EXSLT
crypto extensions based on libgcrypt if found at configure time.
* tests/namespaces/Makefile.am: fixed a small breakage
Daniel
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | config.h.in | 3 | ||||
-rw-r--r-- | configure.in | 19 | ||||
-rw-r--r-- | libexslt/Makefile.am | 4 | ||||
-rw-r--r-- | libexslt/crypto.c | 714 | ||||
-rw-r--r-- | libexslt/exslt.c | 1 | ||||
-rw-r--r-- | libexslt/exslt.h | 7 | ||||
-rw-r--r-- | tests/namespaces/Makefile.am | 2 | ||||
-rw-r--r-- | win32/Makefile.mingw | 2 | ||||
-rw-r--r-- | win32/Makefile.msvc | 2 | ||||
-rw-r--r-- | xsltproc/Makefile.am | 6 |
11 files changed, 764 insertions, 4 deletions
@@ -1,3 +1,11 @@ +Wed Jun 30 18:41:20 CEST 2004 Daniel Veillard <daniel@veillard.com> + + * win32/Makefile.msvc win32/Makefile.mingw libexslt/Makefile.am + libexslt/exslt.c libexslt/exslt.h config.h.in configure.in + libexslt/crypto.c: applied patch from Joel Reed to get EXSLT + crypto extensions based on libgcrypt if found at configure time. + * tests/namespaces/Makefile.am: fixed a small breakage + Wed Jun 30 12:28:34 HKT 2004 William Brack <wbrack@mmm.com.hk> * libxslt/namespaces: some enhancement for fixing bug 142768 diff --git a/config.h.in b/config.h.in index 3388df5e..1f36e2c3 100644 --- a/config.h.in +++ b/config.h.in @@ -27,6 +27,9 @@ /* Define to 1 if you have the `ftime' function. */ #undef HAVE_FTIME +/* Define if gcrypt library is available. */ +#undef HAVE_GCRYPT + /* Define to 1 if you have the `gettimeofday' function. */ #undef HAVE_GETTIMEOFDAY diff --git a/configure.in b/configure.in index 5395eba4..770cf3cc 100644 --- a/configure.in +++ b/configure.in @@ -200,6 +200,23 @@ AC_SUBST(pythondir) AC_SUBST(PYTHON_SUBDIR) dnl +dnl check for gcrypt +dnl +AC_PATH_PROG(LIBGCRYPT_CONFIG, libgcrypt-config, no) +if test "$LIBGCRYPT_CONFIG" != "no" ; then + LIBGCRYPT_CFLAGS=`$LIBGCRYPT_CONFIG $libgcrypt_config_args --cflags` + LIBGCRYPT_LIBS=`$LIBGCRYPT_CONFIG $libgcrypt_config_args --libs` + AC_DEFINE(HAVE_GCRYPT, 1, [Define if gcrypt library is available.]) + AC_MSG_NOTICE([Crypto extensions will be available.]) +else + LIBGCRYPT_CFLAGS="" + LIBGCRYPT_LIBS="" + AC_MSG_NOTICE([Crypto extensions will not be available. Install libgcrypt and reconfigure to make available.]) +fi + +AC_SUBST(LIBGCRYPT_CFLAGS) +AC_SUBST(LIBGCRYPT_LIBS) +dnl dnl Debug for DV (-Wunreachable-code) dnl if [[ "${LOGNAME}" = "veillard" -a "`pwd`" = "/u/veillard/XSLT" ]] || \ @@ -408,7 +425,7 @@ AC_SUBST(XSLT_LIBS) EXSLT_LIBDIR='-L${libdir}' EXSLT_INCLUDEDIR='-I${includedir}' -EXSLT_LIBS="-lexslt $XSLT_LIBS" +EXSLT_LIBS="-lexslt $XSLT_LIBS $LIBGCRYPT_LIBS" AC_SUBST(EXSLT_LIBDIR) AC_SUBST(EXSLT_INCLUDEDIR) AC_SUBST(EXSLT_LIBS) diff --git a/libexslt/Makefile.am b/libexslt/Makefile.am index ac540991..50fe8af8 100644 --- a/libexslt/Makefile.am +++ b/libexslt/Makefile.am @@ -2,6 +2,9 @@ INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/libxslt -I$(top_srcdir)/libexslt \ -I$(top_builddir) -I$(top_builddir)/libxslt \ -I$(top_builddir)/libexslt $(LIBXML_CFLAGS) $(CFLAGS) +AM_CFLAGS = $(LIBGCRYPT_CFLAGS) +AM_LDFLAGS = $(LIBGCRYPT_LIBS) + lib_LTLIBRARIES = libexslt.la exsltincdir = $(includedir)/libexslt @@ -16,6 +19,7 @@ exsltinc_HEADERS = \ libexslt_la_SOURCES = \ exslt.c \ common.c \ + crypto.c \ math.c \ sets.c \ functions.c \ diff --git a/libexslt/crypto.c b/libexslt/crypto.c new file mode 100644 index 00000000..218e38a0 --- /dev/null +++ b/libexslt/crypto.c @@ -0,0 +1,714 @@ +#define IN_LIBEXSLT +#include "libexslt/libexslt.h" + +#if defined(WIN32) && !defined (__CYGWIN__) && (!__MINGW32__) +#include <win32config.h> +#else +#include "config.h" +#endif + +#include <libxml/tree.h> +#include <libxml/xpath.h> +#include <libxml/xpathInternals.h> +#include <libxml/parser.h> +#include <libxml/encoding.h> +#include <libxml/uri.h> + +#include <libxslt/xsltconfig.h> +#include <libxslt/xsltutils.h> +#include <libxslt/xsltInternals.h> +#include <libxslt/extensions.h> + +#include "exslt.h" + +#define HASH_DIGEST_LENGTH 32 +#define MD5_DIGEST_LENGTH 16 +#define SHA1_DIGEST_LENGTH 20 + +/* gcrypt rc4 can do 256 bit keys, but cryptoapi limit + seems to be 128 for the default provider */ +#define RC4_KEY_LENGTH 128 + +/** + * exsltCryptoBin2Hex: + * @bin: binary blob to convert + * @binlen: length of binary blob + * @hex: buffer to store hex version of blob + * @hexlen: length of buffer to store hex version of blob + * + * Helper function which encodes a binary blob as hex. + */ +void exsltCryptoBin2Hex(const unsigned char* bin, int binlen, + unsigned char* hex, int hexlen) +{ + static const char bin2hex[] = { '0', '1', '2', '3', + '4', '5', '6', '7', + '8', '9', 'a', 'b', + 'c', 'd', 'e', 'f' }; + + unsigned char lo, hi; + int i, pos; + for (i = 0, pos = 0; (i < binlen && pos < hexlen); i++) + { + lo = bin[i] & 0xf; + hi = bin[i] >> 4; + hex[pos++] = bin2hex[hi]; + hex[pos++] = bin2hex[lo]; + } + + hex[pos] = '\0'; +} + +/** + * exsltCryptoHex2Bin: + * @hex: hex version of blob to convert + * @hexlen: length of hex buffer + * @bin: destination binary buffer + * @binlen: length of binary buffer + * + * Helper function which decodes a hex blob to binary + */ +int exsltCryptoHex2Bin(const unsigned char* hex, int hexlen, + unsigned char* bin, int binlen) +{ + int i = 0, j = 0; + unsigned char lo, hi, result, tmp; + + while (i<hexlen && j<binlen) + { + hi = lo = 0; + + tmp = hex[i++]; + if (tmp >= '0' && tmp <= '9') hi = tmp - '0'; + else if (tmp >= 'a' && tmp <= 'f') hi = 10 + (tmp - 'a'); + + tmp = hex[i++]; + if (tmp >= '0' && tmp <= '9') lo = tmp - '0'; + else if (tmp >= 'a' && tmp <= 'f') lo = 10 + (tmp - 'a'); + + result = hi << 4; + result += lo; + bin[j++] = result; + } + + return j; +} + +#if defined(WIN32) + +#define HAVE_CRYPTO +#define PLATFORM_HASH exsltCryptoCryptoApiHash +#define PLATFORM_RC4_ENCRYPT exsltCryptoCryptoApiRc4Encrypt +#define PLATFORM_RC4_DECRYPT exsltCryptoCryptoApiRc4Decrypt +#define PLATFORM_MD4 CALG_MD4 +#define PLATFORM_MD5 CALG_MD5 +#define PLATFORM_SHA1 CALG_SHA1 + +#include <windows.h> +#include <wincrypt.h> +#pragma comment(lib, "advapi32.lib") + +void exsltCryptoCryptoApiReportError(xmlXPathParserContextPtr ctxt, int line) +{ + LPVOID lpMsgBuf; + DWORD dw = GetLastError(); + + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR) &lpMsgBuf, 0, NULL ); + + xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, + "exslt:crypto error (line %d). %s", line, lpMsgBuf); + LocalFree(lpMsgBuf); +} + +HCRYPTHASH exsltCryptoCryptoApiCreateHash(xmlXPathParserContextPtr ctxt, + HCRYPTPROV hCryptProv, ALG_ID algorithm, + const char* msg, unsigned int msglen, + char* dest, unsigned int destlen) +{ + HCRYPTHASH hHash = 0; + DWORD dwHashLen = destlen; + + if (!CryptCreateHash(hCryptProv, algorithm, 0, 0, &hHash)) + { + exsltCryptoCryptoApiReportError(ctxt, __LINE__); + return 0; + } + + if(!CryptHashData(hHash, (const BYTE*)msg, msglen, 0)) + { + exsltCryptoCryptoApiReportError(ctxt, __LINE__); + goto fail; + } + + if (!CryptGetHashParam(hHash, HP_HASHVAL, dest, &dwHashLen, 0)) + { + exsltCryptoCryptoApiReportError(ctxt, __LINE__); + goto fail; + } + +fail: + return hHash; +} + +/** + * exsltCryptoCryptoApiHash: + * @ctxt: an XPath parser context + * @algorithm: hashing algorithm to use + * @msg: text to be hashed + * @msglen: length of text to be hashed + * @dest: buffer to place hash result + * + * Helper function which hashes a message using MD4, MD5, or SHA1. + * Uses Win32 CryptoAPI. + */ +void exsltCryptoCryptoApiHash(xmlXPathParserContextPtr ctxt, ALG_ID algorithm, + const char* msg, unsigned long msglen, char dest[HASH_DIGEST_LENGTH]) +{ + HCRYPTPROV hCryptProv; + HCRYPTHASH hHash; + + if(! CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, + CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) + { + exsltCryptoCryptoApiReportError(ctxt, __LINE__); + return; + } + + hHash = exsltCryptoCryptoApiCreateHash(ctxt, hCryptProv, + algorithm, msg, msglen, + dest, HASH_DIGEST_LENGTH); + if (0 != hHash) + { + CryptDestroyHash(hHash); + } + + CryptReleaseContext(hCryptProv, 0); +} + +void exsltCryptoCryptoApiRc4Encrypt(xmlXPathParserContextPtr ctxt, + const unsigned char* key, + const unsigned char* msg, int msglen, + unsigned char* dest, int destlen) +{ + HCRYPTPROV hCryptProv; + HCRYPTKEY hKey; + HCRYPTHASH hHash; + DWORD dwDataLen; + unsigned char hash[HASH_DIGEST_LENGTH]; + + if (msglen > destlen) + { + xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, + "exslt:crypto : internal error exsltCryptoCryptoApiRc4Encrypt dest buffer too small.\n"); + return; + } + + if(! CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, + CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) + { + exsltCryptoCryptoApiReportError(ctxt, __LINE__); + return; + } + + hHash = exsltCryptoCryptoApiCreateHash(ctxt, hCryptProv, + CALG_SHA1, key, RC4_KEY_LENGTH, + hash, HASH_DIGEST_LENGTH); + + if (!CryptDeriveKey(hCryptProv, CALG_RC4, hHash, 0x00800000, &hKey)) + { + exsltCryptoCryptoApiReportError(ctxt, __LINE__); + goto fail; + } + +// Now encrypt data. + dwDataLen = msglen; + memcpy(dest, msg, msglen); + if (!CryptEncrypt(hKey, 0, TRUE, 0, dest, &dwDataLen, msglen)) + { + exsltCryptoCryptoApiReportError(ctxt, __LINE__); + goto fail; + } + +fail: + if (0 != hHash) + { + CryptDestroyHash(hHash); + } + + CryptDestroyKey(hKey); + CryptReleaseContext(hCryptProv, 0); +} + +void exsltCryptoCryptoApiRc4Decrypt(xmlXPathParserContextPtr ctxt, + const unsigned char* key, + const unsigned char* msg, int msglen, + unsigned char* dest, int destlen) +{ + HCRYPTPROV hCryptProv; + HCRYPTKEY hKey; + HCRYPTHASH hHash; + DWORD dwDataLen; + unsigned char hash[HASH_DIGEST_LENGTH]; + + if (msglen > destlen) + { + xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, + "exslt:crypto : internal error exsltCryptoCryptoApiRc4Encrypt dest buffer too small.\n"); + return; + } + + if(! CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, + CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) + { + exsltCryptoCryptoApiReportError(ctxt, __LINE__); + return; + } + + hHash = exsltCryptoCryptoApiCreateHash(ctxt, hCryptProv, + CALG_SHA1, key, RC4_KEY_LENGTH, + hash, HASH_DIGEST_LENGTH); + + if (!CryptDeriveKey(hCryptProv, CALG_RC4, hHash, 0x00800000, &hKey)) + { + exsltCryptoCryptoApiReportError(ctxt, __LINE__); + goto fail; + } + +// Now encrypt data. + dwDataLen = msglen; + memcpy(dest, msg, msglen); + if (!CryptDecrypt(hKey, 0, TRUE, 0, dest, &dwDataLen)) + { + exsltCryptoCryptoApiReportError(ctxt, __LINE__); + goto fail; + } + +fail: + if (0 != hHash) + { + CryptDestroyHash(hHash); + } + + CryptDestroyKey(hKey); + CryptReleaseContext(hCryptProv, 0); +} + +#endif /* defined(WIN32) */ + +#if defined(HAVE_GCRYPT) + +#define HAVE_CRYPTO +#define PLATFORM_HASH exsltCryptoGcryptHash +#define PLATFORM_RC4_ENCRYPT exsltCryptoGcryptRc4Encrypt +#define PLATFORM_RC4_DECRYPT exsltCryptoGcryptRc4Decrypt +#define PLATFORM_MD4 GCRY_MD_MD4 +#define PLATFORM_MD5 GCRY_MD_MD5 +#define PLATFORM_SHA1 GCRY_MD_SHA1 + +#include <gcrypt.h> + +void exsltCryptoGcryptInit (void) +{ + static int gcrypt_init; + xmlLockLibrary(); + + if (! gcrypt_init) + { +/* The function `gcry_check_version' must be called before any other + function in the library, because it initializes the thread support + subsystem in Libgcrypt. To achieve this in all generality, it is + necessary to synchronize the call to this function with all other calls + to functions in the library, using the synchronization mechanisms + available in your thread library. (from gcrypt.info) +*/ + gcry_check_version(GCRYPT_VERSION); + gcrypt_init=1; + } + + xmlUnlockLibrary(); +} + +/** + * exsltCryptoGcryptHash: + * @ctxt: an XPath parser context + * @algorithm: hashing algorithm to use + * @msg: text to be hashed + * @msglen: length of text to be hashed + * @dest: buffer to place hash result + * + * Helper function which hashes a message using MD4, MD5, or SHA1. + * using gcrypt + */ +void exsltCryptoGcryptHash(xmlXPathParserContextPtr ctxt, enum gcry_md_algos algorithm, + const char* msg, unsigned long msglen, char dest[HASH_DIGEST_LENGTH]) +{ + exsltCryptoGcryptInit(); + gcry_md_hash_buffer(algorithm, dest, msg, msglen); +} + +void exsltCryptoGcryptRc4Encrypt(xmlXPathParserContextPtr ctxt, + const unsigned char* key, + const unsigned char* msg, int msglen, + unsigned char* dest, int destlen) +{ + gcry_cipher_hd_t cipher; + gcry_error_t rc = 0; + + exsltCryptoGcryptInit(); + + rc = gcry_cipher_open(&cipher, GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM, 0); + if (rc) + { + xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, + "exslt:crypto internal error %s (gcry_cipher_open)\n", + gcry_strerror(rc)); + } + + rc = gcry_cipher_setkey(cipher, key, RC4_KEY_LENGTH); + if (rc) + { + xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, + "exslt:crypto internal error %s (gcry_cipher_setkey)\n", + gcry_strerror(rc)); + } + + rc = gcry_cipher_encrypt(cipher, (unsigned char*)dest, destlen, + (const unsigned char*)msg, msglen); + if (rc) + { + xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, + "exslt:crypto internal error %s (gcry_cipher_encrypt)\n", + gcry_strerror(rc)); + } + + gcry_cipher_close(cipher); +} + +void exsltCryptoGcryptRc4Decrypt(xmlXPathParserContextPtr ctxt, + const unsigned char* key, + const unsigned char* msg, int msglen, + unsigned char* dest, int destlen) +{ + gcry_cipher_hd_t cipher; + gcry_error_t rc = 0; + + exsltCryptoGcryptInit(); + + rc = gcry_cipher_open(&cipher, GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM, 0); + if (rc) + { + xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, + "exslt:crypto internal error %s (gcry_cipher_open)\n", + gcry_strerror(rc)); + } + + rc = gcry_cipher_setkey(cipher, key, RC4_KEY_LENGTH); + if (rc) + { + xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, + "exslt:crypto internal error %s (gcry_cipher_setkey)\n", + gcry_strerror(rc)); + } + + rc = gcry_cipher_decrypt(cipher, (unsigned char*)dest, destlen, + (const unsigned char*)msg, msglen); + if (rc) + { + xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, + "exslt:crypto internal error %s (gcry_cipher_decrypt)\n", + gcry_strerror(rc)); + } + + gcry_cipher_close(cipher); +} + +#endif /* defined(HAVE_GCRYPT) */ + +#if defined(HAVE_CRYPTO) + +/** + * exsltCryptoPopString: + * @ctxt: an XPath parser context + * @nargs: the number of arguments + * + * Helper function which checks for and returns first string argument and its length + */ +static int +exsltCryptoPopString (xmlXPathParserContextPtr ctxt, int nargs, xmlChar **str) { + + int str_len = 0; + + if ((nargs < 1) || (nargs > 2)) { + xmlXPathSetArityError(ctxt); + return 0; + } + + *str = xmlXPathPopString(ctxt); + str_len = xmlUTF8Strlen(*str); + + if (str_len == 0) { + xmlXPathReturnEmptyString(ctxt); + xmlFree(*str); + return 0; + } + + return str_len; +} + +/** + * exsltCryptoMd4Function: + * @ctxt: an XPath parser context + * @nargs: the number of arguments + * + * computes the md4 hash of a string and returns as hex + */ +static void +exsltCryptoMd4Function (xmlXPathParserContextPtr ctxt, int nargs) { + + int str_len = 0; + xmlChar *str = NULL, *ret = NULL; + unsigned char hash[HASH_DIGEST_LENGTH]; + unsigned char hex[MD5_DIGEST_LENGTH*2+1]; + + str_len = exsltCryptoPopString(ctxt, nargs, &str); + if (str_len == 0) { + xmlXPathReturnEmptyString(ctxt); + xmlFree(str); + return; + } + + PLATFORM_HASH(ctxt, PLATFORM_MD4, str, str_len, hash); + exsltCryptoBin2Hex(hash, sizeof(hash)-1, hex, sizeof(hex)-1); + + ret = xmlStrdup((xmlChar *)hex); + xmlXPathReturnString(ctxt, ret); + + if (str != NULL) + xmlFree(str); +} + +/** + * exsltCryptoMd5Function: + * @ctxt: an XPath parser context + * @nargs: the number of arguments + * + * computes the md5 hash of a string and returns as hex + */ +static void +exsltCryptoMd5Function (xmlXPathParserContextPtr ctxt, int nargs) { + + int str_len = 0; + xmlChar *str = NULL, *ret = NULL; + unsigned char hash[HASH_DIGEST_LENGTH]; + unsigned char hex[MD5_DIGEST_LENGTH*2+1]; + + str_len = exsltCryptoPopString(ctxt, nargs, &str); + if (str_len == 0) { + xmlXPathReturnEmptyString(ctxt); + xmlFree(str); + return; + } + + PLATFORM_HASH(ctxt, PLATFORM_MD5, str, str_len, hash); + exsltCryptoBin2Hex(hash, sizeof(hash)-1, hex, sizeof(hex)-1); + + ret = xmlStrdup((xmlChar *)hex); + xmlXPathReturnString(ctxt, ret); + + if (str != NULL) + xmlFree(str); +} + +/** + * exsltCryptoSha1Function: + * @ctxt: an XPath parser context + * @nargs: the number of arguments + * + * computes the sha1 hash of a string and returns as hex + */ +static void +exsltCryptoSha1Function (xmlXPathParserContextPtr ctxt, int nargs) { + + int str_len = 0; + xmlChar *str = NULL, *ret = NULL; + unsigned char hash[HASH_DIGEST_LENGTH]; + unsigned char hex[SHA1_DIGEST_LENGTH*2+1]; + + str_len = exsltCryptoPopString(ctxt, nargs, &str); + if (str_len == 0) { + xmlXPathReturnEmptyString(ctxt); + xmlFree(str); + return; + } + + PLATFORM_HASH(ctxt, PLATFORM_SHA1, str, str_len, hash); + exsltCryptoBin2Hex(hash, sizeof(hash)-1, hex, sizeof(hex)-1); + + ret = xmlStrdup((xmlChar *)hex); + xmlXPathReturnString(ctxt, ret); + + if (str != NULL) + xmlFree(str); +} + +/** + * exsltCryptoRc4EncryptFunction: + * @ctxt: an XPath parser context + * @nargs: the number of arguments + * + * computes the sha1 hash of a string and returns as hex + */ +static void +exsltCryptoRc4EncryptFunction (xmlXPathParserContextPtr ctxt, int nargs) { + + int key_len = 0, key_size = 0; + int str_len = 0, bin_len = 0, hex_len = 0; + xmlChar *key = NULL, *str = NULL, *padkey = NULL; + xmlChar *bin = NULL, *hex = NULL; + + if ((nargs < 1) || (nargs > 3)) { + xmlXPathSetArityError(ctxt); + return; + } + + str = xmlXPathPopString(ctxt); + str_len = xmlUTF8Strlen(str); + + if (str_len == 0) { + xmlXPathReturnEmptyString(ctxt); + xmlFree(str); + return; + } + + key = xmlXPathPopString(ctxt); + key_len = xmlUTF8Strlen(str); + + if (key_len == 0) { + xmlXPathReturnEmptyString(ctxt); + xmlFree(key); + xmlFree(str); + return; + } + + padkey = xmlMallocAtomic(RC4_KEY_LENGTH); + key_size = xmlUTF8Strsize(key, key_len); + memcpy(padkey, key, key_size); + memset(padkey+key_size, '\0', sizeof(padkey)); + +/* encrypt it */ + bin_len = str_len; + bin = xmlStrdup(str); + PLATFORM_RC4_ENCRYPT(ctxt, padkey, str, str_len, bin, bin_len); + +/* encode it */ + hex_len = str_len*2+1; + hex = xmlMallocAtomic(hex_len); + + exsltCryptoBin2Hex(bin, str_len, hex, hex_len); + xmlXPathReturnString(ctxt, hex); + + if (key != NULL) + xmlFree(key); + if (str != NULL) + xmlFree(str); + if (padkey != NULL) + xmlFree(padkey); + if (bin != NULL) + xmlFree(bin); +} + +/** + * exsltCryptoRc4DecryptFunction: + * @ctxt: an XPath parser context + * @nargs: the number of arguments + * + * computes the sha1 hash of a string and returns as hex + */ +static void +exsltCryptoRc4DecryptFunction (xmlXPathParserContextPtr ctxt, int nargs) { + + int key_len = 0, key_size = 0; + int str_len = 0, bin_len = 0, ret_len = 0; + xmlChar *key = NULL, *str = NULL, *padkey = NULL, *bin = NULL, *ret = NULL; + + if ((nargs < 1) || (nargs > 3)) { + xmlXPathSetArityError(ctxt); + return; + } + + str = xmlXPathPopString(ctxt); + str_len = xmlUTF8Strlen(str); + + if (str_len == 0) { + xmlXPathReturnEmptyString(ctxt); + xmlFree(str); + return; + } + + key = xmlXPathPopString(ctxt); + key_len = xmlUTF8Strlen(str); + + if (key_len == 0) { + xmlXPathReturnEmptyString(ctxt); + xmlFree(key); + xmlFree(str); + return; + } + + padkey = xmlMallocAtomic(RC4_KEY_LENGTH); + key_size = xmlUTF8Strsize(key, key_len); + memcpy(padkey, key, key_size); + memset(padkey+key_size, '\0', sizeof(padkey)); + +/* decode hex to binary */ + bin_len = str_len; + bin = xmlMallocAtomic(bin_len); + ret_len = exsltCryptoHex2Bin(str, str_len, bin, bin_len); + +/* decrypt the binary blob */ + ret = xmlMallocAtomic(ret_len); + PLATFORM_RC4_DECRYPT(ctxt, padkey, bin, ret_len, ret, ret_len); + + xmlXPathReturnString(ctxt, ret); + + if (key != NULL) + xmlFree(key); + if (str != NULL) + xmlFree(str); + if (padkey != NULL) + xmlFree(padkey); + if (bin != NULL) + xmlFree(bin); +} + +/** + * exsltCryptoRegister: + * + * Registers the EXSLT - Crypto module + */ + +void +exsltCryptoRegister (void) { + xsltRegisterExtModuleFunction ((const xmlChar *) "md4", + EXSLT_CRYPTO_NAMESPACE, + exsltCryptoMd4Function); + xsltRegisterExtModuleFunction ((const xmlChar *) "md5", + EXSLT_CRYPTO_NAMESPACE, + exsltCryptoMd5Function); + xsltRegisterExtModuleFunction ((const xmlChar *) "sha1", + EXSLT_CRYPTO_NAMESPACE, + exsltCryptoSha1Function); + xsltRegisterExtModuleFunction ((const xmlChar *) "rc4_encrypt", + EXSLT_CRYPTO_NAMESPACE, + exsltCryptoRc4EncryptFunction); + xsltRegisterExtModuleFunction ((const xmlChar *) "rc4_decrypt", + EXSLT_CRYPTO_NAMESPACE, + exsltCryptoRc4DecryptFunction); +} + +#else +void exsltCryptoRegister (void) { } + +#endif /* defined(HAVE_CRYPTO) */ diff --git a/libexslt/exslt.c b/libexslt/exslt.c index 6f419135..9b6a6ac1 100644 --- a/libexslt/exslt.c +++ b/libexslt/exslt.c @@ -32,6 +32,7 @@ const int exsltLibxmlVersion = LIBXML_VERSION; void exsltRegisterAll (void) { exsltCommonRegister(); + exsltCryptoRegister(); exsltMathRegister(); exsltSetsRegister(); exsltFuncRegister(); diff --git a/libexslt/exslt.h b/libexslt/exslt.h index dca38233..9cdaaa02 100644 --- a/libexslt/exslt.h +++ b/libexslt/exslt.h @@ -22,6 +22,12 @@ EXSLTPUBVAR const int exsltLibxmlVersion; */ #define EXSLT_COMMON_NAMESPACE ((const xmlChar *) "http://exslt.org/common") /** + * EXSLT_CRYPTO_NAMESPACE: + * + * Namespace for EXSLT crypto functions + */ +#define EXSLT_CRYPTO_NAMESPACE ((const xmlChar *) "http://exslt.org/crypto") +/** * EXSLT_MATH_NAMESPACE: * * Namespace for EXSLT math functions @@ -66,6 +72,7 @@ EXSLTPUBVAR const int exsltLibxmlVersion; #define SAXON_NAMESPACE ((const xmlChar *) "http://icl.com/saxon") EXSLTPUBFUN void EXSLTCALL exsltCommonRegister (void); +EXSLTPUBFUN void EXSLTCALL exsltCryptoRegister (void); EXSLTPUBFUN void EXSLTCALL exsltMathRegister (void); EXSLTPUBFUN void EXSLTCALL exsltSetsRegister (void); EXSLTPUBFUN void EXSLTCALL exsltFuncRegister (void); diff --git a/tests/namespaces/Makefile.am b/tests/namespaces/Makefile.am index 229e0a11..52fa03db 100644 --- a/tests/namespaces/Makefile.am +++ b/tests/namespaces/Makefile.am @@ -10,8 +10,8 @@ EXTRA_DIST = \ tst2.xml tst2.xsl tst2.out \ tst3.xml tst3.xsl tst3.out \ tst4.xml tst4.xsl tst4.out \ -# tst5.xml tst5.xsl tst5.out tst6.xml tst6.xsl tst6.out +# tst5.xml tst5.xsl tst5.out all: diff --git a/win32/Makefile.mingw b/win32/Makefile.mingw index e2353cda..4d4fde0b 100644 --- a/win32/Makefile.mingw +++ b/win32/Makefile.mingw @@ -111,6 +111,7 @@ XSLT_OBJS_A = $(XSLT_INTDIR_A)/attributes.o\ # Libexslt object files. EXSLT_OBJS = $(EXSLT_INTDIR)/common.o\ + $(EXSLT_INTDIR)/crypto.o\ $(EXSLT_INTDIR)/date.o\ $(EXSLT_INTDIR)/exslt.o\ $(EXSLT_INTDIR)/functions.o\ @@ -123,6 +124,7 @@ EXSLT_SRCS = $(subst .o,.c,$(subst $(EXSLT_INTDIR)/,$(EXSLT_SRCDIR)/,$(EXSLT_OBJ # Static libexslt object files. EXSLT_OBJS_A = $(EXSLT_INTDIR_A)/common.o\ + $(EXSLT_INTDIR_A)/crypto.o\ $(EXSLT_INTDIR_A)/date.o\ $(EXSLT_INTDIR_A)/exslt.o\ $(EXSLT_INTDIR_A)/functions.o\ diff --git a/win32/Makefile.msvc b/win32/Makefile.msvc index 638df4aa..cf40a8b3 100644 --- a/win32/Makefile.msvc +++ b/win32/Makefile.msvc @@ -115,6 +115,7 @@ XSLT_OBJS_A = $(XSLT_INTDIR_A)\attributes.obj\ # Libexslt object files. EXSLT_OBJS = $(EXSLT_INTDIR)\common.obj\ + $(EXSLT_INTDIR)\crypto.obj\ $(EXSLT_INTDIR)\date.obj\ $(EXSLT_INTDIR)\exslt.obj\ $(EXSLT_INTDIR)\functions.obj\ @@ -126,6 +127,7 @@ EXSLT_OBJS = $(EXSLT_INTDIR)\common.obj\ # Static libexslt object files. EXSLT_OBJS_A = $(EXSLT_INTDIR_A)\common.obj\ + $(EXSLT_INTDIR_A)\crypto.obj\ $(EXSLT_INTDIR_A)\date.obj\ $(EXSLT_INTDIR_A)\exslt.obj\ $(EXSLT_INTDIR_A)\functions.obj\ diff --git a/xsltproc/Makefile.am b/xsltproc/Makefile.am index a8828de5..44210c89 100644 --- a/xsltproc/Makefile.am +++ b/xsltproc/Makefile.am @@ -5,10 +5,12 @@ INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/libxslt -I$(top_srcdir)/libexslt \ EXTRA_PROGRAMS= bin_PROGRAMS = xsltproc $(XSLTPROCDV) +AM_CFLAGS = $(LIBGCRYPT_CFLAGS) + xsltproc_SOURCES = xsltproc.c -xsltproc_LDFLAGS = +xsltproc_LDFLAGS = xsltproc_DEPENDENCIES = $(DEPS) -xsltproc_LDADD = $(LDADDS) +xsltproc_LDADD = $(LDADDS) $(LIBGCRYPT_LIBS) DEPS = $(top_builddir)/libxslt/libxslt.la \ $(top_builddir)/libexslt/libexslt.la |