applied patch from Joel Reed to get EXSLT crypto extensions based on
authorDaniel Veillard <veillard@src.gnome.org>
Wed, 30 Jun 2004 16:43:53 +0000 (16:43 +0000)
committerDaniel Veillard <veillard@src.gnome.org>
Wed, 30 Jun 2004 16:43:53 +0000 (16:43 +0000)
* 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

ChangeLog
config.h.in
configure.in
libexslt/Makefile.am
libexslt/crypto.c [new file with mode: 0644]
libexslt/exslt.c
libexslt/exslt.h
tests/namespaces/Makefile.am
win32/Makefile.mingw
win32/Makefile.msvc
xsltproc/Makefile.am

index 52ba365..995535a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
index 3388df5..1f36e2c 100644 (file)
@@ -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
 
index 5395eba..770cf3c 100644 (file)
@@ -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)
index ac54099..50fe8af 100644 (file)
@@ -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 (file)
index 0000000..218e38a
--- /dev/null
@@ -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) */
index 6f41913..9b6a6ac 100644 (file)
@@ -32,6 +32,7 @@ const int exsltLibxmlVersion = LIBXML_VERSION;
 void
 exsltRegisterAll (void) {
     exsltCommonRegister();
+    exsltCryptoRegister();
     exsltMathRegister();
     exsltSetsRegister();
     exsltFuncRegister();
index dca3823..9cdaaa0 100644 (file)
@@ -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);
index 229e0a1..52fa03d 100644 (file)
@@ -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:
 
index e2353cd..4d4fde0 100644 (file)
@@ -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\
index 638df4a..cf40a8b 100644 (file)
@@ -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\
index a8828de..44210c8 100644 (file)
@@ -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